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 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/blkdev.h>
171 #include <linux/module.h>
172 #include <linux/errno.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 #include <linux/init.h>
184 #include <asm/system.h>
187 #include <asm/uaccess.h>
189 /*###########################################################################
191 ###########################################################################
194 #define MAJOR_NR AZTECH_CDROM_MAJOR
195 #define QUEUE (azt_queue)
196 #define CURRENT elv_next_request(azt_queue)
197 #define SET_TIMER(func, jifs) delay_timer.expires = jiffies + (jifs); \
198 delay_timer.function = (void *) (func); \
199 add_timer(&delay_timer);
201 #define CLEAR_TIMER del_timer(&delay_timer);
203 #define RETURNM(message,value) {printk("aztcd: Warning: %s failed\n",message);\
205 #define RETURN(message) {printk("aztcd: Warning: %s failed\n",message);\
208 /* Macros to switch the IDE-interface to the slave device and back to the master*/
209 #define SWITCH_IDE_SLAVE outb_p(0xa0,azt_port+6); \
210 outb_p(0x10,azt_port+6); \
211 outb_p(0x00,azt_port+7); \
212 outb_p(0x10,azt_port+6);
213 #define SWITCH_IDE_MASTER outb_p(0xa0,azt_port+6);
218 #define AZT_TEST1 /* <int-..> */
219 #define AZT_TEST2 /* do_aztcd_request */
220 #define AZT_TEST3 /* AZT_S_state */
221 #define AZT_TEST4 /* QUICK_LOOP-counter */
222 #define AZT_TEST5 /* port(1) state */
224 #define AZT_DEBUG_MULTISESSION
227 static struct request_queue *azt_queue;
229 static int current_valid(void)
232 CURRENT->cmd == READ &&
233 CURRENT->sector != -1;
236 #define AFL_STATUSorDATA (AFL_STATUS | AFL_DATA)
237 #define AZT_BUF_SIZ 16
239 #define READ_TIMEOUT 3000
241 #define azt_port aztcd /*needed for the modutils */
243 /*##########################################################################
245 ##########################################################################
247 enum azt_state_e { AZT_S_IDLE, /* 0 */
253 AZT_S_STOPPING /* 6 */
255 enum azt_read_modes { AZT_MODE_0, /*read mode for audio disks, not supported by Aztech firmware */
256 AZT_MODE_1, /*read mode for normal CD-ROMs */
257 AZT_MODE_2 /*read mode for XA CD-ROMs */
260 /*##########################################################################
262 ##########################################################################
264 static int aztPresent = 0;
266 static volatile int azt_transfer_is_active = 0;
268 static char azt_buf[CD_FRAMESIZE_RAW * AZT_BUF_SIZ]; /*buffer for block size conversion */
269 #if AZT_PRIVATE_IOCTLS
270 static char buf[CD_FRAMESIZE_RAW]; /*separate buffer for the ioctls */
273 static volatile int azt_buf_bn[AZT_BUF_SIZ], azt_next_bn;
274 static volatile int azt_buf_in, azt_buf_out = -1;
275 static volatile int azt_error = 0;
276 static int azt_open_count = 0;
277 static volatile enum azt_state_e azt_state = AZT_S_IDLE;
279 static volatile enum azt_state_e azt_state_old = AZT_S_STOP;
280 static volatile int azt_st_old = 0;
282 static volatile enum azt_read_modes azt_read_mode = AZT_MODE_1;
284 static int azt_mode = -1;
285 static volatile int azt_read_count = 1;
287 static int azt_port = AZT_BASE_ADDR;
289 module_param(azt_port, int, 0);
291 static int azt_port_auto[16] = AZT_BASE_AUTO;
293 static char azt_cont = 0;
294 static char azt_init_end = 0;
295 static char azt_auto_eject = AZT_AUTO_EJECT;
297 static int AztTimeout, AztTries;
298 static DECLARE_WAIT_QUEUE_HEAD(azt_waitq);
299 static DEFINE_TIMER(delay_timer, NULL, 0, 0);
301 static struct azt_DiskInfo DiskInfo;
302 static struct azt_Toc Toc[MAX_TRACKS];
303 static struct azt_Play_msf azt_Play;
305 static int aztAudioStatus = CDROM_AUDIO_NO_STATUS;
306 static char aztDiskChanged = 1;
307 static char aztTocUpToDate = 0;
309 static unsigned char aztIndatum;
310 static unsigned long aztTimeOutCount;
311 static int aztCmd = 0;
313 static DEFINE_SPINLOCK(aztSpin);
315 /*###########################################################################
317 ###########################################################################
319 /* CDROM Drive Low Level I/O Functions */
320 static void aztStatTimer(void);
322 /* CDROM Drive Command Functions */
323 static int aztGetDiskInfo(void);
325 static int aztGetMultiDiskInfo(void);
327 static int aztGetToc(int multi);
329 /* Kernel Interface Functions */
330 static int check_aztcd_media_change(struct gendisk *disk);
331 static int aztcd_ioctl(struct inode *ip, struct file *fp, unsigned int cmd,
333 static int aztcd_open(struct inode *ip, struct file *fp);
334 static int aztcd_release(struct inode *inode, struct file *file);
336 static struct block_device_operations azt_fops = {
337 .owner = THIS_MODULE,
339 .release = aztcd_release,
340 .ioctl = aztcd_ioctl,
341 .media_changed = check_aztcd_media_change,
344 /* Aztcd State Machine: Controls Drive Operating State */
345 static void azt_poll(void);
347 /* Miscellaneous support functions */
348 static void azt_hsg2msf(long hsg, struct msf *msf);
349 static long azt_msf2hsg(struct msf *mp);
350 static void azt_bin2bcd(unsigned char *p);
351 static int azt_bcd2bin(unsigned char bcd);
353 /*##########################################################################
354 CDROM Drive Low Level I/O Functions
355 ##########################################################################
357 /* Macros for the drive hardware interface handshake, these macros use
359 /* Wait for OP_OK = drive answers with AFL_OP_OK after receiving a command*/
360 # define OP_OK op_ok()
361 static void op_ok(void)
365 aztIndatum = inb(DATA_PORT);
367 if (aztTimeOutCount >= AZT_TIMEOUT) {
368 printk("aztcd: Error Wait OP_OK\n");
371 } while (aztIndatum != AFL_OP_OK);
374 /* Wait for PA_OK = drive answers with AFL_PA_OK after receiving parameters*/
376 # define PA_OK pa_ok()
377 static void pa_ok(void)
381 aztIndatum = inb(DATA_PORT);
383 if (aztTimeOutCount >= AZT_TIMEOUT) {
384 printk("aztcd: Error Wait PA_OK\n");
387 } 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(void)
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;
1168 void __user *argp = (void __user *)arg;
1171 printk("aztcd: starting aztcd_ioctl - Command:%x Time: %li\n",
1173 printk("aztcd Status %x\n", getAztStatus());
1176 RETURNM("aztcd_ioctl 1", -EINVAL);
1177 if (getAztStatus() < 0)
1178 RETURNM("aztcd_ioctl 2", -EIO);
1179 if ((!aztTocUpToDate) || (aztDiskChanged)) {
1180 if ((i = aztUpdateToc()) < 0)
1181 RETURNM("aztcd_ioctl 3", i); /* error reading TOC */
1185 case CDROMSTART: /* Spin up the drive. Don't know, what to do,
1186 at least close the tray */
1187 #if AZT_PRIVATE_IOCTLS
1188 if (aztSendCmd(ACMD_CLOSE))
1189 RETURNM("aztcd_ioctl 4", -1);
1193 case CDROMSTOP: /* Spin down the drive */
1194 if (aztSendCmd(ACMD_STOP))
1195 RETURNM("aztcd_ioctl 5", -1);
1197 /* should we do anything if it fails? */
1198 aztAudioStatus = CDROM_AUDIO_NO_STATUS;
1200 case CDROMPAUSE: /* Pause the drive */
1201 if (aztAudioStatus != CDROM_AUDIO_PLAY)
1204 if (aztGetQChannelInfo(&qInfo) < 0) { /* didn't get q channel info */
1205 aztAudioStatus = CDROM_AUDIO_NO_STATUS;
1206 RETURNM("aztcd_ioctl 7", 0);
1208 azt_Play.start = qInfo.diskTime; /* remember restart point */
1210 if (aztSendCmd(ACMD_PAUSE))
1211 RETURNM("aztcd_ioctl 8", -1);
1213 aztAudioStatus = CDROM_AUDIO_PAUSED;
1215 case CDROMRESUME: /* Play it again, Sam */
1216 if (aztAudioStatus != CDROM_AUDIO_PAUSED)
1218 /* restart the drive at the saved position. */
1219 i = aztPlay(&azt_Play);
1221 aztAudioStatus = CDROM_AUDIO_ERROR;
1224 aztAudioStatus = CDROM_AUDIO_PLAY;
1226 case CDROMMULTISESSION: /*multisession support -- experimental */
1228 struct cdrom_multisession ms;
1230 printk("aztcd ioctl MULTISESSION\n");
1232 if (copy_from_user(&ms, argp,
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;
1249 if (copy_to_user(argp, &ms,
1250 sizeof(struct cdrom_multisession)))
1253 if (ms.addr_format == CDROM_MSF)
1255 ("aztcd multisession xa:%d, msf:%02x:%02x.%02x [%02x:%02x.%02x])\n",
1256 ms.xa_flag, ms.addr.msf.minute,
1257 ms.addr.msf.second, ms.addr.msf.frame,
1258 DiskInfo.lastSession.min,
1259 DiskInfo.lastSession.sec,
1260 DiskInfo.lastSession.frame);
1263 ("aztcd multisession %d, lba:0x%08x [%02x:%02x.%02x])\n",
1264 ms.xa_flag, ms.addr.lba,
1265 DiskInfo.lastSession.min,
1266 DiskInfo.lastSession.sec,
1267 DiskInfo.lastSession.frame);
1271 case CDROMPLAYTRKIND: /* Play a track. This currently ignores index. */
1272 if (copy_from_user(&ti, argp, sizeof ti))
1274 if (ti.cdti_trk0 < DiskInfo.first
1275 || ti.cdti_trk0 > DiskInfo.last
1276 || ti.cdti_trk1 < ti.cdti_trk0) {
1279 if (ti.cdti_trk1 > DiskInfo.last)
1280 ti.cdti_trk1 = DiskInfo.last;
1281 azt_Play.start = Toc[ti.cdti_trk0].diskTime;
1282 azt_Play.end = Toc[ti.cdti_trk1 + 1].diskTime;
1284 printk("aztcd play: %02x:%02x.%02x to %02x:%02x.%02x\n",
1285 azt_Play.start.min, azt_Play.start.sec,
1286 azt_Play.start.frame, azt_Play.end.min,
1287 azt_Play.end.sec, azt_Play.end.frame);
1289 i = aztPlay(&azt_Play);
1291 aztAudioStatus = CDROM_AUDIO_ERROR;
1294 aztAudioStatus = CDROM_AUDIO_PLAY;
1296 case CDROMPLAYMSF: /* Play starting at the given MSF address. */
1297 /* if (aztAudioStatus == CDROM_AUDIO_PLAY)
1298 { if (aztSendCmd(ACMD_STOP)) RETURNM("aztcd_ioctl 9",-1);
1300 aztAudioStatus = CDROM_AUDIO_NO_STATUS;
1303 if (copy_from_user(&msf, argp, sizeof msf))
1305 /* convert to bcd */
1306 azt_bin2bcd(&msf.cdmsf_min0);
1307 azt_bin2bcd(&msf.cdmsf_sec0);
1308 azt_bin2bcd(&msf.cdmsf_frame0);
1309 azt_bin2bcd(&msf.cdmsf_min1);
1310 azt_bin2bcd(&msf.cdmsf_sec1);
1311 azt_bin2bcd(&msf.cdmsf_frame1);
1312 azt_Play.start.min = msf.cdmsf_min0;
1313 azt_Play.start.sec = msf.cdmsf_sec0;
1314 azt_Play.start.frame = msf.cdmsf_frame0;
1315 azt_Play.end.min = msf.cdmsf_min1;
1316 azt_Play.end.sec = msf.cdmsf_sec1;
1317 azt_Play.end.frame = msf.cdmsf_frame1;
1319 printk("aztcd play: %02x:%02x.%02x to %02x:%02x.%02x\n",
1320 azt_Play.start.min, azt_Play.start.sec,
1321 azt_Play.start.frame, azt_Play.end.min,
1322 azt_Play.end.sec, azt_Play.end.frame);
1324 i = aztPlay(&azt_Play);
1326 aztAudioStatus = CDROM_AUDIO_ERROR;
1329 aztAudioStatus = CDROM_AUDIO_PLAY;
1332 case CDROMREADTOCHDR: /* Read the table of contents header */
1333 tocHdr.cdth_trk0 = DiskInfo.first;
1334 tocHdr.cdth_trk1 = DiskInfo.last;
1335 if (copy_to_user(argp, &tocHdr, sizeof tocHdr))
1338 case CDROMREADTOCENTRY: /* Read an entry in the table of contents */
1339 if (copy_from_user(&entry, argp, sizeof entry))
1341 if ((!aztTocUpToDate) || aztDiskChanged)
1343 if (entry.cdte_track == CDROM_LEADOUT)
1344 tocPtr = &Toc[DiskInfo.last + 1];
1345 else if (entry.cdte_track > DiskInfo.last
1346 || entry.cdte_track < DiskInfo.first) {
1349 tocPtr = &Toc[entry.cdte_track];
1350 entry.cdte_adr = tocPtr->ctrl_addr;
1351 entry.cdte_ctrl = tocPtr->ctrl_addr >> 4;
1352 if (entry.cdte_format == CDROM_LBA)
1353 entry.cdte_addr.lba =
1354 azt_msf2hsg(&tocPtr->diskTime);
1355 else if (entry.cdte_format == CDROM_MSF) {
1356 entry.cdte_addr.msf.minute =
1357 azt_bcd2bin(tocPtr->diskTime.min);
1358 entry.cdte_addr.msf.second =
1359 azt_bcd2bin(tocPtr->diskTime.sec);
1360 entry.cdte_addr.msf.frame =
1361 azt_bcd2bin(tocPtr->diskTime.frame);
1365 if (copy_to_user(argp, &entry, sizeof entry))
1368 case CDROMSUBCHNL: /* Get subchannel info */
1370 (&subchnl, argp, sizeof(struct cdrom_subchnl)))
1372 if (aztGetQChannelInfo(&qInfo) < 0) {
1375 ("aztcd: exiting aztcd_ioctl - Error 3 - Command:%x\n",
1380 subchnl.cdsc_audiostatus = aztAudioStatus;
1381 subchnl.cdsc_adr = qInfo.ctrl_addr;
1382 subchnl.cdsc_ctrl = qInfo.ctrl_addr >> 4;
1383 subchnl.cdsc_trk = azt_bcd2bin(qInfo.track);
1384 subchnl.cdsc_ind = azt_bcd2bin(qInfo.pointIndex);
1385 if (subchnl.cdsc_format == CDROM_LBA) {
1386 subchnl.cdsc_absaddr.lba =
1387 azt_msf2hsg(&qInfo.diskTime);
1388 subchnl.cdsc_reladdr.lba =
1389 azt_msf2hsg(&qInfo.trackTime);
1390 } else { /*default */
1391 subchnl.cdsc_format = CDROM_MSF;
1392 subchnl.cdsc_absaddr.msf.minute =
1393 azt_bcd2bin(qInfo.diskTime.min);
1394 subchnl.cdsc_absaddr.msf.second =
1395 azt_bcd2bin(qInfo.diskTime.sec);
1396 subchnl.cdsc_absaddr.msf.frame =
1397 azt_bcd2bin(qInfo.diskTime.frame);
1398 subchnl.cdsc_reladdr.msf.minute =
1399 azt_bcd2bin(qInfo.trackTime.min);
1400 subchnl.cdsc_reladdr.msf.second =
1401 azt_bcd2bin(qInfo.trackTime.sec);
1402 subchnl.cdsc_reladdr.msf.frame =
1403 azt_bcd2bin(qInfo.trackTime.frame);
1405 if (copy_to_user(argp, &subchnl, sizeof(struct cdrom_subchnl)))
1408 case CDROMVOLCTRL: /* Volume control
1409 * With my Aztech CD268-01A volume control does not work, I can only
1410 turn the channels on (any value !=0) or off (value==0). Maybe it
1411 works better with your drive */
1412 if (copy_from_user(&volctrl, argp, sizeof(volctrl)))
1414 azt_Play.start.min = 0x21;
1415 azt_Play.start.sec = 0x84;
1416 azt_Play.start.frame = volctrl.channel0;
1417 azt_Play.end.min = volctrl.channel1;
1418 azt_Play.end.sec = volctrl.channel2;
1419 azt_Play.end.frame = volctrl.channel3;
1420 sendAztCmd(ACMD_SET_VOLUME, &azt_Play);
1424 aztUnlockDoor(); /* Assume user knows what they're doing */
1425 /* all drives can at least stop! */
1426 if (aztAudioStatus == CDROM_AUDIO_PLAY) {
1427 if (aztSendCmd(ACMD_STOP))
1428 RETURNM("azt_ioctl 10", -1);
1431 if (aztSendCmd(ACMD_EJECT))
1432 RETURNM("azt_ioctl 11", -1);
1434 aztAudioStatus = CDROM_AUDIO_NO_STATUS;
1437 azt_auto_eject = (char) arg;
1440 outb(ACMD_SOFT_RESET, CMD_PORT); /*send reset */
1442 if (inb(DATA_PORT) != AFL_OP_OK) { /*OP_OK? */
1444 ("aztcd: AZTECH CD-ROM drive does not respond\n");
1447 /*Take care, the following code is not compatible with other CD-ROM drivers,
1448 use it at your own risk with cdplay.c. Set AZT_PRIVATE_IOCTLS to 0 in aztcd.h,
1449 if you do not want to use it!
1451 #if AZT_PRIVATE_IOCTLS
1452 case CDROMREADCOOKED: /*read data in mode 1 (2048 Bytes) */
1453 case CDROMREADRAW: /*read data in mode 2 (2336 Bytes) */
1455 if (copy_from_user(&msf, argp, sizeof msf))
1457 /* convert to bcd */
1458 azt_bin2bcd(&msf.cdmsf_min0);
1459 azt_bin2bcd(&msf.cdmsf_sec0);
1460 azt_bin2bcd(&msf.cdmsf_frame0);
1463 msf.cdmsf_frame1 = 1; /*read only one frame */
1464 azt_Play.start.min = msf.cdmsf_min0;
1465 azt_Play.start.sec = msf.cdmsf_sec0;
1466 azt_Play.start.frame = msf.cdmsf_frame0;
1467 azt_Play.end.min = msf.cdmsf_min1;
1468 azt_Play.end.sec = msf.cdmsf_sec1;
1469 azt_Play.end.frame = msf.cdmsf_frame1;
1470 if (cmd == CDROMREADRAW) {
1472 return -1; /*XA Disks can't be read raw */
1474 if (sendAztCmd(ACMD_PLAY_READ_RAW, &azt_Play))
1477 insb(DATA_PORT, buf, CD_FRAMESIZE_RAW);
1478 if (copy_to_user(argp, &buf, CD_FRAMESIZE_RAW))
1482 /*CDROMREADCOOKED*/ {
1483 if (sendAztCmd(ACMD_PLAY_READ, &azt_Play))
1486 insb(DATA_PORT, buf, CD_FRAMESIZE);
1487 if (copy_to_user(argp, &buf, CD_FRAMESIZE))
1492 case CDROMSEEK: /*seek msf address */
1493 if (copy_from_user(&msf, argp, sizeof msf))
1495 /* convert to bcd */
1496 azt_bin2bcd(&msf.cdmsf_min0);
1497 azt_bin2bcd(&msf.cdmsf_sec0);
1498 azt_bin2bcd(&msf.cdmsf_frame0);
1499 azt_Play.start.min = msf.cdmsf_min0;
1500 azt_Play.start.sec = msf.cdmsf_sec0;
1501 azt_Play.start.frame = msf.cdmsf_frame0;
1502 if (aztSeek(&azt_Play))
1505 #endif /*end of incompatible code */
1506 case CDROMREADMODE1: /*set read data in mode 1 */
1507 return aztSetDiskType(AZT_MODE_1);
1508 case CDROMREADMODE2: /*set read data in mode 2 */
1509 return aztSetDiskType(AZT_MODE_2);
1514 printk("aztcd: exiting aztcd_ioctl Command:%x Time:%li\n", cmd,
1521 * Take care of the different block sizes between cdrom and Linux.
1522 * When Linux gets variable block sizes this will probably go away.
1524 static void azt_transfer(void)
1527 printk("aztcd: executing azt_transfer Time:%li\n", jiffies);
1529 if (!current_valid())
1532 while (CURRENT->nr_sectors) {
1533 int bn = CURRENT->sector / 4;
1535 for (i = 0; i < AZT_BUF_SIZ && azt_buf_bn[i] != bn; ++i);
1536 if (i < AZT_BUF_SIZ) {
1537 int offs = (i * 4 + (CURRENT->sector & 3)) * 512;
1538 int nr_sectors = 4 - (CURRENT->sector & 3);
1539 if (azt_buf_out != i) {
1541 if (azt_buf_bn[i] != bn) {
1546 if (nr_sectors > CURRENT->nr_sectors)
1547 nr_sectors = CURRENT->nr_sectors;
1548 memcpy(CURRENT->buffer, azt_buf + offs,
1550 CURRENT->nr_sectors -= nr_sectors;
1551 CURRENT->sector += nr_sectors;
1552 CURRENT->buffer += nr_sectors * 512;
1560 static void do_aztcd_request(request_queue_t * q)
1563 printk(" do_aztcd_request(%ld+%ld) Time:%li\n", CURRENT->sector,
1564 CURRENT->nr_sectors, jiffies);
1566 if (DiskInfo.audio) {
1567 printk("aztcd: Error, tried to mount an Audio CD\n");
1568 end_request(CURRENT, 0);
1571 azt_transfer_is_active = 1;
1572 while (current_valid()) {
1574 if (CURRENT->nr_sectors == 0) {
1575 end_request(CURRENT, 1);
1577 azt_buf_out = -1; /* Want to read a block not in buffer */
1578 if (azt_state == AZT_S_IDLE) {
1579 if ((!aztTocUpToDate) || aztDiskChanged) {
1580 if (aztUpdateToc() < 0) {
1581 while (current_valid())
1582 end_request(CURRENT, 0);
1586 azt_state = AZT_S_START;
1588 SET_TIMER(azt_poll, HZ / 100);
1593 azt_transfer_is_active = 0;
1596 ("azt_next_bn:%x azt_buf_in:%x azt_buf_out:%x azt_buf_bn:%x\n",
1597 azt_next_bn, azt_buf_in, azt_buf_out, azt_buf_bn[azt_buf_in]);
1598 printk(" do_aztcd_request ends Time:%li\n", jiffies);
1603 static void azt_invalidate_buffers(void)
1608 printk("aztcd: executing azt_invalidate_buffers\n");
1610 for (i = 0; i < AZT_BUF_SIZ; ++i)
1616 * Open the device special file. Check that a disk is in.
1618 static int aztcd_open(struct inode *ip, struct file *fp)
1623 printk("aztcd: starting aztcd_open\n");
1626 if (aztPresent == 0)
1627 return -ENXIO; /* no hardware */
1629 if (!azt_open_count && azt_state == AZT_S_IDLE) {
1630 azt_invalidate_buffers();
1632 st = getAztStatus(); /* check drive status */
1634 goto err_out; /* drive doesn't respond */
1636 if (st & AST_DOOR_OPEN) { /* close door, then get the status again. */
1637 printk("aztcd: Door Open?\n");
1639 st = getAztStatus();
1642 if ((st & AST_NOT_READY) || (st & AST_DSK_CHG)) { /*no disk in drive or changed */
1644 ("aztcd: Disk Changed or No Disk in Drive?\n");
1655 printk("aztcd: exiting aztcd_open\n");
1665 * On close, we flush all azt blocks from the buffer cache.
1667 static int aztcd_release(struct inode *inode, struct file *file)
1670 printk("aztcd: executing aztcd_release\n");
1671 printk("inode: %p, device: %s file: %p\n", inode,
1672 inode->i_bdev->bd_disk->disk_name, file);
1674 if (!--azt_open_count) {
1675 azt_invalidate_buffers();
1678 aztSendCmd(ACMD_EJECT);
1684 static struct gendisk *azt_disk;
1687 * Test for presence of drive and initialize it. Called at boot time.
1690 static int __init aztcd_init(void)
1692 long int count, max_count;
1693 unsigned char result[50];
1695 void* status = NULL;
1699 if (azt_port == 0) {
1700 printk(KERN_INFO "aztcd: no Aztech CD-ROM Initialization");
1704 printk(KERN_INFO "aztcd: AZTECH, ORCHID, OKANO, WEARNES, TXC, CyDROM "
1706 printk(KERN_INFO "aztcd: (C) 1994-98 W.Zimmermann\n");
1707 if (azt_port == -1) {
1709 ("aztcd: DriverVersion=%s For IDE/ATAPI-drives use ide-cd.c\n",
1713 ("aztcd: DriverVersion=%s BaseAddress=0x%x For IDE/ATAPI-drives use ide-cd.c\n",
1714 AZT_VERSION, azt_port);
1715 printk(KERN_INFO "aztcd: If you have problems, read /usr/src/linux/"
1716 "Documentation/cdrom/aztcd\n");
1719 #ifdef AZT_SW32 /*CDROM connected to Soundwave32 card */
1720 if ((0xFF00 & inw(AZT_SW32_ID_REG)) != 0x4500) {
1722 ("aztcd: no Soundwave32 card detected at base:%x init:%x config:%x id:%x\n",
1723 AZT_SW32_BASE_ADDR, AZT_SW32_INIT,
1724 AZT_SW32_CONFIG_REG, AZT_SW32_ID_REG);
1728 "aztcd: Soundwave32 card detected at %x Version %x\n",
1729 AZT_SW32_BASE_ADDR, inw(AZT_SW32_ID_REG));
1730 outw(AZT_SW32_INIT, AZT_SW32_CONFIG_REG);
1731 for (count = 0; count < 10000; count++); /*delay a bit */
1735 /* check for presence of drive */
1737 if (azt_port == -1) { /* autoprobing for proprietary interface */
1738 for (i = 0; (azt_port_auto[i] != 0) && (i < 16); i++) {
1739 azt_port = azt_port_auto[i];
1740 printk(KERN_INFO "aztcd: Autoprobing BaseAddress=0x%x"
1742 /*proprietary interfaces need 4 bytes */
1743 if (!request_region(azt_port, 4, "aztcd")) {
1746 outb(POLLED, MODE_PORT);
1749 outb(ACMD_GET_VERSION, CMD_PORT); /*Try to get version info */
1751 aztTimeOutCount = 0;
1753 aztIndatum = inb(STATUS_PORT);
1755 if (aztTimeOutCount >= AZT_FAST_TIMEOUT)
1757 } while (aztIndatum & AFL_STATUS);
1758 if (inb(DATA_PORT) == AFL_OP_OK) { /* OK drive found */
1761 else { /* Drive not found on this port - try next one */
1762 release_region(azt_port, 4);
1765 if ((i == 16) || (azt_port_auto[i] == 0)) {
1766 printk(KERN_INFO "aztcd: no AZTECH CD-ROM drive found\n");
1769 } else { /* no autoprobing */
1770 if ((azt_port == 0x1f0) || (azt_port == 0x170))
1771 status = request_region(azt_port, 8, "aztcd"); /*IDE-interfaces need 8 bytes */
1773 status = request_region(azt_port, 4, "aztcd"); /*proprietary interfaces need 4 bytes */
1775 printk(KERN_WARNING "aztcd: conflict, I/O port (%X) "
1776 "already used\n", azt_port);
1780 if ((azt_port == 0x1f0) || (azt_port == 0x170))
1781 SWITCH_IDE_SLAVE; /*switch IDE interface to slave configuration */
1783 outb(POLLED, MODE_PORT);
1786 outb(ACMD_GET_VERSION, CMD_PORT); /*Try to get version info */
1788 aztTimeOutCount = 0;
1790 aztIndatum = inb(STATUS_PORT);
1792 if (aztTimeOutCount >= AZT_FAST_TIMEOUT)
1794 } while (aztIndatum & AFL_STATUS);
1796 if (inb(DATA_PORT) != AFL_OP_OK) { /*OP_OK? If not, reset and try again */
1798 if (azt_cont != 0x79) {
1799 printk(KERN_WARNING "aztcd: no AZTECH CD-ROM "
1800 "drive found-Try boot parameter aztcd="
1801 "<BaseAddress>,0x79\n");
1810 printk(KERN_INFO "aztcd: drive reset - "
1812 for (count = 0; count < 50; count++) {
1813 inb(STATUS_PORT); /*removing all data from earlier tries */
1816 outb(POLLED, MODE_PORT);
1819 getAztStatus(); /*trap errors */
1820 outb(ACMD_SOFT_RESET, CMD_PORT); /*send reset */
1822 if (inb(DATA_PORT) != AFL_OP_OK) { /*OP_OK? */
1823 printk(KERN_WARNING "aztcd: no AZTECH "
1824 "CD-ROM drive found\n");
1829 for (count = 0; count < AZT_TIMEOUT;
1831 barrier(); /* Stop gcc 2.96 being smart */
1832 /* use udelay(), damnit -- AV */
1834 if ((st = getAztStatus()) == -1) {
1835 printk(KERN_WARNING "aztcd: Drive Status"
1836 " Error Status=%x\n", st);
1841 printk(KERN_DEBUG "aztcd: Status = %x\n", st);
1843 outb(POLLED, MODE_PORT);
1846 outb(ACMD_GET_VERSION, CMD_PORT); /*GetVersion */
1855 result[0] = inb(DATA_PORT); /*reading in a null byte??? */
1856 for (count = 1; count < 50; count++) { /*Reading version string */
1857 aztTimeOutCount = 0; /*here we must implement STEN_LOW differently */
1859 aztIndatum = inb(STATUS_PORT); /*because we want to exit by timeout */
1861 if (aztTimeOutCount >= AZT_FAST_TIMEOUT)
1863 } while (aztIndatum & AFL_STATUS);
1864 if (aztTimeOutCount >= AZT_FAST_TIMEOUT)
1865 break; /*all chars read? */
1866 result[count] = inb(DATA_PORT);
1869 max_count = 30; /*print max.30 chars of the version string */
1872 printk(KERN_INFO "aztcd: FirmwareVersion=");
1873 for (count = 1; count < max_count; count++)
1874 printk("%c", result[count]);
1877 if ((result[1] == 'A') && (result[2] == 'Z') && (result[3] == 'T')) {
1878 printk("AZTECH drive detected\n");
1880 else if ((result[2] == 'C') && (result[3] == 'D')
1881 && (result[4] == 'D')) {
1882 printk("ORCHID or WEARNES drive detected\n"); /*ORCHID or WEARNES */
1883 } else if ((result[1] == 0x03) && (result[2] == '5')) {
1884 printk("TXC or CyCDROM drive detected\n"); /*Conrad TXC, CyCDROM */
1885 } else { /*OTHERS or none */
1886 printk("\nunknown drive or firmware version detected\n");
1888 ("aztcd may not run stable, if you want to try anyhow,\n");
1889 printk("boot with: aztcd=<BaseAddress>,0x79\n");
1890 if ((azt_cont != 0x79)) {
1891 printk("aztcd: FirmwareVersion=");
1892 for (count = 1; count < 5; count++)
1893 printk("%c", result[count]);
1895 printk("Aborted\n");
1900 azt_disk = alloc_disk(1);
1904 if (register_blkdev(MAJOR_NR, "aztcd")) {
1909 azt_queue = blk_init_queue(do_aztcd_request, &aztSpin);
1915 blk_queue_hardsect_size(azt_queue, 2048);
1916 azt_disk->major = MAJOR_NR;
1917 azt_disk->first_minor = 0;
1918 azt_disk->fops = &azt_fops;
1919 sprintf(azt_disk->disk_name, "aztcd");
1920 azt_disk->queue = azt_queue;
1922 azt_invalidate_buffers();
1927 unregister_blkdev(MAJOR_NR, "aztcd");
1931 if ((azt_port == 0x1f0) || (azt_port == 0x170)) {
1933 release_region(azt_port, 8); /*IDE-interface */
1935 release_region(azt_port, 4); /*proprietary interface */
1940 static void __exit aztcd_exit(void)
1942 del_gendisk(azt_disk);
1944 if ((unregister_blkdev(MAJOR_NR, "aztcd") == -EINVAL)) {
1945 printk("What's that: can't unregister aztcd\n");
1948 blk_cleanup_queue(azt_queue);
1949 if ((azt_port == 0x1f0) || (azt_port == 0x170)) {
1951 release_region(azt_port, 8); /*IDE-interface */
1953 release_region(azt_port, 4); /*proprietary interface */
1954 printk(KERN_INFO "aztcd module released.\n");
1957 module_init(aztcd_init);
1958 module_exit(aztcd_exit);
1960 /*##########################################################################
1961 Aztcd State Machine: Controls Drive Operating State
1962 ##########################################################################
1964 static void azt_poll(void)
1971 if (aztSendCmd(ACMD_GET_ERROR))
1972 RETURN("azt_poll 1");
1974 azt_error = inb(DATA_PORT) & 0xFF;
1975 printk("aztcd: I/O error 0x%02x\n", azt_error);
1976 azt_invalidate_buffers();
1977 #ifdef WARN_IF_READ_FAILURE
1980 ("aztcd: Read of Block %d Failed - Maybe Audio Disk?\n",
1985 ("aztcd: Read of Block %d Failed, Maybe Audio Disk? Giving up\n",
1987 if (azt_transfer_is_active) {
1991 if (current_valid())
1992 end_request(CURRENT, 0);
1996 azt_state = AZT_S_STOP;
2000 loop_ctl = 0; /* each case must flip this back to 1 if we want
2001 to come back up here */
2002 switch (azt_state) {
2006 if (azt_state != azt_state_old) {
2007 azt_state_old = azt_state;
2008 printk("AZT_S_IDLE\n");
2015 if (azt_state != azt_state_old) {
2016 azt_state_old = azt_state;
2017 printk("AZT_S_START\n");
2020 if (aztSendCmd(ACMD_GET_STATUS))
2021 RETURN("azt_poll 2"); /*result will be checked by aztStatus() */
2023 azt_mode == 1 ? AZT_S_READ : AZT_S_MODE;
2029 if (azt_state != azt_state_old) {
2030 azt_state_old = azt_state;
2031 printk("AZT_S_MODE\n");
2035 if ((st = aztStatus()) != -1) {
2036 if ((st & AST_DSK_CHG)
2037 || (st & AST_NOT_READY)) {
2040 azt_invalidate_buffers();
2041 end_request(CURRENT, 0);
2043 ("aztcd: Disk Changed or Not Ready 1 - Unmount Disk!\n");
2050 if ((st & AST_DOOR_OPEN) || (st & AST_NOT_READY)) {
2054 ("aztcd: Disk Changed or Not Ready 2 - Unmount Disk!\n");
2055 end_request(CURRENT, 0);
2056 printk((st & AST_DOOR_OPEN) ?
2057 "aztcd: door open\n" :
2058 "aztcd: disk removed\n");
2059 if (azt_transfer_is_active) {
2060 azt_state = AZT_S_START;
2061 loop_ctl = 1; /* goto immediately */
2064 azt_state = AZT_S_IDLE;
2065 while (current_valid())
2066 end_request(CURRENT, 0);
2070 /* if (aztSendCmd(ACMD_SET_MODE)) RETURN("azt_poll 3");
2071 outb(0x01, DATA_PORT);
2075 if (aztSendCmd(ACMD_GET_STATUS))
2076 RETURN("azt_poll 4");
2079 azt_state = AZT_S_READ;
2087 if (azt_state != azt_state_old) {
2088 azt_state_old = azt_state;
2089 printk("AZT_S_READ\n");
2093 if ((st = aztStatus()) != -1) {
2094 if ((st & AST_DSK_CHG)
2095 || (st & AST_NOT_READY)) {
2098 azt_invalidate_buffers();
2100 ("aztcd: Disk Changed or Not Ready 3 - Unmount Disk!\n");
2101 end_request(CURRENT, 0);
2108 if ((st & AST_DOOR_OPEN) || (st & AST_NOT_READY)) {
2111 printk((st & AST_DOOR_OPEN) ?
2112 "aztcd: door open\n" :
2113 "aztcd: disk removed\n");
2114 if (azt_transfer_is_active) {
2115 azt_state = AZT_S_START;
2119 azt_state = AZT_S_IDLE;
2120 while (current_valid())
2121 end_request(CURRENT, 0);
2125 if (current_valid()) {
2126 struct azt_Play_msf msf;
2128 azt_next_bn = CURRENT->sector / 4;
2129 azt_hsg2msf(azt_next_bn, &msf.start);
2131 /* find out in which track we are */
2132 while (azt_msf2hsg(&msf.start) >
2133 azt_msf2hsg(&Toc[++i].trackTime)) {
2135 if (azt_msf2hsg(&msf.start) <
2136 azt_msf2hsg(&Toc[i].trackTime) -
2138 azt_read_count = AZT_BUF_SIZ; /*fast, because we read ahead */
2139 /*azt_read_count=CURRENT->nr_sectors; slow, no read ahead */
2140 } else /* don't read beyond end of track */
2141 #if AZT_MULTISESSION
2144 (azt_msf2hsg(&Toc[i].trackTime)
2146 azt_msf2hsg(&msf.start);
2147 if (azt_read_count < 0)
2149 if (azt_read_count > AZT_BUF_SIZ)
2153 ("aztcd: warning - trying to read beyond end of track\n");
2154 /* printk("%i %i %li %li\n",i,azt_read_count,azt_msf2hsg(&msf.start),azt_msf2hsg(&Toc[i].trackTime));
2158 azt_read_count = AZT_BUF_SIZ;
2163 msf.end.frame = azt_read_count; /*Mitsumi here reads 0xffffff sectors */
2166 ("---reading msf-address %x:%x:%x %x:%x:%x\n",
2167 msf.start.min, msf.start.sec,
2168 msf.start.frame, msf.end.min,
2169 msf.end.sec, msf.end.frame);
2171 ("azt_next_bn:%x azt_buf_in:%x azt_buf_out:%x azt_buf_bn:%x\n",
2172 azt_next_bn, azt_buf_in, azt_buf_out,
2173 azt_buf_bn[azt_buf_in]);
2175 if (azt_read_mode == AZT_MODE_2) {
2176 sendAztCmd(ACMD_PLAY_READ_RAW, &msf); /*XA disks in raw mode */
2178 sendAztCmd(ACMD_PLAY_READ, &msf); /*others in cooked mode */
2180 azt_state = AZT_S_DATA;
2181 AztTimeout = READ_TIMEOUT;
2183 azt_state = AZT_S_STOP;
2193 if (azt_state != azt_state_old) {
2194 azt_state_old = azt_state;
2195 printk("AZT_S_DATA\n");
2199 st = inb(STATUS_PORT) & AFL_STATUSorDATA;
2205 if (st != azt_st_old) {
2207 printk("---AFL_DATA st:%x\n", st);
2212 ("aztcd: Read of Block %d Failed, Maybe Audio Disk ? Giving up\n",
2214 if (azt_transfer_is_active) {
2218 if (current_valid())
2219 end_request(CURRENT, 0);
2222 azt_state = AZT_S_START;
2223 AztTimeout = READ_TIMEOUT;
2227 case AFL_STATUSorDATA:
2229 if (st != azt_st_old) {
2232 ("---AFL_STATUSorDATA st:%x\n",
2240 if (st != azt_st_old) {
2242 printk("---default: st:%x\n", st);
2246 if (!current_valid() && azt_buf_in == azt_buf_out) {
2247 azt_state = AZT_S_STOP;
2251 if (azt_read_count <= 0)
2253 ("aztcd: warning - try to read 0 frames\n");
2254 while (azt_read_count) { /*??? fast read ahead loop */
2255 azt_buf_bn[azt_buf_in] = -1;
2256 DTEN_LOW; /*??? unsolved problem, very
2257 seldom we get timeouts
2258 here, don't now the real
2259 reason. With my drive this
2260 sometimes also happens with
2261 Aztech's original driver under
2262 DOS. Is it a hardware bug?
2263 I tried to recover from such
2264 situations here. Zimmermann */
2265 if (aztTimeOutCount >= AZT_TIMEOUT) {
2267 ("read_count:%d CURRENT->nr_sectors:%ld azt_buf_in:%d\n",
2269 CURRENT->nr_sectors,
2272 ("azt_transfer_is_active:%x\n",
2273 azt_transfer_is_active);
2275 azt_state = AZT_S_STOP;
2277 end_request(CURRENT, 1); /*should we have here (1) or (0)? */
2279 if (azt_read_mode ==
2296 ("AZT_S_DATA; ---I've read data- read_count: %d\n",
2299 ("azt_next_bn:%d azt_buf_in:%d azt_buf_out:%d azt_buf_bn:%d\n",
2306 azt_buf_bn[azt_buf_in] =
2308 if (azt_buf_out == -1)
2317 if (!azt_transfer_is_active) {
2318 while (current_valid()) {
2320 if (CURRENT->nr_sectors ==
2322 end_request(CURRENT, 1);
2329 && (CURRENT->sector / 4 < azt_next_bn
2330 || CURRENT->sector / 4 >
2331 azt_next_bn + AZT_BUF_SIZ)) {
2332 azt_state = AZT_S_STOP;
2336 AztTimeout = READ_TIMEOUT;
2337 if (azt_read_count == 0) {
2338 azt_state = AZT_S_STOP;
2349 if (azt_state != azt_state_old) {
2350 azt_state_old = azt_state;
2351 printk("AZT_S_STOP\n");
2354 if (azt_read_count != 0)
2355 printk("aztcd: discard data=%x frames\n",
2357 while (azt_read_count != 0) {
2359 if (!(inb(STATUS_PORT) & AFL_DATA)) {
2360 if (azt_read_mode == AZT_MODE_2)
2362 i < CD_FRAMESIZE_RAW;
2367 i < CD_FRAMESIZE; i++)
2372 if (aztSendCmd(ACMD_GET_STATUS))
2373 RETURN("azt_poll 5");
2374 azt_state = AZT_S_STOPPING;
2378 case AZT_S_STOPPING:
2380 if (azt_state != azt_state_old) {
2381 azt_state_old = azt_state;
2382 printk("AZT_S_STOPPING\n");
2386 if ((st = aztStatus()) == -1 && AztTimeout)
2390 && ((st & AST_DSK_CHG)
2391 || (st & AST_NOT_READY))) {
2394 azt_invalidate_buffers();
2396 ("aztcd: Disk Changed or Not Ready 4 - Unmount Disk!\n");
2397 end_request(CURRENT, 0);
2401 printk("CURRENT_VALID %d azt_mode %d\n",
2402 current_valid(), azt_mode);
2405 if (current_valid()) {
2407 if (azt_mode == 1) {
2408 azt_state = AZT_S_READ;
2413 azt_state = AZT_S_MODE;
2419 azt_state = AZT_S_START;
2423 azt_state = AZT_S_IDLE;
2429 printk("aztcd: invalid state %d\n", azt_state);
2435 if (!AztTimeout--) {
2436 printk("aztcd: timeout in state %d\n", azt_state);
2437 azt_state = AZT_S_STOP;
2438 if (aztSendCmd(ACMD_STOP))
2439 RETURN("azt_poll 6");
2443 SET_TIMER(azt_poll, HZ / 100);
2447 /*###########################################################################
2448 * Miscellaneous support functions
2449 ###########################################################################
2451 static void azt_hsg2msf(long hsg, struct msf *msf)
2454 msf->min = hsg / 4500;
2456 msf->sec = hsg / 75;
2457 msf->frame = hsg % 75;
2460 printk("aztcd: Error hsg2msf address Minutes\n");
2462 printk("aztcd: Error hsg2msf address Seconds\n");
2463 if (msf->frame >= 75)
2464 printk("aztcd: Error hsg2msf address Frames\n");
2466 azt_bin2bcd(&msf->min); /* convert to BCD */
2467 azt_bin2bcd(&msf->sec);
2468 azt_bin2bcd(&msf->frame);
2471 static long azt_msf2hsg(struct msf *mp)
2473 return azt_bcd2bin(mp->frame) + azt_bcd2bin(mp->sec) * 75
2474 + azt_bcd2bin(mp->min) * 4500 - CD_MSF_OFFSET;
2477 static void azt_bin2bcd(unsigned char *p)
2486 static int azt_bcd2bin(unsigned char bcd)
2488 return (bcd >> 4) * 10 + (bcd & 0xF);
2491 MODULE_LICENSE("GPL");
2492 MODULE_ALIAS_BLOCKDEV_MAJOR(AZTECH_CDROM_MAJOR);