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
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>
168 #include <linux/version.h>
169 #include <linux/blkdev.h>
172 #include <linux/module.h>
173 #include <linux/errno.h>
174 #include <linux/sched.h>
175 #include <linux/mm.h>
176 #include <linux/timer.h>
177 #include <linux/fs.h>
178 #include <linux/kernel.h>
179 #include <linux/cdrom.h>
180 #include <linux/ioport.h>
181 #include <linux/string.h>
182 #include <linux/major.h>
184 #include <linux/init.h>
186 #include <asm/system.h>
189 #include <asm/uaccess.h>
191 /*###########################################################################
193 ###########################################################################
196 #define MAJOR_NR AZTECH_CDROM_MAJOR
197 #define QUEUE (azt_queue)
198 #define CURRENT elv_next_request(azt_queue)
199 #define SET_TIMER(func, jifs) delay_timer.expires = jiffies + (jifs); \
200 delay_timer.function = (void *) (func); \
201 add_timer(&delay_timer);
203 #define CLEAR_TIMER del_timer(&delay_timer);
205 #define RETURNM(message,value) {printk("aztcd: Warning: %s failed\n",message);\
207 #define RETURN(message) {printk("aztcd: Warning: %s failed\n",message);\
210 /* Macros to switch the IDE-interface to the slave device and back to the master*/
211 #define SWITCH_IDE_SLAVE outb_p(0xa0,azt_port+6); \
212 outb_p(0x10,azt_port+6); \
213 outb_p(0x00,azt_port+7); \
214 outb_p(0x10,azt_port+6);
215 #define SWITCH_IDE_MASTER outb_p(0xa0,azt_port+6);
220 #define AZT_TEST1 /* <int-..> */
221 #define AZT_TEST2 /* do_aztcd_request */
222 #define AZT_TEST3 /* AZT_S_state */
223 #define AZT_TEST4 /* QUICK_LOOP-counter */
224 #define AZT_TEST5 /* port(1) state */
226 #define AZT_DEBUG_MULTISESSION
229 static struct request_queue *azt_queue;
231 static int current_valid(void)
234 CURRENT->cmd == READ &&
235 CURRENT->sector != -1;
238 #define AFL_STATUSorDATA (AFL_STATUS | AFL_DATA)
239 #define AZT_BUF_SIZ 16
241 #define READ_TIMEOUT 3000
243 #define azt_port aztcd /*needed for the modutils */
245 /*##########################################################################
247 ##########################################################################
249 enum azt_state_e { AZT_S_IDLE, /* 0 */
255 AZT_S_STOPPING /* 6 */
257 enum azt_read_modes { AZT_MODE_0, /*read mode for audio disks, not supported by Aztech firmware */
258 AZT_MODE_1, /*read mode for normal CD-ROMs */
259 AZT_MODE_2 /*read mode for XA CD-ROMs */
262 /*##########################################################################
264 ##########################################################################
266 static int aztPresent = 0;
268 static volatile int azt_transfer_is_active = 0;
270 static char azt_buf[CD_FRAMESIZE_RAW * AZT_BUF_SIZ]; /*buffer for block size conversion */
271 #if AZT_PRIVATE_IOCTLS
272 static char buf[CD_FRAMESIZE_RAW]; /*separate buffer for the ioctls */
275 static volatile int azt_buf_bn[AZT_BUF_SIZ], azt_next_bn;
276 static volatile int azt_buf_in, azt_buf_out = -1;
277 static volatile int azt_error = 0;
278 static int azt_open_count = 0;
279 static volatile enum azt_state_e azt_state = AZT_S_IDLE;
281 static volatile enum azt_state_e azt_state_old = AZT_S_STOP;
282 static volatile int azt_st_old = 0;
284 static volatile enum azt_read_modes azt_read_mode = AZT_MODE_1;
286 static int azt_mode = -1;
287 static volatile int azt_read_count = 1;
289 static int azt_port = AZT_BASE_ADDR;
291 MODULE_PARM(azt_port, "i");
293 static int azt_port_auto[16] = AZT_BASE_AUTO;
295 static char azt_cont = 0;
296 static char azt_init_end = 0;
297 static char azt_auto_eject = AZT_AUTO_EJECT;
299 static int AztTimeout, AztTries;
300 static DECLARE_WAIT_QUEUE_HEAD(azt_waitq);
301 static struct timer_list delay_timer = TIMER_INITIALIZER(NULL, 0, 0);
303 static struct azt_DiskInfo DiskInfo;
304 static struct azt_Toc Toc[MAX_TRACKS];
305 static struct azt_Play_msf azt_Play;
307 static int aztAudioStatus = CDROM_AUDIO_NO_STATUS;
308 static char aztDiskChanged = 1;
309 static char aztTocUpToDate = 0;
311 static unsigned char aztIndatum;
312 static unsigned long aztTimeOutCount;
313 static int aztCmd = 0;
315 static spinlock_t aztSpin = SPIN_LOCK_UNLOCKED;
317 /*###########################################################################
319 ###########################################################################
321 /* CDROM Drive Low Level I/O Functions */
322 static void aztStatTimer(void);
324 /* CDROM Drive Command Functions */
325 static int aztGetDiskInfo(void);
327 static int aztGetMultiDiskInfo(void);
329 static int aztGetToc(int multi);
331 /* Kernel Interface Functions */
332 static int check_aztcd_media_change(struct gendisk *disk);
333 static int aztcd_ioctl(struct inode *ip, struct file *fp, unsigned int cmd,
335 static int aztcd_open(struct inode *ip, struct file *fp);
336 static int aztcd_release(struct inode *inode, struct file *file);
338 static struct block_device_operations azt_fops = {
339 .owner = THIS_MODULE,
341 .release = aztcd_release,
342 .ioctl = aztcd_ioctl,
343 .media_changed = check_aztcd_media_change,
346 /* Aztcd State Machine: Controls Drive Operating State */
347 static void azt_poll(void);
349 /* Miscellaneous support functions */
350 static void azt_hsg2msf(long hsg, struct msf *msf);
351 static long azt_msf2hsg(struct msf *mp);
352 static void azt_bin2bcd(unsigned char *p);
353 static int azt_bcd2bin(unsigned char bcd);
355 /*##########################################################################
356 CDROM Drive Low Level I/O Functions
357 ##########################################################################
359 /* Macros for the drive hardware interface handshake, these macros use
361 /* Wait for OP_OK = drive answers with AFL_OP_OK after receiving a command*/
362 # define OP_OK op_ok()
363 static void op_ok(void)
367 aztIndatum = inb(DATA_PORT);
369 if (aztTimeOutCount >= AZT_TIMEOUT) {
370 printk("aztcd: Error Wait OP_OK\n");
373 } while (aztIndatum != AFL_OP_OK);
376 /* Wait for PA_OK = drive answers with AFL_PA_OK after receiving parameters*/
377 # define PA_OK pa_ok()
378 static void pa_ok(void)
382 aztIndatum = inb(DATA_PORT);
384 if (aztTimeOutCount >= AZT_TIMEOUT) {
385 printk("aztcd: Error Wait PA_OK\n");
388 } while (aztIndatum != AFL_PA_OK);
391 /* Wait for STEN=Low = handshake signal 'AFL_.._OK available or command executed*/
392 # define STEN_LOW sten_low()
393 static void sten_low(void)
397 aztIndatum = inb(STATUS_PORT);
399 if (aztTimeOutCount >= AZT_TIMEOUT) {
402 ("aztcd: Error Wait STEN_LOW commands:%x\n",
406 } while (aztIndatum & AFL_STATUS);
409 /* Wait for DTEN=Low = handshake signal 'Data available'*/
410 # define DTEN_LOW dten_low()
411 static void dten_low(void)
415 aztIndatum = inb(STATUS_PORT);
417 if (aztTimeOutCount >= AZT_TIMEOUT) {
418 printk("aztcd: Error Wait DTEN_OK\n");
421 } while (aztIndatum & AFL_DATA);
425 * Macro for timer wait on STEN=Low, should only be used for 'slow' commands;
426 * may cause kernel panic when used in the wrong place
428 #define STEN_LOW_WAIT statusAzt()
429 static void statusAzt(void)
431 AztTimeout = AZT_STATUS_DELAY;
432 SET_TIMER(aztStatTimer, HZ / 100);
433 sleep_on(&azt_waitq);
435 printk("aztcd: Error Wait STEN_LOW_WAIT command:%x\n",
440 static void aztStatTimer(void)
442 if (!(inb(STATUS_PORT) & AFL_STATUS)) {
447 if (AztTimeout <= 0) {
449 printk("aztcd: Error aztStatTimer: Timeout\n");
452 SET_TIMER(aztStatTimer, HZ / 100);
455 /*##########################################################################
456 CDROM Drive Command Functions
457 ##########################################################################
460 * Send a single command, return -1 on error, else 0
462 static int aztSendCmd(int cmd)
468 printk("aztcd: Executing command %x\n", cmd);
471 if ((azt_port == 0x1f0) || (azt_port == 0x170))
472 SWITCH_IDE_SLAVE; /*switch IDE interface to slave configuration */
475 outb(POLLED, MODE_PORT);
477 if (inb(STATUS_PORT) & AFL_STATUS)
479 inb(DATA_PORT); /* if status left from last command, read and */
480 } while (1); /* discard it */
482 if (inb(STATUS_PORT) & AFL_DATA)
484 inb(DATA_PORT); /* if data left from last command, read and */
485 } while (1); /* discard it */
486 for (retry = 0; retry < AZT_RETRY_ATTEMPTS; retry++) {
487 outb((unsigned char) cmd, CMD_PORT);
489 data = inb(DATA_PORT);
490 if (data == AFL_OP_OK) {
493 if (data == AFL_OP_ERR) {
495 data = inb(DATA_PORT);
497 ("### Error 1 aztcd: aztSendCmd %x Error Code %x\n",
501 if (retry >= AZT_RETRY_ATTEMPTS) {
502 printk("### Error 2 aztcd: aztSendCmd %x \n", cmd);
505 RETURNM("aztSendCmd", -1);
509 * Send a play or read command to the drive, return -1 on error, else 0
511 static int sendAztCmd(int cmd, struct azt_Play_msf *params)
517 printk("aztcd: play start=%02x:%02x:%02x end=%02x:%02x:%02x\n",
518 params->start.min, params->start.sec, params->start.frame,
519 params->end.min, params->end.sec, params->end.frame);
521 for (retry = 0; retry < AZT_RETRY_ATTEMPTS; retry++) {
523 outb(params->start.min, CMD_PORT);
524 outb(params->start.sec, CMD_PORT);
525 outb(params->start.frame, CMD_PORT);
526 outb(params->end.min, CMD_PORT);
527 outb(params->end.sec, CMD_PORT);
528 outb(params->end.frame, CMD_PORT);
530 data = inb(DATA_PORT);
531 if (data == AFL_PA_OK) {
534 if (data == AFL_PA_ERR) {
536 data = inb(DATA_PORT);
538 ("### Error 1 aztcd: sendAztCmd %x Error Code %x\n",
542 if (retry >= AZT_RETRY_ATTEMPTS) {
543 printk("### Error 2 aztcd: sendAztCmd %x\n ", cmd);
546 RETURNM("sendAztCmd", -1);
550 * Send a seek command to the drive, return -1 on error, else 0
552 static int aztSeek(struct azt_Play_msf *params)
558 printk("aztcd: aztSeek %02x:%02x:%02x\n",
559 params->start.min, params->start.sec, params->start.frame);
561 for (retry = 0; retry < AZT_RETRY_ATTEMPTS; retry++) {
562 aztSendCmd(ACMD_SEEK);
563 outb(params->start.min, CMD_PORT);
564 outb(params->start.sec, CMD_PORT);
565 outb(params->start.frame, CMD_PORT);
567 data = inb(DATA_PORT);
568 if (data == AFL_PA_OK) {
571 if (data == AFL_PA_ERR) {
573 data = inb(DATA_PORT);
574 printk("### Error 1 aztcd: aztSeek\n");
577 if (retry >= AZT_RETRY_ATTEMPTS) {
578 printk("### Error 2 aztcd: aztSeek\n ");
581 RETURNM("aztSeek", -1);
584 /* Send a Set Disk Type command
585 does not seem to work with Aztech drives, behavior is completely indepen-
586 dent on which mode is set ???
588 static int aztSetDiskType(int type)
594 printk("aztcd: set disk type command: type= %i\n", type);
596 for (retry = 0; retry < AZT_RETRY_ATTEMPTS; retry++) {
597 aztSendCmd(ACMD_SET_DISK_TYPE);
598 outb(type, CMD_PORT);
600 data = inb(DATA_PORT);
601 if (data == AFL_PA_OK) { /*PA_OK ? */
602 azt_read_mode = type;
605 if (data == AFL_PA_ERR) {
607 data = inb(DATA_PORT);
609 ("### Error 1 aztcd: aztSetDiskType %x Error Code %x\n",
613 if (retry >= AZT_RETRY_ATTEMPTS) {
614 printk("### Error 2 aztcd: aztSetDiskType %x\n ", type);
617 RETURNM("aztSetDiskType", -1);
621 /* used in azt_poll to poll the status, expects another program to issue a
622 * ACMD_GET_STATUS directly before
624 static int aztStatus(void)
629 i = inb(STATUS_PORT) & AFL_STATUS; is STEN=0? ???
632 if (aztTimeOutCount < AZT_TIMEOUT) {
633 st = inb(DATA_PORT) & 0xFF;
636 RETURNM("aztStatus", -1);
640 * Get the drive status
642 static int getAztStatus(void)
646 if (aztSendCmd(ACMD_GET_STATUS))
647 RETURNM("getAztStatus 1", -1);
649 st = inb(DATA_PORT) & 0xFF;
651 printk("aztcd: Status = %x\n", st);
653 if ((st == 0xFF) || (st & AST_CMD_CHECK)) {
655 ("aztcd: AST_CMD_CHECK error or no status available\n");
659 if (((st & AST_MODE_BITS) != AST_BUSY)
660 && (aztAudioStatus == CDROM_AUDIO_PLAY))
661 /* XXX might be an error? look at q-channel? */
662 aztAudioStatus = CDROM_AUDIO_COMPLETED;
664 if ((st & AST_DSK_CHG) || (st & AST_NOT_READY)) {
667 aztAudioStatus = CDROM_AUDIO_NO_STATUS;
674 * Send a 'Play' command and get the status. Use only from the top half.
676 static int aztPlay(struct azt_Play_msf *arg)
678 if (sendAztCmd(ACMD_PLAY_AUDIO, arg) < 0)
679 RETURNM("aztPlay", -1);
684 * Subroutines to automatically close the door (tray) and
685 * lock it closed when the cd is mounted. Leave the tray
686 * locking as an option
688 static void aztCloseDoor(void)
690 aztSendCmd(ACMD_CLOSE);
695 static void aztLockDoor(void)
697 #if AZT_ALLOW_TRAY_LOCK
698 aztSendCmd(ACMD_LOCK);
704 static void aztUnlockDoor(void)
706 #if AZT_ALLOW_TRAY_LOCK
707 aztSendCmd(ACMD_UNLOCK);
714 * Read a value from the drive. Should return quickly, so a busy wait
715 * is used to avoid excessive rescheduling. The read command itself must
716 * be issued with aztSendCmd() directly before
718 static int aztGetValue(unsigned char *result)
723 if (aztTimeOutCount >= AZT_TIMEOUT) {
724 printk("aztcd: aztGetValue timeout\n");
727 s = inb(DATA_PORT) & 0xFF;
728 *result = (unsigned char) s;
733 * Read the current Q-channel info. Also used for reading the
736 static int aztGetQChannelInfo(struct azt_Toc *qp)
738 unsigned char notUsed;
742 printk("aztcd: starting aztGetQChannelInfo Time:%li\n", jiffies);
744 if ((st = getAztStatus()) == -1)
745 RETURNM("aztGetQChannelInfo 1", -1);
746 if (aztSendCmd(ACMD_GET_Q_CHANNEL))
747 RETURNM("aztGetQChannelInfo 2", -1);
748 /*STEN_LOW_WAIT; ??? Dosemu0.60's cdrom.c does not like STEN_LOW_WAIT here */
749 if (aztGetValue(¬Used))
750 RETURNM("aztGetQChannelInfo 3", -1); /*??? Nullbyte einlesen */
751 if ((st & AST_MODE_BITS) == AST_INITIAL) {
752 qp->ctrl_addr = 0; /* when audio stop ACMD_GET_Q_CHANNEL returns */
753 qp->track = 0; /* only one byte with Aztech drives */
755 qp->trackTime.min = 0;
756 qp->trackTime.sec = 0;
757 qp->trackTime.frame = 0;
758 qp->diskTime.min = 0;
759 qp->diskTime.sec = 0;
760 qp->diskTime.frame = 0;
763 if (aztGetValue(&qp->ctrl_addr) < 0)
764 RETURNM("aztGetQChannelInfo 4", -1);
765 if (aztGetValue(&qp->track) < 0)
766 RETURNM("aztGetQChannelInfo 4", -1);
767 if (aztGetValue(&qp->pointIndex) < 0)
768 RETURNM("aztGetQChannelInfo 4", -1);
769 if (aztGetValue(&qp->trackTime.min) < 0)
770 RETURNM("aztGetQChannelInfo 4", -1);
771 if (aztGetValue(&qp->trackTime.sec) < 0)
772 RETURNM("aztGetQChannelInfo 4", -1);
773 if (aztGetValue(&qp->trackTime.frame) < 0)
774 RETURNM("aztGetQChannelInfo 4", -1);
775 if (aztGetValue(¬Used) < 0)
776 RETURNM("aztGetQChannelInfo 4", -1);
777 if (aztGetValue(&qp->diskTime.min) < 0)
778 RETURNM("aztGetQChannelInfo 4", -1);
779 if (aztGetValue(&qp->diskTime.sec) < 0)
780 RETURNM("aztGetQChannelInfo 4", -1);
781 if (aztGetValue(&qp->diskTime.frame) < 0)
782 RETURNM("aztGetQChannelInfo 4", -1);
785 printk("aztcd: exiting aztGetQChannelInfo Time:%li\n", jiffies);
791 * Read the table of contents (TOC) and TOC header if necessary
793 static int aztUpdateToc(void)
798 printk("aztcd: starting aztUpdateToc Time:%li\n", jiffies);
803 if (aztGetDiskInfo() < 0)
806 if (aztGetToc(0) < 0)
809 /*audio disk detection
810 with my Aztech drive there is no audio status bit, so I use the copy
811 protection bit of the first track. If this track is copy protected
812 (copy bit = 0), I assume, it's an audio disk. Strange, but works ??? */
813 if (!(Toc[DiskInfo.first].ctrl_addr & 0x40))
819 if (!DiskInfo.audio) {
820 azt_Play.start.min = 0; /*XA detection only seems to work */
821 azt_Play.start.sec = 2; /*when we play a track */
822 azt_Play.start.frame = 0;
823 azt_Play.end.min = 0;
824 azt_Play.end.sec = 0;
825 azt_Play.end.frame = 1;
826 if (sendAztCmd(ACMD_PLAY_READ, &azt_Play))
829 for (st = 0; st < CD_FRAMESIZE; st++)
832 DiskInfo.xa = getAztStatus() & AST_MODE;
835 ("aztcd: XA support experimental - mail results to Werner.Zimmermann@fht-esslingen.de\n");
838 /*multisession detection
839 support for multisession CDs is done automatically with Aztech drives,
840 we don't have to take care about TOC redirection; if we want the isofs
841 to take care about redirection, we have to set AZT_MULTISESSION to 1 */
845 aztGetMultiDiskInfo(); /*here Disk.Info.multi is set */
848 if (DiskInfo.multi) {
849 DiskInfo.lastSession.min = Toc[DiskInfo.next].diskTime.min;
850 DiskInfo.lastSession.sec = Toc[DiskInfo.next].diskTime.sec;
851 DiskInfo.lastSession.frame =
852 Toc[DiskInfo.next].diskTime.frame;
853 printk("aztcd: Multisession support experimental\n");
855 DiskInfo.lastSession.min =
856 Toc[DiskInfo.first].diskTime.min;
857 DiskInfo.lastSession.sec =
858 Toc[DiskInfo.first].diskTime.sec;
859 DiskInfo.lastSession.frame =
860 Toc[DiskInfo.first].diskTime.frame;
865 printk("aztcd: exiting aztUpdateToc Time:%li\n", jiffies);
871 /* Read the table of contents header, i.e. no. of tracks and start of first
874 static int aztGetDiskInfo()
878 struct azt_Toc qInfo;
881 printk("aztcd: starting aztGetDiskInfo Time:%li\n", jiffies);
883 if (aztSendCmd(ACMD_SEEK_TO_LEADIN))
884 RETURNM("aztGetDiskInfo 1", -1);
887 for (limit = 300; limit > 0; limit--) {
888 if (aztGetQChannelInfo(&qInfo) < 0)
889 RETURNM("aztGetDiskInfo 2", -1);
890 if (qInfo.pointIndex == 0xA0) { /*Number of FirstTrack */
891 DiskInfo.first = qInfo.diskTime.min;
892 DiskInfo.first = azt_bcd2bin(DiskInfo.first);
895 if (qInfo.pointIndex == 0xA1) { /*Number of LastTrack */
896 DiskInfo.last = qInfo.diskTime.min;
897 DiskInfo.last = azt_bcd2bin(DiskInfo.last);
900 if (qInfo.pointIndex == 0xA2) { /*DiskLength */
901 DiskInfo.diskLength.min = qInfo.diskTime.min;
902 DiskInfo.diskLength.sec = qInfo.diskTime.sec;
903 DiskInfo.diskLength.frame = qInfo.diskTime.frame;
906 if ((qInfo.pointIndex == DiskInfo.first) && (test & 0x01)) { /*StartTime of First Track */
907 DiskInfo.firstTrack.min = qInfo.diskTime.min;
908 DiskInfo.firstTrack.sec = qInfo.diskTime.sec;
909 DiskInfo.firstTrack.frame = qInfo.diskTime.frame;
916 printk("aztcd: exiting aztGetDiskInfo Time:%li\n", jiffies);
918 ("Disk Info: first %d last %d length %02X:%02X.%02X dez first %02X:%02X.%02X dez\n",
919 DiskInfo.first, DiskInfo.last, DiskInfo.diskLength.min,
920 DiskInfo.diskLength.sec, DiskInfo.diskLength.frame,
921 DiskInfo.firstTrack.min, DiskInfo.firstTrack.sec,
922 DiskInfo.firstTrack.frame);
931 * Get Multisession Disk Info
933 static int aztGetMultiDiskInfo(void)
937 struct azt_Toc qInfo;
940 printk("aztcd: starting aztGetMultiDiskInfo\n");
944 azt_Play.start.min = Toc[DiskInfo.last + 1].diskTime.min;
945 azt_Play.start.sec = Toc[DiskInfo.last + 1].diskTime.sec;
946 azt_Play.start.frame =
947 Toc[DiskInfo.last + 1].diskTime.frame;
950 for (limit = 30; limit > 0; limit--) { /*Seek for LeadIn of next session */
951 if (aztSeek(&azt_Play))
952 RETURNM("aztGetMultiDiskInfo 1", -1);
953 if (aztGetQChannelInfo(&qInfo) < 0)
954 RETURNM("aztGetMultiDiskInfo 2", -1);
955 if ((qInfo.track == 0) && (qInfo.pointIndex))
956 break; /*LeadIn found */
957 if ((azt_Play.start.sec += 10) > 59) {
958 azt_Play.start.sec = 0;
959 azt_Play.start.min++;
963 break; /*Check, if a leadin track was found, if not we're
964 at the end of the disk */
965 #ifdef AZT_DEBUG_MULTISESSION
966 printk("leadin found track %d pointIndex %x limit %d\n",
967 qInfo.track, qInfo.pointIndex, limit);
969 for (limit = 300; limit > 0; limit--) {
970 if (++azt_Play.start.frame > 74) {
971 azt_Play.start.frame = 0;
972 if (azt_Play.start.sec > 59) {
973 azt_Play.start.sec = 0;
974 azt_Play.start.min++;
977 if (aztSeek(&azt_Play))
978 RETURNM("aztGetMultiDiskInfo 3", -1);
979 if (aztGetQChannelInfo(&qInfo) < 0)
980 RETURNM("aztGetMultiDiskInfo 4", -1);
981 if (qInfo.pointIndex == 0xA0) { /*Number of NextTrack */
982 DiskInfo.next = qInfo.diskTime.min;
983 DiskInfo.next = azt_bcd2bin(DiskInfo.next);
986 if (qInfo.pointIndex == 0xA1) { /*Number of LastTrack */
987 DiskInfo.last = qInfo.diskTime.min;
988 DiskInfo.last = azt_bcd2bin(DiskInfo.last);
991 if (qInfo.pointIndex == 0xA2) { /*DiskLength */
992 DiskInfo.diskLength.min =
994 DiskInfo.diskLength.sec =
996 DiskInfo.diskLength.frame =
997 qInfo.diskTime.frame;
1000 if ((qInfo.pointIndex == DiskInfo.next) && (test & 0x01)) { /*StartTime of Next Track */
1001 DiskInfo.nextSession.min =
1003 DiskInfo.nextSession.sec =
1005 DiskInfo.nextSession.frame =
1006 qInfo.diskTime.frame;
1012 #ifdef AZT_DEBUG_MULTISESSION
1014 ("MultiDisk Info: first %d next %d last %d length %02x:%02x.%02x dez first %02x:%02x.%02x dez next %02x:%02x.%02x dez\n",
1015 DiskInfo.first, DiskInfo.next, DiskInfo.last,
1016 DiskInfo.diskLength.min, DiskInfo.diskLength.sec,
1017 DiskInfo.diskLength.frame, DiskInfo.firstTrack.min,
1018 DiskInfo.firstTrack.sec, DiskInfo.firstTrack.frame,
1019 DiskInfo.nextSession.min, DiskInfo.nextSession.sec,
1020 DiskInfo.nextSession.frame);
1025 DiskInfo.multi = 1; /*found TOC of more than one session */
1030 printk("aztcd: exiting aztGetMultiDiskInfo Time:%li\n", jiffies);
1037 * Read the table of contents (TOC)
1039 static int aztGetToc(int multi)
1043 struct azt_Toc qInfo;
1046 printk("aztcd: starting aztGetToc Time:%li\n", jiffies);
1049 for (i = 0; i < MAX_TRACKS; i++)
1050 Toc[i].pointIndex = 0;
1051 i = DiskInfo.last + 3;
1053 for (i = DiskInfo.next; i < MAX_TRACKS; i++)
1054 Toc[i].pointIndex = 0;
1055 i = DiskInfo.last + 4 - DiskInfo.next;
1058 /*Is there a good reason to stop motor before TOC read?
1059 if (aztSendCmd(ACMD_STOP)) RETURNM("aztGetToc 1",-1);
1065 if (aztSendCmd(ACMD_SEEK_TO_LEADIN))
1066 RETURNM("aztGetToc 2", -1);
1069 for (limit = 300; limit > 0; limit--) {
1071 if (++azt_Play.start.sec > 59) {
1072 azt_Play.start.sec = 0;
1073 azt_Play.start.min++;
1075 if (aztSeek(&azt_Play))
1076 RETURNM("aztGetToc 3", -1);
1078 if (aztGetQChannelInfo(&qInfo) < 0)
1081 px = azt_bcd2bin(qInfo.pointIndex);
1083 if (px > 0 && px < MAX_TRACKS && qInfo.track == 0)
1084 if (Toc[px].pointIndex == 0) {
1093 Toc[DiskInfo.last + 1].diskTime = DiskInfo.diskLength;
1094 Toc[DiskInfo.last].trackTime = DiskInfo.diskLength;
1096 #ifdef AZT_DEBUG_MULTISESSION
1097 printk("aztcd: exiting aztGetToc\n");
1098 for (i = 1; i <= DiskInfo.last + 1; i++)
1100 ("i = %2d ctl-adr = %02X track %2d px %02X %02X:%02X.%02X dez %02X:%02X.%02X dez\n",
1101 i, Toc[i].ctrl_addr, Toc[i].track, Toc[i].pointIndex,
1102 Toc[i].trackTime.min, Toc[i].trackTime.sec,
1103 Toc[i].trackTime.frame, Toc[i].diskTime.min,
1104 Toc[i].diskTime.sec, Toc[i].diskTime.frame);
1105 for (i = 100; i < 103; i++)
1107 ("i = %2d ctl-adr = %02X track %2d px %02X %02X:%02X.%02X dez %02X:%02X.%02X dez\n",
1108 i, Toc[i].ctrl_addr, Toc[i].track, Toc[i].pointIndex,
1109 Toc[i].trackTime.min, Toc[i].trackTime.sec,
1110 Toc[i].trackTime.frame, Toc[i].diskTime.min,
1111 Toc[i].diskTime.sec, Toc[i].diskTime.frame);
1114 return limit > 0 ? 0 : -1;
1118 /*##########################################################################
1119 Kernel Interface Functions
1120 ##########################################################################
1124 static int __init aztcd_setup(char *str)
1128 (void) get_options(str, ARRAY_SIZE(ints), ints);
1137 __setup("aztcd=", aztcd_setup);
1139 #endif /* !MODULE */
1142 * Checking if the media has been changed
1144 static int check_aztcd_media_change(struct gendisk *disk)
1146 if (aztDiskChanged) { /* disk changed */
1150 return 0; /* no change */
1154 * Kernel IO-controls
1156 static int aztcd_ioctl(struct inode *ip, struct file *fp, unsigned int cmd,
1160 struct azt_Toc qInfo;
1162 struct cdrom_tochdr tocHdr;
1163 struct cdrom_msf msf;
1164 struct cdrom_tocentry entry;
1165 struct azt_Toc *tocPtr;
1166 struct cdrom_subchnl subchnl;
1167 struct cdrom_volctrl volctrl;
1170 printk("aztcd: starting aztcd_ioctl - Command:%x Time: %li\n",
1172 printk("aztcd Status %x\n", getAztStatus());
1175 RETURNM("aztcd_ioctl 1", -EINVAL);
1176 if (getAztStatus() < 0)
1177 RETURNM("aztcd_ioctl 2", -EIO);
1178 if ((!aztTocUpToDate) || (aztDiskChanged)) {
1179 if ((i = aztUpdateToc()) < 0)
1180 RETURNM("aztcd_ioctl 3", i); /* error reading TOC */
1184 case CDROMSTART: /* Spin up the drive. Don't know, what to do,
1185 at least close the tray */
1186 #if AZT_PRIVATE_IOCTLS
1187 if (aztSendCmd(ACMD_CLOSE))
1188 RETURNM("aztcd_ioctl 4", -1);
1192 case CDROMSTOP: /* Spin down the drive */
1193 if (aztSendCmd(ACMD_STOP))
1194 RETURNM("aztcd_ioctl 5", -1);
1196 /* should we do anything if it fails? */
1197 aztAudioStatus = CDROM_AUDIO_NO_STATUS;
1199 case CDROMPAUSE: /* Pause the drive */
1200 if (aztAudioStatus != CDROM_AUDIO_PLAY)
1203 if (aztGetQChannelInfo(&qInfo) < 0) { /* didn't get q channel info */
1204 aztAudioStatus = CDROM_AUDIO_NO_STATUS;
1205 RETURNM("aztcd_ioctl 7", 0);
1207 azt_Play.start = qInfo.diskTime; /* remember restart point */
1209 if (aztSendCmd(ACMD_PAUSE))
1210 RETURNM("aztcd_ioctl 8", -1);
1212 aztAudioStatus = CDROM_AUDIO_PAUSED;
1214 case CDROMRESUME: /* Play it again, Sam */
1215 if (aztAudioStatus != CDROM_AUDIO_PAUSED)
1217 /* restart the drive at the saved position. */
1218 i = aztPlay(&azt_Play);
1220 aztAudioStatus = CDROM_AUDIO_ERROR;
1223 aztAudioStatus = CDROM_AUDIO_PLAY;
1225 case CDROMMULTISESSION: /*multisession support -- experimental */
1227 struct cdrom_multisession ms;
1229 printk("aztcd ioctl MULTISESSION\n");
1233 sizeof(struct cdrom_multisession)))
1235 if (ms.addr_format == CDROM_MSF) {
1236 ms.addr.msf.minute =
1237 azt_bcd2bin(DiskInfo.lastSession.min);
1238 ms.addr.msf.second =
1239 azt_bcd2bin(DiskInfo.lastSession.sec);
1241 azt_bcd2bin(DiskInfo.lastSession.
1243 } else if (ms.addr_format == CDROM_LBA)
1245 azt_msf2hsg(&DiskInfo.lastSession);
1248 ms.xa_flag = DiskInfo.xa;
1251 sizeof(struct cdrom_multisession)))
1254 if (ms.addr_format == CDROM_MSF)
1256 ("aztcd multisession xa:%d, msf:%02x:%02x.%02x [%02x:%02x.%02x])\n",
1257 ms.xa_flag, ms.addr.msf.minute,
1258 ms.addr.msf.second, ms.addr.msf.frame,
1259 DiskInfo.lastSession.min,
1260 DiskInfo.lastSession.sec,
1261 DiskInfo.lastSession.frame);
1264 ("aztcd multisession %d, lba:0x%08x [%02x:%02x.%02x])\n",
1265 ms.xa_flag, ms.addr.lba,
1266 DiskInfo.lastSession.min,
1267 DiskInfo.lastSession.sec,
1268 DiskInfo.lastSession.frame);
1272 case CDROMPLAYTRKIND: /* Play a track. This currently ignores index. */
1273 if (copy_from_user(&ti, (void *) arg, sizeof ti))
1275 if (ti.cdti_trk0 < DiskInfo.first
1276 || ti.cdti_trk0 > DiskInfo.last
1277 || ti.cdti_trk1 < ti.cdti_trk0) {
1280 if (ti.cdti_trk1 > DiskInfo.last)
1281 ti.cdti_trk1 = DiskInfo.last;
1282 azt_Play.start = Toc[ti.cdti_trk0].diskTime;
1283 azt_Play.end = Toc[ti.cdti_trk1 + 1].diskTime;
1285 printk("aztcd play: %02x:%02x.%02x to %02x:%02x.%02x\n",
1286 azt_Play.start.min, azt_Play.start.sec,
1287 azt_Play.start.frame, azt_Play.end.min,
1288 azt_Play.end.sec, azt_Play.end.frame);
1290 i = aztPlay(&azt_Play);
1292 aztAudioStatus = CDROM_AUDIO_ERROR;
1295 aztAudioStatus = CDROM_AUDIO_PLAY;
1297 case CDROMPLAYMSF: /* Play starting at the given MSF address. */
1298 /* if (aztAudioStatus == CDROM_AUDIO_PLAY)
1299 { if (aztSendCmd(ACMD_STOP)) RETURNM("aztcd_ioctl 9",-1);
1301 aztAudioStatus = CDROM_AUDIO_NO_STATUS;
1304 if (copy_from_user(&msf, (void *) arg, sizeof msf))
1306 /* convert to bcd */
1307 azt_bin2bcd(&msf.cdmsf_min0);
1308 azt_bin2bcd(&msf.cdmsf_sec0);
1309 azt_bin2bcd(&msf.cdmsf_frame0);
1310 azt_bin2bcd(&msf.cdmsf_min1);
1311 azt_bin2bcd(&msf.cdmsf_sec1);
1312 azt_bin2bcd(&msf.cdmsf_frame1);
1313 azt_Play.start.min = msf.cdmsf_min0;
1314 azt_Play.start.sec = msf.cdmsf_sec0;
1315 azt_Play.start.frame = msf.cdmsf_frame0;
1316 azt_Play.end.min = msf.cdmsf_min1;
1317 azt_Play.end.sec = msf.cdmsf_sec1;
1318 azt_Play.end.frame = msf.cdmsf_frame1;
1320 printk("aztcd play: %02x:%02x.%02x to %02x:%02x.%02x\n",
1321 azt_Play.start.min, azt_Play.start.sec,
1322 azt_Play.start.frame, azt_Play.end.min,
1323 azt_Play.end.sec, azt_Play.end.frame);
1325 i = aztPlay(&azt_Play);
1327 aztAudioStatus = CDROM_AUDIO_ERROR;
1330 aztAudioStatus = CDROM_AUDIO_PLAY;
1333 case CDROMREADTOCHDR: /* Read the table of contents header */
1334 tocHdr.cdth_trk0 = DiskInfo.first;
1335 tocHdr.cdth_trk1 = DiskInfo.last;
1336 if (copy_to_user((void *) arg, &tocHdr, sizeof tocHdr))
1339 case CDROMREADTOCENTRY: /* Read an entry in the table of contents */
1340 if (copy_from_user(&entry, (void *) arg, sizeof entry))
1342 if ((!aztTocUpToDate) || aztDiskChanged)
1344 if (entry.cdte_track == CDROM_LEADOUT)
1345 tocPtr = &Toc[DiskInfo.last + 1];
1346 else if (entry.cdte_track > DiskInfo.last
1347 || entry.cdte_track < DiskInfo.first) {
1350 tocPtr = &Toc[entry.cdte_track];
1351 entry.cdte_adr = tocPtr->ctrl_addr;
1352 entry.cdte_ctrl = tocPtr->ctrl_addr >> 4;
1353 if (entry.cdte_format == CDROM_LBA)
1354 entry.cdte_addr.lba =
1355 azt_msf2hsg(&tocPtr->diskTime);
1356 else if (entry.cdte_format == CDROM_MSF) {
1357 entry.cdte_addr.msf.minute =
1358 azt_bcd2bin(tocPtr->diskTime.min);
1359 entry.cdte_addr.msf.second =
1360 azt_bcd2bin(tocPtr->diskTime.sec);
1361 entry.cdte_addr.msf.frame =
1362 azt_bcd2bin(tocPtr->diskTime.frame);
1366 if (copy_to_user((void *) arg, &entry, sizeof entry))
1369 case CDROMSUBCHNL: /* Get subchannel info */
1371 (&subchnl, (void *) arg, sizeof(struct cdrom_subchnl)))
1373 if (aztGetQChannelInfo(&qInfo) < 0) {
1376 ("aztcd: exiting aztcd_ioctl - Error 3 - Command:%x\n",
1381 subchnl.cdsc_audiostatus = aztAudioStatus;
1382 subchnl.cdsc_adr = qInfo.ctrl_addr;
1383 subchnl.cdsc_ctrl = qInfo.ctrl_addr >> 4;
1384 subchnl.cdsc_trk = azt_bcd2bin(qInfo.track);
1385 subchnl.cdsc_ind = azt_bcd2bin(qInfo.pointIndex);
1386 if (subchnl.cdsc_format == CDROM_LBA) {
1387 subchnl.cdsc_absaddr.lba =
1388 azt_msf2hsg(&qInfo.diskTime);
1389 subchnl.cdsc_reladdr.lba =
1390 azt_msf2hsg(&qInfo.trackTime);
1391 } else { /*default */
1392 subchnl.cdsc_format = CDROM_MSF;
1393 subchnl.cdsc_absaddr.msf.minute =
1394 azt_bcd2bin(qInfo.diskTime.min);
1395 subchnl.cdsc_absaddr.msf.second =
1396 azt_bcd2bin(qInfo.diskTime.sec);
1397 subchnl.cdsc_absaddr.msf.frame =
1398 azt_bcd2bin(qInfo.diskTime.frame);
1399 subchnl.cdsc_reladdr.msf.minute =
1400 azt_bcd2bin(qInfo.trackTime.min);
1401 subchnl.cdsc_reladdr.msf.second =
1402 azt_bcd2bin(qInfo.trackTime.sec);
1403 subchnl.cdsc_reladdr.msf.frame =
1404 azt_bcd2bin(qInfo.trackTime.frame);
1407 ((void *) arg, &subchnl, sizeof(struct cdrom_subchnl)))
1410 case CDROMVOLCTRL: /* Volume control
1411 * With my Aztech CD268-01A volume control does not work, I can only
1412 turn the channels on (any value !=0) or off (value==0). Maybe it
1413 works better with your drive */
1415 (&volctrl, (char *) arg, sizeof(volctrl)))
1417 azt_Play.start.min = 0x21;
1418 azt_Play.start.sec = 0x84;
1419 azt_Play.start.frame = volctrl.channel0;
1420 azt_Play.end.min = volctrl.channel1;
1421 azt_Play.end.sec = volctrl.channel2;
1422 azt_Play.end.frame = volctrl.channel3;
1423 sendAztCmd(ACMD_SET_VOLUME, &azt_Play);
1427 aztUnlockDoor(); /* Assume user knows what they're doing */
1428 /* all drives can at least stop! */
1429 if (aztAudioStatus == CDROM_AUDIO_PLAY) {
1430 if (aztSendCmd(ACMD_STOP))
1431 RETURNM("azt_ioctl 10", -1);
1434 if (aztSendCmd(ACMD_EJECT))
1435 RETURNM("azt_ioctl 11", -1);
1437 aztAudioStatus = CDROM_AUDIO_NO_STATUS;
1440 azt_auto_eject = (char) arg;
1443 outb(ACMD_SOFT_RESET, CMD_PORT); /*send reset */
1445 if (inb(DATA_PORT) != AFL_OP_OK) { /*OP_OK? */
1447 ("aztcd: AZTECH CD-ROM drive does not respond\n");
1450 /*Take care, the following code is not compatible with other CD-ROM drivers,
1451 use it at your own risk with cdplay.c. Set AZT_PRIVATE_IOCTLS to 0 in aztcd.h,
1452 if you do not want to use it!
1454 #if AZT_PRIVATE_IOCTLS
1455 case CDROMREADCOOKED: /*read data in mode 1 (2048 Bytes) */
1456 case CDROMREADRAW: /*read data in mode 2 (2336 Bytes) */
1458 if (copy_from_user(&msf, (void *) arg, sizeof msf))
1460 /* convert to bcd */
1461 azt_bin2bcd(&msf.cdmsf_min0);
1462 azt_bin2bcd(&msf.cdmsf_sec0);
1463 azt_bin2bcd(&msf.cdmsf_frame0);
1466 msf.cdmsf_frame1 = 1; /*read only one frame */
1467 azt_Play.start.min = msf.cdmsf_min0;
1468 azt_Play.start.sec = msf.cdmsf_sec0;
1469 azt_Play.start.frame = msf.cdmsf_frame0;
1470 azt_Play.end.min = msf.cdmsf_min1;
1471 azt_Play.end.sec = msf.cdmsf_sec1;
1472 azt_Play.end.frame = msf.cdmsf_frame1;
1473 if (cmd == CDROMREADRAW) {
1475 return -1; /*XA Disks can't be read raw */
1478 (ACMD_PLAY_READ_RAW,
1482 insb(DATA_PORT, buf,
1485 ((void *) arg, &buf,
1490 /*CDROMREADCOOKED*/ {
1491 if (sendAztCmd(ACMD_PLAY_READ, &azt_Play))
1494 insb(DATA_PORT, buf, CD_FRAMESIZE);
1496 ((void *) arg, &buf, CD_FRAMESIZE))
1501 case CDROMSEEK: /*seek msf address */
1502 if (copy_from_user(&msf, (void *) arg, sizeof msf))
1504 /* convert to bcd */
1505 azt_bin2bcd(&msf.cdmsf_min0);
1506 azt_bin2bcd(&msf.cdmsf_sec0);
1507 azt_bin2bcd(&msf.cdmsf_frame0);
1508 azt_Play.start.min = msf.cdmsf_min0;
1509 azt_Play.start.sec = msf.cdmsf_sec0;
1510 azt_Play.start.frame = msf.cdmsf_frame0;
1511 if (aztSeek(&azt_Play))
1514 #endif /*end of incompatible code */
1515 case CDROMREADMODE1: /*set read data in mode 1 */
1516 return aztSetDiskType(AZT_MODE_1);
1517 case CDROMREADMODE2: /*set read data in mode 2 */
1518 return aztSetDiskType(AZT_MODE_2);
1523 printk("aztcd: exiting aztcd_ioctl Command:%x Time:%li\n", cmd,
1530 * Take care of the different block sizes between cdrom and Linux.
1531 * When Linux gets variable block sizes this will probably go away.
1533 static void azt_transfer(void)
1536 printk("aztcd: executing azt_transfer Time:%li\n", jiffies);
1538 if (!current_valid())
1541 while (CURRENT->nr_sectors) {
1542 int bn = CURRENT->sector / 4;
1544 for (i = 0; i < AZT_BUF_SIZ && azt_buf_bn[i] != bn; ++i);
1545 if (i < AZT_BUF_SIZ) {
1546 int offs = (i * 4 + (CURRENT->sector & 3)) * 512;
1547 int nr_sectors = 4 - (CURRENT->sector & 3);
1548 if (azt_buf_out != i) {
1550 if (azt_buf_bn[i] != bn) {
1555 if (nr_sectors > CURRENT->nr_sectors)
1556 nr_sectors = CURRENT->nr_sectors;
1557 memcpy(CURRENT->buffer, azt_buf + offs,
1559 CURRENT->nr_sectors -= nr_sectors;
1560 CURRENT->sector += nr_sectors;
1561 CURRENT->buffer += nr_sectors * 512;
1569 static void do_aztcd_request(request_queue_t * q)
1572 printk(" do_aztcd_request(%ld+%ld) Time:%li\n", CURRENT->sector,
1573 CURRENT->nr_sectors, jiffies);
1575 if (DiskInfo.audio) {
1576 printk("aztcd: Error, tried to mount an Audio CD\n");
1577 end_request(CURRENT, 0);
1580 azt_transfer_is_active = 1;
1581 while (current_valid()) {
1583 if (CURRENT->nr_sectors == 0) {
1584 end_request(CURRENT, 1);
1586 azt_buf_out = -1; /* Want to read a block not in buffer */
1587 if (azt_state == AZT_S_IDLE) {
1588 if ((!aztTocUpToDate) || aztDiskChanged) {
1589 if (aztUpdateToc() < 0) {
1590 while (current_valid())
1591 end_request(CURRENT, 0);
1595 azt_state = AZT_S_START;
1597 SET_TIMER(azt_poll, HZ / 100);
1602 azt_transfer_is_active = 0;
1605 ("azt_next_bn:%x azt_buf_in:%x azt_buf_out:%x azt_buf_bn:%x\n",
1606 azt_next_bn, azt_buf_in, azt_buf_out, azt_buf_bn[azt_buf_in]);
1607 printk(" do_aztcd_request ends Time:%li\n", jiffies);
1612 static void azt_invalidate_buffers(void)
1617 printk("aztcd: executing azt_invalidate_buffers\n");
1619 for (i = 0; i < AZT_BUF_SIZ; ++i)
1625 * Open the device special file. Check that a disk is in.
1627 static int aztcd_open(struct inode *ip, struct file *fp)
1632 printk("aztcd: starting aztcd_open\n");
1635 if (aztPresent == 0)
1636 return -ENXIO; /* no hardware */
1638 if (!azt_open_count && azt_state == AZT_S_IDLE) {
1639 azt_invalidate_buffers();
1641 st = getAztStatus(); /* check drive status */
1643 goto err_out; /* drive doesn't respond */
1645 if (st & AST_DOOR_OPEN) { /* close door, then get the status again. */
1646 printk("aztcd: Door Open?\n");
1648 st = getAztStatus();
1651 if ((st & AST_NOT_READY) || (st & AST_DSK_CHG)) { /*no disk in drive or changed */
1653 ("aztcd: Disk Changed or No Disk in Drive?\n");
1664 printk("aztcd: exiting aztcd_open\n");
1674 * On close, we flush all azt blocks from the buffer cache.
1676 static int aztcd_release(struct inode *inode, struct file *file)
1679 printk("aztcd: executing aztcd_release\n");
1680 printk("inode: %p, device: %s file: %p\n", inode,
1681 inode->i_bdev->bd_disk->disk_name, file);
1683 if (!--azt_open_count) {
1684 azt_invalidate_buffers();
1687 aztSendCmd(ACMD_EJECT);
1693 static struct gendisk *azt_disk;
1696 * Test for presence of drive and initialize it. Called at boot time.
1699 static int __init aztcd_init(void)
1701 long int count, max_count;
1702 unsigned char result[50];
1704 void* status = NULL;
1708 if (azt_port == 0) {
1709 printk(KERN_INFO "aztcd: no Aztech CD-ROM Initialization");
1713 printk(KERN_INFO "aztcd: AZTECH, ORCHID, OKANO, WEARNES, TXC, CyDROM "
1715 printk(KERN_INFO "aztcd: (C) 1994-98 W.Zimmermann\n");
1716 if (azt_port == -1) {
1718 ("aztcd: KernelVersion=%s DriverVersion=%s For IDE/ATAPI-drives use ide-cd.c\n",
1719 UTS_RELEASE, AZT_VERSION);
1722 ("aztcd: DriverVersion=%s BaseAddress=0x%x For IDE/ATAPI-drives use ide-cd.c\n",
1723 AZT_VERSION, azt_port);
1724 printk(KERN_INFO "aztcd: If you have problems, read /usr/src/linux/"
1725 "Documentation/cdrom/aztcd\n");
1728 #ifdef AZT_SW32 /*CDROM connected to Soundwave32 card */
1729 if ((0xFF00 & inw(AZT_SW32_ID_REG)) != 0x4500) {
1731 ("aztcd: no Soundwave32 card detected at base:%x init:%x config:%x id:%x\n",
1732 AZT_SW32_BASE_ADDR, AZT_SW32_INIT,
1733 AZT_SW32_CONFIG_REG, AZT_SW32_ID_REG);
1737 "aztcd: Soundwave32 card detected at %x Version %x\n",
1738 AZT_SW32_BASE_ADDR, inw(AZT_SW32_ID_REG));
1739 outw(AZT_SW32_INIT, AZT_SW32_CONFIG_REG);
1740 for (count = 0; count < 10000; count++); /*delay a bit */
1744 /* check for presence of drive */
1746 if (azt_port == -1) { /* autoprobing for proprietary interface */
1747 for (i = 0; (azt_port_auto[i] != 0) && (i < 16); i++) {
1748 azt_port = azt_port_auto[i];
1749 printk(KERN_INFO "aztcd: Autoprobing BaseAddress=0x%x"
1751 /*proprietary interfaces need 4 bytes */
1752 if (!request_region(azt_port, 4, "aztcd")) {
1755 outb(POLLED, MODE_PORT);
1758 outb(ACMD_GET_VERSION, CMD_PORT); /*Try to get version info */
1760 aztTimeOutCount = 0;
1762 aztIndatum = inb(STATUS_PORT);
1764 if (aztTimeOutCount >= AZT_FAST_TIMEOUT)
1766 } while (aztIndatum & AFL_STATUS);
1767 if (inb(DATA_PORT) == AFL_OP_OK) { /* OK drive found */
1770 else { /* Drive not found on this port - try next one */
1771 release_region(azt_port, 4);
1774 if ((azt_port_auto[i] == 0) || (i == 16)) {
1775 printk(KERN_INFO "aztcd: no AZTECH CD-ROM drive found\n");
1778 } else { /* no autoprobing */
1779 if ((azt_port == 0x1f0) || (azt_port == 0x170))
1780 status = request_region(azt_port, 8, "aztcd"); /*IDE-interfaces need 8 bytes */
1782 status = request_region(azt_port, 4, "aztcd"); /*proprietary interfaces need 4 bytes */
1784 printk(KERN_WARNING "aztcd: conflict, I/O port (%X) "
1785 "already used\n", azt_port);
1789 if ((azt_port == 0x1f0) || (azt_port == 0x170))
1790 SWITCH_IDE_SLAVE; /*switch IDE interface to slave configuration */
1792 outb(POLLED, MODE_PORT);
1795 outb(ACMD_GET_VERSION, CMD_PORT); /*Try to get version info */
1797 aztTimeOutCount = 0;
1799 aztIndatum = inb(STATUS_PORT);
1801 if (aztTimeOutCount >= AZT_FAST_TIMEOUT)
1803 } while (aztIndatum & AFL_STATUS);
1805 if (inb(DATA_PORT) != AFL_OP_OK) { /*OP_OK? If not, reset and try again */
1807 if (azt_cont != 0x79) {
1808 printk(KERN_WARNING "aztcd: no AZTECH CD-ROM "
1809 "drive found-Try boot parameter aztcd="
1810 "<BaseAddress>,0x79\n");
1819 printk(KERN_INFO "aztcd: drive reset - "
1821 for (count = 0; count < 50; count++) {
1822 inb(STATUS_PORT); /*removing all data from earlier tries */
1825 outb(POLLED, MODE_PORT);
1828 getAztStatus(); /*trap errors */
1829 outb(ACMD_SOFT_RESET, CMD_PORT); /*send reset */
1831 if (inb(DATA_PORT) != AFL_OP_OK) { /*OP_OK? */
1832 printk(KERN_WARNING "aztcd: no AZTECH "
1833 "CD-ROM drive found\n");
1838 for (count = 0; count < AZT_TIMEOUT;
1840 barrier(); /* Stop gcc 2.96 being smart */
1841 /* use udelay(), damnit -- AV */
1843 if ((st = getAztStatus()) == -1) {
1844 printk(KERN_WARNING "aztcd: Drive Status"
1845 " Error Status=%x\n", st);
1850 printk(KERN_DEBUG "aztcd: Status = %x\n", st);
1852 outb(POLLED, MODE_PORT);
1855 outb(ACMD_GET_VERSION, CMD_PORT); /*GetVersion */
1864 result[0] = inb(DATA_PORT); /*reading in a null byte??? */
1865 for (count = 1; count < 50; count++) { /*Reading version string */
1866 aztTimeOutCount = 0; /*here we must implement STEN_LOW differently */
1868 aztIndatum = inb(STATUS_PORT); /*because we want to exit by timeout */
1870 if (aztTimeOutCount >= AZT_FAST_TIMEOUT)
1872 } while (aztIndatum & AFL_STATUS);
1873 if (aztTimeOutCount >= AZT_FAST_TIMEOUT)
1874 break; /*all chars read? */
1875 result[count] = inb(DATA_PORT);
1878 max_count = 30; /*print max.30 chars of the version string */
1881 printk(KERN_INFO "aztcd: FirmwareVersion=");
1882 for (count = 1; count < max_count; count++)
1883 printk("%c", result[count]);
1886 if ((result[1] == 'A') && (result[2] == 'Z') && (result[3] == 'T')) {
1887 printk("AZTECH drive detected\n");
1889 else if ((result[2] == 'C') && (result[3] == 'D')
1890 && (result[4] == 'D')) {
1891 printk("ORCHID or WEARNES drive detected\n"); /*ORCHID or WEARNES */
1892 } else if ((result[1] == 0x03) && (result[2] == '5')) {
1893 printk("TXC or CyCDROM drive detected\n"); /*Conrad TXC, CyCDROM */
1894 } else { /*OTHERS or none */
1895 printk("\nunknown drive or firmware version detected\n");
1897 ("aztcd may not run stable, if you want to try anyhow,\n");
1898 printk("boot with: aztcd=<BaseAddress>,0x79\n");
1899 if ((azt_cont != 0x79)) {
1900 printk("aztcd: FirmwareVersion=");
1901 for (count = 1; count < 5; count++)
1902 printk("%c", result[count]);
1904 printk("Aborted\n");
1909 azt_disk = alloc_disk(1);
1913 if (register_blkdev(MAJOR_NR, "aztcd")) {
1918 azt_queue = blk_init_queue(do_aztcd_request, &aztSpin);
1924 blk_queue_hardsect_size(azt_queue, 2048);
1925 azt_disk->major = MAJOR_NR;
1926 azt_disk->first_minor = 0;
1927 azt_disk->fops = &azt_fops;
1928 sprintf(azt_disk->disk_name, "aztcd");
1929 sprintf(azt_disk->devfs_name, "aztcd");
1930 azt_disk->queue = azt_queue;
1932 azt_invalidate_buffers();
1937 unregister_blkdev(MAJOR_NR, "aztcd");
1941 if ((azt_port == 0x1f0) || (azt_port == 0x170)) {
1943 release_region(azt_port, 8); /*IDE-interface */
1945 release_region(azt_port, 4); /*proprietary interface */
1950 static void __exit aztcd_exit(void)
1952 del_gendisk(azt_disk);
1954 if ((unregister_blkdev(MAJOR_NR, "aztcd") == -EINVAL)) {
1955 printk("What's that: can't unregister aztcd\n");
1958 blk_cleanup_queue(azt_queue);
1959 if ((azt_port == 0x1f0) || (azt_port == 0x170)) {
1961 release_region(azt_port, 8); /*IDE-interface */
1963 release_region(azt_port, 4); /*proprietary interface */
1964 printk(KERN_INFO "aztcd module released.\n");
1967 module_init(aztcd_init);
1968 module_exit(aztcd_exit);
1970 /*##########################################################################
1971 Aztcd State Machine: Controls Drive Operating State
1972 ##########################################################################
1974 static void azt_poll(void)
1981 if (aztSendCmd(ACMD_GET_ERROR))
1982 RETURN("azt_poll 1");
1984 azt_error = inb(DATA_PORT) & 0xFF;
1985 printk("aztcd: I/O error 0x%02x\n", azt_error);
1986 azt_invalidate_buffers();
1987 #ifdef WARN_IF_READ_FAILURE
1990 ("aztcd: Read of Block %d Failed - Maybe Audio Disk?\n",
1995 ("aztcd: Read of Block %d Failed, Maybe Audio Disk? Giving up\n",
1997 if (azt_transfer_is_active) {
2001 if (current_valid())
2002 end_request(CURRENT, 0);
2006 azt_state = AZT_S_STOP;
2010 loop_ctl = 0; /* each case must flip this back to 1 if we want
2011 to come back up here */
2012 switch (azt_state) {
2016 if (azt_state != azt_state_old) {
2017 azt_state_old = azt_state;
2018 printk("AZT_S_IDLE\n");
2025 if (azt_state != azt_state_old) {
2026 azt_state_old = azt_state;
2027 printk("AZT_S_START\n");
2030 if (aztSendCmd(ACMD_GET_STATUS))
2031 RETURN("azt_poll 2"); /*result will be checked by aztStatus() */
2033 azt_mode == 1 ? AZT_S_READ : AZT_S_MODE;
2039 if (azt_state != azt_state_old) {
2040 azt_state_old = azt_state;
2041 printk("AZT_S_MODE\n");
2045 if ((st = aztStatus()) != -1) {
2046 if ((st & AST_DSK_CHG)
2047 || (st & AST_NOT_READY)) {
2050 azt_invalidate_buffers();
2051 end_request(CURRENT, 0);
2053 ("aztcd: Disk Changed or Not Ready 1 - Unmount Disk!\n");
2060 if ((st & AST_DOOR_OPEN) || (st & AST_NOT_READY)) {
2064 ("aztcd: Disk Changed or Not Ready 2 - Unmount Disk!\n");
2065 end_request(CURRENT, 0);
2066 printk((st & AST_DOOR_OPEN) ?
2067 "aztcd: door open\n" :
2068 "aztcd: disk removed\n");
2069 if (azt_transfer_is_active) {
2070 azt_state = AZT_S_START;
2071 loop_ctl = 1; /* goto immediately */
2074 azt_state = AZT_S_IDLE;
2075 while (current_valid())
2076 end_request(CURRENT, 0);
2080 /* if (aztSendCmd(ACMD_SET_MODE)) RETURN("azt_poll 3");
2081 outb(0x01, DATA_PORT);
2085 if (aztSendCmd(ACMD_GET_STATUS))
2086 RETURN("azt_poll 4");
2089 azt_state = AZT_S_READ;
2097 if (azt_state != azt_state_old) {
2098 azt_state_old = azt_state;
2099 printk("AZT_S_READ\n");
2103 if ((st = aztStatus()) != -1) {
2104 if ((st & AST_DSK_CHG)
2105 || (st & AST_NOT_READY)) {
2108 azt_invalidate_buffers();
2110 ("aztcd: Disk Changed or Not Ready 3 - Unmount Disk!\n");
2111 end_request(CURRENT, 0);
2118 if ((st & AST_DOOR_OPEN) || (st & AST_NOT_READY)) {
2121 printk((st & AST_DOOR_OPEN) ?
2122 "aztcd: door open\n" :
2123 "aztcd: disk removed\n");
2124 if (azt_transfer_is_active) {
2125 azt_state = AZT_S_START;
2129 azt_state = AZT_S_IDLE;
2130 while (current_valid())
2131 end_request(CURRENT, 0);
2135 if (current_valid()) {
2136 struct azt_Play_msf msf;
2138 azt_next_bn = CURRENT->sector / 4;
2139 azt_hsg2msf(azt_next_bn, &msf.start);
2141 /* find out in which track we are */
2142 while (azt_msf2hsg(&msf.start) >
2143 azt_msf2hsg(&Toc[++i].trackTime)) {
2145 if (azt_msf2hsg(&msf.start) <
2146 azt_msf2hsg(&Toc[i].trackTime) -
2148 azt_read_count = AZT_BUF_SIZ; /*fast, because we read ahead */
2149 /*azt_read_count=CURRENT->nr_sectors; slow, no read ahead */
2150 } else /* don't read beyond end of track */
2151 #if AZT_MULTISESSION
2154 (azt_msf2hsg(&Toc[i].trackTime)
2156 azt_msf2hsg(&msf.start);
2157 if (azt_read_count < 0)
2159 if (azt_read_count > AZT_BUF_SIZ)
2163 ("aztcd: warning - trying to read beyond end of track\n");
2164 /* printk("%i %i %li %li\n",i,azt_read_count,azt_msf2hsg(&msf.start),azt_msf2hsg(&Toc[i].trackTime));
2168 azt_read_count = AZT_BUF_SIZ;
2173 msf.end.frame = azt_read_count; /*Mitsumi here reads 0xffffff sectors */
2176 ("---reading msf-address %x:%x:%x %x:%x:%x\n",
2177 msf.start.min, msf.start.sec,
2178 msf.start.frame, msf.end.min,
2179 msf.end.sec, msf.end.frame);
2181 ("azt_next_bn:%x azt_buf_in:%x azt_buf_out:%x azt_buf_bn:%x\n",
2182 azt_next_bn, azt_buf_in, azt_buf_out,
2183 azt_buf_bn[azt_buf_in]);
2185 if (azt_read_mode == AZT_MODE_2) {
2186 sendAztCmd(ACMD_PLAY_READ_RAW, &msf); /*XA disks in raw mode */
2188 sendAztCmd(ACMD_PLAY_READ, &msf); /*others in cooked mode */
2190 azt_state = AZT_S_DATA;
2191 AztTimeout = READ_TIMEOUT;
2193 azt_state = AZT_S_STOP;
2203 if (azt_state != azt_state_old) {
2204 azt_state_old = azt_state;
2205 printk("AZT_S_DATA\n");
2209 st = inb(STATUS_PORT) & AFL_STATUSorDATA;
2215 if (st != azt_st_old) {
2217 printk("---AFL_DATA st:%x\n", st);
2222 ("aztcd: Read of Block %d Failed, Maybe Audio Disk ? Giving up\n",
2224 if (azt_transfer_is_active) {
2228 if (current_valid())
2229 end_request(CURRENT, 0);
2232 azt_state = AZT_S_START;
2233 AztTimeout = READ_TIMEOUT;
2237 case AFL_STATUSorDATA:
2239 if (st != azt_st_old) {
2242 ("---AFL_STATUSorDATA st:%x\n",
2250 if (st != azt_st_old) {
2252 printk("---default: st:%x\n", st);
2256 if (!current_valid() && azt_buf_in == azt_buf_out) {
2257 azt_state = AZT_S_STOP;
2261 if (azt_read_count <= 0)
2263 ("aztcd: warning - try to read 0 frames\n");
2264 while (azt_read_count) { /*??? fast read ahead loop */
2265 azt_buf_bn[azt_buf_in] = -1;
2266 DTEN_LOW; /*??? unsolved problem, very
2267 seldom we get timeouts
2268 here, don't now the real
2269 reason. With my drive this
2270 sometimes also happens with
2271 Aztech's original driver under
2272 DOS. Is it a hardware bug?
2273 I tried to recover from such
2274 situations here. Zimmermann */
2275 if (aztTimeOutCount >= AZT_TIMEOUT) {
2277 ("read_count:%d CURRENT->nr_sectors:%ld azt_buf_in:%d\n",
2279 CURRENT->nr_sectors,
2282 ("azt_transfer_is_active:%x\n",
2283 azt_transfer_is_active);
2285 azt_state = AZT_S_STOP;
2287 end_request(CURRENT, 1); /*should we have here (1) or (0)? */
2289 if (azt_read_mode ==
2306 ("AZT_S_DATA; ---I've read data- read_count: %d\n",
2309 ("azt_next_bn:%d azt_buf_in:%d azt_buf_out:%d azt_buf_bn:%d\n",
2316 azt_buf_bn[azt_buf_in] =
2318 if (azt_buf_out == -1)
2327 if (!azt_transfer_is_active) {
2328 while (current_valid()) {
2330 if (CURRENT->nr_sectors ==
2332 end_request(CURRENT, 1);
2339 && (CURRENT->sector / 4 < azt_next_bn
2340 || CURRENT->sector / 4 >
2341 azt_next_bn + AZT_BUF_SIZ)) {
2342 azt_state = AZT_S_STOP;
2346 AztTimeout = READ_TIMEOUT;
2347 if (azt_read_count == 0) {
2348 azt_state = AZT_S_STOP;
2359 if (azt_state != azt_state_old) {
2360 azt_state_old = azt_state;
2361 printk("AZT_S_STOP\n");
2364 if (azt_read_count != 0)
2365 printk("aztcd: discard data=%x frames\n",
2367 while (azt_read_count != 0) {
2369 if (!(inb(STATUS_PORT) & AFL_DATA)) {
2370 if (azt_read_mode == AZT_MODE_2)
2372 i < CD_FRAMESIZE_RAW;
2377 i < CD_FRAMESIZE; i++)
2382 if (aztSendCmd(ACMD_GET_STATUS))
2383 RETURN("azt_poll 5");
2384 azt_state = AZT_S_STOPPING;
2388 case AZT_S_STOPPING:
2390 if (azt_state != azt_state_old) {
2391 azt_state_old = azt_state;
2392 printk("AZT_S_STOPPING\n");
2396 if ((st = aztStatus()) == -1 && AztTimeout)
2400 && ((st & AST_DSK_CHG)
2401 || (st & AST_NOT_READY))) {
2404 azt_invalidate_buffers();
2406 ("aztcd: Disk Changed or Not Ready 4 - Unmount Disk!\n");
2407 end_request(CURRENT, 0);
2411 printk("CURRENT_VALID %d azt_mode %d\n",
2412 current_valid(), azt_mode);
2415 if (current_valid()) {
2417 if (azt_mode == 1) {
2418 azt_state = AZT_S_READ;
2423 azt_state = AZT_S_MODE;
2429 azt_state = AZT_S_START;
2433 azt_state = AZT_S_IDLE;
2439 printk("aztcd: invalid state %d\n", azt_state);
2445 if (!AztTimeout--) {
2446 printk("aztcd: timeout in state %d\n", azt_state);
2447 azt_state = AZT_S_STOP;
2448 if (aztSendCmd(ACMD_STOP))
2449 RETURN("azt_poll 6");
2453 SET_TIMER(azt_poll, HZ / 100);
2457 /*###########################################################################
2458 * Miscellaneous support functions
2459 ###########################################################################
2461 static void azt_hsg2msf(long hsg, struct msf *msf)
2464 msf->min = hsg / 4500;
2466 msf->sec = hsg / 75;
2467 msf->frame = hsg % 75;
2470 printk("aztcd: Error hsg2msf address Minutes\n");
2472 printk("aztcd: Error hsg2msf address Seconds\n");
2473 if (msf->frame >= 75)
2474 printk("aztcd: Error hsg2msf address Frames\n");
2476 azt_bin2bcd(&msf->min); /* convert to BCD */
2477 azt_bin2bcd(&msf->sec);
2478 azt_bin2bcd(&msf->frame);
2481 static long azt_msf2hsg(struct msf *mp)
2483 return azt_bcd2bin(mp->frame) + azt_bcd2bin(mp->sec) * 75
2484 + azt_bcd2bin(mp->min) * 4500 - CD_MSF_OFFSET;
2487 static void azt_bin2bcd(unsigned char *p)
2496 static int azt_bcd2bin(unsigned char bcd)
2498 return (bcd >> 4) * 10 + (bcd & 0xF);
2501 MODULE_LICENSE("GPL");
2502 MODULE_ALIAS_BLOCKDEV_MAJOR(AZTECH_CDROM_MAJOR);