1 #define AZT_VERSION "2.60"
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
6 Copyright (C) 1994-98 Werner Zimmermann(Werner.Zimmermann@fht-esslingen.de)
8 based on Mitsumi CDROM driver by Martin Hariss and preworks by
9 Eberhard Moenkeberg; contains contributions by Joe Nardone and Robby
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)
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.
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.
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
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
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
61 Speeded up drive recognition during init (will be a little bit
62 slower than before if no drive is installed!); suggested by
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
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
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
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
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.
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-
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
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
163 #include <linux/version.h>
165 #define MAJOR_NR AZTECH_CDROM_MAJOR
167 #include <linux/blk.h>
170 #include <linux/module.h>
171 #include <linux/errno.h>
172 #include <linux/sched.h>
173 #include <linux/mm.h>
174 #include <linux/timer.h>
175 #include <linux/fs.h>
176 #include <linux/kernel.h>
177 #include <linux/cdrom.h>
178 #include <linux/ioport.h>
179 #include <linux/string.h>
180 #include <linux/major.h>
182 #ifndef AZT_KERNEL_PRIOR_2_1
183 #include <linux/init.h>
186 #include <asm/system.h>
189 #ifdef AZT_KERNEL_PRIOR_2_1
190 #include <asm/segment.h>
192 #include <asm/uaccess.h>
193 static int aztcd_blocksizes
[1] = {2048};
197 /*###########################################################################
199 ###########################################################################
201 #define SET_TIMER(func, jifs) delay_timer.expires = jiffies + (jifs); \
202 delay_timer.function = (void *) (func); \
203 add_timer(&delay_timer);
205 #define CLEAR_TIMER del_timer(&delay_timer);
207 #define RETURNM(message,value) {printk("aztcd: Warning: %s failed\n",message);\
209 #define RETURN(message) {printk("aztcd: Warning: %s failed\n",message);\
212 /* Macros to switch the IDE-interface to the slave device and back to the master*/
213 #define SWITCH_IDE_SLAVE outb_p(0xa0,azt_port+6); \
214 outb_p(0x10,azt_port+6); \
215 outb_p(0x00,azt_port+7); \
216 outb_p(0x10,azt_port+6);
217 #define SWITCH_IDE_MASTER outb_p(0xa0,azt_port+6);
222 #define AZT_TEST1 /* <int-..> */
223 #define AZT_TEST2 /* do_aztcd_request */
224 #define AZT_TEST3 /* AZT_S_state */
225 #define AZT_TEST4 /* QUICK_LOOP-counter */
226 #define AZT_TEST5 /* port(1) state */
228 #define AZT_DEBUG_MULTISESSION
231 #define CURRENT_VALID \
232 (CURRENT && MAJOR(CURRENT -> rq_dev) == MAJOR_NR && CURRENT -> cmd == READ \
233 && CURRENT -> sector != -1)
235 #define AFL_STATUSorDATA (AFL_STATUS | AFL_DATA)
236 #define AZT_BUF_SIZ 16
238 #define READ_TIMEOUT 3000
240 #define azt_port aztcd /*needed for the modutils*/
242 #ifndef AZT_KERNEL_PRIOR_2_1
243 #define memcpy_fromfs copy_from_user
244 #define memcpy_tofs copy_to_user
247 /*##########################################################################
249 ##########################################################################
252 { AZT_S_IDLE
, /* 0 */
258 AZT_S_STOPPING
/* 6 */
261 { AZT_MODE_0
, /*read mode for audio disks, not supported by Aztech firmware*/
262 AZT_MODE_1
, /*read mode for normal CD-ROMs*/
263 AZT_MODE_2
/*read mode for XA CD-ROMs*/
266 /*##########################################################################
268 ##########################################################################
270 static int aztPresent
= 0;
272 static volatile int azt_transfer_is_active
=0;
274 static char azt_buf
[CD_FRAMESIZE_RAW
*AZT_BUF_SIZ
];/*buffer for block size conversion*/
275 #if AZT_PRIVATE_IOCTLS
276 static char buf
[CD_FRAMESIZE_RAW
]; /*separate buffer for the ioctls*/
279 static volatile int azt_buf_bn
[AZT_BUF_SIZ
], azt_next_bn
;
280 static volatile int azt_buf_in
, azt_buf_out
= -1;
281 static volatile int azt_error
=0;
282 static int azt_open_count
=0;
283 static volatile enum azt_state_e azt_state
= AZT_S_IDLE
;
285 static volatile enum azt_state_e azt_state_old
= AZT_S_STOP
;
286 static volatile int azt_st_old
= 0;
288 static volatile enum azt_read_modes azt_read_mode
= AZT_MODE_1
;
290 static int azt_mode
= -1;
291 static volatile int azt_read_count
= 1;
293 static int azt_port
= AZT_BASE_ADDR
;
295 #ifndef AZT_KERNEL_PRIOR_2_1
296 MODULE_PARM(azt_port
, "i");
299 static int azt_port_auto
[16] = AZT_BASE_AUTO
;
301 static char azt_cont
= 0;
302 static char azt_init_end
= 0;
303 static char azt_auto_eject
= AZT_AUTO_EJECT
;
305 static int AztTimeout
, AztTries
;
306 static struct wait_queue
*azt_waitq
= NULL
;
307 static struct timer_list delay_timer
= { NULL
, NULL
, 0, 0, NULL
};
309 static struct azt_DiskInfo DiskInfo
;
310 static struct azt_Toc Toc
[MAX_TRACKS
];
311 static struct azt_Play_msf azt_Play
;
313 static int aztAudioStatus
= CDROM_AUDIO_NO_STATUS
;
314 static char aztDiskChanged
= 1;
315 static char aztTocUpToDate
= 0;
317 static unsigned char aztIndatum
;
318 static unsigned long aztTimeOutCount
;
319 static int aztCmd
= 0;
321 /*###########################################################################
323 ###########################################################################
325 /* CDROM Drive Low Level I/O Functions */
330 void statusAzt(void);
331 static void aztStatTimer(void);
333 /* CDROM Drive Command Functions */
334 static int aztSendCmd(int cmd
);
335 static int sendAztCmd(int cmd
, struct azt_Play_msf
*params
);
336 static int aztSeek(struct azt_Play_msf
*params
);
337 static int aztSetDiskType(int type
);
338 static int aztStatus(void);
339 static int getAztStatus(void);
340 static int aztPlay(struct azt_Play_msf
*arg
);
341 static void aztCloseDoor(void);
342 static void aztLockDoor(void);
343 static void aztUnlockDoor(void);
344 static int aztGetValue(unsigned char *result
);
345 static int aztGetQChannelInfo(struct azt_Toc
*qp
);
346 static int aztUpdateToc(void);
347 static int aztGetDiskInfo(void);
349 static int aztGetMultiDiskInfo(void);
351 static int aztGetToc(int multi
);
353 /* Kernel Interface Functions */
354 void aztcd_setup(char *str
, int *ints
);
355 static int check_aztcd_media_change(kdev_t full_dev
);
356 static int aztcd_ioctl(struct inode
*ip
, struct file
*fp
, unsigned int cmd
, unsigned long arg
);
357 static void azt_transfer(void);
358 static void do_aztcd_request(void);
359 static void azt_invalidate_buffers(void);
360 int aztcd_open(struct inode
*ip
, struct file
*fp
);
362 #ifdef AZT_KERNEL_PRIOR_2_1
363 static void aztcd_release(struct inode
* inode
, struct file
* file
);
365 static int aztcd_release(struct inode
* inode
, struct file
* file
);
368 int aztcd_init(void);
370 int init_module(void);
371 void cleanup_module(void);
373 static struct file_operations azt_fops
= {
374 NULL
, /* lseek - default */
375 block_read
, /* read - general block-dev read */
376 block_write
, /* write - general block-dev write */
377 NULL
, /* readdir - bad */
379 aztcd_ioctl
, /* ioctl */
381 aztcd_open
, /* open */
383 aztcd_release
, /* release */
386 check_aztcd_media_change
, /*media change*/
390 /* Aztcd State Machine: Controls Drive Operating State */
391 static void azt_poll(void);
393 /* Miscellaneous support functions */
394 static void azt_hsg2msf(long hsg
, struct msf
*msf
);
395 static long azt_msf2hsg(struct msf
*mp
);
396 static void azt_bin2bcd(unsigned char *p
);
397 static int azt_bcd2bin(unsigned char bcd
);
399 /*##########################################################################
400 CDROM Drive Low Level I/O Functions
401 ##########################################################################
403 /* Macros for the drive hardware interface handshake, these macros use
405 /* Wait for OP_OK = drive answers with AFL_OP_OK after receiving a command*/
406 # define OP_OK op_ok()
409 do { aztIndatum
=inb(DATA_PORT
);
411 if (aztTimeOutCount
>=AZT_TIMEOUT
)
412 { printk("aztcd: Error Wait OP_OK\n");
415 } while (aztIndatum
!=AFL_OP_OK
);
418 /* Wait for PA_OK = drive answers with AFL_PA_OK after receiving parameters*/
419 # define PA_OK pa_ok()
422 do { aztIndatum
=inb(DATA_PORT
);
424 if (aztTimeOutCount
>=AZT_TIMEOUT
)
425 { printk("aztcd: Error Wait PA_OK\n");
428 } while (aztIndatum
!=AFL_PA_OK
);
431 /* Wait for STEN=Low = handshake signal 'AFL_.._OK available or command executed*/
432 # define STEN_LOW sten_low()
435 do { aztIndatum
=inb(STATUS_PORT
);
437 if (aztTimeOutCount
>=AZT_TIMEOUT
)
438 { if (azt_init_end
) printk("aztcd: Error Wait STEN_LOW commands:%x\n",aztCmd
);
441 } while (aztIndatum
&AFL_STATUS
);
444 /* Wait for DTEN=Low = handshake signal 'Data available'*/
445 # define DTEN_LOW dten_low()
448 do { aztIndatum
=inb(STATUS_PORT
);
450 if (aztTimeOutCount
>=AZT_TIMEOUT
)
451 { printk("aztcd: Error Wait DTEN_OK\n");
454 } while (aztIndatum
&AFL_DATA
);
458 * Macro for timer wait on STEN=Low, should only be used for 'slow' commands;
459 * may cause kernel panic when used in the wrong place
461 #define STEN_LOW_WAIT statusAzt()
463 { AztTimeout
= AZT_STATUS_DELAY
;
464 SET_TIMER(aztStatTimer
, HZ
/100);
465 sleep_on(&azt_waitq
);
466 if (AztTimeout
<= 0) printk("aztcd: Error Wait STEN_LOW_WAIT command:%x\n",aztCmd
);
470 static void aztStatTimer(void)
471 { if (!(inb(STATUS_PORT
) & AFL_STATUS
))
472 { wake_up(&azt_waitq
);
477 { wake_up(&azt_waitq
);
478 printk("aztcd: Error aztStatTimer: Timeout\n");
481 SET_TIMER(aztStatTimer
, HZ
/100);
484 /*##########################################################################
485 CDROM Drive Command Functions
486 ##########################################################################
489 * Send a single command, return -1 on error, else 0
491 static int aztSendCmd(int cmd
)
492 { unsigned char data
;
496 printk("aztcd: Executing command %x\n",cmd
);
499 if ((azt_port
==0x1f0)||(azt_port
==0x170))
500 SWITCH_IDE_SLAVE
; /*switch IDE interface to slave configuration*/
503 outb(POLLED
,MODE_PORT
);
504 do { if (inb(STATUS_PORT
)&AFL_STATUS
) break;
505 inb(DATA_PORT
); /* if status left from last command, read and */
506 } while (1); /* discard it */
507 do { if (inb(STATUS_PORT
)&AFL_DATA
) break;
508 inb(DATA_PORT
); /* if data left from last command, read and */
509 } while (1); /* discard it */
510 for (retry
=0;retry
<AZT_RETRY_ATTEMPTS
;retry
++)
511 { outb((unsigned char) cmd
,CMD_PORT
);
515 { return 0;} /*OP_OK?*/
516 if (data
==AFL_OP_ERR
)
519 printk("### Error 1 aztcd: aztSendCmd %x Error Code %x\n",cmd
,data
);
522 if (retry
>=AZT_RETRY_ATTEMPTS
)
523 { printk("### Error 2 aztcd: aztSendCmd %x \n",cmd
);
526 RETURNM("aztSendCmd",-1);
530 * Send a play or read command to the drive, return -1 on error, else 0
532 static int sendAztCmd(int cmd
, struct azt_Play_msf
*params
)
533 { unsigned char data
;
537 printk("aztcd: play start=%02x:%02x:%02x end=%02x:%02x:%02x\n", \
538 params
->start
.min
, params
->start
.sec
, params
->start
.frame
, \
539 params
->end
.min
, params
->end
.sec
, params
->end
.frame
);
541 for (retry
=0;retry
<AZT_RETRY_ATTEMPTS
;retry
++)
543 outb(params
-> start
.min
,CMD_PORT
);
544 outb(params
-> start
.sec
,CMD_PORT
);
545 outb(params
-> start
.frame
,CMD_PORT
);
546 outb(params
-> end
.min
,CMD_PORT
);
547 outb(params
-> end
.sec
,CMD_PORT
);
548 outb(params
-> end
.frame
,CMD_PORT
);
552 { return 0;} /*PA_OK ?*/
553 if (data
==AFL_PA_ERR
)
556 printk("### Error 1 aztcd: sendAztCmd %x Error Code %x\n",cmd
,data
);
559 if (retry
>=AZT_RETRY_ATTEMPTS
)
560 { printk("### Error 2 aztcd: sendAztCmd %x\n ",cmd
);
563 RETURNM("sendAztCmd",-1);
567 * Send a seek command to the drive, return -1 on error, else 0
569 static int aztSeek(struct azt_Play_msf
*params
)
570 { unsigned char data
;
574 printk("aztcd: aztSeek %02x:%02x:%02x\n", \
575 params
->start
.min
, params
->start
.sec
, params
->start
.frame
);
577 for (retry
=0;retry
<AZT_RETRY_ATTEMPTS
;retry
++)
578 { aztSendCmd(ACMD_SEEK
);
579 outb(params
-> start
.min
,CMD_PORT
);
580 outb(params
-> start
.sec
,CMD_PORT
);
581 outb(params
-> start
.frame
,CMD_PORT
);
585 { return 0;} /*PA_OK ?*/
586 if (data
==AFL_PA_ERR
)
589 printk("### Error 1 aztcd: aztSeek\n");
592 if (retry
>=AZT_RETRY_ATTEMPTS
)
593 { printk("### Error 2 aztcd: aztSeek\n ");
596 RETURNM("aztSeek",-1);
599 /* Send a Set Disk Type command
600 does not seem to work with Aztech drives, behavior is completely indepen-
601 dent on which mode is set ???
603 static int aztSetDiskType(int type
)
604 { unsigned char data
;
608 printk("aztcd: set disk type command: type= %i\n",type
);
610 for (retry
=0;retry
<AZT_RETRY_ATTEMPTS
;retry
++)
611 { aztSendCmd(ACMD_SET_DISK_TYPE
);
615 if (data
==AFL_PA_OK
) /*PA_OK ?*/
616 { azt_read_mode
=type
;
619 if (data
==AFL_PA_ERR
)
622 printk("### Error 1 aztcd: aztSetDiskType %x Error Code %x\n",type
,data
);
625 if (retry
>=AZT_RETRY_ATTEMPTS
)
626 { printk("### Error 2 aztcd: aztSetDiskType %x\n ",type
);
629 RETURNM("aztSetDiskType",-1);
633 /* used in azt_poll to poll the status, expects another program to issue a
634 * ACMD_GET_STATUS directly before
636 static int aztStatus(void)
640 i = inb(STATUS_PORT) & AFL_STATUS; is STEN=0? ???
643 if (aztTimeOutCount
<AZT_TIMEOUT
)
644 { st
= inb(DATA_PORT
) & 0xFF;
648 RETURNM("aztStatus",-1);
652 * Get the drive status
654 static int getAztStatus(void)
657 if (aztSendCmd(ACMD_GET_STATUS
)) RETURNM("getAztStatus 1",-1);
659 st
= inb(DATA_PORT
) & 0xFF;
661 printk("aztcd: Status = %x\n",st
);
663 if ((st
== 0xFF)||(st
&AST_CMD_CHECK
))
664 { printk("aztcd: AST_CMD_CHECK error or no status available\n");
668 if (((st
&AST_MODE_BITS
)!=AST_BUSY
) && (aztAudioStatus
== CDROM_AUDIO_PLAY
))
669 /* XXX might be an error? look at q-channel? */
670 aztAudioStatus
= CDROM_AUDIO_COMPLETED
;
672 if ((st
& AST_DSK_CHG
)||(st
& AST_NOT_READY
))
673 { aztDiskChanged
= 1;
675 aztAudioStatus
= CDROM_AUDIO_NO_STATUS
;
682 * Send a 'Play' command and get the status. Use only from the top half.
684 static int aztPlay(struct azt_Play_msf
*arg
)
685 { if (sendAztCmd(ACMD_PLAY_AUDIO
, arg
) < 0) RETURNM("aztPlay",-1);
690 * Subroutines to automatically close the door (tray) and
691 * lock it closed when the cd is mounted. Leave the tray
692 * locking as an option
694 static void aztCloseDoor(void)
696 aztSendCmd(ACMD_CLOSE
);
701 static void aztLockDoor(void)
703 #if AZT_ALLOW_TRAY_LOCK
704 aztSendCmd(ACMD_LOCK
);
710 static void aztUnlockDoor(void)
712 #if AZT_ALLOW_TRAY_LOCK
713 aztSendCmd(ACMD_UNLOCK
);
720 * Read a value from the drive. Should return quickly, so a busy wait
721 * is used to avoid excessive rescheduling. The read command itself must
722 * be issued with aztSendCmd() directly before
724 static int aztGetValue(unsigned char *result
)
728 if (aztTimeOutCount
>=AZT_TIMEOUT
)
729 { printk("aztcd: aztGetValue timeout\n");
732 s
= inb(DATA_PORT
) & 0xFF;
733 *result
= (unsigned char) s
;
738 * Read the current Q-channel info. Also used for reading the
741 int aztGetQChannelInfo(struct azt_Toc
*qp
)
742 { unsigned char notUsed
;
746 printk("aztcd: starting aztGetQChannelInfo Time:%li\n",jiffies
);
748 if ((st
=getAztStatus())==-1) RETURNM("aztGetQChannelInfo 1",-1);
749 if (aztSendCmd(ACMD_GET_Q_CHANNEL
)) RETURNM("aztGetQChannelInfo 2",-1);
750 /*STEN_LOW_WAIT; ??? Dosemu0.60's cdrom.c does not like STEN_LOW_WAIT here*/
751 if (aztGetValue(¬Used
)) RETURNM("aztGetQChannelInfo 3",-1); /*??? Nullbyte einlesen*/
752 if ((st
&AST_MODE_BITS
)==AST_INITIAL
)
753 { qp
->ctrl_addr
=0; /* when audio stop ACMD_GET_Q_CHANNEL returns */
754 qp
->track
=0; /* only one byte with Aztech drives */
758 qp
->trackTime
.frame
=0;
761 qp
->diskTime
.frame
=0;
765 { if (aztGetValue(&qp
-> ctrl_addr
) < 0) RETURNM("aztGetQChannelInfo 4",-1);
766 if (aztGetValue(&qp
-> track
) < 0) RETURNM("aztGetQChannelInfo 4",-1);
767 if (aztGetValue(&qp
-> pointIndex
) < 0) RETURNM("aztGetQChannelInfo 4",-1);
768 if (aztGetValue(&qp
-> trackTime
.min
) < 0) RETURNM("aztGetQChannelInfo 4",-1);
769 if (aztGetValue(&qp
-> trackTime
.sec
) < 0) RETURNM("aztGetQChannelInfo 4",-1);
770 if (aztGetValue(&qp
-> trackTime
.frame
) < 0) RETURNM("aztGetQChannelInfo 4",-1);
771 if (aztGetValue(¬Used
) < 0) RETURNM("aztGetQChannelInfo 4",-1);
772 if (aztGetValue(&qp
-> diskTime
.min
) < 0) RETURNM("aztGetQChannelInfo 4",-1);
773 if (aztGetValue(&qp
-> diskTime
.sec
) < 0) RETURNM("aztGetQChannelInfo 4",-1);
774 if (aztGetValue(&qp
-> diskTime
.frame
) < 0) RETURNM("aztGetQChannelInfo 4",-1);
777 printk("aztcd: exiting aztGetQChannelInfo Time:%li\n",jiffies
);
783 * Read the table of contents (TOC) and TOC header if necessary
785 static int aztUpdateToc()
789 printk("aztcd: starting aztUpdateToc Time:%li\n",jiffies
);
794 if (aztGetDiskInfo() < 0)
797 if (aztGetToc(0) < 0)
800 /*audio disk detection
801 with my Aztech drive there is no audio status bit, so I use the copy
802 protection bit of the first track. If this track is copy protected
803 (copy bit = 0), I assume, it's an audio disk. Strange, but works ??? */
804 if (!(Toc
[DiskInfo
.first
].ctrl_addr
& 0x40))
810 if (! DiskInfo
.audio
)
811 { azt_Play
.start
.min
= 0; /*XA detection only seems to work*/
812 azt_Play
.start
.sec
= 2; /*when we play a track*/
813 azt_Play
.start
.frame
= 0;
814 azt_Play
.end
.min
= 0;
815 azt_Play
.end
.sec
= 0;
816 azt_Play
.end
.frame
= 1;
817 if (sendAztCmd(ACMD_PLAY_READ
, &azt_Play
)) return -1;
819 for (st
=0;st
<CD_FRAMESIZE
;st
++) inb(DATA_PORT
);
821 DiskInfo
.xa
= getAztStatus() & AST_MODE
;
823 { printk("aztcd: XA support experimental - mail results to Werner.Zimmermann@fht-esslingen.de\n");
826 /*multisession detection
827 support for multisession CDs is done automatically with Aztech drives,
828 we don't have to take care about TOC redirection; if we want the isofs
829 to take care about redirection, we have to set AZT_MULTISESSION to 1*/
833 { aztGetMultiDiskInfo(); /*here Disk.Info.multi is set*/
837 { DiskInfo
.lastSession
.min
= Toc
[DiskInfo
.next
].diskTime
.min
;
838 DiskInfo
.lastSession
.sec
= Toc
[DiskInfo
.next
].diskTime
.sec
;
839 DiskInfo
.lastSession
.frame
= Toc
[DiskInfo
.next
].diskTime
.frame
;
840 printk("aztcd: Multisession support experimental\n");
843 { DiskInfo
.lastSession
.min
= Toc
[DiskInfo
.first
].diskTime
.min
;
844 DiskInfo
.lastSession
.sec
= Toc
[DiskInfo
.first
].diskTime
.sec
;
845 DiskInfo
.lastSession
.frame
= Toc
[DiskInfo
.first
].diskTime
.frame
;
850 printk("aztcd: exiting aztUpdateToc Time:%li\n",jiffies
);
856 /* Read the table of contents header, i.e. no. of tracks and start of first
859 static int aztGetDiskInfo()
862 struct azt_Toc qInfo
;
865 printk("aztcd: starting aztGetDiskInfo Time:%li\n",jiffies
);
867 if (aztSendCmd(ACMD_SEEK_TO_LEADIN
)) RETURNM("aztGetDiskInfo 1",-1);
870 for (limit
=300;limit
>0;limit
--)
871 { if (aztGetQChannelInfo(&qInfo
)<0) RETURNM("aztGetDiskInfo 2",-1);
872 if (qInfo
.pointIndex
==0xA0) /*Number of FirstTrack*/
873 { DiskInfo
.first
= qInfo
.diskTime
.min
;
874 DiskInfo
.first
= azt_bcd2bin(DiskInfo
.first
);
877 if (qInfo
.pointIndex
==0xA1) /*Number of LastTrack*/
878 { DiskInfo
.last
= qInfo
.diskTime
.min
;
879 DiskInfo
.last
= azt_bcd2bin(DiskInfo
.last
);
882 if (qInfo
.pointIndex
==0xA2) /*DiskLength*/
883 { DiskInfo
.diskLength
.min
=qInfo
.diskTime
.min
;
884 DiskInfo
.diskLength
.sec
=qInfo
.diskTime
.sec
;
885 DiskInfo
.diskLength
.frame
=qInfo
.diskTime
.frame
;
888 if ((qInfo
.pointIndex
==DiskInfo
.first
)&&(test
&0x01)) /*StartTime of First Track*/
889 { DiskInfo
.firstTrack
.min
=qInfo
.diskTime
.min
;
890 DiskInfo
.firstTrack
.sec
=qInfo
.diskTime
.sec
;
891 DiskInfo
.firstTrack
.frame
=qInfo
.diskTime
.frame
;
894 if (test
==0x0F) break;
897 printk ("aztcd: exiting aztGetDiskInfo Time:%li\n",jiffies
);
898 printk("Disk Info: first %d last %d length %02X:%02X.%02X dez first %02X:%02X.%02X dez\n",
901 DiskInfo
.diskLength
.min
,
902 DiskInfo
.diskLength
.sec
,
903 DiskInfo
.diskLength
.frame
,
904 DiskInfo
.firstTrack
.min
,
905 DiskInfo
.firstTrack
.sec
,
906 DiskInfo
.firstTrack
.frame
);
908 if (test
!=0x0F) return -1;
914 * Get Multisession Disk Info
916 static int aztGetMultiDiskInfo(void)
919 struct azt_Toc qInfo
;
922 printk("aztcd: starting aztGetMultiDiskInfo\n");
925 do { azt_Play
.start
.min
= Toc
[DiskInfo
.last
+1].diskTime
.min
;
926 azt_Play
.start
.sec
= Toc
[DiskInfo
.last
+1].diskTime
.sec
;
927 azt_Play
.start
.frame
= Toc
[DiskInfo
.last
+1].diskTime
.frame
;
930 for (limit
=30;limit
>0;limit
--) /*Seek for LeadIn of next session*/
931 { if (aztSeek(&azt_Play
)) RETURNM("aztGetMultiDiskInfo 1",-1);
932 if (aztGetQChannelInfo(&qInfo
)<0) RETURNM("aztGetMultiDiskInfo 2",-1);
933 if ((qInfo
.track
==0)&&(qInfo
.pointIndex
)) break; /*LeadIn found*/
934 if ((azt_Play
.start
.sec
+=10) > 59)
935 { azt_Play
.start
.sec
=0;
936 azt_Play
.start
.min
++;
939 if (!limit
) break; /*Check, if a leadin track was found, if not we're
940 at the end of the disk*/
941 #ifdef AZT_DEBUG_MULTISESSION
942 printk("leadin found track %d pointIndex %x limit %d\n",qInfo
.track
,qInfo
.pointIndex
,limit
);
944 for (limit
=300;limit
>0;limit
--)
945 { if (++azt_Play
.start
.frame
>74)
946 { azt_Play
.start
.frame
=0;
947 if (azt_Play
.start
.sec
> 59)
948 { azt_Play
.start
.sec
=0;
949 azt_Play
.start
.min
++;
952 if (aztSeek(&azt_Play
)) RETURNM("aztGetMultiDiskInfo 3",-1);
953 if (aztGetQChannelInfo(&qInfo
)<0) RETURNM("aztGetMultiDiskInfo 4",-1);
954 if (qInfo
.pointIndex
==0xA0) /*Number of NextTrack*/
955 { DiskInfo
.next
= qInfo
.diskTime
.min
;
956 DiskInfo
.next
= azt_bcd2bin(DiskInfo
.next
);
959 if (qInfo
.pointIndex
==0xA1) /*Number of LastTrack*/
960 { DiskInfo
.last
= qInfo
.diskTime
.min
;
961 DiskInfo
.last
= azt_bcd2bin(DiskInfo
.last
);
964 if (qInfo
.pointIndex
==0xA2) /*DiskLength*/
965 { DiskInfo
.diskLength
.min
=qInfo
.diskTime
.min
;
966 DiskInfo
.diskLength
.sec
=qInfo
.diskTime
.sec
;
967 DiskInfo
.diskLength
.frame
=qInfo
.diskTime
.frame
;
970 if ((qInfo
.pointIndex
==DiskInfo
.next
)&&(test
&0x01)) /*StartTime of Next Track*/
971 { DiskInfo
.nextSession
.min
=qInfo
.diskTime
.min
;
972 DiskInfo
.nextSession
.sec
=qInfo
.diskTime
.sec
;
973 DiskInfo
.nextSession
.frame
=qInfo
.diskTime
.frame
;
976 if (test
==0x0F) break;
978 #ifdef AZT_DEBUG_MULTISESSION
979 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",
983 DiskInfo
.diskLength
.min
,
984 DiskInfo
.diskLength
.sec
,
985 DiskInfo
.diskLength
.frame
,
986 DiskInfo
.firstTrack
.min
,
987 DiskInfo
.firstTrack
.sec
,
988 DiskInfo
.firstTrack
.frame
,
989 DiskInfo
.nextSession
.min
,
990 DiskInfo
.nextSession
.sec
,
991 DiskInfo
.nextSession
.frame
);
996 DiskInfo
.multi
=1; /*found TOC of more than one session*/
1001 printk ("aztcd: exiting aztGetMultiDiskInfo Time:%li\n",jiffies
);
1008 * Read the table of contents (TOC)
1010 static int aztGetToc(int multi
)
1013 struct azt_Toc qInfo
;
1016 printk("aztcd: starting aztGetToc Time:%li\n",jiffies
);
1019 { for (i
= 0; i
< MAX_TRACKS
; i
++)
1020 Toc
[i
].pointIndex
= 0;
1021 i
= DiskInfo
.last
+ 3;
1024 { for (i
= DiskInfo
.next
; i
< MAX_TRACKS
; i
++)
1025 Toc
[i
].pointIndex
= 0;
1026 i
= DiskInfo
.last
+ 4 - DiskInfo
.next
;
1029 /*Is there a good reason to stop motor before TOC read?
1030 if (aztSendCmd(ACMD_STOP)) RETURNM("aztGetToc 1",-1);
1036 if (aztSendCmd(ACMD_SEEK_TO_LEADIN
)) RETURNM("aztGetToc 2",-1);
1039 for (limit
= 300; limit
> 0; limit
--)
1041 { if (++azt_Play
.start
.sec
> 59)
1042 { azt_Play
.start
.sec
=0;
1043 azt_Play
.start
.min
++;
1045 if (aztSeek(&azt_Play
)) RETURNM("aztGetToc 3",-1);
1047 if (aztGetQChannelInfo(&qInfo
) < 0)
1050 px
= azt_bcd2bin(qInfo
.pointIndex
);
1052 if (px
> 0 && px
< MAX_TRACKS
&& qInfo
.track
== 0)
1053 if (Toc
[px
].pointIndex
== 0)
1062 Toc
[DiskInfo
.last
+ 1].diskTime
= DiskInfo
.diskLength
;
1063 Toc
[DiskInfo
.last
].trackTime
= DiskInfo
.diskLength
;
1065 #ifdef AZT_DEBUG_MULTISESSION
1066 printk("aztcd: exiting aztGetToc\n");
1067 for (i
= 1; i
<= DiskInfo
.last
+1; i
++)
1068 printk("i = %2d ctl-adr = %02X track %2d px %02X %02X:%02X.%02X dez %02X:%02X.%02X dez\n",
1069 i
, Toc
[i
].ctrl_addr
, Toc
[i
].track
, Toc
[i
].pointIndex
,
1070 Toc
[i
].trackTime
.min
, Toc
[i
].trackTime
.sec
, Toc
[i
].trackTime
.frame
,
1071 Toc
[i
].diskTime
.min
, Toc
[i
].diskTime
.sec
, Toc
[i
].diskTime
.frame
);
1072 for (i
= 100; i
< 103; i
++)
1073 printk("i = %2d ctl-adr = %02X track %2d px %02X %02X:%02X.%02X dez %02X:%02X.%02X dez\n",
1074 i
, Toc
[i
].ctrl_addr
, Toc
[i
].track
, Toc
[i
].pointIndex
,
1075 Toc
[i
].trackTime
.min
, Toc
[i
].trackTime
.sec
, Toc
[i
].trackTime
.frame
,
1076 Toc
[i
].diskTime
.min
, Toc
[i
].diskTime
.sec
, Toc
[i
].diskTime
.frame
);
1079 return limit
> 0 ? 0 : -1;
1083 /*##########################################################################
1084 Kernel Interface Functions
1085 ##########################################################################
1087 #ifdef AZT_KERNEL_PRIOR_2_1
1088 void aztcd_setup(char *str
, int *ints
)
1090 __initfunc(void aztcd_setup(char *str
, int *ints
))
1099 * Checking if the media has been changed
1101 static int check_aztcd_media_change(kdev_t full_dev
)
1102 { if (aztDiskChanged
) /* disk changed */
1107 return 0; /* no change */
1111 * Kernel IO-controls
1113 static int aztcd_ioctl(struct inode
*ip
, struct file
*fp
, unsigned int cmd
, unsigned long arg
)
1115 struct azt_Toc qInfo
;
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
;
1125 printk("aztcd: starting aztcd_ioctl - Command:%x Time: %li\n",cmd
, jiffies
);
1126 printk("aztcd Status %x\n", getAztStatus());
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 */
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);
1143 case CDROMSTOP
: /* Spin down the drive */
1144 if (aztSendCmd(ACMD_STOP
)) RETURNM("aztcd_ioctl 5",-1);
1146 /* should we do anything if it fails? */
1147 aztAudioStatus
= CDROM_AUDIO_NO_STATUS
;
1149 case CDROMPAUSE
: /* Pause the drive */
1150 if (aztAudioStatus
!= CDROM_AUDIO_PLAY
) return -EINVAL
;
1152 if (aztGetQChannelInfo(&qInfo
) < 0)
1153 { /* didn't get q channel info */
1154 aztAudioStatus
= CDROM_AUDIO_NO_STATUS
;
1155 RETURNM("aztcd_ioctl 7",0);
1157 azt_Play
.start
= qInfo
.diskTime
; /* remember restart point */
1159 if (aztSendCmd(ACMD_PAUSE
)) RETURNM("aztcd_ioctl 8",-1);
1161 aztAudioStatus
= CDROM_AUDIO_PAUSED
;
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
);
1168 { aztAudioStatus
= CDROM_AUDIO_ERROR
;
1171 aztAudioStatus
= CDROM_AUDIO_PLAY
;
1173 case CDROMMULTISESSION
: /*multisession support -- experimental*/
1174 { struct cdrom_multisession ms
;
1176 printk("aztcd ioctl MULTISESSION\n");
1178 st
= verify_area(VERIFY_WRITE
, (void*) arg
, sizeof(struct cdrom_multisession
));
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
);
1186 else if (ms
.addr_format
== CDROM_LBA
)
1187 ms
.addr
.lba
= azt_msf2hsg(&DiskInfo
.lastSession
);
1190 ms
.xa_flag
= DiskInfo
.xa
;
1191 memcpy_tofs((void*) arg
, &ms
, sizeof(struct cdrom_multisession
));
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
);
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
);
1205 case CDROMPLAYTRKIND
: /* Play a track. This currently ignores index. */
1206 st
= verify_area(VERIFY_READ
, (void *) arg
, sizeof ti
);
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
)
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
;
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
);
1223 i
= aztPlay(&azt_Play
);
1225 { aztAudioStatus
= CDROM_AUDIO_ERROR
;
1228 aztAudioStatus
= CDROM_AUDIO_PLAY
;
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);
1234 aztAudioStatus = CDROM_AUDIO_NO_STATUS;
1237 st
= verify_area(VERIFY_READ
, (void *) arg
, sizeof msf
);
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
;
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
);
1258 i
= aztPlay(&azt_Play
);
1260 { aztAudioStatus
= CDROM_AUDIO_ERROR
;
1263 aztAudioStatus
= CDROM_AUDIO_PLAY
;
1266 case CDROMREADTOCHDR
: /* Read the table of contents header */
1267 st
= verify_area(VERIFY_WRITE
, (void *) arg
, sizeof tocHdr
);
1269 tocHdr
.cdth_trk0
= DiskInfo
.first
;
1270 tocHdr
.cdth_trk1
= DiskInfo
.last
;
1271 memcpy_tofs((void *) arg
, &tocHdr
, sizeof tocHdr
);
1273 case CDROMREADTOCENTRY
: /* Read an entry in the table of contents */
1274 st
= verify_area(VERIFY_WRITE
, (void *) arg
, sizeof entry
);
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
)
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
);
1298 memcpy_tofs((void *) arg
, &entry
, sizeof entry
);
1300 case CDROMSUBCHNL
: /* Get subchannel info */
1301 st
= verify_area(VERIFY_WRITE
, (void *) arg
, sizeof(struct cdrom_subchnl
));
1304 printk("aztcd: exiting aztcd_ioctl - Error 1 - Command:%x\n",cmd
);
1308 memcpy_fromfs(&subchnl
, (void *) arg
, sizeof (struct cdrom_subchnl
));
1309 if (aztGetQChannelInfo(&qInfo
) < 0)
1312 printk("aztcd: exiting aztcd_ioctl - Error 3 - Command:%x\n",cmd
);
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
);
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
);
1334 memcpy_tofs((void *) arg
, &subchnl
, sizeof (struct cdrom_subchnl
));
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
);
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);
1359 if (aztSendCmd(ACMD_EJECT
)) RETURNM("azt_ioctl 11",-1);
1361 aztAudioStatus
= CDROM_AUDIO_NO_STATUS
;
1364 azt_auto_eject
= (char) arg
;
1367 outb(ACMD_SOFT_RESET
,CMD_PORT
); /*send reset*/
1369 if (inb(DATA_PORT
)!=AFL_OP_OK
) /*OP_OK?*/
1370 { printk("aztcd: AZTECH CD-ROM drive does not respond\n");
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!
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
);
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
);
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
)
1398 { return -1; /*XA Disks can't be read raw*/
1401 { if (sendAztCmd(ACMD_PLAY_READ_RAW
, &azt_Play
)) return -1;
1403 insb(DATA_PORT
,buf
,CD_FRAMESIZE_RAW
);
1404 memcpy_tofs((void *) arg
, &buf
, CD_FRAMESIZE_RAW
);
1407 else /*CDROMREADCOOKED*/
1408 { if (sendAztCmd(ACMD_PLAY_READ
, &azt_Play
)) return -1;
1410 insb(DATA_PORT
,buf
,CD_FRAMESIZE
);
1411 memcpy_tofs((void *) arg
, &buf
, CD_FRAMESIZE
);
1415 case CDROMSEEK
: /*seek msf address*/
1416 st
= verify_area(VERIFY_READ
, (void *) arg
, sizeof msf
);
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;
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
);
1437 printk("aztcd: exiting aztcd_ioctl Command:%x Time:%li\n",cmd
,jiffies
);
1443 * Take care of the different block sizes between cdrom and Linux.
1444 * When Linux gets variable block sizes this will probably go away.
1446 static void azt_transfer(void)
1449 printk("aztcd: executing azt_transfer Time:%li\n",jiffies
);
1451 if (CURRENT_VALID
) {
1452 while (CURRENT
-> nr_sectors
) {
1453 int bn
= CURRENT
-> sector
/ 4;
1455 for (i
= 0; i
< AZT_BUF_SIZ
&& azt_buf_bn
[i
] != bn
; ++i
)
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
) {
1462 if (azt_buf_bn
[i
] != bn
) {
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;
1481 static void do_aztcd_request(void)
1484 printk(" do_aztcd_request(%ld+%ld) Time:%li\n", CURRENT
-> sector
, CURRENT
-> nr_sectors
,jiffies
);
1487 { printk("aztcd: Error, tried to mount an Audio CD\n");
1491 azt_transfer_is_active
= 1;
1492 while (CURRENT_VALID
) {
1494 if (!buffer_locked(CURRENT
->bh
))
1495 panic(DEVICE_NAME
": block not locked");
1498 if (CURRENT
-> nr_sectors
== 0) {
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
)
1510 azt_state
= AZT_S_START
;
1512 SET_TIMER(azt_poll
, HZ
/100);
1517 azt_transfer_is_active
= 0;
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
);
1526 static void azt_invalidate_buffers(void)
1530 printk("aztcd: executing azt_invalidate_buffers\n");
1532 for (i
= 0; i
< AZT_BUF_SIZ
; ++i
)
1538 * Open the device special file. Check that a disk is in.
1540 int aztcd_open(struct inode
*ip
, struct file
*fp
)
1544 printk("aztcd: starting aztcd_open\n");
1546 if (aztPresent
== 0)
1547 return -ENXIO
; /* no hardware */
1549 if (!azt_open_count
&& azt_state
== AZT_S_IDLE
)
1550 { azt_invalidate_buffers();
1552 st
= getAztStatus(); /* check drive status */
1553 if (st
== -1) return -EIO
; /* drive doesn't respond */
1555 if (st
& AST_DOOR_OPEN
)
1556 { /* close door, then get the status again. */
1557 printk("aztcd: Door Open?\n");
1559 st
= getAztStatus();
1562 if ((st
& AST_NOT_READY
) || (st
& AST_DSK_CHG
)) /*no disk in drive or changed*/
1563 { printk("aztcd: Disk Changed or No Disk in Drive?\n");
1566 if (aztUpdateToc()) return -EIO
;
1575 printk("aztcd: exiting aztcd_open\n");
1582 * On close, we flush all azt blocks from the buffer cache.
1584 #ifdef AZT_KERNEL_PRIOR_2_1
1585 static void aztcd_release(struct inode
* inode
, struct file
* file
)
1587 static int aztcd_release(struct inode
* inode
, struct file
* file
)
1591 printk("aztcd: executing aztcd_release\n");
1592 printk("inode: %p, inode->i_rdev: %x file: %p\n",inode
,inode
->i_rdev
,file
);
1595 if (!--azt_open_count
) {
1596 azt_invalidate_buffers();
1597 sync_dev(inode
->i_rdev
); /*??? isn't it a read only dev?*/
1598 invalidate_buffers(inode
-> i_rdev
);
1601 aztSendCmd(ACMD_EJECT
);
1604 #ifdef AZT_KERNEL_PRIOR_2_1
1614 * Test for presence of drive and initialize it. Called at boot time.
1617 #ifdef AZT_KERNEL_PRIOR_2_1
1618 int aztcd_init(void)
1620 __initfunc(int aztcd_init(void))
1622 { long int count
, max_count
;
1623 unsigned char result
[50];
1628 { printk("aztcd: no Aztech CD-ROM Initialization");
1632 printk("aztcd: AZTECH, ORCHID, OKANO, WEARNES, TXC, CyDROM CD-ROM Driver\n");
1633 printk("aztcd: (C) 1994-98 W.Zimmermann\n");
1635 { printk("aztcd: KernelVersion=%s DriverVersion=%s For IDE/ATAPI-drives use ide-cd.c\n",UTS_RELEASE
,AZT_VERSION
);
1638 printk("aztcd: DriverVersion=%s BaseAddress=0x%x For IDE/ATAPI-drives use ide-cd.c\n",AZT_VERSION
,azt_port
);
1639 printk("aztcd: If you have problems, read /usr/src/linux/Documentation/cdrom/aztcd\n");
1642 #ifdef AZT_SW32 /*CDROM connected to Soundwave32 card*/
1643 if ((0xFF00 & inw(AZT_SW32_ID_REG
)) != 0x4500)
1644 { printk("aztcd: no Soundwave32 card detected at base:%x init:%x config:%x id:%x\n",
1645 AZT_SW32_BASE_ADDR
,AZT_SW32_INIT
,AZT_SW32_CONFIG_REG
,AZT_SW32_ID_REG
);
1649 { printk(KERN_INFO
"aztcd: Soundwave32 card detected at %x Version %x\n",
1650 AZT_SW32_BASE_ADDR
, inw(AZT_SW32_ID_REG
));
1651 outw(AZT_SW32_INIT
,AZT_SW32_CONFIG_REG
);
1652 for (count
=0;count
<10000;count
++); /*delay a bit*/
1656 /* check for presence of drive */
1658 if (azt_port
== -1) /* autoprobing */
1659 { for (i
=0;(azt_port_auto
[i
]!=0)&&(i
<16);i
++)
1660 { azt_port
= azt_port_auto
[i
];
1661 printk("aztcd: Autoprobing BaseAddress=0x%x \n",azt_port
);
1662 st
= check_region(azt_port
, 4); /*proprietary interfaces need 4 bytes*/
1665 outb(POLLED
,MODE_PORT
);
1668 outb(ACMD_GET_VERSION
,CMD_PORT
); /*Try to get version info*/
1671 do { aztIndatum
=inb(STATUS_PORT
);
1673 if (aztTimeOutCount
>=AZT_FAST_TIMEOUT
) break;
1674 } while (aztIndatum
&AFL_STATUS
);
1675 if (inb(DATA_PORT
)==AFL_OP_OK
)
1678 if ((azt_port_auto
[i
]==0)||(i
==16))
1679 { printk("aztcd: no AZTECH CD-ROM drive found\n");
1683 else /* no autoprobing */
1684 { if ((azt_port
==0x1f0)||(azt_port
==0x170))
1685 st
= check_region(azt_port
, 8); /*IDE-interfaces need 8 bytes*/
1687 st
= check_region(azt_port
, 4); /*proprietary interfaces need 4 bytes*/
1689 { printk("aztcd: conflict, I/O port (%X) already used\n",azt_port
);
1693 if ((azt_port
==0x1f0)||(azt_port
==0x170))
1694 SWITCH_IDE_SLAVE
; /*switch IDE interface to slave configuration*/
1696 outb(POLLED
,MODE_PORT
);
1699 outb(ACMD_GET_VERSION
,CMD_PORT
); /*Try to get version info*/
1702 do { aztIndatum
=inb(STATUS_PORT
);
1704 if (aztTimeOutCount
>=AZT_FAST_TIMEOUT
) break;
1705 } while (aztIndatum
&AFL_STATUS
);
1707 if (inb(DATA_PORT
)!=AFL_OP_OK
) /*OP_OK? If not, reset and try again*/
1711 { printk("aztcd: no AZTECH CD-ROM drive found-Try boot parameter aztcd=<BaseAddress>,0x79\n");
1720 { printk("aztcd: drive reset - please wait\n");
1721 for (count
=0;count
<50;count
++)
1722 { inb(STATUS_PORT
); /*removing all data from earlier tries*/
1725 outb(POLLED
,MODE_PORT
);
1728 getAztStatus(); /*trap errors*/
1729 outb(ACMD_SOFT_RESET
,CMD_PORT
); /*send reset*/
1731 if (inb(DATA_PORT
)!=AFL_OP_OK
) /*OP_OK?*/
1732 { printk("aztcd: no AZTECH CD-ROM drive found\n");
1735 for (count
= 0; count
< AZT_TIMEOUT
; count
++);
1736 { count
=count
*2; /* delay a bit */
1739 if ((st
=getAztStatus())==-1)
1740 { printk("aztcd: Drive Status Error Status=%x\n",st
);
1744 printk("aztcd: Status = %x\n",st
);
1746 outb(POLLED
,MODE_PORT
);
1749 outb(ACMD_GET_VERSION
,CMD_PORT
); /*GetVersion*/
1758 result
[0]=inb(DATA_PORT
); /*reading in a null byte???*/
1759 for (count
=1;count
<50;count
++) /*Reading version string*/
1760 { aztTimeOutCount
=0; /*here we must implement STEN_LOW differently*/
1761 do { aztIndatum
=inb(STATUS_PORT
);/*because we want to exit by timeout*/
1763 if (aztTimeOutCount
>=AZT_FAST_TIMEOUT
) break;
1764 } while (aztIndatum
&AFL_STATUS
);
1765 if (aztTimeOutCount
>=AZT_FAST_TIMEOUT
) break; /*all chars read?*/
1766 result
[count
]=inb(DATA_PORT
);
1768 if (count
>30) max_count
=30; /*print max.30 chars of the version string*/
1769 else max_count
=count
;
1770 printk(KERN_INFO
"aztcd: FirmwareVersion=");
1771 for (count
=1;count
<max_count
;count
++) printk("%c",result
[count
]);
1774 if ((result
[1]=='A')&&(result
[2]=='Z')&&(result
[3]=='T'))
1775 { printk("AZTECH drive detected\n"); /*AZTECH*/
1777 else if ((result
[2]=='C')&&(result
[3]=='D')&&(result
[4]=='D'))
1778 { printk("ORCHID or WEARNES drive detected\n"); /*ORCHID or WEARNES*/
1780 else if ((result
[1]==0x03)&&(result
[2]=='5'))
1781 { printk("TXC or CyCDROM drive detected\n"); /*Conrad TXC, CyCDROM*/
1783 else /*OTHERS or none*/
1784 { printk("\nunknown drive or firmware version detected\n");
1785 printk("aztcd may not run stable, if you want to try anyhow,\n");
1786 printk("boot with: aztcd=<BaseAddress>,0x79\n");
1787 if ((azt_cont
!=0x79))
1788 { printk("aztcd: FirmwareVersion=");
1789 for (count
=1;count
<5;count
++) printk("%c",result
[count
]);
1791 printk("Aborted\n");
1795 if (register_blkdev(MAJOR_NR
, "aztcd", &azt_fops
) != 0)
1797 printk("aztcd: Unable to get major %d for Aztech CD-ROM\n",
1801 blk_dev
[MAJOR_NR
].request_fn
= DEVICE_REQUEST
;
1802 #ifndef AZT_KERNEL_PRIOR_2_1
1803 blksize_size
[MAJOR_NR
] = aztcd_blocksizes
;
1805 read_ahead
[MAJOR_NR
] = 4;
1807 if ((azt_port
==0x1f0)||(azt_port
==0x170))
1808 request_region(azt_port
, 8, "aztcd"); /*IDE-interface*/
1810 request_region(azt_port
, 4, "aztcd"); /*proprietary interface*/
1812 azt_invalidate_buffers();
1820 int init_module(void)
1822 return aztcd_init();
1825 void cleanup_module(void)
1827 if ((unregister_blkdev(MAJOR_NR
, "aztcd") == -EINVAL
))
1828 { printk("What's that: can't unregister aztcd\n");
1831 if ((azt_port
==0x1f0)||(azt_port
==0x170))
1832 { SWITCH_IDE_MASTER
;
1833 release_region(azt_port
,8); /*IDE-interface*/
1836 release_region(azt_port
,4); /*proprietary interface*/
1837 printk(KERN_INFO
"aztcd module released.\n");
1842 /*##########################################################################
1843 Aztcd State Machine: Controls Drive Operating State
1844 ##########################################################################
1846 static void azt_poll(void)
1853 if (aztSendCmd(ACMD_GET_ERROR
)) RETURN("azt_poll 1");
1855 azt_error
=inb(DATA_PORT
)&0xFF;
1856 printk("aztcd: I/O error 0x%02x\n", azt_error
);
1857 azt_invalidate_buffers();
1858 #ifdef WARN_IF_READ_FAILURE
1860 printk("aztcd: Read of Block %d Failed - Maybe Audio Disk?\n", azt_next_bn
);
1863 printk("aztcd: Read of Block %d Failed, Maybe Audio Disk? Giving up\n", azt_next_bn
);
1864 if (azt_transfer_is_active
) {
1873 azt_state
= AZT_S_STOP
;
1878 loop_ctl
= 0; /* each case must flip this back to 1 if we want
1879 to come back up here */
1880 switch (azt_state
) {
1884 if (azt_state
!=azt_state_old
) {
1885 azt_state_old
=azt_state
;
1886 printk("AZT_S_IDLE\n");
1893 if (azt_state
!=azt_state_old
) {
1894 azt_state_old
=azt_state
;
1895 printk("AZT_S_START\n");
1898 if(aztSendCmd(ACMD_GET_STATUS
)) RETURN("azt_poll 2"); /*result will be checked by aztStatus() */
1899 azt_state
= azt_mode
== 1 ? AZT_S_READ
: AZT_S_MODE
;
1905 if (azt_state
!=azt_state_old
) {
1906 azt_state_old
=azt_state
;
1907 printk("AZT_S_MODE\n");
1911 if ((st
= aztStatus()) != -1) {
1912 if ((st
& AST_DSK_CHG
)||(st
& AST_NOT_READY
)) {
1915 azt_invalidate_buffers();
1917 printk("aztcd: Disk Changed or Not Ready 1 - Unmount Disk!\n");
1923 if ((st
& AST_DOOR_OPEN
)||(st
& AST_NOT_READY
)) {
1926 printk("aztcd: Disk Changed or Not Ready 2 - Unmount Disk!\n");
1928 printk((st
& AST_DOOR_OPEN
) ? "aztcd: door open\n" : "aztcd: disk removed\n");
1929 if (azt_transfer_is_active
) {
1930 azt_state
= AZT_S_START
;
1931 loop_ctl
= 1; /* goto immediately */
1934 azt_state
= AZT_S_IDLE
;
1935 while (CURRENT_VALID
)
1940 /* if (aztSendCmd(ACMD_SET_MODE)) RETURN("azt_poll 3");
1941 outb(0x01, DATA_PORT);
1944 */ if (aztSendCmd(ACMD_GET_STATUS
)) RETURN("azt_poll 4");
1947 azt_state
= AZT_S_READ
;
1955 if (azt_state
!=azt_state_old
) {
1956 azt_state_old
=azt_state
;
1957 printk("AZT_S_READ\n");
1961 if ((st
= aztStatus()) != -1) {
1962 if ((st
& AST_DSK_CHG
)||(st
& AST_NOT_READY
)) {
1965 azt_invalidate_buffers();
1966 printk("aztcd: Disk Changed or Not Ready 3 - Unmount Disk!\n");
1973 if ((st
& AST_DOOR_OPEN
)||(st
& AST_NOT_READY
)) {
1976 printk((st
& AST_DOOR_OPEN
) ? "aztcd: door open\n" : "aztcd: disk removed\n");
1977 if (azt_transfer_is_active
) {
1978 azt_state
= AZT_S_START
;
1982 azt_state
= AZT_S_IDLE
;
1983 while (CURRENT_VALID
)
1988 if (CURRENT_VALID
) {
1989 struct azt_Play_msf msf
;
1991 azt_next_bn
= CURRENT
-> sector
/ 4;
1992 azt_hsg2msf(azt_next_bn
, &msf
.start
);
1994 /* find out in which track we are */
1995 while (azt_msf2hsg(&msf
.start
)>azt_msf2hsg(&Toc
[++i
].trackTime
)) {};
1996 if (azt_msf2hsg(&msf
.start
)<azt_msf2hsg(&Toc
[i
].trackTime
)-AZT_BUF_SIZ
)
1997 { azt_read_count
=AZT_BUF_SIZ
; /*fast, because we read ahead*/
1998 /*azt_read_count=CURRENT->nr_sectors; slow, no read ahead*/
2000 else /* don't read beyond end of track */
2001 #if AZT_MULTISESSION
2002 { azt_read_count
=(azt_msf2hsg(&Toc
[i
].trackTime
)/4)*4-azt_msf2hsg(&msf
.start
);
2003 if (azt_read_count
< 0) azt_read_count
=0;
2004 if (azt_read_count
> AZT_BUF_SIZ
) azt_read_count
=AZT_BUF_SIZ
;
2005 printk("aztcd: warning - trying to read beyond end of track\n");
2006 /* printk("%i %i %li %li\n",i,azt_read_count,azt_msf2hsg(&msf.start),azt_msf2hsg(&Toc[i].trackTime));
2009 { azt_read_count
=AZT_BUF_SIZ
;
2014 msf
.end
.frame
= azt_read_count
;/*Mitsumi here reads 0xffffff sectors*/
2016 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
);
2017 printk("azt_next_bn:%x azt_buf_in:%x azt_buf_out:%x azt_buf_bn:%x\n", \
2018 azt_next_bn
, azt_buf_in
, azt_buf_out
, azt_buf_bn
[azt_buf_in
]);
2020 if (azt_read_mode
==AZT_MODE_2
)
2021 { sendAztCmd(ACMD_PLAY_READ_RAW
, &msf
); /*XA disks in raw mode*/
2024 { sendAztCmd(ACMD_PLAY_READ
, &msf
); /*others in cooked mode*/
2026 azt_state
= AZT_S_DATA
;
2027 AztTimeout
= READ_TIMEOUT
;
2029 azt_state
= AZT_S_STOP
;
2039 if (azt_state
!=azt_state_old
) {
2040 azt_state_old
=azt_state
;
2041 printk("AZT_S_DATA\n");
2045 st
= inb(STATUS_PORT
) & AFL_STATUSorDATA
;
2051 if (st
!=azt_st_old
) {
2053 printk("---AFL_DATA st:%x\n",st
);
2057 printk("aztcd: Read of Block %d Failed, Maybe Audio Disk ? Giving up\n", azt_next_bn
);
2058 if (azt_transfer_is_active
) {
2066 azt_state
= AZT_S_START
;
2067 AztTimeout
= READ_TIMEOUT
;
2071 case AFL_STATUSorDATA
:
2073 if (st
!=azt_st_old
) {
2075 printk("---AFL_STATUSorDATA st:%x\n",st
);
2082 if (st
!=azt_st_old
) {
2084 printk("---default: st:%x\n",st
);
2088 if (!CURRENT_VALID
&& azt_buf_in
== azt_buf_out
) {
2089 azt_state
= AZT_S_STOP
;
2093 if (azt_read_count
<=0)
2094 printk("aztcd: warning - try to read 0 frames\n");
2095 while (azt_read_count
) /*??? fast read ahead loop*/
2096 { azt_buf_bn
[azt_buf_in
] = -1;
2097 DTEN_LOW
; /*??? unsolved problem, very
2098 seldom we get timeouts
2099 here, don't now the real
2100 reason. With my drive this
2101 sometimes also happens with
2102 Aztech's original driver under
2103 DOS. Is it a hardware bug?
2104 I tried to recover from such
2105 situations here. Zimmermann*/
2106 if (aztTimeOutCount
>=AZT_TIMEOUT
)
2107 { printk("read_count:%d CURRENT->nr_sectors:%ld azt_buf_in:%d\n", azt_read_count
,CURRENT
->nr_sectors
,azt_buf_in
);
2108 printk("azt_transfer_is_active:%x\n",azt_transfer_is_active
);
2110 azt_state
= AZT_S_STOP
;
2112 end_request(1); /*should we have here (1) or (0)? */
2115 { if (azt_read_mode
==AZT_MODE_2
)
2116 { insb(DATA_PORT
, azt_buf
+ CD_FRAMESIZE_RAW
* azt_buf_in
, CD_FRAMESIZE_RAW
);
2119 { insb(DATA_PORT
, azt_buf
+ CD_FRAMESIZE
* azt_buf_in
, CD_FRAMESIZE
);
2123 printk("AZT_S_DATA; ---I've read data- read_count: %d\n",azt_read_count
);
2124 printk("azt_next_bn:%d azt_buf_in:%d azt_buf_out:%d azt_buf_bn:%d\n", \
2125 azt_next_bn
, azt_buf_in
, azt_buf_out
, azt_buf_bn
[azt_buf_in
]);
2127 azt_buf_bn
[azt_buf_in
] = azt_next_bn
++;
2128 if (azt_buf_out
== -1)
2129 azt_buf_out
= azt_buf_in
;
2130 azt_buf_in
= azt_buf_in
+ 1 == AZT_BUF_SIZ
? 0 : azt_buf_in
+ 1;
2133 if (!azt_transfer_is_active
) {
2134 while (CURRENT_VALID
) {
2136 if (CURRENT
-> nr_sectors
== 0)
2144 && (CURRENT
-> sector
/ 4 < azt_next_bn
||
2145 CURRENT
-> sector
/ 4 > azt_next_bn
+ AZT_BUF_SIZ
)) {
2146 azt_state
= AZT_S_STOP
;
2150 AztTimeout
= READ_TIMEOUT
;
2151 if (azt_read_count
==0) {
2152 azt_state
= AZT_S_STOP
;
2163 if (azt_state
!=azt_state_old
) {
2164 azt_state_old
=azt_state
;
2165 printk("AZT_S_STOP\n");
2168 if (azt_read_count
!=0) printk("aztcd: discard data=%x frames\n",azt_read_count
);
2169 while (azt_read_count
!=0) {
2171 if ( !(inb(STATUS_PORT
) & AFL_DATA
) ) {
2172 if (azt_read_mode
==AZT_MODE_2
)
2173 for (i
=0; i
<CD_FRAMESIZE_RAW
; i
++) inb(DATA_PORT
);
2175 for (i
=0; i
<CD_FRAMESIZE
; i
++) inb(DATA_PORT
);
2179 if (aztSendCmd(ACMD_GET_STATUS
)) RETURN("azt_poll 5");
2180 azt_state
= AZT_S_STOPPING
;
2184 case AZT_S_STOPPING
:
2186 if (azt_state
!=azt_state_old
) {
2187 azt_state_old
=azt_state
;
2188 printk("AZT_S_STOPPING\n");
2192 if ((st
= aztStatus()) == -1 && AztTimeout
)
2195 if ((st
!= -1) && ((st
& AST_DSK_CHG
)||(st
& AST_NOT_READY
))) {
2198 azt_invalidate_buffers();
2199 printk("aztcd: Disk Changed or Not Ready 4 - Unmount Disk!\n");
2205 printk("CURRENT_VALID %d azt_mode %d\n",
2206 CURRENT_VALID
, azt_mode
);
2209 if (CURRENT_VALID
) {
2211 if (azt_mode
== 1) {
2212 azt_state
= AZT_S_READ
;
2217 azt_state
= AZT_S_MODE
;
2223 azt_state
= AZT_S_START
;
2227 azt_state
= AZT_S_IDLE
;
2233 printk("aztcd: invalid state %d\n", azt_state
);
2240 { printk("aztcd: timeout in state %d\n", azt_state
);
2241 azt_state
= AZT_S_STOP
;
2242 if (aztSendCmd(ACMD_STOP
)) RETURN("azt_poll 6");
2246 SET_TIMER(azt_poll
, HZ
/100);
2250 /*###########################################################################
2251 * Miscellaneous support functions
2252 ###########################################################################
2254 static void azt_hsg2msf(long hsg
, struct msf
*msf
)
2256 msf
-> min
= hsg
/ 4500;
2258 msf
-> sec
= hsg
/ 75;
2259 msf
-> frame
= hsg
% 75;
2261 if (msf
->min
>=70) printk("aztcd: Error hsg2msf address Minutes\n");
2262 if (msf
->sec
>=60) printk("aztcd: Error hsg2msf address Seconds\n");
2263 if (msf
->frame
>=75) printk("aztcd: Error hsg2msf address Frames\n");
2265 azt_bin2bcd(&msf
-> min
); /* convert to BCD */
2266 azt_bin2bcd(&msf
-> sec
);
2267 azt_bin2bcd(&msf
-> frame
);
2270 static long azt_msf2hsg(struct msf
*mp
)
2271 { return azt_bcd2bin(mp
-> frame
) + azt_bcd2bin(mp
-> sec
) * 75
2272 + azt_bcd2bin(mp
-> min
) * 4500 - CD_MSF_OFFSET
;
2275 static void azt_bin2bcd(unsigned char *p
)
2283 static int azt_bcd2bin(unsigned char bcd
)
2284 { return (bcd
>> 4) * 10 + (bcd
& 0xF);