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>
170 #define MAJOR_NR AZTECH_CDROM_MAJOR
172 #include <linux/blk.h>
175 #include <linux/module.h>
176 #include <linux/errno.h>
177 #include <linux/sched.h>
178 #include <linux/mm.h>
179 #include <linux/timer.h>
180 #include <linux/fs.h>
181 #include <linux/kernel.h>
182 #include <linux/cdrom.h>
183 #include <linux/ioport.h>
184 #include <linux/string.h>
185 #include <linux/major.h>
186 #include <linux/devfs_fs_kernel.h>
188 #include <linux/init.h>
190 #include <asm/system.h>
193 #include <asm/uaccess.h>
194 static int aztcd_blocksizes[1] = { 2048 };
197 /*###########################################################################
199 ###########################################################################
201 #define SET_TIMER(func, jifs) delay_timer.expires = jiffies + (jifs); \
202 delay_timer.function = (void *) (func); \
203 add_timer(&delay_timer);
205 #define CLEAR_TIMER del_timer(&delay_timer);
207 #define RETURNM(message,value) {printk("aztcd: Warning: %s failed\n",message);\
209 #define RETURN(message) {printk("aztcd: Warning: %s failed\n",message);\
212 /* Macros to switch the IDE-interface to the slave device and back to the master*/
213 #define SWITCH_IDE_SLAVE outb_p(0xa0,azt_port+6); \
214 outb_p(0x10,azt_port+6); \
215 outb_p(0x00,azt_port+7); \
216 outb_p(0x10,azt_port+6);
217 #define SWITCH_IDE_MASTER outb_p(0xa0,azt_port+6);
222 #define AZT_TEST1 /* <int-..> */
223 #define AZT_TEST2 /* do_aztcd_request */
224 #define AZT_TEST3 /* AZT_S_state */
225 #define AZT_TEST4 /* QUICK_LOOP-counter */
226 #define AZT_TEST5 /* port(1) state */
228 #define AZT_DEBUG_MULTISESSION
231 #define CURRENT_VALID \
232 (!QUEUE_EMPTY && MAJOR(CURRENT -> rq_dev) == MAJOR_NR && CURRENT -> cmd == READ \
233 && CURRENT -> sector != -1)
235 #define AFL_STATUSorDATA (AFL_STATUS | AFL_DATA)
236 #define AZT_BUF_SIZ 16
238 #define READ_TIMEOUT 3000
240 #define azt_port aztcd /*needed for the modutils */
242 /*##########################################################################
244 ##########################################################################
246 enum azt_state_e { AZT_S_IDLE, /* 0 */
252 AZT_S_STOPPING /* 6 */
254 enum azt_read_modes { AZT_MODE_0, /*read mode for audio disks, not supported by Aztech firmware */
255 AZT_MODE_1, /*read mode for normal CD-ROMs */
256 AZT_MODE_2 /*read mode for XA CD-ROMs */
259 /*##########################################################################
261 ##########################################################################
263 static int aztPresent = 0;
265 static volatile int azt_transfer_is_active = 0;
267 static char azt_buf[CD_FRAMESIZE_RAW * AZT_BUF_SIZ]; /*buffer for block size conversion */
268 #if AZT_PRIVATE_IOCTLS
269 static char buf[CD_FRAMESIZE_RAW]; /*separate buffer for the ioctls */
272 static volatile int azt_buf_bn[AZT_BUF_SIZ], azt_next_bn;
273 static volatile int azt_buf_in, azt_buf_out = -1;
274 static volatile int azt_error = 0;
275 static int azt_open_count = 0;
276 static volatile enum azt_state_e azt_state = AZT_S_IDLE;
278 static volatile enum azt_state_e azt_state_old = AZT_S_STOP;
279 static volatile int azt_st_old = 0;
281 static volatile enum azt_read_modes azt_read_mode = AZT_MODE_1;
283 static int azt_mode = -1;
284 static volatile int azt_read_count = 1;
286 static int azt_port = AZT_BASE_ADDR;
288 MODULE_PARM(azt_port, "i");
290 static int azt_port_auto[16] = AZT_BASE_AUTO;
292 static char azt_cont = 0;
293 static char azt_init_end = 0;
294 static char azt_auto_eject = AZT_AUTO_EJECT;
296 static int AztTimeout, AztTries;
297 static DECLARE_WAIT_QUEUE_HEAD(azt_waitq);
298 static struct timer_list delay_timer;
300 static struct azt_DiskInfo DiskInfo;
301 static struct azt_Toc Toc[MAX_TRACKS];
302 static struct azt_Play_msf azt_Play;
304 static int aztAudioStatus = CDROM_AUDIO_NO_STATUS;
305 static char aztDiskChanged = 1;
306 static char aztTocUpToDate = 0;
308 static unsigned char aztIndatum;
309 static unsigned long aztTimeOutCount;
310 static int aztCmd = 0;
312 /*###########################################################################
314 ###########################################################################
316 /* CDROM Drive Low Level I/O Functions */
321 void statusAzt(void);
322 static void aztStatTimer(void);
324 /* CDROM Drive Command Functions */
325 static int aztSendCmd(int cmd);
326 static int sendAztCmd(int cmd, struct azt_Play_msf *params);
327 static int aztSeek(struct azt_Play_msf *params);
328 static int aztSetDiskType(int type);
329 static int aztStatus(void);
330 static int getAztStatus(void);
331 static int aztPlay(struct azt_Play_msf *arg);
332 static void aztCloseDoor(void);
333 static void aztLockDoor(void);
334 static void aztUnlockDoor(void);
335 static int aztGetValue(unsigned char *result);
336 static int aztGetQChannelInfo(struct azt_Toc *qp);
337 static int aztUpdateToc(void);
338 static int aztGetDiskInfo(void);
340 static int aztGetMultiDiskInfo(void);
342 static int aztGetToc(int multi);
344 /* Kernel Interface Functions */
345 static int check_aztcd_media_change(kdev_t full_dev);
346 static int aztcd_ioctl(struct inode *ip, struct file *fp, unsigned int cmd,
348 static void azt_transfer(void);
349 static void do_aztcd_request(request_queue_t *);
350 static void azt_invalidate_buffers(void);
351 int aztcd_open(struct inode *ip, struct file *fp);
353 static int aztcd_release(struct inode *inode, struct file *file);
355 int aztcd_init(void);
357 static struct block_device_operations azt_fops = {
360 release:aztcd_release,
362 check_media_change:check_aztcd_media_change,
365 /* Aztcd State Machine: Controls Drive Operating State */
366 static void azt_poll(void);
368 /* Miscellaneous support functions */
369 static void azt_hsg2msf(long hsg, struct msf *msf);
370 static long azt_msf2hsg(struct msf *mp);
371 static void azt_bin2bcd(unsigned char *p);
372 static int azt_bcd2bin(unsigned char bcd);
374 /*##########################################################################
375 CDROM Drive Low Level I/O Functions
376 ##########################################################################
378 /* Macros for the drive hardware interface handshake, these macros use
380 /* Wait for OP_OK = drive answers with AFL_OP_OK after receiving a command*/
381 # define OP_OK op_ok()
386 aztIndatum = inb(DATA_PORT);
388 if (aztTimeOutCount >= AZT_TIMEOUT) {
389 printk("aztcd: Error Wait OP_OK\n");
392 } while (aztIndatum != AFL_OP_OK);
395 /* Wait for PA_OK = drive answers with AFL_PA_OK after receiving parameters*/
396 # define PA_OK pa_ok()
401 aztIndatum = inb(DATA_PORT);
403 if (aztTimeOutCount >= AZT_TIMEOUT) {
404 printk("aztcd: Error Wait PA_OK\n");
407 } while (aztIndatum != AFL_PA_OK);
410 /* Wait for STEN=Low = handshake signal 'AFL_.._OK available or command executed*/
411 # define STEN_LOW sten_low()
416 aztIndatum = inb(STATUS_PORT);
418 if (aztTimeOutCount >= AZT_TIMEOUT) {
421 ("aztcd: Error Wait STEN_LOW commands:%x\n",
425 } while (aztIndatum & AFL_STATUS);
428 /* Wait for DTEN=Low = handshake signal 'Data available'*/
429 # define DTEN_LOW dten_low()
434 aztIndatum = inb(STATUS_PORT);
436 if (aztTimeOutCount >= AZT_TIMEOUT) {
437 printk("aztcd: Error Wait DTEN_OK\n");
440 } while (aztIndatum & AFL_DATA);
444 * Macro for timer wait on STEN=Low, should only be used for 'slow' commands;
445 * may cause kernel panic when used in the wrong place
447 #define STEN_LOW_WAIT statusAzt()
450 AztTimeout = AZT_STATUS_DELAY;
451 SET_TIMER(aztStatTimer, HZ / 100);
452 sleep_on(&azt_waitq);
454 printk("aztcd: Error Wait STEN_LOW_WAIT command:%x\n",
459 static void aztStatTimer(void)
461 if (!(inb(STATUS_PORT) & AFL_STATUS)) {
466 if (AztTimeout <= 0) {
468 printk("aztcd: Error aztStatTimer: Timeout\n");
471 SET_TIMER(aztStatTimer, HZ / 100);
474 /*##########################################################################
475 CDROM Drive Command Functions
476 ##########################################################################
479 * Send a single command, return -1 on error, else 0
481 static int aztSendCmd(int cmd)
487 printk("aztcd: Executing command %x\n", cmd);
490 if ((azt_port == 0x1f0) || (azt_port == 0x170))
491 SWITCH_IDE_SLAVE; /*switch IDE interface to slave configuration */
494 outb(POLLED, MODE_PORT);
496 if (inb(STATUS_PORT) & AFL_STATUS)
498 inb(DATA_PORT); /* if status left from last command, read and */
499 } while (1); /* discard it */
501 if (inb(STATUS_PORT) & AFL_DATA)
503 inb(DATA_PORT); /* if data left from last command, read and */
504 } while (1); /* discard it */
505 for (retry = 0; retry < AZT_RETRY_ATTEMPTS; retry++) {
506 outb((unsigned char) cmd, CMD_PORT);
508 data = inb(DATA_PORT);
509 if (data == AFL_OP_OK) {
512 if (data == AFL_OP_ERR) {
514 data = inb(DATA_PORT);
516 ("### Error 1 aztcd: aztSendCmd %x Error Code %x\n",
520 if (retry >= AZT_RETRY_ATTEMPTS) {
521 printk("### Error 2 aztcd: aztSendCmd %x \n", cmd);
524 RETURNM("aztSendCmd", -1);
528 * Send a play or read command to the drive, return -1 on error, else 0
530 static int sendAztCmd(int cmd, struct azt_Play_msf *params)
536 printk("aztcd: play start=%02x:%02x:%02x end=%02x:%02x:%02x\n",
537 params->start.min, params->start.sec, params->start.frame,
538 params->end.min, params->end.sec, params->end.frame);
540 for (retry = 0; retry < AZT_RETRY_ATTEMPTS; retry++) {
542 outb(params->start.min, CMD_PORT);
543 outb(params->start.sec, CMD_PORT);
544 outb(params->start.frame, CMD_PORT);
545 outb(params->end.min, CMD_PORT);
546 outb(params->end.sec, CMD_PORT);
547 outb(params->end.frame, CMD_PORT);
549 data = inb(DATA_PORT);
550 if (data == AFL_PA_OK) {
553 if (data == AFL_PA_ERR) {
555 data = inb(DATA_PORT);
557 ("### Error 1 aztcd: sendAztCmd %x Error Code %x\n",
561 if (retry >= AZT_RETRY_ATTEMPTS) {
562 printk("### Error 2 aztcd: sendAztCmd %x\n ", cmd);
565 RETURNM("sendAztCmd", -1);
569 * Send a seek command to the drive, return -1 on error, else 0
571 static int aztSeek(struct azt_Play_msf *params)
577 printk("aztcd: aztSeek %02x:%02x:%02x\n",
578 params->start.min, params->start.sec, params->start.frame);
580 for (retry = 0; retry < AZT_RETRY_ATTEMPTS; retry++) {
581 aztSendCmd(ACMD_SEEK);
582 outb(params->start.min, CMD_PORT);
583 outb(params->start.sec, CMD_PORT);
584 outb(params->start.frame, CMD_PORT);
586 data = inb(DATA_PORT);
587 if (data == AFL_PA_OK) {
590 if (data == AFL_PA_ERR) {
592 data = inb(DATA_PORT);
593 printk("### Error 1 aztcd: aztSeek\n");
596 if (retry >= AZT_RETRY_ATTEMPTS) {
597 printk("### Error 2 aztcd: aztSeek\n ");
600 RETURNM("aztSeek", -1);
603 /* Send a Set Disk Type command
604 does not seem to work with Aztech drives, behavior is completely indepen-
605 dent on which mode is set ???
607 static int aztSetDiskType(int type)
613 printk("aztcd: set disk type command: type= %i\n", type);
615 for (retry = 0; retry < AZT_RETRY_ATTEMPTS; retry++) {
616 aztSendCmd(ACMD_SET_DISK_TYPE);
617 outb(type, CMD_PORT);
619 data = inb(DATA_PORT);
620 if (data == AFL_PA_OK) { /*PA_OK ? */
621 azt_read_mode = type;
624 if (data == AFL_PA_ERR) {
626 data = inb(DATA_PORT);
628 ("### Error 1 aztcd: aztSetDiskType %x Error Code %x\n",
632 if (retry >= AZT_RETRY_ATTEMPTS) {
633 printk("### Error 2 aztcd: aztSetDiskType %x\n ", type);
636 RETURNM("aztSetDiskType", -1);
640 /* used in azt_poll to poll the status, expects another program to issue a
641 * ACMD_GET_STATUS directly before
643 static int aztStatus(void)
648 i = inb(STATUS_PORT) & AFL_STATUS; is STEN=0? ???
651 if (aztTimeOutCount < AZT_TIMEOUT) {
652 st = inb(DATA_PORT) & 0xFF;
655 RETURNM("aztStatus", -1);
659 * Get the drive status
661 static int getAztStatus(void)
665 if (aztSendCmd(ACMD_GET_STATUS))
666 RETURNM("getAztStatus 1", -1);
668 st = inb(DATA_PORT) & 0xFF;
670 printk("aztcd: Status = %x\n", st);
672 if ((st == 0xFF) || (st & AST_CMD_CHECK)) {
674 ("aztcd: AST_CMD_CHECK error or no status available\n");
678 if (((st & AST_MODE_BITS) != AST_BUSY)
679 && (aztAudioStatus == CDROM_AUDIO_PLAY))
680 /* XXX might be an error? look at q-channel? */
681 aztAudioStatus = CDROM_AUDIO_COMPLETED;
683 if ((st & AST_DSK_CHG) || (st & AST_NOT_READY)) {
686 aztAudioStatus = CDROM_AUDIO_NO_STATUS;
693 * Send a 'Play' command and get the status. Use only from the top half.
695 static int aztPlay(struct azt_Play_msf *arg)
697 if (sendAztCmd(ACMD_PLAY_AUDIO, arg) < 0)
698 RETURNM("aztPlay", -1);
703 * Subroutines to automatically close the door (tray) and
704 * lock it closed when the cd is mounted. Leave the tray
705 * locking as an option
707 static void aztCloseDoor(void)
709 aztSendCmd(ACMD_CLOSE);
714 static void aztLockDoor(void)
716 #if AZT_ALLOW_TRAY_LOCK
717 aztSendCmd(ACMD_LOCK);
723 static void aztUnlockDoor(void)
725 #if AZT_ALLOW_TRAY_LOCK
726 aztSendCmd(ACMD_UNLOCK);
733 * Read a value from the drive. Should return quickly, so a busy wait
734 * is used to avoid excessive rescheduling. The read command itself must
735 * be issued with aztSendCmd() directly before
737 static int aztGetValue(unsigned char *result)
742 if (aztTimeOutCount >= AZT_TIMEOUT) {
743 printk("aztcd: aztGetValue timeout\n");
746 s = inb(DATA_PORT) & 0xFF;
747 *result = (unsigned char) s;
752 * Read the current Q-channel info. Also used for reading the
755 int aztGetQChannelInfo(struct azt_Toc *qp)
757 unsigned char notUsed;
761 printk("aztcd: starting aztGetQChannelInfo Time:%li\n", jiffies);
763 if ((st = getAztStatus()) == -1)
764 RETURNM("aztGetQChannelInfo 1", -1);
765 if (aztSendCmd(ACMD_GET_Q_CHANNEL))
766 RETURNM("aztGetQChannelInfo 2", -1);
767 /*STEN_LOW_WAIT; ??? Dosemu0.60's cdrom.c does not like STEN_LOW_WAIT here */
768 if (aztGetValue(¬Used))
769 RETURNM("aztGetQChannelInfo 3", -1); /*??? Nullbyte einlesen */
770 if ((st & AST_MODE_BITS) == AST_INITIAL) {
771 qp->ctrl_addr = 0; /* when audio stop ACMD_GET_Q_CHANNEL returns */
772 qp->track = 0; /* only one byte with Aztech drives */
774 qp->trackTime.min = 0;
775 qp->trackTime.sec = 0;
776 qp->trackTime.frame = 0;
777 qp->diskTime.min = 0;
778 qp->diskTime.sec = 0;
779 qp->diskTime.frame = 0;
782 if (aztGetValue(&qp->ctrl_addr) < 0)
783 RETURNM("aztGetQChannelInfo 4", -1);
784 if (aztGetValue(&qp->track) < 0)
785 RETURNM("aztGetQChannelInfo 4", -1);
786 if (aztGetValue(&qp->pointIndex) < 0)
787 RETURNM("aztGetQChannelInfo 4", -1);
788 if (aztGetValue(&qp->trackTime.min) < 0)
789 RETURNM("aztGetQChannelInfo 4", -1);
790 if (aztGetValue(&qp->trackTime.sec) < 0)
791 RETURNM("aztGetQChannelInfo 4", -1);
792 if (aztGetValue(&qp->trackTime.frame) < 0)
793 RETURNM("aztGetQChannelInfo 4", -1);
794 if (aztGetValue(¬Used) < 0)
795 RETURNM("aztGetQChannelInfo 4", -1);
796 if (aztGetValue(&qp->diskTime.min) < 0)
797 RETURNM("aztGetQChannelInfo 4", -1);
798 if (aztGetValue(&qp->diskTime.sec) < 0)
799 RETURNM("aztGetQChannelInfo 4", -1);
800 if (aztGetValue(&qp->diskTime.frame) < 0)
801 RETURNM("aztGetQChannelInfo 4", -1);
804 printk("aztcd: exiting aztGetQChannelInfo Time:%li\n", jiffies);
810 * Read the table of contents (TOC) and TOC header if necessary
812 static int aztUpdateToc()
817 printk("aztcd: starting aztUpdateToc Time:%li\n", jiffies);
822 if (aztGetDiskInfo() < 0)
825 if (aztGetToc(0) < 0)
828 /*audio disk detection
829 with my Aztech drive there is no audio status bit, so I use the copy
830 protection bit of the first track. If this track is copy protected
831 (copy bit = 0), I assume, it's an audio disk. Strange, but works ??? */
832 if (!(Toc[DiskInfo.first].ctrl_addr & 0x40))
838 if (!DiskInfo.audio) {
839 azt_Play.start.min = 0; /*XA detection only seems to work */
840 azt_Play.start.sec = 2; /*when we play a track */
841 azt_Play.start.frame = 0;
842 azt_Play.end.min = 0;
843 azt_Play.end.sec = 0;
844 azt_Play.end.frame = 1;
845 if (sendAztCmd(ACMD_PLAY_READ, &azt_Play))
848 for (st = 0; st < CD_FRAMESIZE; st++)
851 DiskInfo.xa = getAztStatus() & AST_MODE;
854 ("aztcd: XA support experimental - mail results to Werner.Zimmermann@fht-esslingen.de\n");
857 /*multisession detection
858 support for multisession CDs is done automatically with Aztech drives,
859 we don't have to take care about TOC redirection; if we want the isofs
860 to take care about redirection, we have to set AZT_MULTISESSION to 1 */
864 aztGetMultiDiskInfo(); /*here Disk.Info.multi is set */
867 if (DiskInfo.multi) {
868 DiskInfo.lastSession.min = Toc[DiskInfo.next].diskTime.min;
869 DiskInfo.lastSession.sec = Toc[DiskInfo.next].diskTime.sec;
870 DiskInfo.lastSession.frame =
871 Toc[DiskInfo.next].diskTime.frame;
872 printk("aztcd: Multisession support experimental\n");
874 DiskInfo.lastSession.min =
875 Toc[DiskInfo.first].diskTime.min;
876 DiskInfo.lastSession.sec =
877 Toc[DiskInfo.first].diskTime.sec;
878 DiskInfo.lastSession.frame =
879 Toc[DiskInfo.first].diskTime.frame;
884 printk("aztcd: exiting aztUpdateToc Time:%li\n", jiffies);
890 /* Read the table of contents header, i.e. no. of tracks and start of first
893 static int aztGetDiskInfo()
897 struct azt_Toc qInfo;
900 printk("aztcd: starting aztGetDiskInfo Time:%li\n", jiffies);
902 if (aztSendCmd(ACMD_SEEK_TO_LEADIN))
903 RETURNM("aztGetDiskInfo 1", -1);
906 for (limit = 300; limit > 0; limit--) {
907 if (aztGetQChannelInfo(&qInfo) < 0)
908 RETURNM("aztGetDiskInfo 2", -1);
909 if (qInfo.pointIndex == 0xA0) { /*Number of FirstTrack */
910 DiskInfo.first = qInfo.diskTime.min;
911 DiskInfo.first = azt_bcd2bin(DiskInfo.first);
914 if (qInfo.pointIndex == 0xA1) { /*Number of LastTrack */
915 DiskInfo.last = qInfo.diskTime.min;
916 DiskInfo.last = azt_bcd2bin(DiskInfo.last);
919 if (qInfo.pointIndex == 0xA2) { /*DiskLength */
920 DiskInfo.diskLength.min = qInfo.diskTime.min;
921 DiskInfo.diskLength.sec = qInfo.diskTime.sec;
922 DiskInfo.diskLength.frame = qInfo.diskTime.frame;
925 if ((qInfo.pointIndex == DiskInfo.first) && (test & 0x01)) { /*StartTime of First Track */
926 DiskInfo.firstTrack.min = qInfo.diskTime.min;
927 DiskInfo.firstTrack.sec = qInfo.diskTime.sec;
928 DiskInfo.firstTrack.frame = qInfo.diskTime.frame;
935 printk("aztcd: exiting aztGetDiskInfo Time:%li\n", jiffies);
937 ("Disk Info: first %d last %d length %02X:%02X.%02X dez first %02X:%02X.%02X dez\n",
938 DiskInfo.first, DiskInfo.last, DiskInfo.diskLength.min,
939 DiskInfo.diskLength.sec, DiskInfo.diskLength.frame,
940 DiskInfo.firstTrack.min, DiskInfo.firstTrack.sec,
941 DiskInfo.firstTrack.frame);
950 * Get Multisession Disk Info
952 static int aztGetMultiDiskInfo(void)
956 struct azt_Toc qInfo;
959 printk("aztcd: starting aztGetMultiDiskInfo\n");
963 azt_Play.start.min = Toc[DiskInfo.last + 1].diskTime.min;
964 azt_Play.start.sec = Toc[DiskInfo.last + 1].diskTime.sec;
965 azt_Play.start.frame =
966 Toc[DiskInfo.last + 1].diskTime.frame;
969 for (limit = 30; limit > 0; limit--) { /*Seek for LeadIn of next session */
970 if (aztSeek(&azt_Play))
971 RETURNM("aztGetMultiDiskInfo 1", -1);
972 if (aztGetQChannelInfo(&qInfo) < 0)
973 RETURNM("aztGetMultiDiskInfo 2", -1);
974 if ((qInfo.track == 0) && (qInfo.pointIndex))
975 break; /*LeadIn found */
976 if ((azt_Play.start.sec += 10) > 59) {
977 azt_Play.start.sec = 0;
978 azt_Play.start.min++;
982 break; /*Check, if a leadin track was found, if not we're
983 at the end of the disk */
984 #ifdef AZT_DEBUG_MULTISESSION
985 printk("leadin found track %d pointIndex %x limit %d\n",
986 qInfo.track, qInfo.pointIndex, limit);
988 for (limit = 300; limit > 0; limit--) {
989 if (++azt_Play.start.frame > 74) {
990 azt_Play.start.frame = 0;
991 if (azt_Play.start.sec > 59) {
992 azt_Play.start.sec = 0;
993 azt_Play.start.min++;
996 if (aztSeek(&azt_Play))
997 RETURNM("aztGetMultiDiskInfo 3", -1);
998 if (aztGetQChannelInfo(&qInfo) < 0)
999 RETURNM("aztGetMultiDiskInfo 4", -1);
1000 if (qInfo.pointIndex == 0xA0) { /*Number of NextTrack */
1001 DiskInfo.next = qInfo.diskTime.min;
1002 DiskInfo.next = azt_bcd2bin(DiskInfo.next);
1005 if (qInfo.pointIndex == 0xA1) { /*Number of LastTrack */
1006 DiskInfo.last = qInfo.diskTime.min;
1007 DiskInfo.last = azt_bcd2bin(DiskInfo.last);
1010 if (qInfo.pointIndex == 0xA2) { /*DiskLength */
1011 DiskInfo.diskLength.min =
1013 DiskInfo.diskLength.sec =
1015 DiskInfo.diskLength.frame =
1016 qInfo.diskTime.frame;
1019 if ((qInfo.pointIndex == DiskInfo.next) && (test & 0x01)) { /*StartTime of Next Track */
1020 DiskInfo.nextSession.min =
1022 DiskInfo.nextSession.sec =
1024 DiskInfo.nextSession.frame =
1025 qInfo.diskTime.frame;
1031 #ifdef AZT_DEBUG_MULTISESSION
1033 ("MultiDisk Info: first %d next %d last %d length %02x:%02x.%02x dez first %02x:%02x.%02x dez next %02x:%02x.%02x dez\n",
1034 DiskInfo.first, DiskInfo.next, DiskInfo.last,
1035 DiskInfo.diskLength.min, DiskInfo.diskLength.sec,
1036 DiskInfo.diskLength.frame, DiskInfo.firstTrack.min,
1037 DiskInfo.firstTrack.sec, DiskInfo.firstTrack.frame,
1038 DiskInfo.nextSession.min, DiskInfo.nextSession.sec,
1039 DiskInfo.nextSession.frame);
1044 DiskInfo.multi = 1; /*found TOC of more than one session */
1049 printk("aztcd: exiting aztGetMultiDiskInfo Time:%li\n", jiffies);
1056 * Read the table of contents (TOC)
1058 static int aztGetToc(int multi)
1062 struct azt_Toc qInfo;
1065 printk("aztcd: starting aztGetToc Time:%li\n", jiffies);
1068 for (i = 0; i < MAX_TRACKS; i++)
1069 Toc[i].pointIndex = 0;
1070 i = DiskInfo.last + 3;
1072 for (i = DiskInfo.next; i < MAX_TRACKS; i++)
1073 Toc[i].pointIndex = 0;
1074 i = DiskInfo.last + 4 - DiskInfo.next;
1077 /*Is there a good reason to stop motor before TOC read?
1078 if (aztSendCmd(ACMD_STOP)) RETURNM("aztGetToc 1",-1);
1084 if (aztSendCmd(ACMD_SEEK_TO_LEADIN))
1085 RETURNM("aztGetToc 2", -1);
1088 for (limit = 300; limit > 0; limit--) {
1090 if (++azt_Play.start.sec > 59) {
1091 azt_Play.start.sec = 0;
1092 azt_Play.start.min++;
1094 if (aztSeek(&azt_Play))
1095 RETURNM("aztGetToc 3", -1);
1097 if (aztGetQChannelInfo(&qInfo) < 0)
1100 px = azt_bcd2bin(qInfo.pointIndex);
1102 if (px > 0 && px < MAX_TRACKS && qInfo.track == 0)
1103 if (Toc[px].pointIndex == 0) {
1112 Toc[DiskInfo.last + 1].diskTime = DiskInfo.diskLength;
1113 Toc[DiskInfo.last].trackTime = DiskInfo.diskLength;
1115 #ifdef AZT_DEBUG_MULTISESSION
1116 printk("aztcd: exiting aztGetToc\n");
1117 for (i = 1; i <= DiskInfo.last + 1; i++)
1119 ("i = %2d ctl-adr = %02X track %2d px %02X %02X:%02X.%02X dez %02X:%02X.%02X dez\n",
1120 i, Toc[i].ctrl_addr, Toc[i].track, Toc[i].pointIndex,
1121 Toc[i].trackTime.min, Toc[i].trackTime.sec,
1122 Toc[i].trackTime.frame, Toc[i].diskTime.min,
1123 Toc[i].diskTime.sec, Toc[i].diskTime.frame);
1124 for (i = 100; i < 103; i++)
1126 ("i = %2d ctl-adr = %02X track %2d px %02X %02X:%02X.%02X dez %02X:%02X.%02X dez\n",
1127 i, Toc[i].ctrl_addr, Toc[i].track, Toc[i].pointIndex,
1128 Toc[i].trackTime.min, Toc[i].trackTime.sec,
1129 Toc[i].trackTime.frame, Toc[i].diskTime.min,
1130 Toc[i].diskTime.sec, Toc[i].diskTime.frame);
1133 return limit > 0 ? 0 : -1;
1137 /*##########################################################################
1138 Kernel Interface Functions
1139 ##########################################################################
1143 static int __init aztcd_setup(char *str)
1147 (void) get_options(str, ARRAY_SIZE(ints), ints);
1156 __setup("aztcd=", aztcd_setup);
1158 #endif /* !MODULE */
1161 * Checking if the media has been changed
1163 static int check_aztcd_media_change(kdev_t full_dev)
1165 if (aztDiskChanged) { /* disk changed */
1169 return 0; /* no change */
1173 * Kernel IO-controls
1175 static int aztcd_ioctl(struct inode *ip, struct file *fp, unsigned int cmd,
1179 struct azt_Toc qInfo;
1181 struct cdrom_tochdr tocHdr;
1182 struct cdrom_msf msf;
1183 struct cdrom_tocentry entry;
1184 struct azt_Toc *tocPtr;
1185 struct cdrom_subchnl subchnl;
1186 struct cdrom_volctrl volctrl;
1189 printk("aztcd: starting aztcd_ioctl - Command:%x Time: %li\n",
1191 printk("aztcd Status %x\n", getAztStatus());
1194 RETURNM("aztcd_ioctl 1", -EINVAL);
1195 if (getAztStatus() < 0)
1196 RETURNM("aztcd_ioctl 2", -EIO);
1197 if ((!aztTocUpToDate) || (aztDiskChanged)) {
1198 if ((i = aztUpdateToc()) < 0)
1199 RETURNM("aztcd_ioctl 3", i); /* error reading TOC */
1203 case CDROMSTART: /* Spin up the drive. Don't know, what to do,
1204 at least close the tray */
1205 #if AZT_PRIVATE_IOCTLS
1206 if (aztSendCmd(ACMD_CLOSE))
1207 RETURNM("aztcd_ioctl 4", -1);
1211 case CDROMSTOP: /* Spin down the drive */
1212 if (aztSendCmd(ACMD_STOP))
1213 RETURNM("aztcd_ioctl 5", -1);
1215 /* should we do anything if it fails? */
1216 aztAudioStatus = CDROM_AUDIO_NO_STATUS;
1218 case CDROMPAUSE: /* Pause the drive */
1219 if (aztAudioStatus != CDROM_AUDIO_PLAY)
1222 if (aztGetQChannelInfo(&qInfo) < 0) { /* didn't get q channel info */
1223 aztAudioStatus = CDROM_AUDIO_NO_STATUS;
1224 RETURNM("aztcd_ioctl 7", 0);
1226 azt_Play.start = qInfo.diskTime; /* remember restart point */
1228 if (aztSendCmd(ACMD_PAUSE))
1229 RETURNM("aztcd_ioctl 8", -1);
1231 aztAudioStatus = CDROM_AUDIO_PAUSED;
1233 case CDROMRESUME: /* Play it again, Sam */
1234 if (aztAudioStatus != CDROM_AUDIO_PAUSED)
1236 /* restart the drive at the saved position. */
1237 i = aztPlay(&azt_Play);
1239 aztAudioStatus = CDROM_AUDIO_ERROR;
1242 aztAudioStatus = CDROM_AUDIO_PLAY;
1244 case CDROMMULTISESSION: /*multisession support -- experimental */
1246 struct cdrom_multisession ms;
1248 printk("aztcd ioctl MULTISESSION\n");
1252 sizeof(struct cdrom_multisession)))
1254 if (ms.addr_format == CDROM_MSF) {
1255 ms.addr.msf.minute =
1256 azt_bcd2bin(DiskInfo.lastSession.min);
1257 ms.addr.msf.second =
1258 azt_bcd2bin(DiskInfo.lastSession.sec);
1260 azt_bcd2bin(DiskInfo.lastSession.
1262 } else if (ms.addr_format == CDROM_LBA)
1264 azt_msf2hsg(&DiskInfo.lastSession);
1267 ms.xa_flag = DiskInfo.xa;
1270 sizeof(struct cdrom_multisession)))
1273 if (ms.addr_format == CDROM_MSF)
1275 ("aztcd multisession xa:%d, msf:%02x:%02x.%02x [%02x:%02x.%02x])\n",
1276 ms.xa_flag, ms.addr.msf.minute,
1277 ms.addr.msf.second, ms.addr.msf.frame,
1278 DiskInfo.lastSession.min,
1279 DiskInfo.lastSession.sec,
1280 DiskInfo.lastSession.frame);
1283 ("aztcd multisession %d, lba:0x%08x [%02x:%02x.%02x])\n",
1284 ms.xa_flag, ms.addr.lba,
1285 DiskInfo.lastSession.min,
1286 DiskInfo.lastSession.sec,
1287 DiskInfo.lastSession.frame);
1291 case CDROMPLAYTRKIND: /* Play a track. This currently ignores index. */
1292 if (copy_from_user(&ti, (void *) arg, sizeof ti))
1294 if (ti.cdti_trk0 < DiskInfo.first
1295 || ti.cdti_trk0 > DiskInfo.last
1296 || ti.cdti_trk1 < ti.cdti_trk0) {
1299 if (ti.cdti_trk1 > DiskInfo.last)
1300 ti.cdti_trk1 = DiskInfo.last;
1301 azt_Play.start = Toc[ti.cdti_trk0].diskTime;
1302 azt_Play.end = Toc[ti.cdti_trk1 + 1].diskTime;
1304 printk("aztcd play: %02x:%02x.%02x to %02x:%02x.%02x\n",
1305 azt_Play.start.min, azt_Play.start.sec,
1306 azt_Play.start.frame, azt_Play.end.min,
1307 azt_Play.end.sec, azt_Play.end.frame);
1309 i = aztPlay(&azt_Play);
1311 aztAudioStatus = CDROM_AUDIO_ERROR;
1314 aztAudioStatus = CDROM_AUDIO_PLAY;
1316 case CDROMPLAYMSF: /* Play starting at the given MSF address. */
1317 /* if (aztAudioStatus == CDROM_AUDIO_PLAY)
1318 { if (aztSendCmd(ACMD_STOP)) RETURNM("aztcd_ioctl 9",-1);
1320 aztAudioStatus = CDROM_AUDIO_NO_STATUS;
1323 if (copy_from_user(&msf, (void *) arg, sizeof msf))
1325 /* convert to bcd */
1326 azt_bin2bcd(&msf.cdmsf_min0);
1327 azt_bin2bcd(&msf.cdmsf_sec0);
1328 azt_bin2bcd(&msf.cdmsf_frame0);
1329 azt_bin2bcd(&msf.cdmsf_min1);
1330 azt_bin2bcd(&msf.cdmsf_sec1);
1331 azt_bin2bcd(&msf.cdmsf_frame1);
1332 azt_Play.start.min = msf.cdmsf_min0;
1333 azt_Play.start.sec = msf.cdmsf_sec0;
1334 azt_Play.start.frame = msf.cdmsf_frame0;
1335 azt_Play.end.min = msf.cdmsf_min1;
1336 azt_Play.end.sec = msf.cdmsf_sec1;
1337 azt_Play.end.frame = msf.cdmsf_frame1;
1339 printk("aztcd play: %02x:%02x.%02x to %02x:%02x.%02x\n",
1340 azt_Play.start.min, azt_Play.start.sec,
1341 azt_Play.start.frame, azt_Play.end.min,
1342 azt_Play.end.sec, azt_Play.end.frame);
1344 i = aztPlay(&azt_Play);
1346 aztAudioStatus = CDROM_AUDIO_ERROR;
1349 aztAudioStatus = CDROM_AUDIO_PLAY;
1352 case CDROMREADTOCHDR: /* Read the table of contents header */
1353 tocHdr.cdth_trk0 = DiskInfo.first;
1354 tocHdr.cdth_trk1 = DiskInfo.last;
1355 if (copy_to_user((void *) arg, &tocHdr, sizeof tocHdr))
1358 case CDROMREADTOCENTRY: /* Read an entry in the table of contents */
1359 if (copy_from_user(&entry, (void *) arg, sizeof entry))
1361 if ((!aztTocUpToDate) || aztDiskChanged)
1363 if (entry.cdte_track == CDROM_LEADOUT)
1364 tocPtr = &Toc[DiskInfo.last + 1];
1365 else if (entry.cdte_track > DiskInfo.last
1366 || entry.cdte_track < DiskInfo.first) {
1369 tocPtr = &Toc[entry.cdte_track];
1370 entry.cdte_adr = tocPtr->ctrl_addr;
1371 entry.cdte_ctrl = tocPtr->ctrl_addr >> 4;
1372 if (entry.cdte_format == CDROM_LBA)
1373 entry.cdte_addr.lba =
1374 azt_msf2hsg(&tocPtr->diskTime);
1375 else if (entry.cdte_format == CDROM_MSF) {
1376 entry.cdte_addr.msf.minute =
1377 azt_bcd2bin(tocPtr->diskTime.min);
1378 entry.cdte_addr.msf.second =
1379 azt_bcd2bin(tocPtr->diskTime.sec);
1380 entry.cdte_addr.msf.frame =
1381 azt_bcd2bin(tocPtr->diskTime.frame);
1385 if (copy_to_user((void *) arg, &entry, sizeof entry))
1388 case CDROMSUBCHNL: /* Get subchannel info */
1390 (&subchnl, (void *) arg, sizeof(struct cdrom_subchnl)))
1392 if (aztGetQChannelInfo(&qInfo) < 0) {
1395 ("aztcd: exiting aztcd_ioctl - Error 3 - Command:%x\n",
1400 subchnl.cdsc_audiostatus = aztAudioStatus;
1401 subchnl.cdsc_adr = qInfo.ctrl_addr;
1402 subchnl.cdsc_ctrl = qInfo.ctrl_addr >> 4;
1403 subchnl.cdsc_trk = azt_bcd2bin(qInfo.track);
1404 subchnl.cdsc_ind = azt_bcd2bin(qInfo.pointIndex);
1405 if (subchnl.cdsc_format == CDROM_LBA) {
1406 subchnl.cdsc_absaddr.lba =
1407 azt_msf2hsg(&qInfo.diskTime);
1408 subchnl.cdsc_reladdr.lba =
1409 azt_msf2hsg(&qInfo.trackTime);
1410 } else { /*default */
1411 subchnl.cdsc_format = CDROM_MSF;
1412 subchnl.cdsc_absaddr.msf.minute =
1413 azt_bcd2bin(qInfo.diskTime.min);
1414 subchnl.cdsc_absaddr.msf.second =
1415 azt_bcd2bin(qInfo.diskTime.sec);
1416 subchnl.cdsc_absaddr.msf.frame =
1417 azt_bcd2bin(qInfo.diskTime.frame);
1418 subchnl.cdsc_reladdr.msf.minute =
1419 azt_bcd2bin(qInfo.trackTime.min);
1420 subchnl.cdsc_reladdr.msf.second =
1421 azt_bcd2bin(qInfo.trackTime.sec);
1422 subchnl.cdsc_reladdr.msf.frame =
1423 azt_bcd2bin(qInfo.trackTime.frame);
1426 ((void *) arg, &subchnl, sizeof(struct cdrom_subchnl)))
1429 case CDROMVOLCTRL: /* Volume control
1430 * With my Aztech CD268-01A volume control does not work, I can only
1431 turn the channels on (any value !=0) or off (value==0). Maybe it
1432 works better with your drive */
1434 (&volctrl, (char *) arg, sizeof(volctrl)))
1436 azt_Play.start.min = 0x21;
1437 azt_Play.start.sec = 0x84;
1438 azt_Play.start.frame = volctrl.channel0;
1439 azt_Play.end.min = volctrl.channel1;
1440 azt_Play.end.sec = volctrl.channel2;
1441 azt_Play.end.frame = volctrl.channel3;
1442 sendAztCmd(ACMD_SET_VOLUME, &azt_Play);
1446 aztUnlockDoor(); /* Assume user knows what they're doing */
1447 /* all drives can at least stop! */
1448 if (aztAudioStatus == CDROM_AUDIO_PLAY) {
1449 if (aztSendCmd(ACMD_STOP))
1450 RETURNM("azt_ioctl 10", -1);
1453 if (aztSendCmd(ACMD_EJECT))
1454 RETURNM("azt_ioctl 11", -1);
1456 aztAudioStatus = CDROM_AUDIO_NO_STATUS;
1459 azt_auto_eject = (char) arg;
1462 outb(ACMD_SOFT_RESET, CMD_PORT); /*send reset */
1464 if (inb(DATA_PORT) != AFL_OP_OK) { /*OP_OK? */
1466 ("aztcd: AZTECH CD-ROM drive does not respond\n");
1469 /*Take care, the following code is not compatible with other CD-ROM drivers,
1470 use it at your own risk with cdplay.c. Set AZT_PRIVATE_IOCTLS to 0 in aztcd.h,
1471 if you do not want to use it!
1473 #if AZT_PRIVATE_IOCTLS
1474 case CDROMREADCOOKED: /*read data in mode 1 (2048 Bytes) */
1475 case CDROMREADRAW: /*read data in mode 2 (2336 Bytes) */
1477 if (copy_from_user(&msf, (void *) arg, sizeof msf))
1479 /* convert to bcd */
1480 azt_bin2bcd(&msf.cdmsf_min0);
1481 azt_bin2bcd(&msf.cdmsf_sec0);
1482 azt_bin2bcd(&msf.cdmsf_frame0);
1485 msf.cdmsf_frame1 = 1; /*read only one frame */
1486 azt_Play.start.min = msf.cdmsf_min0;
1487 azt_Play.start.sec = msf.cdmsf_sec0;
1488 azt_Play.start.frame = msf.cdmsf_frame0;
1489 azt_Play.end.min = msf.cdmsf_min1;
1490 azt_Play.end.sec = msf.cdmsf_sec1;
1491 azt_Play.end.frame = msf.cdmsf_frame1;
1492 if (cmd == CDROMREADRAW) {
1494 return -1; /*XA Disks can't be read raw */
1497 (ACMD_PLAY_READ_RAW,
1501 insb(DATA_PORT, buf,
1504 ((void *) arg, &buf,
1509 /*CDROMREADCOOKED*/ {
1510 if (sendAztCmd(ACMD_PLAY_READ, &azt_Play))
1513 insb(DATA_PORT, buf, CD_FRAMESIZE);
1515 ((void *) arg, &buf, CD_FRAMESIZE))
1520 case CDROMSEEK: /*seek msf address */
1521 if (copy_from_user(&msf, (void *) arg, sizeof msf))
1523 /* convert to bcd */
1524 azt_bin2bcd(&msf.cdmsf_min0);
1525 azt_bin2bcd(&msf.cdmsf_sec0);
1526 azt_bin2bcd(&msf.cdmsf_frame0);
1527 azt_Play.start.min = msf.cdmsf_min0;
1528 azt_Play.start.sec = msf.cdmsf_sec0;
1529 azt_Play.start.frame = msf.cdmsf_frame0;
1530 if (aztSeek(&azt_Play))
1533 #endif /*end of incompatible code */
1534 case CDROMREADMODE1: /*set read data in mode 1 */
1535 return aztSetDiskType(AZT_MODE_1);
1536 case CDROMREADMODE2: /*set read data in mode 2 */
1537 return aztSetDiskType(AZT_MODE_2);
1542 printk("aztcd: exiting aztcd_ioctl Command:%x Time:%li\n", cmd,
1549 * Take care of the different block sizes between cdrom and Linux.
1550 * When Linux gets variable block sizes this will probably go away.
1552 static void azt_transfer(void)
1555 printk("aztcd: executing azt_transfer Time:%li\n", jiffies);
1557 if (CURRENT_VALID) {
1558 while (CURRENT->nr_sectors) {
1559 int bn = CURRENT->sector / 4;
1561 for (i = 0; i < AZT_BUF_SIZ && azt_buf_bn[i] != bn;
1563 if (i < AZT_BUF_SIZ) {
1565 (i * 4 + (CURRENT->sector & 3)) * 512;
1566 int nr_sectors = 4 - (CURRENT->sector & 3);
1567 if (azt_buf_out != i) {
1569 if (azt_buf_bn[i] != bn) {
1574 if (nr_sectors > CURRENT->nr_sectors)
1575 nr_sectors = CURRENT->nr_sectors;
1576 memcpy(CURRENT->buffer, azt_buf + offs,
1578 CURRENT->nr_sectors -= nr_sectors;
1579 CURRENT->sector += nr_sectors;
1580 CURRENT->buffer += nr_sectors * 512;
1589 static void do_aztcd_request(request_queue_t * q)
1592 printk(" do_aztcd_request(%ld+%ld) Time:%li\n", CURRENT->sector,
1593 CURRENT->nr_sectors, jiffies);
1595 if (DiskInfo.audio) {
1596 printk("aztcd: Error, tried to mount an Audio CD\n");
1600 azt_transfer_is_active = 1;
1601 while (CURRENT_VALID) {
1603 if (!buffer_locked(CURRENT->bh))
1604 panic(DEVICE_NAME ": block not locked");
1607 if (CURRENT->nr_sectors == 0) {
1610 azt_buf_out = -1; /* Want to read a block not in buffer */
1611 if (azt_state == AZT_S_IDLE) {
1612 if ((!aztTocUpToDate) || aztDiskChanged) {
1613 if (aztUpdateToc() < 0) {
1614 while (CURRENT_VALID)
1619 azt_state = AZT_S_START;
1621 SET_TIMER(azt_poll, HZ / 100);
1626 azt_transfer_is_active = 0;
1629 ("azt_next_bn:%x azt_buf_in:%x azt_buf_out:%x azt_buf_bn:%x\n",
1630 azt_next_bn, azt_buf_in, azt_buf_out, azt_buf_bn[azt_buf_in]);
1631 printk(" do_aztcd_request ends Time:%li\n", jiffies);
1636 static void azt_invalidate_buffers(void)
1641 printk("aztcd: executing azt_invalidate_buffers\n");
1643 for (i = 0; i < AZT_BUF_SIZ; ++i)
1649 * Open the device special file. Check that a disk is in.
1651 int aztcd_open(struct inode *ip, struct file *fp)
1656 printk("aztcd: starting aztcd_open\n");
1659 if (aztPresent == 0)
1660 return -ENXIO; /* no hardware */
1662 if (!azt_open_count && azt_state == AZT_S_IDLE) {
1663 azt_invalidate_buffers();
1665 st = getAztStatus(); /* check drive status */
1667 goto err_out; /* drive doesn't respond */
1669 if (st & AST_DOOR_OPEN) { /* close door, then get the status again. */
1670 printk("aztcd: Door Open?\n");
1672 st = getAztStatus();
1675 if ((st & AST_NOT_READY) || (st & AST_DSK_CHG)) { /*no disk in drive or changed */
1677 ("aztcd: Disk Changed or No Disk in Drive?\n");
1688 printk("aztcd: exiting aztcd_open\n");
1698 * On close, we flush all azt blocks from the buffer cache.
1700 static int aztcd_release(struct inode *inode, struct file *file)
1703 printk("aztcd: executing aztcd_release\n");
1704 printk("inode: %p, inode->i_rdev: %x file: %p\n", inode,
1705 inode->i_rdev, file);
1707 if (!--azt_open_count) {
1708 azt_invalidate_buffers();
1711 aztSendCmd(ACMD_EJECT);
1720 * Test for presence of drive and initialize it. Called at boot time.
1723 int __init aztcd_init(void)
1725 long int count, max_count;
1726 unsigned char result[50];
1730 if (azt_port == 0) {
1731 printk("aztcd: no Aztech CD-ROM Initialization");
1736 ("aztcd: AZTECH, ORCHID, OKANO, WEARNES, TXC, CyDROM CD-ROM Driver\n");
1737 printk("aztcd: (C) 1994-98 W.Zimmermann\n");
1738 if (azt_port == -1) {
1740 ("aztcd: KernelVersion=%s DriverVersion=%s For IDE/ATAPI-drives use ide-cd.c\n",
1741 UTS_RELEASE, AZT_VERSION);
1744 ("aztcd: DriverVersion=%s BaseAddress=0x%x For IDE/ATAPI-drives use ide-cd.c\n",
1745 AZT_VERSION, azt_port);
1747 ("aztcd: If you have problems, read /usr/src/linux/Documentation/cdrom/aztcd\n");
1750 #ifdef AZT_SW32 /*CDROM connected to Soundwave32 card */
1751 if ((0xFF00 & inw(AZT_SW32_ID_REG)) != 0x4500) {
1753 ("aztcd: no Soundwave32 card detected at base:%x init:%x config:%x id:%x\n",
1754 AZT_SW32_BASE_ADDR, AZT_SW32_INIT,
1755 AZT_SW32_CONFIG_REG, AZT_SW32_ID_REG);
1759 "aztcd: Soundwave32 card detected at %x Version %x\n",
1760 AZT_SW32_BASE_ADDR, inw(AZT_SW32_ID_REG));
1761 outw(AZT_SW32_INIT, AZT_SW32_CONFIG_REG);
1762 for (count = 0; count < 10000; count++); /*delay a bit */
1766 /* check for presence of drive */
1768 if (azt_port == -1) { /* autoprobing */
1769 for (i = 0; (azt_port_auto[i] != 0) && (i < 16); i++) {
1770 azt_port = azt_port_auto[i];
1771 printk("aztcd: Autoprobing BaseAddress=0x%x \n",
1773 st = check_region(azt_port, 4); /*proprietary interfaces need 4 bytes */
1777 outb(POLLED, MODE_PORT);
1780 outb(ACMD_GET_VERSION, CMD_PORT); /*Try to get version info */
1782 aztTimeOutCount = 0;
1784 aztIndatum = inb(STATUS_PORT);
1786 if (aztTimeOutCount >= AZT_FAST_TIMEOUT)
1788 } while (aztIndatum & AFL_STATUS);
1789 if (inb(DATA_PORT) == AFL_OP_OK)
1792 if ((azt_port_auto[i] == 0) || (i == 16)) {
1793 printk("aztcd: no AZTECH CD-ROM drive found\n");
1796 } else { /* no autoprobing */
1797 if ((azt_port == 0x1f0) || (azt_port == 0x170))
1798 st = check_region(azt_port, 8); /*IDE-interfaces need 8 bytes */
1800 st = check_region(azt_port, 4); /*proprietary interfaces need 4 bytes */
1803 ("aztcd: conflict, I/O port (%X) already used\n",
1808 if ((azt_port == 0x1f0) || (azt_port == 0x170))
1809 SWITCH_IDE_SLAVE; /*switch IDE interface to slave configuration */
1811 outb(POLLED, MODE_PORT);
1814 outb(ACMD_GET_VERSION, CMD_PORT); /*Try to get version info */
1816 aztTimeOutCount = 0;
1818 aztIndatum = inb(STATUS_PORT);
1820 if (aztTimeOutCount >= AZT_FAST_TIMEOUT)
1822 } while (aztIndatum & AFL_STATUS);
1824 if (inb(DATA_PORT) != AFL_OP_OK) { /*OP_OK? If not, reset and try again */
1826 if (azt_cont != 0x79) {
1828 ("aztcd: no AZTECH CD-ROM drive found-Try boot parameter aztcd=<BaseAddress>,0x79\n");
1837 ("aztcd: drive reset - please wait\n");
1838 for (count = 0; count < 50; count++) {
1839 inb(STATUS_PORT); /*removing all data from earlier tries */
1842 outb(POLLED, MODE_PORT);
1845 getAztStatus(); /*trap errors */
1846 outb(ACMD_SOFT_RESET, CMD_PORT); /*send reset */
1848 if (inb(DATA_PORT) != AFL_OP_OK) { /*OP_OK? */
1850 ("aztcd: no AZTECH CD-ROM drive found\n");
1854 for (count = 0; count < AZT_TIMEOUT;
1856 barrier(); /* Stop gcc 2.96 being smart */
1858 if ((st = getAztStatus()) == -1) {
1860 ("aztcd: Drive Status Error Status=%x\n",
1865 printk("aztcd: Status = %x\n", st);
1867 outb(POLLED, MODE_PORT);
1870 outb(ACMD_GET_VERSION, CMD_PORT); /*GetVersion */
1879 result[0] = inb(DATA_PORT); /*reading in a null byte??? */
1880 for (count = 1; count < 50; count++) { /*Reading version string */
1881 aztTimeOutCount = 0; /*here we must implement STEN_LOW differently */
1883 aztIndatum = inb(STATUS_PORT); /*because we want to exit by timeout */
1885 if (aztTimeOutCount >= AZT_FAST_TIMEOUT)
1887 } while (aztIndatum & AFL_STATUS);
1888 if (aztTimeOutCount >= AZT_FAST_TIMEOUT)
1889 break; /*all chars read? */
1890 result[count] = inb(DATA_PORT);
1893 max_count = 30; /*print max.30 chars of the version string */
1896 printk(KERN_INFO "aztcd: FirmwareVersion=");
1897 for (count = 1; count < max_count; count++)
1898 printk("%c", result[count]);
1901 if ((result[1] == 'A') && (result[2] == 'Z') && (result[3] == 'T')) {
1902 printk("AZTECH drive detected\n");
1904 else if ((result[2] == 'C') && (result[3] == 'D')
1905 && (result[4] == 'D')) {
1906 printk("ORCHID or WEARNES drive detected\n"); /*ORCHID or WEARNES */
1907 } else if ((result[1] == 0x03) && (result[2] == '5')) {
1908 printk("TXC or CyCDROM drive detected\n"); /*Conrad TXC, CyCDROM */
1909 } else { /*OTHERS or none */
1910 printk("\nunknown drive or firmware version detected\n");
1912 ("aztcd may not run stable, if you want to try anyhow,\n");
1913 printk("boot with: aztcd=<BaseAddress>,0x79\n");
1914 if ((azt_cont != 0x79)) {
1915 printk("aztcd: FirmwareVersion=");
1916 for (count = 1; count < 5; count++)
1917 printk("%c", result[count]);
1919 printk("Aborted\n");
1923 devfs_register(NULL, "aztcd", DEVFS_FL_DEFAULT, MAJOR_NR, 0,
1924 S_IFBLK | S_IRUGO | S_IWUGO, &azt_fops, NULL);
1925 if (devfs_register_blkdev(MAJOR_NR, "aztcd", &azt_fops) != 0) {
1926 printk("aztcd: Unable to get major %d for Aztech CD-ROM\n",
1930 blk_init_queue(BLK_DEFAULT_QUEUE(MAJOR_NR), DEVICE_REQUEST);
1931 blksize_size[MAJOR_NR] = aztcd_blocksizes;
1932 read_ahead[MAJOR_NR] = 4;
1933 register_disk(NULL, MKDEV(MAJOR_NR, 0), 1, &azt_fops, 0);
1935 if ((azt_port == 0x1f0) || (azt_port == 0x170))
1936 request_region(azt_port, 8, "aztcd"); /*IDE-interface */
1938 request_region(azt_port, 4, "aztcd"); /*proprietary interface */
1940 azt_invalidate_buffers();
1946 void __exit aztcd_exit(void)
1948 devfs_unregister(devfs_find_handle
1949 (NULL, "aztcd", 0, 0, DEVFS_SPECIAL_BLK, 0));
1950 if ((devfs_unregister_blkdev(MAJOR_NR, "aztcd") == -EINVAL)) {
1951 printk("What's that: can't unregister aztcd\n");
1954 blk_cleanup_queue(BLK_DEFAULT_QUEUE(MAJOR_NR));
1955 if ((azt_port == 0x1f0) || (azt_port == 0x170)) {
1957 release_region(azt_port, 8); /*IDE-interface */
1959 release_region(azt_port, 4); /*proprietary interface */
1960 printk(KERN_INFO "aztcd module released.\n");
1964 module_init(aztcd_init);
1966 module_exit(aztcd_exit);
1968 /*##########################################################################
1969 Aztcd State Machine: Controls Drive Operating State
1970 ##########################################################################
1972 static void azt_poll(void)
1979 if (aztSendCmd(ACMD_GET_ERROR))
1980 RETURN("azt_poll 1");
1982 azt_error = inb(DATA_PORT) & 0xFF;
1983 printk("aztcd: I/O error 0x%02x\n", azt_error);
1984 azt_invalidate_buffers();
1985 #ifdef WARN_IF_READ_FAILURE
1988 ("aztcd: Read of Block %d Failed - Maybe Audio Disk?\n",
1993 ("aztcd: Read of Block %d Failed, Maybe Audio Disk? Giving up\n",
1995 if (azt_transfer_is_active) {
2004 azt_state = AZT_S_STOP;
2008 loop_ctl = 0; /* each case must flip this back to 1 if we want
2009 to come back up here */
2010 switch (azt_state) {
2014 if (azt_state != azt_state_old) {
2015 azt_state_old = azt_state;
2016 printk("AZT_S_IDLE\n");
2023 if (azt_state != azt_state_old) {
2024 azt_state_old = azt_state;
2025 printk("AZT_S_START\n");
2028 if (aztSendCmd(ACMD_GET_STATUS))
2029 RETURN("azt_poll 2"); /*result will be checked by aztStatus() */
2031 azt_mode == 1 ? AZT_S_READ : AZT_S_MODE;
2037 if (azt_state != azt_state_old) {
2038 azt_state_old = azt_state;
2039 printk("AZT_S_MODE\n");
2043 if ((st = aztStatus()) != -1) {
2044 if ((st & AST_DSK_CHG)
2045 || (st & AST_NOT_READY)) {
2048 azt_invalidate_buffers();
2051 ("aztcd: Disk Changed or Not Ready 1 - Unmount Disk!\n");
2058 if ((st & AST_DOOR_OPEN) || (st & AST_NOT_READY)) {
2062 ("aztcd: Disk Changed or Not Ready 2 - Unmount Disk!\n");
2064 printk((st & AST_DOOR_OPEN) ?
2065 "aztcd: door open\n" :
2066 "aztcd: disk removed\n");
2067 if (azt_transfer_is_active) {
2068 azt_state = AZT_S_START;
2069 loop_ctl = 1; /* goto immediately */
2072 azt_state = AZT_S_IDLE;
2073 while (CURRENT_VALID)
2078 /* if (aztSendCmd(ACMD_SET_MODE)) RETURN("azt_poll 3");
2079 outb(0x01, DATA_PORT);
2083 if (aztSendCmd(ACMD_GET_STATUS))
2084 RETURN("azt_poll 4");
2087 azt_state = AZT_S_READ;
2095 if (azt_state != azt_state_old) {
2096 azt_state_old = azt_state;
2097 printk("AZT_S_READ\n");
2101 if ((st = aztStatus()) != -1) {
2102 if ((st & AST_DSK_CHG)
2103 || (st & AST_NOT_READY)) {
2106 azt_invalidate_buffers();
2108 ("aztcd: Disk Changed or Not Ready 3 - Unmount Disk!\n");
2116 if ((st & AST_DOOR_OPEN) || (st & AST_NOT_READY)) {
2119 printk((st & AST_DOOR_OPEN) ?
2120 "aztcd: door open\n" :
2121 "aztcd: disk removed\n");
2122 if (azt_transfer_is_active) {
2123 azt_state = AZT_S_START;
2127 azt_state = AZT_S_IDLE;
2128 while (CURRENT_VALID)
2133 if (CURRENT_VALID) {
2134 struct azt_Play_msf msf;
2136 azt_next_bn = CURRENT->sector / 4;
2137 azt_hsg2msf(azt_next_bn, &msf.start);
2139 /* find out in which track we are */
2140 while (azt_msf2hsg(&msf.start) >
2141 azt_msf2hsg(&Toc[++i].trackTime)) {
2143 if (azt_msf2hsg(&msf.start) <
2144 azt_msf2hsg(&Toc[i].trackTime) -
2146 azt_read_count = AZT_BUF_SIZ; /*fast, because we read ahead */
2147 /*azt_read_count=CURRENT->nr_sectors; slow, no read ahead */
2148 } else /* don't read beyond end of track */
2149 #if AZT_MULTISESSION
2152 (azt_msf2hsg(&Toc[i].trackTime)
2154 azt_msf2hsg(&msf.start);
2155 if (azt_read_count < 0)
2157 if (azt_read_count > AZT_BUF_SIZ)
2161 ("aztcd: warning - trying to read beyond end of track\n");
2162 /* printk("%i %i %li %li\n",i,azt_read_count,azt_msf2hsg(&msf.start),azt_msf2hsg(&Toc[i].trackTime));
2166 azt_read_count = AZT_BUF_SIZ;
2171 msf.end.frame = azt_read_count; /*Mitsumi here reads 0xffffff sectors */
2174 ("---reading msf-address %x:%x:%x %x:%x:%x\n",
2175 msf.start.min, msf.start.sec,
2176 msf.start.frame, msf.end.min,
2177 msf.end.sec, msf.end.frame);
2179 ("azt_next_bn:%x azt_buf_in:%x azt_buf_out:%x azt_buf_bn:%x\n",
2180 azt_next_bn, azt_buf_in, azt_buf_out,
2181 azt_buf_bn[azt_buf_in]);
2183 if (azt_read_mode == AZT_MODE_2) {
2184 sendAztCmd(ACMD_PLAY_READ_RAW, &msf); /*XA disks in raw mode */
2186 sendAztCmd(ACMD_PLAY_READ, &msf); /*others in cooked mode */
2188 azt_state = AZT_S_DATA;
2189 AztTimeout = READ_TIMEOUT;
2191 azt_state = AZT_S_STOP;
2201 if (azt_state != azt_state_old) {
2202 azt_state_old = azt_state;
2203 printk("AZT_S_DATA\n");
2207 st = inb(STATUS_PORT) & AFL_STATUSorDATA;
2213 if (st != azt_st_old) {
2215 printk("---AFL_DATA st:%x\n", st);
2220 ("aztcd: Read of Block %d Failed, Maybe Audio Disk ? Giving up\n",
2222 if (azt_transfer_is_active) {
2230 azt_state = AZT_S_START;
2231 AztTimeout = READ_TIMEOUT;
2235 case AFL_STATUSorDATA:
2237 if (st != azt_st_old) {
2240 ("---AFL_STATUSorDATA st:%x\n",
2248 if (st != azt_st_old) {
2250 printk("---default: st:%x\n", st);
2255 && azt_buf_in == azt_buf_out) {
2256 azt_state = AZT_S_STOP;
2260 if (azt_read_count <= 0)
2262 ("aztcd: warning - try to read 0 frames\n");
2263 while (azt_read_count) { /*??? fast read ahead loop */
2264 azt_buf_bn[azt_buf_in] = -1;
2265 DTEN_LOW; /*??? unsolved problem, very
2266 seldom we get timeouts
2267 here, don't now the real
2268 reason. With my drive this
2269 sometimes also happens with
2270 Aztech's original driver under
2271 DOS. Is it a hardware bug?
2272 I tried to recover from such
2273 situations here. Zimmermann */
2274 if (aztTimeOutCount >= AZT_TIMEOUT) {
2276 ("read_count:%d CURRENT->nr_sectors:%ld azt_buf_in:%d\n",
2278 CURRENT->nr_sectors,
2281 ("azt_transfer_is_active:%x\n",
2282 azt_transfer_is_active);
2284 azt_state = AZT_S_STOP;
2286 end_request(1); /*should we have here (1) or (0)? */
2288 if (azt_read_mode ==
2305 ("AZT_S_DATA; ---I've read data- read_count: %d\n",
2308 ("azt_next_bn:%d azt_buf_in:%d azt_buf_out:%d azt_buf_bn:%d\n",
2315 azt_buf_bn[azt_buf_in] =
2317 if (azt_buf_out == -1)
2326 if (!azt_transfer_is_active) {
2327 while (CURRENT_VALID) {
2329 if (CURRENT->nr_sectors ==
2338 && (CURRENT->sector / 4 < azt_next_bn
2339 || CURRENT->sector / 4 >
2340 azt_next_bn + AZT_BUF_SIZ)) {
2341 azt_state = AZT_S_STOP;
2345 AztTimeout = READ_TIMEOUT;
2346 if (azt_read_count == 0) {
2347 azt_state = AZT_S_STOP;
2358 if (azt_state != azt_state_old) {
2359 azt_state_old = azt_state;
2360 printk("AZT_S_STOP\n");
2363 if (azt_read_count != 0)
2364 printk("aztcd: discard data=%x frames\n",
2366 while (azt_read_count != 0) {
2368 if (!(inb(STATUS_PORT) & AFL_DATA)) {
2369 if (azt_read_mode == AZT_MODE_2)
2371 i < CD_FRAMESIZE_RAW;
2376 i < CD_FRAMESIZE; i++)
2381 if (aztSendCmd(ACMD_GET_STATUS))
2382 RETURN("azt_poll 5");
2383 azt_state = AZT_S_STOPPING;
2387 case AZT_S_STOPPING:
2389 if (azt_state != azt_state_old) {
2390 azt_state_old = azt_state;
2391 printk("AZT_S_STOPPING\n");
2395 if ((st = aztStatus()) == -1 && AztTimeout)
2399 && ((st & AST_DSK_CHG)
2400 || (st & AST_NOT_READY))) {
2403 azt_invalidate_buffers();
2405 ("aztcd: Disk Changed or Not Ready 4 - Unmount Disk!\n");
2410 printk("CURRENT_VALID %d azt_mode %d\n",
2411 CURRENT_VALID, azt_mode);
2414 if (CURRENT_VALID) {
2416 if (azt_mode == 1) {
2417 azt_state = AZT_S_READ;
2422 azt_state = AZT_S_MODE;
2428 azt_state = AZT_S_START;
2432 azt_state = AZT_S_IDLE;
2438 printk("aztcd: invalid state %d\n", azt_state);
2444 if (!AztTimeout--) {
2445 printk("aztcd: timeout in state %d\n", azt_state);
2446 azt_state = AZT_S_STOP;
2447 if (aztSendCmd(ACMD_STOP))
2448 RETURN("azt_poll 6");
2452 SET_TIMER(azt_poll, HZ / 100);
2456 /*###########################################################################
2457 * Miscellaneous support functions
2458 ###########################################################################
2460 static void azt_hsg2msf(long hsg, struct msf *msf)
2463 msf->min = hsg / 4500;
2465 msf->sec = hsg / 75;
2466 msf->frame = hsg % 75;
2469 printk("aztcd: Error hsg2msf address Minutes\n");
2471 printk("aztcd: Error hsg2msf address Seconds\n");
2472 if (msf->frame >= 75)
2473 printk("aztcd: Error hsg2msf address Frames\n");
2475 azt_bin2bcd(&msf->min); /* convert to BCD */
2476 azt_bin2bcd(&msf->sec);
2477 azt_bin2bcd(&msf->frame);
2480 static long azt_msf2hsg(struct msf *mp)
2482 return azt_bcd2bin(mp->frame) + azt_bcd2bin(mp->sec) * 75
2483 + azt_bcd2bin(mp->min) * 4500 - CD_MSF_OFFSET;
2486 static void azt_bin2bcd(unsigned char *p)
2495 static int azt_bcd2bin(unsigned char bcd)
2497 return (bcd >> 4) * 10 + (bcd & 0xF);
2500 MODULE_LICENSE("GPL");