1 #define AZT_VERSION "2.60"
3 /* $Id: aztcd.c,v 2.60 1997/11/29 09:51:19 root Exp root $
4 linux/drivers/block/aztcd.c - Aztech CD268 CDROM driver
6 Copyright (C) 1994-98 Werner Zimmermann(Werner.Zimmermann@fht-esslingen.de)
8 based on Mitsumi CDROM driver by Martin Hariss and preworks by
9 Eberhard Moenkeberg; contains contributions by Joe Nardone and Robby
12 This program is free software; you can redistribute it and/or modify
13 it under the terms of the GNU General Public License as published by
14 the Free Software Foundation; either version 2, or (at your option)
17 This program is distributed in the hope that it will be useful,
18 but WITHOUT ANY WARRANTY; without even the implied warranty of
19 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 GNU General Public License for more details.
22 You should have received a copy of the GNU General Public License
23 along with this program; if not, write to the Free Software
24 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
27 V0.0 Adaption to Aztech CD268-01A Version 1.3
28 Version is PRE_ALPHA, unresolved points:
29 1. I use busy wait instead of timer wait in STEN_LOW,DTEN_LOW
30 thus driver causes CPU overhead and is very slow
31 2. could not find a way to stop the drive, when it is
32 in data read mode, therefore I had to set
33 msf.end.min/sec/frame to 0:0:1 (in azt_poll); so only one
34 frame can be read in sequence, this is also the reason for
35 3. getting 'timeout in state 4' messages, but nevertheless
37 W.Zimmermann, Oct. 31, 1994
38 V0.1 Version is ALPHA, problems #2 and #3 resolved.
39 W.Zimmermann, Nov. 3, 1994
40 V0.2 Modification to some comments, debugging aids for partial test
41 with Borland C under DOS eliminated. Timer interrupt wait
42 STEN_LOW_WAIT additionally to busy wait for STEN_LOW implemented;
43 use it only for the 'slow' commands (ACMD_GET_Q_CHANNEL, ACMD_
44 SEEK_TO_LEAD_IN), all other commands are so 'fast', that busy
45 waiting seems better to me than interrupt rescheduling.
46 Besides that, when used in the wrong place, STEN_LOW_WAIT causes
48 In function aztPlay command ACMD_PLAY_AUDIO added, should make
49 audio functions work. The Aztech drive needs different commands
50 to read data tracks and play audio tracks.
51 W.Zimmermann, Nov. 8, 1994
52 V0.3 Recognition of missing drive during boot up improved (speeded up).
53 W.Zimmermann, Nov. 13, 1994
54 V0.35 Rewrote the control mechanism in azt_poll (formerly mcd_poll)
55 including removal of all 'goto' commands. :-);
56 J. Nardone, Nov. 14, 1994
57 V0.4 Renamed variables and constants to 'azt' instead of 'mcd'; had
58 to make some "compatibility" defines in azt.h; please note,
59 that the source file was renamed to azt.c, the include file to
61 Speeded up drive recognition during init (will be a little bit
62 slower than before if no drive is installed!); suggested by
64 read_count declared volatile and set to AZT_BUF_SIZ to make
65 drive faster (now 300kB/sec, was 60kB/sec before, measured
66 by 'time dd if=/dev/cdrom of=/dev/null bs=2048 count=4096';
67 different AZT_BUF_SIZes were test, above 16 no further im-
68 provement seems to be possible; suggested by E.Moenkeberg.
69 W.Zimmermann, Nov. 18, 1994
70 V0.42 Included getAztStatus command in GetQChannelInfo() to allow
71 reading Q-channel info on audio disks, if drive is stopped,
72 and some other bug fixes in the audio stuff, suggested by
74 Added more ioctls (reading data in mode 1 and mode 2).
75 Completely removed the old azt_poll() routine.
76 Detection of ORCHID CDS-3110 in aztcd_init implemented.
77 Additional debugging aids (see the readme file).
78 W.Zimmermann, Dec. 9, 1994
79 V0.50 Autodetection of drives implemented.
80 W.Zimmermann, Dec. 12, 1994
81 V0.52 Prepared for including in the standard kernel, renamed most
82 variables to contain 'azt', included autoconf.h
83 W.Zimmermann, Dec. 16, 1994
84 V0.6 Version for being included in the standard Linux kernel.
85 Renamed source and header file to aztcd.c and aztcd.h
86 W.Zimmermann, Dec. 24, 1994
87 V0.7 Changed VERIFY_READ to VERIFY_WRITE in aztcd_ioctl, case
88 CDROMREADMODE1 and CDROMREADMODE2; bug fix in the ioctl,
89 which causes kernel crashes when playing audio, changed
90 include-files (config.h instead of autoconf.h, removed
92 W.Zimmermann, Jan. 8, 1995
93 V0.72 Some more modifications for adaption to the standard kernel.
94 W.Zimmermann, Jan. 16, 1995
95 V0.80 aztcd is now part of the standard kernel since version 1.1.83.
96 Modified the SET_TIMER and CLEAR_TIMER macros to comply with
98 W.Zimmermann, Jan. 21, 1995
99 V0.90 Included CDROMVOLCTRL, but with my Aztech drive I can only turn
100 the channels on and off. If it works better with your drive,
101 please mail me. Also implemented ACMD_CLOSE for CDROMSTART.
102 W.Zimmermann, Jan. 24, 1995
103 V1.00 Implemented close and lock tray commands. Patches supplied by
105 Added support for loadable MODULEs, so aztcd can now also be
106 loaded by insmod and removed by rmmod during run time
107 Werner Zimmermann, Mar. 24, 95
108 V1.10 Implemented soundcard configuration for Orchid CDS-3110 drives
109 connected to Soundwave32 cards. Release for LST 2.1.
111 Werner Zimmermann, May 8, 95
112 V1.20 Implemented limited support for DOSEMU0.60's cdrom.c. Now it works, but
113 sometimes DOSEMU may hang for 30 seconds or so. A fully functional ver-
114 sion needs an update of Dosemu0.60's cdrom.c, which will come with the
115 next revision of Dosemu.
116 Also Soundwave32 support now works.
117 Werner Zimmermann, May 22, 95
118 V1.30 Auto-eject feature. Inspired by Franc Racis (racis@psu.edu)
119 Werner Zimmermann, July 4, 95
120 V1.40 Started multisession support. Implementation copied from mcdx.c
121 by Heiko Schlittermann. Not tested yet.
122 Werner Zimmermann, July 15, 95
123 V1.50 Implementation of ioctl CDROMRESET, continued multisession, began
124 XA, but still untested. Heavy modifications to drive status de-
126 Werner Zimmermann, July 25, 95
127 V1.60 XA support now should work. Speeded up drive recognition in cases,
128 where no drive is installed.
129 Werner Zimmermann, August 8, 1995
130 V1.70 Multisession support now is completed, but there is still not
131 enough testing done. If you can test it, please contact me. For
132 details please read /usr/src/linux/Documentation/cdrom/aztcd
133 Werner Zimmermann, August 19, 1995
134 V1.80 Modification to suit the new kernel boot procedure introduced
135 with kernel 1.3.33. Will definitely not work with older kernels.
136 Programming done by Linus himself.
137 Werner Zimmermann, October 11, 1995
138 V1.90 Support for Conrad TXC drives, thank's to Jochen Kunz and Olaf Kaluza.
139 Werner Zimmermann, October 21, 1995
140 V2.00 Changed #include "blk.h" to <linux/blk.h> as the directory
141 structure was changed. README.aztcd is now /usr/src/docu-
142 mentation/cdrom/aztcd
143 Werner Zimmermann, November 10, 95
144 V2.10 Started to modify azt_poll to prevent reading beyond end of
146 Werner Zimmermann, December 3, 95
147 V2.20 Changed some comments
148 Werner Zimmermann, April 1, 96
149 V2.30 Implemented support for CyCDROM CR520, CR940, Code for CR520
150 delivered by H.Berger with preworks by E.Moenkeberg.
151 Werner Zimmermann, April 29, 96
152 V2.40 Reorganized the placement of functions in the source code file
153 to reflect the layered approach; did not actually change code
154 Werner Zimmermann, May 1, 96
155 V2.50 Heiko Eissfeldt suggested to remove some VERIFY_READs in
156 aztcd_ioctl; check_aztcd_media_change modified
157 Werner Zimmermann, May 16, 96
158 V2.60 Implemented Auto-Probing; made changes for kernel's 2.1.xx blocksize
159 Adaption to linux kernel > 2.1.0
160 Werner Zimmermann, Nov 29, 97
162 November 1999 -- Make kernel-parameter implementation work with 2.3.x
163 Removed init_module & cleanup_module in favor of
164 module_init & module_exit.
165 Torben Mathiasen <tmm@image.dk>
168 #include <linux/version.h>
169 #include <linux/blkdev.h>
172 #include <linux/module.h>
173 #include <linux/errno.h>
174 #include <linux/sched.h>
175 #include <linux/mm.h>
176 #include <linux/timer.h>
177 #include <linux/fs.h>
178 #include <linux/kernel.h>
179 #include <linux/cdrom.h>
180 #include <linux/ioport.h>
181 #include <linux/string.h>
182 #include <linux/major.h>
184 #include <linux/init.h>
186 #include <asm/system.h>
189 #include <asm/uaccess.h>
191 /*###########################################################################
193 ###########################################################################
196 #define MAJOR_NR AZTECH_CDROM_MAJOR
197 #define QUEUE (azt_queue)
198 #define CURRENT elv_next_request(azt_queue)
199 #define SET_TIMER(func, jifs) delay_timer.expires = jiffies + (jifs); \
200 delay_timer.function = (void *) (func); \
201 add_timer(&delay_timer);
203 #define CLEAR_TIMER del_timer(&delay_timer);
205 #define RETURNM(message,value) {printk("aztcd: Warning: %s failed\n",message);\
207 #define RETURN(message) {printk("aztcd: Warning: %s failed\n",message);\
210 /* Macros to switch the IDE-interface to the slave device and back to the master*/
211 #define SWITCH_IDE_SLAVE outb_p(0xa0,azt_port+6); \
212 outb_p(0x10,azt_port+6); \
213 outb_p(0x00,azt_port+7); \
214 outb_p(0x10,azt_port+6);
215 #define SWITCH_IDE_MASTER outb_p(0xa0,azt_port+6);
220 #define AZT_TEST1 /* <int-..> */
221 #define AZT_TEST2 /* do_aztcd_request */
222 #define AZT_TEST3 /* AZT_S_state */
223 #define AZT_TEST4 /* QUICK_LOOP-counter */
224 #define AZT_TEST5 /* port(1) state */
226 #define AZT_DEBUG_MULTISESSION
229 static struct request_queue *azt_queue;
231 static int current_valid(void)
234 CURRENT->cmd == READ &&
235 CURRENT->sector != -1;
238 #define AFL_STATUSorDATA (AFL_STATUS | AFL_DATA)
239 #define AZT_BUF_SIZ 16
241 #define READ_TIMEOUT 3000
243 #define azt_port aztcd /*needed for the modutils */
245 /*##########################################################################
247 ##########################################################################
249 enum azt_state_e { AZT_S_IDLE, /* 0 */
255 AZT_S_STOPPING /* 6 */
257 enum azt_read_modes { AZT_MODE_0, /*read mode for audio disks, not supported by Aztech firmware */
258 AZT_MODE_1, /*read mode for normal CD-ROMs */
259 AZT_MODE_2 /*read mode for XA CD-ROMs */
262 /*##########################################################################
264 ##########################################################################
266 static int aztPresent = 0;
268 static volatile int azt_transfer_is_active = 0;
270 static char azt_buf[CD_FRAMESIZE_RAW * AZT_BUF_SIZ]; /*buffer for block size conversion */
271 #if AZT_PRIVATE_IOCTLS
272 static char buf[CD_FRAMESIZE_RAW]; /*separate buffer for the ioctls */
275 static volatile int azt_buf_bn[AZT_BUF_SIZ], azt_next_bn;
276 static volatile int azt_buf_in, azt_buf_out = -1;
277 static volatile int azt_error = 0;
278 static int azt_open_count = 0;
279 static volatile enum azt_state_e azt_state = AZT_S_IDLE;
281 static volatile enum azt_state_e azt_state_old = AZT_S_STOP;
282 static volatile int azt_st_old = 0;
284 static volatile enum azt_read_modes azt_read_mode = AZT_MODE_1;
286 static int azt_mode = -1;
287 static volatile int azt_read_count = 1;
289 static int azt_port = AZT_BASE_ADDR;
291 MODULE_PARM(azt_port, "i");
293 static int azt_port_auto[16] = AZT_BASE_AUTO;
295 static char azt_cont = 0;
296 static char azt_init_end = 0;
297 static char azt_auto_eject = AZT_AUTO_EJECT;
299 static int AztTimeout, AztTries;
300 static DECLARE_WAIT_QUEUE_HEAD(azt_waitq);
301 static struct timer_list delay_timer = TIMER_INITIALIZER(NULL, 0, 0);
303 static struct azt_DiskInfo DiskInfo;
304 static struct azt_Toc Toc[MAX_TRACKS];
305 static struct azt_Play_msf azt_Play;
307 static int aztAudioStatus = CDROM_AUDIO_NO_STATUS;
308 static char aztDiskChanged = 1;
309 static char aztTocUpToDate = 0;
311 static unsigned char aztIndatum;
312 static unsigned long aztTimeOutCount;
313 static int aztCmd = 0;
315 static spinlock_t aztSpin = SPIN_LOCK_UNLOCKED;
317 /*###########################################################################
319 ###########################################################################
321 /* CDROM Drive Low Level I/O Functions */
322 static void aztStatTimer(void);
324 /* CDROM Drive Command Functions */
325 static int aztGetDiskInfo(void);
327 static int aztGetMultiDiskInfo(void);
329 static int aztGetToc(int multi);
331 /* Kernel Interface Functions */
332 static int check_aztcd_media_change(struct gendisk *disk);
333 static int aztcd_ioctl(struct inode *ip, struct file *fp, unsigned int cmd,
335 static int aztcd_open(struct inode *ip, struct file *fp);
336 static int aztcd_release(struct inode *inode, struct file *file);
338 static struct block_device_operations azt_fops = {
339 .owner = THIS_MODULE,
341 .release = aztcd_release,
342 .ioctl = aztcd_ioctl,
343 .media_changed = check_aztcd_media_change,
346 /* Aztcd State Machine: Controls Drive Operating State */
347 static void azt_poll(void);
349 /* Miscellaneous support functions */
350 static void azt_hsg2msf(long hsg, struct msf *msf);
351 static long azt_msf2hsg(struct msf *mp);
352 static void azt_bin2bcd(unsigned char *p);
353 static int azt_bcd2bin(unsigned char bcd);
355 /*##########################################################################
356 CDROM Drive Low Level I/O Functions
357 ##########################################################################
359 /* Macros for the drive hardware interface handshake, these macros use
361 /* Wait for OP_OK = drive answers with AFL_OP_OK after receiving a command*/
362 # define OP_OK op_ok()
363 static void op_ok(void)
367 aztIndatum = inb(DATA_PORT);
369 if (aztTimeOutCount >= AZT_TIMEOUT) {
370 printk("aztcd: Error Wait OP_OK\n");
373 } while (aztIndatum != AFL_OP_OK);
376 /* Wait for PA_OK = drive answers with AFL_PA_OK after receiving parameters*/
378 # define PA_OK pa_ok()
379 static void pa_ok(void)
383 aztIndatum = inb(DATA_PORT);
385 if (aztTimeOutCount >= AZT_TIMEOUT) {
386 printk("aztcd: Error Wait PA_OK\n");
389 } while (aztIndatum != AFL_PA_OK);
393 /* Wait for STEN=Low = handshake signal 'AFL_.._OK available or command executed*/
394 # define STEN_LOW sten_low()
395 static void sten_low(void)
399 aztIndatum = inb(STATUS_PORT);
401 if (aztTimeOutCount >= AZT_TIMEOUT) {
404 ("aztcd: Error Wait STEN_LOW commands:%x\n",
408 } while (aztIndatum & AFL_STATUS);
411 /* Wait for DTEN=Low = handshake signal 'Data available'*/
412 # define DTEN_LOW dten_low()
413 static void dten_low(void)
417 aztIndatum = inb(STATUS_PORT);
419 if (aztTimeOutCount >= AZT_TIMEOUT) {
420 printk("aztcd: Error Wait DTEN_OK\n");
423 } while (aztIndatum & AFL_DATA);
427 * Macro for timer wait on STEN=Low, should only be used for 'slow' commands;
428 * may cause kernel panic when used in the wrong place
430 #define STEN_LOW_WAIT statusAzt()
431 static void statusAzt(void)
433 AztTimeout = AZT_STATUS_DELAY;
434 SET_TIMER(aztStatTimer, HZ / 100);
435 sleep_on(&azt_waitq);
437 printk("aztcd: Error Wait STEN_LOW_WAIT command:%x\n",
442 static void aztStatTimer(void)
444 if (!(inb(STATUS_PORT) & AFL_STATUS)) {
449 if (AztTimeout <= 0) {
451 printk("aztcd: Error aztStatTimer: Timeout\n");
454 SET_TIMER(aztStatTimer, HZ / 100);
457 /*##########################################################################
458 CDROM Drive Command Functions
459 ##########################################################################
462 * Send a single command, return -1 on error, else 0
464 static int aztSendCmd(int cmd)
470 printk("aztcd: Executing command %x\n", cmd);
473 if ((azt_port == 0x1f0) || (azt_port == 0x170))
474 SWITCH_IDE_SLAVE; /*switch IDE interface to slave configuration */
477 outb(POLLED, MODE_PORT);
479 if (inb(STATUS_PORT) & AFL_STATUS)
481 inb(DATA_PORT); /* if status left from last command, read and */
482 } while (1); /* discard it */
484 if (inb(STATUS_PORT) & AFL_DATA)
486 inb(DATA_PORT); /* if data left from last command, read and */
487 } while (1); /* discard it */
488 for (retry = 0; retry < AZT_RETRY_ATTEMPTS; retry++) {
489 outb((unsigned char) cmd, CMD_PORT);
491 data = inb(DATA_PORT);
492 if (data == AFL_OP_OK) {
495 if (data == AFL_OP_ERR) {
497 data = inb(DATA_PORT);
499 ("### Error 1 aztcd: aztSendCmd %x Error Code %x\n",
503 if (retry >= AZT_RETRY_ATTEMPTS) {
504 printk("### Error 2 aztcd: aztSendCmd %x \n", cmd);
507 RETURNM("aztSendCmd", -1);
511 * Send a play or read command to the drive, return -1 on error, else 0
513 static int sendAztCmd(int cmd, struct azt_Play_msf *params)
519 printk("aztcd: play start=%02x:%02x:%02x end=%02x:%02x:%02x\n",
520 params->start.min, params->start.sec, params->start.frame,
521 params->end.min, params->end.sec, params->end.frame);
523 for (retry = 0; retry < AZT_RETRY_ATTEMPTS; retry++) {
525 outb(params->start.min, CMD_PORT);
526 outb(params->start.sec, CMD_PORT);
527 outb(params->start.frame, CMD_PORT);
528 outb(params->end.min, CMD_PORT);
529 outb(params->end.sec, CMD_PORT);
530 outb(params->end.frame, CMD_PORT);
532 data = inb(DATA_PORT);
533 if (data == AFL_PA_OK) {
536 if (data == AFL_PA_ERR) {
538 data = inb(DATA_PORT);
540 ("### Error 1 aztcd: sendAztCmd %x Error Code %x\n",
544 if (retry >= AZT_RETRY_ATTEMPTS) {
545 printk("### Error 2 aztcd: sendAztCmd %x\n ", cmd);
548 RETURNM("sendAztCmd", -1);
552 * Send a seek command to the drive, return -1 on error, else 0
554 static int aztSeek(struct azt_Play_msf *params)
560 printk("aztcd: aztSeek %02x:%02x:%02x\n",
561 params->start.min, params->start.sec, params->start.frame);
563 for (retry = 0; retry < AZT_RETRY_ATTEMPTS; retry++) {
564 aztSendCmd(ACMD_SEEK);
565 outb(params->start.min, CMD_PORT);
566 outb(params->start.sec, CMD_PORT);
567 outb(params->start.frame, CMD_PORT);
569 data = inb(DATA_PORT);
570 if (data == AFL_PA_OK) {
573 if (data == AFL_PA_ERR) {
575 data = inb(DATA_PORT);
576 printk("### Error 1 aztcd: aztSeek\n");
579 if (retry >= AZT_RETRY_ATTEMPTS) {
580 printk("### Error 2 aztcd: aztSeek\n ");
583 RETURNM("aztSeek", -1);
586 /* Send a Set Disk Type command
587 does not seem to work with Aztech drives, behavior is completely indepen-
588 dent on which mode is set ???
590 static int aztSetDiskType(int type)
596 printk("aztcd: set disk type command: type= %i\n", type);
598 for (retry = 0; retry < AZT_RETRY_ATTEMPTS; retry++) {
599 aztSendCmd(ACMD_SET_DISK_TYPE);
600 outb(type, CMD_PORT);
602 data = inb(DATA_PORT);
603 if (data == AFL_PA_OK) { /*PA_OK ? */
604 azt_read_mode = type;
607 if (data == AFL_PA_ERR) {
609 data = inb(DATA_PORT);
611 ("### Error 1 aztcd: aztSetDiskType %x Error Code %x\n",
615 if (retry >= AZT_RETRY_ATTEMPTS) {
616 printk("### Error 2 aztcd: aztSetDiskType %x\n ", type);
619 RETURNM("aztSetDiskType", -1);
623 /* used in azt_poll to poll the status, expects another program to issue a
624 * ACMD_GET_STATUS directly before
626 static int aztStatus(void)
631 i = inb(STATUS_PORT) & AFL_STATUS; is STEN=0? ???
634 if (aztTimeOutCount < AZT_TIMEOUT) {
635 st = inb(DATA_PORT) & 0xFF;
638 RETURNM("aztStatus", -1);
642 * Get the drive status
644 static int getAztStatus(void)
648 if (aztSendCmd(ACMD_GET_STATUS))
649 RETURNM("getAztStatus 1", -1);
651 st = inb(DATA_PORT) & 0xFF;
653 printk("aztcd: Status = %x\n", st);
655 if ((st == 0xFF) || (st & AST_CMD_CHECK)) {
657 ("aztcd: AST_CMD_CHECK error or no status available\n");
661 if (((st & AST_MODE_BITS) != AST_BUSY)
662 && (aztAudioStatus == CDROM_AUDIO_PLAY))
663 /* XXX might be an error? look at q-channel? */
664 aztAudioStatus = CDROM_AUDIO_COMPLETED;
666 if ((st & AST_DSK_CHG) || (st & AST_NOT_READY)) {
669 aztAudioStatus = CDROM_AUDIO_NO_STATUS;
676 * Send a 'Play' command and get the status. Use only from the top half.
678 static int aztPlay(struct azt_Play_msf *arg)
680 if (sendAztCmd(ACMD_PLAY_AUDIO, arg) < 0)
681 RETURNM("aztPlay", -1);
686 * Subroutines to automatically close the door (tray) and
687 * lock it closed when the cd is mounted. Leave the tray
688 * locking as an option
690 static void aztCloseDoor(void)
692 aztSendCmd(ACMD_CLOSE);
697 static void aztLockDoor(void)
699 #if AZT_ALLOW_TRAY_LOCK
700 aztSendCmd(ACMD_LOCK);
706 static void aztUnlockDoor(void)
708 #if AZT_ALLOW_TRAY_LOCK
709 aztSendCmd(ACMD_UNLOCK);
716 * Read a value from the drive. Should return quickly, so a busy wait
717 * is used to avoid excessive rescheduling. The read command itself must
718 * be issued with aztSendCmd() directly before
720 static int aztGetValue(unsigned char *result)
725 if (aztTimeOutCount >= AZT_TIMEOUT) {
726 printk("aztcd: aztGetValue timeout\n");
729 s = inb(DATA_PORT) & 0xFF;
730 *result = (unsigned char) s;
735 * Read the current Q-channel info. Also used for reading the
738 static int aztGetQChannelInfo(struct azt_Toc *qp)
740 unsigned char notUsed;
744 printk("aztcd: starting aztGetQChannelInfo Time:%li\n", jiffies);
746 if ((st = getAztStatus()) == -1)
747 RETURNM("aztGetQChannelInfo 1", -1);
748 if (aztSendCmd(ACMD_GET_Q_CHANNEL))
749 RETURNM("aztGetQChannelInfo 2", -1);
750 /*STEN_LOW_WAIT; ??? Dosemu0.60's cdrom.c does not like STEN_LOW_WAIT here */
751 if (aztGetValue(¬Used))
752 RETURNM("aztGetQChannelInfo 3", -1); /*??? Nullbyte einlesen */
753 if ((st & AST_MODE_BITS) == AST_INITIAL) {
754 qp->ctrl_addr = 0; /* when audio stop ACMD_GET_Q_CHANNEL returns */
755 qp->track = 0; /* only one byte with Aztech drives */
757 qp->trackTime.min = 0;
758 qp->trackTime.sec = 0;
759 qp->trackTime.frame = 0;
760 qp->diskTime.min = 0;
761 qp->diskTime.sec = 0;
762 qp->diskTime.frame = 0;
765 if (aztGetValue(&qp->ctrl_addr) < 0)
766 RETURNM("aztGetQChannelInfo 4", -1);
767 if (aztGetValue(&qp->track) < 0)
768 RETURNM("aztGetQChannelInfo 4", -1);
769 if (aztGetValue(&qp->pointIndex) < 0)
770 RETURNM("aztGetQChannelInfo 4", -1);
771 if (aztGetValue(&qp->trackTime.min) < 0)
772 RETURNM("aztGetQChannelInfo 4", -1);
773 if (aztGetValue(&qp->trackTime.sec) < 0)
774 RETURNM("aztGetQChannelInfo 4", -1);
775 if (aztGetValue(&qp->trackTime.frame) < 0)
776 RETURNM("aztGetQChannelInfo 4", -1);
777 if (aztGetValue(¬Used) < 0)
778 RETURNM("aztGetQChannelInfo 4", -1);
779 if (aztGetValue(&qp->diskTime.min) < 0)
780 RETURNM("aztGetQChannelInfo 4", -1);
781 if (aztGetValue(&qp->diskTime.sec) < 0)
782 RETURNM("aztGetQChannelInfo 4", -1);
783 if (aztGetValue(&qp->diskTime.frame) < 0)
784 RETURNM("aztGetQChannelInfo 4", -1);
787 printk("aztcd: exiting aztGetQChannelInfo Time:%li\n", jiffies);
793 * Read the table of contents (TOC) and TOC header if necessary
795 static int aztUpdateToc(void)
800 printk("aztcd: starting aztUpdateToc Time:%li\n", jiffies);
805 if (aztGetDiskInfo() < 0)
808 if (aztGetToc(0) < 0)
811 /*audio disk detection
812 with my Aztech drive there is no audio status bit, so I use the copy
813 protection bit of the first track. If this track is copy protected
814 (copy bit = 0), I assume, it's an audio disk. Strange, but works ??? */
815 if (!(Toc[DiskInfo.first].ctrl_addr & 0x40))
821 if (!DiskInfo.audio) {
822 azt_Play.start.min = 0; /*XA detection only seems to work */
823 azt_Play.start.sec = 2; /*when we play a track */
824 azt_Play.start.frame = 0;
825 azt_Play.end.min = 0;
826 azt_Play.end.sec = 0;
827 azt_Play.end.frame = 1;
828 if (sendAztCmd(ACMD_PLAY_READ, &azt_Play))
831 for (st = 0; st < CD_FRAMESIZE; st++)
834 DiskInfo.xa = getAztStatus() & AST_MODE;
837 ("aztcd: XA support experimental - mail results to Werner.Zimmermann@fht-esslingen.de\n");
840 /*multisession detection
841 support for multisession CDs is done automatically with Aztech drives,
842 we don't have to take care about TOC redirection; if we want the isofs
843 to take care about redirection, we have to set AZT_MULTISESSION to 1 */
847 aztGetMultiDiskInfo(); /*here Disk.Info.multi is set */
850 if (DiskInfo.multi) {
851 DiskInfo.lastSession.min = Toc[DiskInfo.next].diskTime.min;
852 DiskInfo.lastSession.sec = Toc[DiskInfo.next].diskTime.sec;
853 DiskInfo.lastSession.frame =
854 Toc[DiskInfo.next].diskTime.frame;
855 printk("aztcd: Multisession support experimental\n");
857 DiskInfo.lastSession.min =
858 Toc[DiskInfo.first].diskTime.min;
859 DiskInfo.lastSession.sec =
860 Toc[DiskInfo.first].diskTime.sec;
861 DiskInfo.lastSession.frame =
862 Toc[DiskInfo.first].diskTime.frame;
867 printk("aztcd: exiting aztUpdateToc Time:%li\n", jiffies);
873 /* Read the table of contents header, i.e. no. of tracks and start of first
876 static int aztGetDiskInfo()
880 struct azt_Toc qInfo;
883 printk("aztcd: starting aztGetDiskInfo Time:%li\n", jiffies);
885 if (aztSendCmd(ACMD_SEEK_TO_LEADIN))
886 RETURNM("aztGetDiskInfo 1", -1);
889 for (limit = 300; limit > 0; limit--) {
890 if (aztGetQChannelInfo(&qInfo) < 0)
891 RETURNM("aztGetDiskInfo 2", -1);
892 if (qInfo.pointIndex == 0xA0) { /*Number of FirstTrack */
893 DiskInfo.first = qInfo.diskTime.min;
894 DiskInfo.first = azt_bcd2bin(DiskInfo.first);
897 if (qInfo.pointIndex == 0xA1) { /*Number of LastTrack */
898 DiskInfo.last = qInfo.diskTime.min;
899 DiskInfo.last = azt_bcd2bin(DiskInfo.last);
902 if (qInfo.pointIndex == 0xA2) { /*DiskLength */
903 DiskInfo.diskLength.min = qInfo.diskTime.min;
904 DiskInfo.diskLength.sec = qInfo.diskTime.sec;
905 DiskInfo.diskLength.frame = qInfo.diskTime.frame;
908 if ((qInfo.pointIndex == DiskInfo.first) && (test & 0x01)) { /*StartTime of First Track */
909 DiskInfo.firstTrack.min = qInfo.diskTime.min;
910 DiskInfo.firstTrack.sec = qInfo.diskTime.sec;
911 DiskInfo.firstTrack.frame = qInfo.diskTime.frame;
918 printk("aztcd: exiting aztGetDiskInfo Time:%li\n", jiffies);
920 ("Disk Info: first %d last %d length %02X:%02X.%02X dez first %02X:%02X.%02X dez\n",
921 DiskInfo.first, DiskInfo.last, DiskInfo.diskLength.min,
922 DiskInfo.diskLength.sec, DiskInfo.diskLength.frame,
923 DiskInfo.firstTrack.min, DiskInfo.firstTrack.sec,
924 DiskInfo.firstTrack.frame);
933 * Get Multisession Disk Info
935 static int aztGetMultiDiskInfo(void)
939 struct azt_Toc qInfo;
942 printk("aztcd: starting aztGetMultiDiskInfo\n");
946 azt_Play.start.min = Toc[DiskInfo.last + 1].diskTime.min;
947 azt_Play.start.sec = Toc[DiskInfo.last + 1].diskTime.sec;
948 azt_Play.start.frame =
949 Toc[DiskInfo.last + 1].diskTime.frame;
952 for (limit = 30; limit > 0; limit--) { /*Seek for LeadIn of next session */
953 if (aztSeek(&azt_Play))
954 RETURNM("aztGetMultiDiskInfo 1", -1);
955 if (aztGetQChannelInfo(&qInfo) < 0)
956 RETURNM("aztGetMultiDiskInfo 2", -1);
957 if ((qInfo.track == 0) && (qInfo.pointIndex))
958 break; /*LeadIn found */
959 if ((azt_Play.start.sec += 10) > 59) {
960 azt_Play.start.sec = 0;
961 azt_Play.start.min++;
965 break; /*Check, if a leadin track was found, if not we're
966 at the end of the disk */
967 #ifdef AZT_DEBUG_MULTISESSION
968 printk("leadin found track %d pointIndex %x limit %d\n",
969 qInfo.track, qInfo.pointIndex, limit);
971 for (limit = 300; limit > 0; limit--) {
972 if (++azt_Play.start.frame > 74) {
973 azt_Play.start.frame = 0;
974 if (azt_Play.start.sec > 59) {
975 azt_Play.start.sec = 0;
976 azt_Play.start.min++;
979 if (aztSeek(&azt_Play))
980 RETURNM("aztGetMultiDiskInfo 3", -1);
981 if (aztGetQChannelInfo(&qInfo) < 0)
982 RETURNM("aztGetMultiDiskInfo 4", -1);
983 if (qInfo.pointIndex == 0xA0) { /*Number of NextTrack */
984 DiskInfo.next = qInfo.diskTime.min;
985 DiskInfo.next = azt_bcd2bin(DiskInfo.next);
988 if (qInfo.pointIndex == 0xA1) { /*Number of LastTrack */
989 DiskInfo.last = qInfo.diskTime.min;
990 DiskInfo.last = azt_bcd2bin(DiskInfo.last);
993 if (qInfo.pointIndex == 0xA2) { /*DiskLength */
994 DiskInfo.diskLength.min =
996 DiskInfo.diskLength.sec =
998 DiskInfo.diskLength.frame =
999 qInfo.diskTime.frame;
1002 if ((qInfo.pointIndex == DiskInfo.next) && (test & 0x01)) { /*StartTime of Next Track */
1003 DiskInfo.nextSession.min =
1005 DiskInfo.nextSession.sec =
1007 DiskInfo.nextSession.frame =
1008 qInfo.diskTime.frame;
1014 #ifdef AZT_DEBUG_MULTISESSION
1016 ("MultiDisk Info: first %d next %d last %d length %02x:%02x.%02x dez first %02x:%02x.%02x dez next %02x:%02x.%02x dez\n",
1017 DiskInfo.first, DiskInfo.next, DiskInfo.last,
1018 DiskInfo.diskLength.min, DiskInfo.diskLength.sec,
1019 DiskInfo.diskLength.frame, DiskInfo.firstTrack.min,
1020 DiskInfo.firstTrack.sec, DiskInfo.firstTrack.frame,
1021 DiskInfo.nextSession.min, DiskInfo.nextSession.sec,
1022 DiskInfo.nextSession.frame);
1027 DiskInfo.multi = 1; /*found TOC of more than one session */
1032 printk("aztcd: exiting aztGetMultiDiskInfo Time:%li\n", jiffies);
1039 * Read the table of contents (TOC)
1041 static int aztGetToc(int multi)
1045 struct azt_Toc qInfo;
1048 printk("aztcd: starting aztGetToc Time:%li\n", jiffies);
1051 for (i = 0; i < MAX_TRACKS; i++)
1052 Toc[i].pointIndex = 0;
1053 i = DiskInfo.last + 3;
1055 for (i = DiskInfo.next; i < MAX_TRACKS; i++)
1056 Toc[i].pointIndex = 0;
1057 i = DiskInfo.last + 4 - DiskInfo.next;
1060 /*Is there a good reason to stop motor before TOC read?
1061 if (aztSendCmd(ACMD_STOP)) RETURNM("aztGetToc 1",-1);
1067 if (aztSendCmd(ACMD_SEEK_TO_LEADIN))
1068 RETURNM("aztGetToc 2", -1);
1071 for (limit = 300; limit > 0; limit--) {
1073 if (++azt_Play.start.sec > 59) {
1074 azt_Play.start.sec = 0;
1075 azt_Play.start.min++;
1077 if (aztSeek(&azt_Play))
1078 RETURNM("aztGetToc 3", -1);
1080 if (aztGetQChannelInfo(&qInfo) < 0)
1083 px = azt_bcd2bin(qInfo.pointIndex);
1085 if (px > 0 && px < MAX_TRACKS && qInfo.track == 0)
1086 if (Toc[px].pointIndex == 0) {
1095 Toc[DiskInfo.last + 1].diskTime = DiskInfo.diskLength;
1096 Toc[DiskInfo.last].trackTime = DiskInfo.diskLength;
1098 #ifdef AZT_DEBUG_MULTISESSION
1099 printk("aztcd: exiting aztGetToc\n");
1100 for (i = 1; i <= DiskInfo.last + 1; i++)
1102 ("i = %2d ctl-adr = %02X track %2d px %02X %02X:%02X.%02X dez %02X:%02X.%02X dez\n",
1103 i, Toc[i].ctrl_addr, Toc[i].track, Toc[i].pointIndex,
1104 Toc[i].trackTime.min, Toc[i].trackTime.sec,
1105 Toc[i].trackTime.frame, Toc[i].diskTime.min,
1106 Toc[i].diskTime.sec, Toc[i].diskTime.frame);
1107 for (i = 100; i < 103; i++)
1109 ("i = %2d ctl-adr = %02X track %2d px %02X %02X:%02X.%02X dez %02X:%02X.%02X dez\n",
1110 i, Toc[i].ctrl_addr, Toc[i].track, Toc[i].pointIndex,
1111 Toc[i].trackTime.min, Toc[i].trackTime.sec,
1112 Toc[i].trackTime.frame, Toc[i].diskTime.min,
1113 Toc[i].diskTime.sec, Toc[i].diskTime.frame);
1116 return limit > 0 ? 0 : -1;
1120 /*##########################################################################
1121 Kernel Interface Functions
1122 ##########################################################################
1126 static int __init aztcd_setup(char *str)
1130 (void) get_options(str, ARRAY_SIZE(ints), ints);
1139 __setup("aztcd=", aztcd_setup);
1141 #endif /* !MODULE */
1144 * Checking if the media has been changed
1146 static int check_aztcd_media_change(struct gendisk *disk)
1148 if (aztDiskChanged) { /* disk changed */
1152 return 0; /* no change */
1156 * Kernel IO-controls
1158 static int aztcd_ioctl(struct inode *ip, struct file *fp, unsigned int cmd,
1162 struct azt_Toc qInfo;
1164 struct cdrom_tochdr tocHdr;
1165 struct cdrom_msf msf;
1166 struct cdrom_tocentry entry;
1167 struct azt_Toc *tocPtr;
1168 struct cdrom_subchnl subchnl;
1169 struct cdrom_volctrl volctrl;
1172 printk("aztcd: starting aztcd_ioctl - Command:%x Time: %li\n",
1174 printk("aztcd Status %x\n", getAztStatus());
1177 RETURNM("aztcd_ioctl 1", -EINVAL);
1178 if (getAztStatus() < 0)
1179 RETURNM("aztcd_ioctl 2", -EIO);
1180 if ((!aztTocUpToDate) || (aztDiskChanged)) {
1181 if ((i = aztUpdateToc()) < 0)
1182 RETURNM("aztcd_ioctl 3", i); /* error reading TOC */
1186 case CDROMSTART: /* Spin up the drive. Don't know, what to do,
1187 at least close the tray */
1188 #if AZT_PRIVATE_IOCTLS
1189 if (aztSendCmd(ACMD_CLOSE))
1190 RETURNM("aztcd_ioctl 4", -1);
1194 case CDROMSTOP: /* Spin down the drive */
1195 if (aztSendCmd(ACMD_STOP))
1196 RETURNM("aztcd_ioctl 5", -1);
1198 /* should we do anything if it fails? */
1199 aztAudioStatus = CDROM_AUDIO_NO_STATUS;
1201 case CDROMPAUSE: /* Pause the drive */
1202 if (aztAudioStatus != CDROM_AUDIO_PLAY)
1205 if (aztGetQChannelInfo(&qInfo) < 0) { /* didn't get q channel info */
1206 aztAudioStatus = CDROM_AUDIO_NO_STATUS;
1207 RETURNM("aztcd_ioctl 7", 0);
1209 azt_Play.start = qInfo.diskTime; /* remember restart point */
1211 if (aztSendCmd(ACMD_PAUSE))
1212 RETURNM("aztcd_ioctl 8", -1);
1214 aztAudioStatus = CDROM_AUDIO_PAUSED;
1216 case CDROMRESUME: /* Play it again, Sam */
1217 if (aztAudioStatus != CDROM_AUDIO_PAUSED)
1219 /* restart the drive at the saved position. */
1220 i = aztPlay(&azt_Play);
1222 aztAudioStatus = CDROM_AUDIO_ERROR;
1225 aztAudioStatus = CDROM_AUDIO_PLAY;
1227 case CDROMMULTISESSION: /*multisession support -- experimental */
1229 struct cdrom_multisession ms;
1231 printk("aztcd ioctl MULTISESSION\n");
1235 sizeof(struct cdrom_multisession)))
1237 if (ms.addr_format == CDROM_MSF) {
1238 ms.addr.msf.minute =
1239 azt_bcd2bin(DiskInfo.lastSession.min);
1240 ms.addr.msf.second =
1241 azt_bcd2bin(DiskInfo.lastSession.sec);
1243 azt_bcd2bin(DiskInfo.lastSession.
1245 } else if (ms.addr_format == CDROM_LBA)
1247 azt_msf2hsg(&DiskInfo.lastSession);
1250 ms.xa_flag = DiskInfo.xa;
1253 sizeof(struct cdrom_multisession)))
1256 if (ms.addr_format == CDROM_MSF)
1258 ("aztcd multisession xa:%d, msf:%02x:%02x.%02x [%02x:%02x.%02x])\n",
1259 ms.xa_flag, ms.addr.msf.minute,
1260 ms.addr.msf.second, ms.addr.msf.frame,
1261 DiskInfo.lastSession.min,
1262 DiskInfo.lastSession.sec,
1263 DiskInfo.lastSession.frame);
1266 ("aztcd multisession %d, lba:0x%08x [%02x:%02x.%02x])\n",
1267 ms.xa_flag, ms.addr.lba,
1268 DiskInfo.lastSession.min,
1269 DiskInfo.lastSession.sec,
1270 DiskInfo.lastSession.frame);
1274 case CDROMPLAYTRKIND: /* Play a track. This currently ignores index. */
1275 if (copy_from_user(&ti, (void *) arg, sizeof ti))
1277 if (ti.cdti_trk0 < DiskInfo.first
1278 || ti.cdti_trk0 > DiskInfo.last
1279 || ti.cdti_trk1 < ti.cdti_trk0) {
1282 if (ti.cdti_trk1 > DiskInfo.last)
1283 ti.cdti_trk1 = DiskInfo.last;
1284 azt_Play.start = Toc[ti.cdti_trk0].diskTime;
1285 azt_Play.end = Toc[ti.cdti_trk1 + 1].diskTime;
1287 printk("aztcd play: %02x:%02x.%02x to %02x:%02x.%02x\n",
1288 azt_Play.start.min, azt_Play.start.sec,
1289 azt_Play.start.frame, azt_Play.end.min,
1290 azt_Play.end.sec, azt_Play.end.frame);
1292 i = aztPlay(&azt_Play);
1294 aztAudioStatus = CDROM_AUDIO_ERROR;
1297 aztAudioStatus = CDROM_AUDIO_PLAY;
1299 case CDROMPLAYMSF: /* Play starting at the given MSF address. */
1300 /* if (aztAudioStatus == CDROM_AUDIO_PLAY)
1301 { if (aztSendCmd(ACMD_STOP)) RETURNM("aztcd_ioctl 9",-1);
1303 aztAudioStatus = CDROM_AUDIO_NO_STATUS;
1306 if (copy_from_user(&msf, (void *) arg, sizeof msf))
1308 /* convert to bcd */
1309 azt_bin2bcd(&msf.cdmsf_min0);
1310 azt_bin2bcd(&msf.cdmsf_sec0);
1311 azt_bin2bcd(&msf.cdmsf_frame0);
1312 azt_bin2bcd(&msf.cdmsf_min1);
1313 azt_bin2bcd(&msf.cdmsf_sec1);
1314 azt_bin2bcd(&msf.cdmsf_frame1);
1315 azt_Play.start.min = msf.cdmsf_min0;
1316 azt_Play.start.sec = msf.cdmsf_sec0;
1317 azt_Play.start.frame = msf.cdmsf_frame0;
1318 azt_Play.end.min = msf.cdmsf_min1;
1319 azt_Play.end.sec = msf.cdmsf_sec1;
1320 azt_Play.end.frame = msf.cdmsf_frame1;
1322 printk("aztcd play: %02x:%02x.%02x to %02x:%02x.%02x\n",
1323 azt_Play.start.min, azt_Play.start.sec,
1324 azt_Play.start.frame, azt_Play.end.min,
1325 azt_Play.end.sec, azt_Play.end.frame);
1327 i = aztPlay(&azt_Play);
1329 aztAudioStatus = CDROM_AUDIO_ERROR;
1332 aztAudioStatus = CDROM_AUDIO_PLAY;
1335 case CDROMREADTOCHDR: /* Read the table of contents header */
1336 tocHdr.cdth_trk0 = DiskInfo.first;
1337 tocHdr.cdth_trk1 = DiskInfo.last;
1338 if (copy_to_user((void *) arg, &tocHdr, sizeof tocHdr))
1341 case CDROMREADTOCENTRY: /* Read an entry in the table of contents */
1342 if (copy_from_user(&entry, (void *) arg, sizeof entry))
1344 if ((!aztTocUpToDate) || aztDiskChanged)
1346 if (entry.cdte_track == CDROM_LEADOUT)
1347 tocPtr = &Toc[DiskInfo.last + 1];
1348 else if (entry.cdte_track > DiskInfo.last
1349 || entry.cdte_track < DiskInfo.first) {
1352 tocPtr = &Toc[entry.cdte_track];
1353 entry.cdte_adr = tocPtr->ctrl_addr;
1354 entry.cdte_ctrl = tocPtr->ctrl_addr >> 4;
1355 if (entry.cdte_format == CDROM_LBA)
1356 entry.cdte_addr.lba =
1357 azt_msf2hsg(&tocPtr->diskTime);
1358 else if (entry.cdte_format == CDROM_MSF) {
1359 entry.cdte_addr.msf.minute =
1360 azt_bcd2bin(tocPtr->diskTime.min);
1361 entry.cdte_addr.msf.second =
1362 azt_bcd2bin(tocPtr->diskTime.sec);
1363 entry.cdte_addr.msf.frame =
1364 azt_bcd2bin(tocPtr->diskTime.frame);
1368 if (copy_to_user((void *) arg, &entry, sizeof entry))
1371 case CDROMSUBCHNL: /* Get subchannel info */
1373 (&subchnl, (void *) arg, sizeof(struct cdrom_subchnl)))
1375 if (aztGetQChannelInfo(&qInfo) < 0) {
1378 ("aztcd: exiting aztcd_ioctl - Error 3 - Command:%x\n",
1383 subchnl.cdsc_audiostatus = aztAudioStatus;
1384 subchnl.cdsc_adr = qInfo.ctrl_addr;
1385 subchnl.cdsc_ctrl = qInfo.ctrl_addr >> 4;
1386 subchnl.cdsc_trk = azt_bcd2bin(qInfo.track);
1387 subchnl.cdsc_ind = azt_bcd2bin(qInfo.pointIndex);
1388 if (subchnl.cdsc_format == CDROM_LBA) {
1389 subchnl.cdsc_absaddr.lba =
1390 azt_msf2hsg(&qInfo.diskTime);
1391 subchnl.cdsc_reladdr.lba =
1392 azt_msf2hsg(&qInfo.trackTime);
1393 } else { /*default */
1394 subchnl.cdsc_format = CDROM_MSF;
1395 subchnl.cdsc_absaddr.msf.minute =
1396 azt_bcd2bin(qInfo.diskTime.min);
1397 subchnl.cdsc_absaddr.msf.second =
1398 azt_bcd2bin(qInfo.diskTime.sec);
1399 subchnl.cdsc_absaddr.msf.frame =
1400 azt_bcd2bin(qInfo.diskTime.frame);
1401 subchnl.cdsc_reladdr.msf.minute =
1402 azt_bcd2bin(qInfo.trackTime.min);
1403 subchnl.cdsc_reladdr.msf.second =
1404 azt_bcd2bin(qInfo.trackTime.sec);
1405 subchnl.cdsc_reladdr.msf.frame =
1406 azt_bcd2bin(qInfo.trackTime.frame);
1409 ((void *) arg, &subchnl, sizeof(struct cdrom_subchnl)))
1412 case CDROMVOLCTRL: /* Volume control
1413 * With my Aztech CD268-01A volume control does not work, I can only
1414 turn the channels on (any value !=0) or off (value==0). Maybe it
1415 works better with your drive */
1417 (&volctrl, (char *) arg, sizeof(volctrl)))
1419 azt_Play.start.min = 0x21;
1420 azt_Play.start.sec = 0x84;
1421 azt_Play.start.frame = volctrl.channel0;
1422 azt_Play.end.min = volctrl.channel1;
1423 azt_Play.end.sec = volctrl.channel2;
1424 azt_Play.end.frame = volctrl.channel3;
1425 sendAztCmd(ACMD_SET_VOLUME, &azt_Play);
1429 aztUnlockDoor(); /* Assume user knows what they're doing */
1430 /* all drives can at least stop! */
1431 if (aztAudioStatus == CDROM_AUDIO_PLAY) {
1432 if (aztSendCmd(ACMD_STOP))
1433 RETURNM("azt_ioctl 10", -1);
1436 if (aztSendCmd(ACMD_EJECT))
1437 RETURNM("azt_ioctl 11", -1);
1439 aztAudioStatus = CDROM_AUDIO_NO_STATUS;
1442 azt_auto_eject = (char) arg;
1445 outb(ACMD_SOFT_RESET, CMD_PORT); /*send reset */
1447 if (inb(DATA_PORT) != AFL_OP_OK) { /*OP_OK? */
1449 ("aztcd: AZTECH CD-ROM drive does not respond\n");
1452 /*Take care, the following code is not compatible with other CD-ROM drivers,
1453 use it at your own risk with cdplay.c. Set AZT_PRIVATE_IOCTLS to 0 in aztcd.h,
1454 if you do not want to use it!
1456 #if AZT_PRIVATE_IOCTLS
1457 case CDROMREADCOOKED: /*read data in mode 1 (2048 Bytes) */
1458 case CDROMREADRAW: /*read data in mode 2 (2336 Bytes) */
1460 if (copy_from_user(&msf, (void *) arg, sizeof msf))
1462 /* convert to bcd */
1463 azt_bin2bcd(&msf.cdmsf_min0);
1464 azt_bin2bcd(&msf.cdmsf_sec0);
1465 azt_bin2bcd(&msf.cdmsf_frame0);
1468 msf.cdmsf_frame1 = 1; /*read only one frame */
1469 azt_Play.start.min = msf.cdmsf_min0;
1470 azt_Play.start.sec = msf.cdmsf_sec0;
1471 azt_Play.start.frame = msf.cdmsf_frame0;
1472 azt_Play.end.min = msf.cdmsf_min1;
1473 azt_Play.end.sec = msf.cdmsf_sec1;
1474 azt_Play.end.frame = msf.cdmsf_frame1;
1475 if (cmd == CDROMREADRAW) {
1477 return -1; /*XA Disks can't be read raw */
1480 (ACMD_PLAY_READ_RAW,
1484 insb(DATA_PORT, buf,
1487 ((void *) arg, &buf,
1492 /*CDROMREADCOOKED*/ {
1493 if (sendAztCmd(ACMD_PLAY_READ, &azt_Play))
1496 insb(DATA_PORT, buf, CD_FRAMESIZE);
1498 ((void *) arg, &buf, CD_FRAMESIZE))
1503 case CDROMSEEK: /*seek msf address */
1504 if (copy_from_user(&msf, (void *) arg, sizeof msf))
1506 /* convert to bcd */
1507 azt_bin2bcd(&msf.cdmsf_min0);
1508 azt_bin2bcd(&msf.cdmsf_sec0);
1509 azt_bin2bcd(&msf.cdmsf_frame0);
1510 azt_Play.start.min = msf.cdmsf_min0;
1511 azt_Play.start.sec = msf.cdmsf_sec0;
1512 azt_Play.start.frame = msf.cdmsf_frame0;
1513 if (aztSeek(&azt_Play))
1516 #endif /*end of incompatible code */
1517 case CDROMREADMODE1: /*set read data in mode 1 */
1518 return aztSetDiskType(AZT_MODE_1);
1519 case CDROMREADMODE2: /*set read data in mode 2 */
1520 return aztSetDiskType(AZT_MODE_2);
1525 printk("aztcd: exiting aztcd_ioctl Command:%x Time:%li\n", cmd,
1532 * Take care of the different block sizes between cdrom and Linux.
1533 * When Linux gets variable block sizes this will probably go away.
1535 static void azt_transfer(void)
1538 printk("aztcd: executing azt_transfer Time:%li\n", jiffies);
1540 if (!current_valid())
1543 while (CURRENT->nr_sectors) {
1544 int bn = CURRENT->sector / 4;
1546 for (i = 0; i < AZT_BUF_SIZ && azt_buf_bn[i] != bn; ++i);
1547 if (i < AZT_BUF_SIZ) {
1548 int offs = (i * 4 + (CURRENT->sector & 3)) * 512;
1549 int nr_sectors = 4 - (CURRENT->sector & 3);
1550 if (azt_buf_out != i) {
1552 if (azt_buf_bn[i] != bn) {
1557 if (nr_sectors > CURRENT->nr_sectors)
1558 nr_sectors = CURRENT->nr_sectors;
1559 memcpy(CURRENT->buffer, azt_buf + offs,
1561 CURRENT->nr_sectors -= nr_sectors;
1562 CURRENT->sector += nr_sectors;
1563 CURRENT->buffer += nr_sectors * 512;
1571 static void do_aztcd_request(request_queue_t * q)
1574 printk(" do_aztcd_request(%ld+%ld) Time:%li\n", CURRENT->sector,
1575 CURRENT->nr_sectors, jiffies);
1577 if (DiskInfo.audio) {
1578 printk("aztcd: Error, tried to mount an Audio CD\n");
1579 end_request(CURRENT, 0);
1582 azt_transfer_is_active = 1;
1583 while (current_valid()) {
1585 if (CURRENT->nr_sectors == 0) {
1586 end_request(CURRENT, 1);
1588 azt_buf_out = -1; /* Want to read a block not in buffer */
1589 if (azt_state == AZT_S_IDLE) {
1590 if ((!aztTocUpToDate) || aztDiskChanged) {
1591 if (aztUpdateToc() < 0) {
1592 while (current_valid())
1593 end_request(CURRENT, 0);
1597 azt_state = AZT_S_START;
1599 SET_TIMER(azt_poll, HZ / 100);
1604 azt_transfer_is_active = 0;
1607 ("azt_next_bn:%x azt_buf_in:%x azt_buf_out:%x azt_buf_bn:%x\n",
1608 azt_next_bn, azt_buf_in, azt_buf_out, azt_buf_bn[azt_buf_in]);
1609 printk(" do_aztcd_request ends Time:%li\n", jiffies);
1614 static void azt_invalidate_buffers(void)
1619 printk("aztcd: executing azt_invalidate_buffers\n");
1621 for (i = 0; i < AZT_BUF_SIZ; ++i)
1627 * Open the device special file. Check that a disk is in.
1629 static int aztcd_open(struct inode *ip, struct file *fp)
1634 printk("aztcd: starting aztcd_open\n");
1637 if (aztPresent == 0)
1638 return -ENXIO; /* no hardware */
1640 if (!azt_open_count && azt_state == AZT_S_IDLE) {
1641 azt_invalidate_buffers();
1643 st = getAztStatus(); /* check drive status */
1645 goto err_out; /* drive doesn't respond */
1647 if (st & AST_DOOR_OPEN) { /* close door, then get the status again. */
1648 printk("aztcd: Door Open?\n");
1650 st = getAztStatus();
1653 if ((st & AST_NOT_READY) || (st & AST_DSK_CHG)) { /*no disk in drive or changed */
1655 ("aztcd: Disk Changed or No Disk in Drive?\n");
1666 printk("aztcd: exiting aztcd_open\n");
1676 * On close, we flush all azt blocks from the buffer cache.
1678 static int aztcd_release(struct inode *inode, struct file *file)
1681 printk("aztcd: executing aztcd_release\n");
1682 printk("inode: %p, device: %s file: %p\n", inode,
1683 inode->i_bdev->bd_disk->disk_name, file);
1685 if (!--azt_open_count) {
1686 azt_invalidate_buffers();
1689 aztSendCmd(ACMD_EJECT);
1695 static struct gendisk *azt_disk;
1698 * Test for presence of drive and initialize it. Called at boot time.
1701 static int __init aztcd_init(void)
1703 long int count, max_count;
1704 unsigned char result[50];
1706 void* status = NULL;
1710 if (azt_port == 0) {
1711 printk(KERN_INFO "aztcd: no Aztech CD-ROM Initialization");
1715 printk(KERN_INFO "aztcd: AZTECH, ORCHID, OKANO, WEARNES, TXC, CyDROM "
1717 printk(KERN_INFO "aztcd: (C) 1994-98 W.Zimmermann\n");
1718 if (azt_port == -1) {
1720 ("aztcd: KernelVersion=%s DriverVersion=%s For IDE/ATAPI-drives use ide-cd.c\n",
1721 UTS_RELEASE, AZT_VERSION);
1724 ("aztcd: DriverVersion=%s BaseAddress=0x%x For IDE/ATAPI-drives use ide-cd.c\n",
1725 AZT_VERSION, azt_port);
1726 printk(KERN_INFO "aztcd: If you have problems, read /usr/src/linux/"
1727 "Documentation/cdrom/aztcd\n");
1730 #ifdef AZT_SW32 /*CDROM connected to Soundwave32 card */
1731 if ((0xFF00 & inw(AZT_SW32_ID_REG)) != 0x4500) {
1733 ("aztcd: no Soundwave32 card detected at base:%x init:%x config:%x id:%x\n",
1734 AZT_SW32_BASE_ADDR, AZT_SW32_INIT,
1735 AZT_SW32_CONFIG_REG, AZT_SW32_ID_REG);
1739 "aztcd: Soundwave32 card detected at %x Version %x\n",
1740 AZT_SW32_BASE_ADDR, inw(AZT_SW32_ID_REG));
1741 outw(AZT_SW32_INIT, AZT_SW32_CONFIG_REG);
1742 for (count = 0; count < 10000; count++); /*delay a bit */
1746 /* check for presence of drive */
1748 if (azt_port == -1) { /* autoprobing for proprietary interface */
1749 for (i = 0; (azt_port_auto[i] != 0) && (i < 16); i++) {
1750 azt_port = azt_port_auto[i];
1751 printk(KERN_INFO "aztcd: Autoprobing BaseAddress=0x%x"
1753 /*proprietary interfaces need 4 bytes */
1754 if (!request_region(azt_port, 4, "aztcd")) {
1757 outb(POLLED, MODE_PORT);
1760 outb(ACMD_GET_VERSION, CMD_PORT); /*Try to get version info */
1762 aztTimeOutCount = 0;
1764 aztIndatum = inb(STATUS_PORT);
1766 if (aztTimeOutCount >= AZT_FAST_TIMEOUT)
1768 } while (aztIndatum & AFL_STATUS);
1769 if (inb(DATA_PORT) == AFL_OP_OK) { /* OK drive found */
1772 else { /* Drive not found on this port - try next one */
1773 release_region(azt_port, 4);
1776 if ((azt_port_auto[i] == 0) || (i == 16)) {
1777 printk(KERN_INFO "aztcd: no AZTECH CD-ROM drive found\n");
1780 } else { /* no autoprobing */
1781 if ((azt_port == 0x1f0) || (azt_port == 0x170))
1782 status = request_region(azt_port, 8, "aztcd"); /*IDE-interfaces need 8 bytes */
1784 status = request_region(azt_port, 4, "aztcd"); /*proprietary interfaces need 4 bytes */
1786 printk(KERN_WARNING "aztcd: conflict, I/O port (%X) "
1787 "already used\n", azt_port);
1791 if ((azt_port == 0x1f0) || (azt_port == 0x170))
1792 SWITCH_IDE_SLAVE; /*switch IDE interface to slave configuration */
1794 outb(POLLED, MODE_PORT);
1797 outb(ACMD_GET_VERSION, CMD_PORT); /*Try to get version info */
1799 aztTimeOutCount = 0;
1801 aztIndatum = inb(STATUS_PORT);
1803 if (aztTimeOutCount >= AZT_FAST_TIMEOUT)
1805 } while (aztIndatum & AFL_STATUS);
1807 if (inb(DATA_PORT) != AFL_OP_OK) { /*OP_OK? If not, reset and try again */
1809 if (azt_cont != 0x79) {
1810 printk(KERN_WARNING "aztcd: no AZTECH CD-ROM "
1811 "drive found-Try boot parameter aztcd="
1812 "<BaseAddress>,0x79\n");
1821 printk(KERN_INFO "aztcd: drive reset - "
1823 for (count = 0; count < 50; count++) {
1824 inb(STATUS_PORT); /*removing all data from earlier tries */
1827 outb(POLLED, MODE_PORT);
1830 getAztStatus(); /*trap errors */
1831 outb(ACMD_SOFT_RESET, CMD_PORT); /*send reset */
1833 if (inb(DATA_PORT) != AFL_OP_OK) { /*OP_OK? */
1834 printk(KERN_WARNING "aztcd: no AZTECH "
1835 "CD-ROM drive found\n");
1840 for (count = 0; count < AZT_TIMEOUT;
1842 barrier(); /* Stop gcc 2.96 being smart */
1843 /* use udelay(), damnit -- AV */
1845 if ((st = getAztStatus()) == -1) {
1846 printk(KERN_WARNING "aztcd: Drive Status"
1847 " Error Status=%x\n", st);
1852 printk(KERN_DEBUG "aztcd: Status = %x\n", st);
1854 outb(POLLED, MODE_PORT);
1857 outb(ACMD_GET_VERSION, CMD_PORT); /*GetVersion */
1866 result[0] = inb(DATA_PORT); /*reading in a null byte??? */
1867 for (count = 1; count < 50; count++) { /*Reading version string */
1868 aztTimeOutCount = 0; /*here we must implement STEN_LOW differently */
1870 aztIndatum = inb(STATUS_PORT); /*because we want to exit by timeout */
1872 if (aztTimeOutCount >= AZT_FAST_TIMEOUT)
1874 } while (aztIndatum & AFL_STATUS);
1875 if (aztTimeOutCount >= AZT_FAST_TIMEOUT)
1876 break; /*all chars read? */
1877 result[count] = inb(DATA_PORT);
1880 max_count = 30; /*print max.30 chars of the version string */
1883 printk(KERN_INFO "aztcd: FirmwareVersion=");
1884 for (count = 1; count < max_count; count++)
1885 printk("%c", result[count]);
1888 if ((result[1] == 'A') && (result[2] == 'Z') && (result[3] == 'T')) {
1889 printk("AZTECH drive detected\n");
1891 else if ((result[2] == 'C') && (result[3] == 'D')
1892 && (result[4] == 'D')) {
1893 printk("ORCHID or WEARNES drive detected\n"); /*ORCHID or WEARNES */
1894 } else if ((result[1] == 0x03) && (result[2] == '5')) {
1895 printk("TXC or CyCDROM drive detected\n"); /*Conrad TXC, CyCDROM */
1896 } else { /*OTHERS or none */
1897 printk("\nunknown drive or firmware version detected\n");
1899 ("aztcd may not run stable, if you want to try anyhow,\n");
1900 printk("boot with: aztcd=<BaseAddress>,0x79\n");
1901 if ((azt_cont != 0x79)) {
1902 printk("aztcd: FirmwareVersion=");
1903 for (count = 1; count < 5; count++)
1904 printk("%c", result[count]);
1906 printk("Aborted\n");
1911 azt_disk = alloc_disk(1);
1915 if (register_blkdev(MAJOR_NR, "aztcd")) {
1920 azt_queue = blk_init_queue(do_aztcd_request, &aztSpin);
1926 blk_queue_hardsect_size(azt_queue, 2048);
1927 azt_disk->major = MAJOR_NR;
1928 azt_disk->first_minor = 0;
1929 azt_disk->fops = &azt_fops;
1930 sprintf(azt_disk->disk_name, "aztcd");
1931 sprintf(azt_disk->devfs_name, "aztcd");
1932 azt_disk->queue = azt_queue;
1934 azt_invalidate_buffers();
1939 unregister_blkdev(MAJOR_NR, "aztcd");
1943 if ((azt_port == 0x1f0) || (azt_port == 0x170)) {
1945 release_region(azt_port, 8); /*IDE-interface */
1947 release_region(azt_port, 4); /*proprietary interface */
1952 static void __exit aztcd_exit(void)
1954 del_gendisk(azt_disk);
1956 if ((unregister_blkdev(MAJOR_NR, "aztcd") == -EINVAL)) {
1957 printk("What's that: can't unregister aztcd\n");
1960 blk_cleanup_queue(azt_queue);
1961 if ((azt_port == 0x1f0) || (azt_port == 0x170)) {
1963 release_region(azt_port, 8); /*IDE-interface */
1965 release_region(azt_port, 4); /*proprietary interface */
1966 printk(KERN_INFO "aztcd module released.\n");
1969 module_init(aztcd_init);
1970 module_exit(aztcd_exit);
1972 /*##########################################################################
1973 Aztcd State Machine: Controls Drive Operating State
1974 ##########################################################################
1976 static void azt_poll(void)
1983 if (aztSendCmd(ACMD_GET_ERROR))
1984 RETURN("azt_poll 1");
1986 azt_error = inb(DATA_PORT) & 0xFF;
1987 printk("aztcd: I/O error 0x%02x\n", azt_error);
1988 azt_invalidate_buffers();
1989 #ifdef WARN_IF_READ_FAILURE
1992 ("aztcd: Read of Block %d Failed - Maybe Audio Disk?\n",
1997 ("aztcd: Read of Block %d Failed, Maybe Audio Disk? Giving up\n",
1999 if (azt_transfer_is_active) {
2003 if (current_valid())
2004 end_request(CURRENT, 0);
2008 azt_state = AZT_S_STOP;
2012 loop_ctl = 0; /* each case must flip this back to 1 if we want
2013 to come back up here */
2014 switch (azt_state) {
2018 if (azt_state != azt_state_old) {
2019 azt_state_old = azt_state;
2020 printk("AZT_S_IDLE\n");
2027 if (azt_state != azt_state_old) {
2028 azt_state_old = azt_state;
2029 printk("AZT_S_START\n");
2032 if (aztSendCmd(ACMD_GET_STATUS))
2033 RETURN("azt_poll 2"); /*result will be checked by aztStatus() */
2035 azt_mode == 1 ? AZT_S_READ : AZT_S_MODE;
2041 if (azt_state != azt_state_old) {
2042 azt_state_old = azt_state;
2043 printk("AZT_S_MODE\n");
2047 if ((st = aztStatus()) != -1) {
2048 if ((st & AST_DSK_CHG)
2049 || (st & AST_NOT_READY)) {
2052 azt_invalidate_buffers();
2053 end_request(CURRENT, 0);
2055 ("aztcd: Disk Changed or Not Ready 1 - Unmount Disk!\n");
2062 if ((st & AST_DOOR_OPEN) || (st & AST_NOT_READY)) {
2066 ("aztcd: Disk Changed or Not Ready 2 - Unmount Disk!\n");
2067 end_request(CURRENT, 0);
2068 printk((st & AST_DOOR_OPEN) ?
2069 "aztcd: door open\n" :
2070 "aztcd: disk removed\n");
2071 if (azt_transfer_is_active) {
2072 azt_state = AZT_S_START;
2073 loop_ctl = 1; /* goto immediately */
2076 azt_state = AZT_S_IDLE;
2077 while (current_valid())
2078 end_request(CURRENT, 0);
2082 /* if (aztSendCmd(ACMD_SET_MODE)) RETURN("azt_poll 3");
2083 outb(0x01, DATA_PORT);
2087 if (aztSendCmd(ACMD_GET_STATUS))
2088 RETURN("azt_poll 4");
2091 azt_state = AZT_S_READ;
2099 if (azt_state != azt_state_old) {
2100 azt_state_old = azt_state;
2101 printk("AZT_S_READ\n");
2105 if ((st = aztStatus()) != -1) {
2106 if ((st & AST_DSK_CHG)
2107 || (st & AST_NOT_READY)) {
2110 azt_invalidate_buffers();
2112 ("aztcd: Disk Changed or Not Ready 3 - Unmount Disk!\n");
2113 end_request(CURRENT, 0);
2120 if ((st & AST_DOOR_OPEN) || (st & AST_NOT_READY)) {
2123 printk((st & AST_DOOR_OPEN) ?
2124 "aztcd: door open\n" :
2125 "aztcd: disk removed\n");
2126 if (azt_transfer_is_active) {
2127 azt_state = AZT_S_START;
2131 azt_state = AZT_S_IDLE;
2132 while (current_valid())
2133 end_request(CURRENT, 0);
2137 if (current_valid()) {
2138 struct azt_Play_msf msf;
2140 azt_next_bn = CURRENT->sector / 4;
2141 azt_hsg2msf(azt_next_bn, &msf.start);
2143 /* find out in which track we are */
2144 while (azt_msf2hsg(&msf.start) >
2145 azt_msf2hsg(&Toc[++i].trackTime)) {
2147 if (azt_msf2hsg(&msf.start) <
2148 azt_msf2hsg(&Toc[i].trackTime) -
2150 azt_read_count = AZT_BUF_SIZ; /*fast, because we read ahead */
2151 /*azt_read_count=CURRENT->nr_sectors; slow, no read ahead */
2152 } else /* don't read beyond end of track */
2153 #if AZT_MULTISESSION
2156 (azt_msf2hsg(&Toc[i].trackTime)
2158 azt_msf2hsg(&msf.start);
2159 if (azt_read_count < 0)
2161 if (azt_read_count > AZT_BUF_SIZ)
2165 ("aztcd: warning - trying to read beyond end of track\n");
2166 /* printk("%i %i %li %li\n",i,azt_read_count,azt_msf2hsg(&msf.start),azt_msf2hsg(&Toc[i].trackTime));
2170 azt_read_count = AZT_BUF_SIZ;
2175 msf.end.frame = azt_read_count; /*Mitsumi here reads 0xffffff sectors */
2178 ("---reading msf-address %x:%x:%x %x:%x:%x\n",
2179 msf.start.min, msf.start.sec,
2180 msf.start.frame, msf.end.min,
2181 msf.end.sec, msf.end.frame);
2183 ("azt_next_bn:%x azt_buf_in:%x azt_buf_out:%x azt_buf_bn:%x\n",
2184 azt_next_bn, azt_buf_in, azt_buf_out,
2185 azt_buf_bn[azt_buf_in]);
2187 if (azt_read_mode == AZT_MODE_2) {
2188 sendAztCmd(ACMD_PLAY_READ_RAW, &msf); /*XA disks in raw mode */
2190 sendAztCmd(ACMD_PLAY_READ, &msf); /*others in cooked mode */
2192 azt_state = AZT_S_DATA;
2193 AztTimeout = READ_TIMEOUT;
2195 azt_state = AZT_S_STOP;
2205 if (azt_state != azt_state_old) {
2206 azt_state_old = azt_state;
2207 printk("AZT_S_DATA\n");
2211 st = inb(STATUS_PORT) & AFL_STATUSorDATA;
2217 if (st != azt_st_old) {
2219 printk("---AFL_DATA st:%x\n", st);
2224 ("aztcd: Read of Block %d Failed, Maybe Audio Disk ? Giving up\n",
2226 if (azt_transfer_is_active) {
2230 if (current_valid())
2231 end_request(CURRENT, 0);
2234 azt_state = AZT_S_START;
2235 AztTimeout = READ_TIMEOUT;
2239 case AFL_STATUSorDATA:
2241 if (st != azt_st_old) {
2244 ("---AFL_STATUSorDATA st:%x\n",
2252 if (st != azt_st_old) {
2254 printk("---default: st:%x\n", st);
2258 if (!current_valid() && azt_buf_in == azt_buf_out) {
2259 azt_state = AZT_S_STOP;
2263 if (azt_read_count <= 0)
2265 ("aztcd: warning - try to read 0 frames\n");
2266 while (azt_read_count) { /*??? fast read ahead loop */
2267 azt_buf_bn[azt_buf_in] = -1;
2268 DTEN_LOW; /*??? unsolved problem, very
2269 seldom we get timeouts
2270 here, don't now the real
2271 reason. With my drive this
2272 sometimes also happens with
2273 Aztech's original driver under
2274 DOS. Is it a hardware bug?
2275 I tried to recover from such
2276 situations here. Zimmermann */
2277 if (aztTimeOutCount >= AZT_TIMEOUT) {
2279 ("read_count:%d CURRENT->nr_sectors:%ld azt_buf_in:%d\n",
2281 CURRENT->nr_sectors,
2284 ("azt_transfer_is_active:%x\n",
2285 azt_transfer_is_active);
2287 azt_state = AZT_S_STOP;
2289 end_request(CURRENT, 1); /*should we have here (1) or (0)? */
2291 if (azt_read_mode ==
2308 ("AZT_S_DATA; ---I've read data- read_count: %d\n",
2311 ("azt_next_bn:%d azt_buf_in:%d azt_buf_out:%d azt_buf_bn:%d\n",
2318 azt_buf_bn[azt_buf_in] =
2320 if (azt_buf_out == -1)
2329 if (!azt_transfer_is_active) {
2330 while (current_valid()) {
2332 if (CURRENT->nr_sectors ==
2334 end_request(CURRENT, 1);
2341 && (CURRENT->sector / 4 < azt_next_bn
2342 || CURRENT->sector / 4 >
2343 azt_next_bn + AZT_BUF_SIZ)) {
2344 azt_state = AZT_S_STOP;
2348 AztTimeout = READ_TIMEOUT;
2349 if (azt_read_count == 0) {
2350 azt_state = AZT_S_STOP;
2361 if (azt_state != azt_state_old) {
2362 azt_state_old = azt_state;
2363 printk("AZT_S_STOP\n");
2366 if (azt_read_count != 0)
2367 printk("aztcd: discard data=%x frames\n",
2369 while (azt_read_count != 0) {
2371 if (!(inb(STATUS_PORT) & AFL_DATA)) {
2372 if (azt_read_mode == AZT_MODE_2)
2374 i < CD_FRAMESIZE_RAW;
2379 i < CD_FRAMESIZE; i++)
2384 if (aztSendCmd(ACMD_GET_STATUS))
2385 RETURN("azt_poll 5");
2386 azt_state = AZT_S_STOPPING;
2390 case AZT_S_STOPPING:
2392 if (azt_state != azt_state_old) {
2393 azt_state_old = azt_state;
2394 printk("AZT_S_STOPPING\n");
2398 if ((st = aztStatus()) == -1 && AztTimeout)
2402 && ((st & AST_DSK_CHG)
2403 || (st & AST_NOT_READY))) {
2406 azt_invalidate_buffers();
2408 ("aztcd: Disk Changed or Not Ready 4 - Unmount Disk!\n");
2409 end_request(CURRENT, 0);
2413 printk("CURRENT_VALID %d azt_mode %d\n",
2414 current_valid(), azt_mode);
2417 if (current_valid()) {
2419 if (azt_mode == 1) {
2420 azt_state = AZT_S_READ;
2425 azt_state = AZT_S_MODE;
2431 azt_state = AZT_S_START;
2435 azt_state = AZT_S_IDLE;
2441 printk("aztcd: invalid state %d\n", azt_state);
2447 if (!AztTimeout--) {
2448 printk("aztcd: timeout in state %d\n", azt_state);
2449 azt_state = AZT_S_STOP;
2450 if (aztSendCmd(ACMD_STOP))
2451 RETURN("azt_poll 6");
2455 SET_TIMER(azt_poll, HZ / 100);
2459 /*###########################################################################
2460 * Miscellaneous support functions
2461 ###########################################################################
2463 static void azt_hsg2msf(long hsg, struct msf *msf)
2466 msf->min = hsg / 4500;
2468 msf->sec = hsg / 75;
2469 msf->frame = hsg % 75;
2472 printk("aztcd: Error hsg2msf address Minutes\n");
2474 printk("aztcd: Error hsg2msf address Seconds\n");
2475 if (msf->frame >= 75)
2476 printk("aztcd: Error hsg2msf address Frames\n");
2478 azt_bin2bcd(&msf->min); /* convert to BCD */
2479 azt_bin2bcd(&msf->sec);
2480 azt_bin2bcd(&msf->frame);
2483 static long azt_msf2hsg(struct msf *mp)
2485 return azt_bcd2bin(mp->frame) + azt_bcd2bin(mp->sec) * 75
2486 + azt_bcd2bin(mp->min) * 4500 - CD_MSF_OFFSET;
2489 static void azt_bin2bcd(unsigned char *p)
2498 static int azt_bcd2bin(unsigned char bcd)
2500 return (bcd >> 4) * 10 + (bcd & 0xF);
2503 MODULE_LICENSE("GPL");
2504 MODULE_ALIAS_BLOCKDEV_MAJOR(AZTECH_CDROM_MAJOR);