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(void)
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;
1170 void __user *argp = (void __user *)arg;
1173 printk("aztcd: starting aztcd_ioctl - Command:%x Time: %li\n",
1175 printk("aztcd Status %x\n", getAztStatus());
1178 RETURNM("aztcd_ioctl 1", -EINVAL);
1179 if (getAztStatus() < 0)
1180 RETURNM("aztcd_ioctl 2", -EIO);
1181 if ((!aztTocUpToDate) || (aztDiskChanged)) {
1182 if ((i = aztUpdateToc()) < 0)
1183 RETURNM("aztcd_ioctl 3", i); /* error reading TOC */
1187 case CDROMSTART: /* Spin up the drive. Don't know, what to do,
1188 at least close the tray */
1189 #if AZT_PRIVATE_IOCTLS
1190 if (aztSendCmd(ACMD_CLOSE))
1191 RETURNM("aztcd_ioctl 4", -1);
1195 case CDROMSTOP: /* Spin down the drive */
1196 if (aztSendCmd(ACMD_STOP))
1197 RETURNM("aztcd_ioctl 5", -1);
1199 /* should we do anything if it fails? */
1200 aztAudioStatus = CDROM_AUDIO_NO_STATUS;
1202 case CDROMPAUSE: /* Pause the drive */
1203 if (aztAudioStatus != CDROM_AUDIO_PLAY)
1206 if (aztGetQChannelInfo(&qInfo) < 0) { /* didn't get q channel info */
1207 aztAudioStatus = CDROM_AUDIO_NO_STATUS;
1208 RETURNM("aztcd_ioctl 7", 0);
1210 azt_Play.start = qInfo.diskTime; /* remember restart point */
1212 if (aztSendCmd(ACMD_PAUSE))
1213 RETURNM("aztcd_ioctl 8", -1);
1215 aztAudioStatus = CDROM_AUDIO_PAUSED;
1217 case CDROMRESUME: /* Play it again, Sam */
1218 if (aztAudioStatus != CDROM_AUDIO_PAUSED)
1220 /* restart the drive at the saved position. */
1221 i = aztPlay(&azt_Play);
1223 aztAudioStatus = CDROM_AUDIO_ERROR;
1226 aztAudioStatus = CDROM_AUDIO_PLAY;
1228 case CDROMMULTISESSION: /*multisession support -- experimental */
1230 struct cdrom_multisession ms;
1232 printk("aztcd ioctl MULTISESSION\n");
1234 if (copy_from_user(&ms, argp,
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;
1251 if (copy_to_user(argp, &ms,
1252 sizeof(struct cdrom_multisession)))
1255 if (ms.addr_format == CDROM_MSF)
1257 ("aztcd multisession xa:%d, msf:%02x:%02x.%02x [%02x:%02x.%02x])\n",
1258 ms.xa_flag, ms.addr.msf.minute,
1259 ms.addr.msf.second, ms.addr.msf.frame,
1260 DiskInfo.lastSession.min,
1261 DiskInfo.lastSession.sec,
1262 DiskInfo.lastSession.frame);
1265 ("aztcd multisession %d, lba:0x%08x [%02x:%02x.%02x])\n",
1266 ms.xa_flag, ms.addr.lba,
1267 DiskInfo.lastSession.min,
1268 DiskInfo.lastSession.sec,
1269 DiskInfo.lastSession.frame);
1273 case CDROMPLAYTRKIND: /* Play a track. This currently ignores index. */
1274 if (copy_from_user(&ti, argp, sizeof ti))
1276 if (ti.cdti_trk0 < DiskInfo.first
1277 || ti.cdti_trk0 > DiskInfo.last
1278 || ti.cdti_trk1 < ti.cdti_trk0) {
1281 if (ti.cdti_trk1 > DiskInfo.last)
1282 ti.cdti_trk1 = DiskInfo.last;
1283 azt_Play.start = Toc[ti.cdti_trk0].diskTime;
1284 azt_Play.end = Toc[ti.cdti_trk1 + 1].diskTime;
1286 printk("aztcd play: %02x:%02x.%02x to %02x:%02x.%02x\n",
1287 azt_Play.start.min, azt_Play.start.sec,
1288 azt_Play.start.frame, azt_Play.end.min,
1289 azt_Play.end.sec, azt_Play.end.frame);
1291 i = aztPlay(&azt_Play);
1293 aztAudioStatus = CDROM_AUDIO_ERROR;
1296 aztAudioStatus = CDROM_AUDIO_PLAY;
1298 case CDROMPLAYMSF: /* Play starting at the given MSF address. */
1299 /* if (aztAudioStatus == CDROM_AUDIO_PLAY)
1300 { if (aztSendCmd(ACMD_STOP)) RETURNM("aztcd_ioctl 9",-1);
1302 aztAudioStatus = CDROM_AUDIO_NO_STATUS;
1305 if (copy_from_user(&msf, argp, sizeof msf))
1307 /* convert to bcd */
1308 azt_bin2bcd(&msf.cdmsf_min0);
1309 azt_bin2bcd(&msf.cdmsf_sec0);
1310 azt_bin2bcd(&msf.cdmsf_frame0);
1311 azt_bin2bcd(&msf.cdmsf_min1);
1312 azt_bin2bcd(&msf.cdmsf_sec1);
1313 azt_bin2bcd(&msf.cdmsf_frame1);
1314 azt_Play.start.min = msf.cdmsf_min0;
1315 azt_Play.start.sec = msf.cdmsf_sec0;
1316 azt_Play.start.frame = msf.cdmsf_frame0;
1317 azt_Play.end.min = msf.cdmsf_min1;
1318 azt_Play.end.sec = msf.cdmsf_sec1;
1319 azt_Play.end.frame = msf.cdmsf_frame1;
1321 printk("aztcd play: %02x:%02x.%02x to %02x:%02x.%02x\n",
1322 azt_Play.start.min, azt_Play.start.sec,
1323 azt_Play.start.frame, azt_Play.end.min,
1324 azt_Play.end.sec, azt_Play.end.frame);
1326 i = aztPlay(&azt_Play);
1328 aztAudioStatus = CDROM_AUDIO_ERROR;
1331 aztAudioStatus = CDROM_AUDIO_PLAY;
1334 case CDROMREADTOCHDR: /* Read the table of contents header */
1335 tocHdr.cdth_trk0 = DiskInfo.first;
1336 tocHdr.cdth_trk1 = DiskInfo.last;
1337 if (copy_to_user(argp, &tocHdr, sizeof tocHdr))
1340 case CDROMREADTOCENTRY: /* Read an entry in the table of contents */
1341 if (copy_from_user(&entry, argp, sizeof entry))
1343 if ((!aztTocUpToDate) || aztDiskChanged)
1345 if (entry.cdte_track == CDROM_LEADOUT)
1346 tocPtr = &Toc[DiskInfo.last + 1];
1347 else if (entry.cdte_track > DiskInfo.last
1348 || entry.cdte_track < DiskInfo.first) {
1351 tocPtr = &Toc[entry.cdte_track];
1352 entry.cdte_adr = tocPtr->ctrl_addr;
1353 entry.cdte_ctrl = tocPtr->ctrl_addr >> 4;
1354 if (entry.cdte_format == CDROM_LBA)
1355 entry.cdte_addr.lba =
1356 azt_msf2hsg(&tocPtr->diskTime);
1357 else if (entry.cdte_format == CDROM_MSF) {
1358 entry.cdte_addr.msf.minute =
1359 azt_bcd2bin(tocPtr->diskTime.min);
1360 entry.cdte_addr.msf.second =
1361 azt_bcd2bin(tocPtr->diskTime.sec);
1362 entry.cdte_addr.msf.frame =
1363 azt_bcd2bin(tocPtr->diskTime.frame);
1367 if (copy_to_user(argp, &entry, sizeof entry))
1370 case CDROMSUBCHNL: /* Get subchannel info */
1372 (&subchnl, argp, sizeof(struct cdrom_subchnl)))
1374 if (aztGetQChannelInfo(&qInfo) < 0) {
1377 ("aztcd: exiting aztcd_ioctl - Error 3 - Command:%x\n",
1382 subchnl.cdsc_audiostatus = aztAudioStatus;
1383 subchnl.cdsc_adr = qInfo.ctrl_addr;
1384 subchnl.cdsc_ctrl = qInfo.ctrl_addr >> 4;
1385 subchnl.cdsc_trk = azt_bcd2bin(qInfo.track);
1386 subchnl.cdsc_ind = azt_bcd2bin(qInfo.pointIndex);
1387 if (subchnl.cdsc_format == CDROM_LBA) {
1388 subchnl.cdsc_absaddr.lba =
1389 azt_msf2hsg(&qInfo.diskTime);
1390 subchnl.cdsc_reladdr.lba =
1391 azt_msf2hsg(&qInfo.trackTime);
1392 } else { /*default */
1393 subchnl.cdsc_format = CDROM_MSF;
1394 subchnl.cdsc_absaddr.msf.minute =
1395 azt_bcd2bin(qInfo.diskTime.min);
1396 subchnl.cdsc_absaddr.msf.second =
1397 azt_bcd2bin(qInfo.diskTime.sec);
1398 subchnl.cdsc_absaddr.msf.frame =
1399 azt_bcd2bin(qInfo.diskTime.frame);
1400 subchnl.cdsc_reladdr.msf.minute =
1401 azt_bcd2bin(qInfo.trackTime.min);
1402 subchnl.cdsc_reladdr.msf.second =
1403 azt_bcd2bin(qInfo.trackTime.sec);
1404 subchnl.cdsc_reladdr.msf.frame =
1405 azt_bcd2bin(qInfo.trackTime.frame);
1407 if (copy_to_user(argp, &subchnl, sizeof(struct cdrom_subchnl)))
1410 case CDROMVOLCTRL: /* Volume control
1411 * With my Aztech CD268-01A volume control does not work, I can only
1412 turn the channels on (any value !=0) or off (value==0). Maybe it
1413 works better with your drive */
1414 if (copy_from_user(&volctrl, argp, sizeof(volctrl)))
1416 azt_Play.start.min = 0x21;
1417 azt_Play.start.sec = 0x84;
1418 azt_Play.start.frame = volctrl.channel0;
1419 azt_Play.end.min = volctrl.channel1;
1420 azt_Play.end.sec = volctrl.channel2;
1421 azt_Play.end.frame = volctrl.channel3;
1422 sendAztCmd(ACMD_SET_VOLUME, &azt_Play);
1426 aztUnlockDoor(); /* Assume user knows what they're doing */
1427 /* all drives can at least stop! */
1428 if (aztAudioStatus == CDROM_AUDIO_PLAY) {
1429 if (aztSendCmd(ACMD_STOP))
1430 RETURNM("azt_ioctl 10", -1);
1433 if (aztSendCmd(ACMD_EJECT))
1434 RETURNM("azt_ioctl 11", -1);
1436 aztAudioStatus = CDROM_AUDIO_NO_STATUS;
1439 azt_auto_eject = (char) arg;
1442 outb(ACMD_SOFT_RESET, CMD_PORT); /*send reset */
1444 if (inb(DATA_PORT) != AFL_OP_OK) { /*OP_OK? */
1446 ("aztcd: AZTECH CD-ROM drive does not respond\n");
1449 /*Take care, the following code is not compatible with other CD-ROM drivers,
1450 use it at your own risk with cdplay.c. Set AZT_PRIVATE_IOCTLS to 0 in aztcd.h,
1451 if you do not want to use it!
1453 #if AZT_PRIVATE_IOCTLS
1454 case CDROMREADCOOKED: /*read data in mode 1 (2048 Bytes) */
1455 case CDROMREADRAW: /*read data in mode 2 (2336 Bytes) */
1457 if (copy_from_user(&msf, argp, sizeof msf))
1459 /* convert to bcd */
1460 azt_bin2bcd(&msf.cdmsf_min0);
1461 azt_bin2bcd(&msf.cdmsf_sec0);
1462 azt_bin2bcd(&msf.cdmsf_frame0);
1465 msf.cdmsf_frame1 = 1; /*read only one frame */
1466 azt_Play.start.min = msf.cdmsf_min0;
1467 azt_Play.start.sec = msf.cdmsf_sec0;
1468 azt_Play.start.frame = msf.cdmsf_frame0;
1469 azt_Play.end.min = msf.cdmsf_min1;
1470 azt_Play.end.sec = msf.cdmsf_sec1;
1471 azt_Play.end.frame = msf.cdmsf_frame1;
1472 if (cmd == CDROMREADRAW) {
1474 return -1; /*XA Disks can't be read raw */
1476 if (sendAztCmd(ACMD_PLAY_READ_RAW, &azt_Play))
1479 insb(DATA_PORT, buf, CD_FRAMESIZE_RAW);
1480 if (copy_to_user(argp, &buf, CD_FRAMESIZE_RAW))
1484 /*CDROMREADCOOKED*/ {
1485 if (sendAztCmd(ACMD_PLAY_READ, &azt_Play))
1488 insb(DATA_PORT, buf, CD_FRAMESIZE);
1489 if (copy_to_user(argp, &buf, CD_FRAMESIZE))
1494 case CDROMSEEK: /*seek msf address */
1495 if (copy_from_user(&msf, argp, sizeof msf))
1497 /* convert to bcd */
1498 azt_bin2bcd(&msf.cdmsf_min0);
1499 azt_bin2bcd(&msf.cdmsf_sec0);
1500 azt_bin2bcd(&msf.cdmsf_frame0);
1501 azt_Play.start.min = msf.cdmsf_min0;
1502 azt_Play.start.sec = msf.cdmsf_sec0;
1503 azt_Play.start.frame = msf.cdmsf_frame0;
1504 if (aztSeek(&azt_Play))
1507 #endif /*end of incompatible code */
1508 case CDROMREADMODE1: /*set read data in mode 1 */
1509 return aztSetDiskType(AZT_MODE_1);
1510 case CDROMREADMODE2: /*set read data in mode 2 */
1511 return aztSetDiskType(AZT_MODE_2);
1516 printk("aztcd: exiting aztcd_ioctl Command:%x Time:%li\n", cmd,
1523 * Take care of the different block sizes between cdrom and Linux.
1524 * When Linux gets variable block sizes this will probably go away.
1526 static void azt_transfer(void)
1529 printk("aztcd: executing azt_transfer Time:%li\n", jiffies);
1531 if (!current_valid())
1534 while (CURRENT->nr_sectors) {
1535 int bn = CURRENT->sector / 4;
1537 for (i = 0; i < AZT_BUF_SIZ && azt_buf_bn[i] != bn; ++i);
1538 if (i < AZT_BUF_SIZ) {
1539 int offs = (i * 4 + (CURRENT->sector & 3)) * 512;
1540 int nr_sectors = 4 - (CURRENT->sector & 3);
1541 if (azt_buf_out != i) {
1543 if (azt_buf_bn[i] != bn) {
1548 if (nr_sectors > CURRENT->nr_sectors)
1549 nr_sectors = CURRENT->nr_sectors;
1550 memcpy(CURRENT->buffer, azt_buf + offs,
1552 CURRENT->nr_sectors -= nr_sectors;
1553 CURRENT->sector += nr_sectors;
1554 CURRENT->buffer += nr_sectors * 512;
1562 static void do_aztcd_request(request_queue_t * q)
1565 printk(" do_aztcd_request(%ld+%ld) Time:%li\n", CURRENT->sector,
1566 CURRENT->nr_sectors, jiffies);
1568 if (DiskInfo.audio) {
1569 printk("aztcd: Error, tried to mount an Audio CD\n");
1570 end_request(CURRENT, 0);
1573 azt_transfer_is_active = 1;
1574 while (current_valid()) {
1576 if (CURRENT->nr_sectors == 0) {
1577 end_request(CURRENT, 1);
1579 azt_buf_out = -1; /* Want to read a block not in buffer */
1580 if (azt_state == AZT_S_IDLE) {
1581 if ((!aztTocUpToDate) || aztDiskChanged) {
1582 if (aztUpdateToc() < 0) {
1583 while (current_valid())
1584 end_request(CURRENT, 0);
1588 azt_state = AZT_S_START;
1590 SET_TIMER(azt_poll, HZ / 100);
1595 azt_transfer_is_active = 0;
1598 ("azt_next_bn:%x azt_buf_in:%x azt_buf_out:%x azt_buf_bn:%x\n",
1599 azt_next_bn, azt_buf_in, azt_buf_out, azt_buf_bn[azt_buf_in]);
1600 printk(" do_aztcd_request ends Time:%li\n", jiffies);
1605 static void azt_invalidate_buffers(void)
1610 printk("aztcd: executing azt_invalidate_buffers\n");
1612 for (i = 0; i < AZT_BUF_SIZ; ++i)
1618 * Open the device special file. Check that a disk is in.
1620 static int aztcd_open(struct inode *ip, struct file *fp)
1625 printk("aztcd: starting aztcd_open\n");
1628 if (aztPresent == 0)
1629 return -ENXIO; /* no hardware */
1631 if (!azt_open_count && azt_state == AZT_S_IDLE) {
1632 azt_invalidate_buffers();
1634 st = getAztStatus(); /* check drive status */
1636 goto err_out; /* drive doesn't respond */
1638 if (st & AST_DOOR_OPEN) { /* close door, then get the status again. */
1639 printk("aztcd: Door Open?\n");
1641 st = getAztStatus();
1644 if ((st & AST_NOT_READY) || (st & AST_DSK_CHG)) { /*no disk in drive or changed */
1646 ("aztcd: Disk Changed or No Disk in Drive?\n");
1657 printk("aztcd: exiting aztcd_open\n");
1667 * On close, we flush all azt blocks from the buffer cache.
1669 static int aztcd_release(struct inode *inode, struct file *file)
1672 printk("aztcd: executing aztcd_release\n");
1673 printk("inode: %p, device: %s file: %p\n", inode,
1674 inode->i_bdev->bd_disk->disk_name, file);
1676 if (!--azt_open_count) {
1677 azt_invalidate_buffers();
1680 aztSendCmd(ACMD_EJECT);
1686 static struct gendisk *azt_disk;
1689 * Test for presence of drive and initialize it. Called at boot time.
1692 static int __init aztcd_init(void)
1694 long int count, max_count;
1695 unsigned char result[50];
1697 void* status = NULL;
1701 if (azt_port == 0) {
1702 printk(KERN_INFO "aztcd: no Aztech CD-ROM Initialization");
1706 printk(KERN_INFO "aztcd: AZTECH, ORCHID, OKANO, WEARNES, TXC, CyDROM "
1708 printk(KERN_INFO "aztcd: (C) 1994-98 W.Zimmermann\n");
1709 if (azt_port == -1) {
1711 ("aztcd: KernelVersion=%s DriverVersion=%s For IDE/ATAPI-drives use ide-cd.c\n",
1712 UTS_RELEASE, AZT_VERSION);
1715 ("aztcd: DriverVersion=%s BaseAddress=0x%x For IDE/ATAPI-drives use ide-cd.c\n",
1716 AZT_VERSION, azt_port);
1717 printk(KERN_INFO "aztcd: If you have problems, read /usr/src/linux/"
1718 "Documentation/cdrom/aztcd\n");
1721 #ifdef AZT_SW32 /*CDROM connected to Soundwave32 card */
1722 if ((0xFF00 & inw(AZT_SW32_ID_REG)) != 0x4500) {
1724 ("aztcd: no Soundwave32 card detected at base:%x init:%x config:%x id:%x\n",
1725 AZT_SW32_BASE_ADDR, AZT_SW32_INIT,
1726 AZT_SW32_CONFIG_REG, AZT_SW32_ID_REG);
1730 "aztcd: Soundwave32 card detected at %x Version %x\n",
1731 AZT_SW32_BASE_ADDR, inw(AZT_SW32_ID_REG));
1732 outw(AZT_SW32_INIT, AZT_SW32_CONFIG_REG);
1733 for (count = 0; count < 10000; count++); /*delay a bit */
1737 /* check for presence of drive */
1739 if (azt_port == -1) { /* autoprobing for proprietary interface */
1740 for (i = 0; (azt_port_auto[i] != 0) && (i < 16); i++) {
1741 azt_port = azt_port_auto[i];
1742 printk(KERN_INFO "aztcd: Autoprobing BaseAddress=0x%x"
1744 /*proprietary interfaces need 4 bytes */
1745 if (!request_region(azt_port, 4, "aztcd")) {
1748 outb(POLLED, MODE_PORT);
1751 outb(ACMD_GET_VERSION, CMD_PORT); /*Try to get version info */
1753 aztTimeOutCount = 0;
1755 aztIndatum = inb(STATUS_PORT);
1757 if (aztTimeOutCount >= AZT_FAST_TIMEOUT)
1759 } while (aztIndatum & AFL_STATUS);
1760 if (inb(DATA_PORT) == AFL_OP_OK) { /* OK drive found */
1763 else { /* Drive not found on this port - try next one */
1764 release_region(azt_port, 4);
1767 if ((azt_port_auto[i] == 0) || (i == 16)) {
1768 printk(KERN_INFO "aztcd: no AZTECH CD-ROM drive found\n");
1771 } else { /* no autoprobing */
1772 if ((azt_port == 0x1f0) || (azt_port == 0x170))
1773 status = request_region(azt_port, 8, "aztcd"); /*IDE-interfaces need 8 bytes */
1775 status = request_region(azt_port, 4, "aztcd"); /*proprietary interfaces need 4 bytes */
1777 printk(KERN_WARNING "aztcd: conflict, I/O port (%X) "
1778 "already used\n", azt_port);
1782 if ((azt_port == 0x1f0) || (azt_port == 0x170))
1783 SWITCH_IDE_SLAVE; /*switch IDE interface to slave configuration */
1785 outb(POLLED, MODE_PORT);
1788 outb(ACMD_GET_VERSION, CMD_PORT); /*Try to get version info */
1790 aztTimeOutCount = 0;
1792 aztIndatum = inb(STATUS_PORT);
1794 if (aztTimeOutCount >= AZT_FAST_TIMEOUT)
1796 } while (aztIndatum & AFL_STATUS);
1798 if (inb(DATA_PORT) != AFL_OP_OK) { /*OP_OK? If not, reset and try again */
1800 if (azt_cont != 0x79) {
1801 printk(KERN_WARNING "aztcd: no AZTECH CD-ROM "
1802 "drive found-Try boot parameter aztcd="
1803 "<BaseAddress>,0x79\n");
1812 printk(KERN_INFO "aztcd: drive reset - "
1814 for (count = 0; count < 50; count++) {
1815 inb(STATUS_PORT); /*removing all data from earlier tries */
1818 outb(POLLED, MODE_PORT);
1821 getAztStatus(); /*trap errors */
1822 outb(ACMD_SOFT_RESET, CMD_PORT); /*send reset */
1824 if (inb(DATA_PORT) != AFL_OP_OK) { /*OP_OK? */
1825 printk(KERN_WARNING "aztcd: no AZTECH "
1826 "CD-ROM drive found\n");
1831 for (count = 0; count < AZT_TIMEOUT;
1833 barrier(); /* Stop gcc 2.96 being smart */
1834 /* use udelay(), damnit -- AV */
1836 if ((st = getAztStatus()) == -1) {
1837 printk(KERN_WARNING "aztcd: Drive Status"
1838 " Error Status=%x\n", st);
1843 printk(KERN_DEBUG "aztcd: Status = %x\n", st);
1845 outb(POLLED, MODE_PORT);
1848 outb(ACMD_GET_VERSION, CMD_PORT); /*GetVersion */
1857 result[0] = inb(DATA_PORT); /*reading in a null byte??? */
1858 for (count = 1; count < 50; count++) { /*Reading version string */
1859 aztTimeOutCount = 0; /*here we must implement STEN_LOW differently */
1861 aztIndatum = inb(STATUS_PORT); /*because we want to exit by timeout */
1863 if (aztTimeOutCount >= AZT_FAST_TIMEOUT)
1865 } while (aztIndatum & AFL_STATUS);
1866 if (aztTimeOutCount >= AZT_FAST_TIMEOUT)
1867 break; /*all chars read? */
1868 result[count] = inb(DATA_PORT);
1871 max_count = 30; /*print max.30 chars of the version string */
1874 printk(KERN_INFO "aztcd: FirmwareVersion=");
1875 for (count = 1; count < max_count; count++)
1876 printk("%c", result[count]);
1879 if ((result[1] == 'A') && (result[2] == 'Z') && (result[3] == 'T')) {
1880 printk("AZTECH drive detected\n");
1882 else if ((result[2] == 'C') && (result[3] == 'D')
1883 && (result[4] == 'D')) {
1884 printk("ORCHID or WEARNES drive detected\n"); /*ORCHID or WEARNES */
1885 } else if ((result[1] == 0x03) && (result[2] == '5')) {
1886 printk("TXC or CyCDROM drive detected\n"); /*Conrad TXC, CyCDROM */
1887 } else { /*OTHERS or none */
1888 printk("\nunknown drive or firmware version detected\n");
1890 ("aztcd may not run stable, if you want to try anyhow,\n");
1891 printk("boot with: aztcd=<BaseAddress>,0x79\n");
1892 if ((azt_cont != 0x79)) {
1893 printk("aztcd: FirmwareVersion=");
1894 for (count = 1; count < 5; count++)
1895 printk("%c", result[count]);
1897 printk("Aborted\n");
1902 azt_disk = alloc_disk(1);
1906 if (register_blkdev(MAJOR_NR, "aztcd")) {
1911 azt_queue = blk_init_queue(do_aztcd_request, &aztSpin);
1917 blk_queue_hardsect_size(azt_queue, 2048);
1918 azt_disk->major = MAJOR_NR;
1919 azt_disk->first_minor = 0;
1920 azt_disk->fops = &azt_fops;
1921 sprintf(azt_disk->disk_name, "aztcd");
1922 sprintf(azt_disk->devfs_name, "aztcd");
1923 azt_disk->queue = azt_queue;
1925 azt_invalidate_buffers();
1930 unregister_blkdev(MAJOR_NR, "aztcd");
1934 if ((azt_port == 0x1f0) || (azt_port == 0x170)) {
1936 release_region(azt_port, 8); /*IDE-interface */
1938 release_region(azt_port, 4); /*proprietary interface */
1943 static void __exit aztcd_exit(void)
1945 del_gendisk(azt_disk);
1947 if ((unregister_blkdev(MAJOR_NR, "aztcd") == -EINVAL)) {
1948 printk("What's that: can't unregister aztcd\n");
1951 blk_cleanup_queue(azt_queue);
1952 if ((azt_port == 0x1f0) || (azt_port == 0x170)) {
1954 release_region(azt_port, 8); /*IDE-interface */
1956 release_region(azt_port, 4); /*proprietary interface */
1957 printk(KERN_INFO "aztcd module released.\n");
1960 module_init(aztcd_init);
1961 module_exit(aztcd_exit);
1963 /*##########################################################################
1964 Aztcd State Machine: Controls Drive Operating State
1965 ##########################################################################
1967 static void azt_poll(void)
1974 if (aztSendCmd(ACMD_GET_ERROR))
1975 RETURN("azt_poll 1");
1977 azt_error = inb(DATA_PORT) & 0xFF;
1978 printk("aztcd: I/O error 0x%02x\n", azt_error);
1979 azt_invalidate_buffers();
1980 #ifdef WARN_IF_READ_FAILURE
1983 ("aztcd: Read of Block %d Failed - Maybe Audio Disk?\n",
1988 ("aztcd: Read of Block %d Failed, Maybe Audio Disk? Giving up\n",
1990 if (azt_transfer_is_active) {
1994 if (current_valid())
1995 end_request(CURRENT, 0);
1999 azt_state = AZT_S_STOP;
2003 loop_ctl = 0; /* each case must flip this back to 1 if we want
2004 to come back up here */
2005 switch (azt_state) {
2009 if (azt_state != azt_state_old) {
2010 azt_state_old = azt_state;
2011 printk("AZT_S_IDLE\n");
2018 if (azt_state != azt_state_old) {
2019 azt_state_old = azt_state;
2020 printk("AZT_S_START\n");
2023 if (aztSendCmd(ACMD_GET_STATUS))
2024 RETURN("azt_poll 2"); /*result will be checked by aztStatus() */
2026 azt_mode == 1 ? AZT_S_READ : AZT_S_MODE;
2032 if (azt_state != azt_state_old) {
2033 azt_state_old = azt_state;
2034 printk("AZT_S_MODE\n");
2038 if ((st = aztStatus()) != -1) {
2039 if ((st & AST_DSK_CHG)
2040 || (st & AST_NOT_READY)) {
2043 azt_invalidate_buffers();
2044 end_request(CURRENT, 0);
2046 ("aztcd: Disk Changed or Not Ready 1 - Unmount Disk!\n");
2053 if ((st & AST_DOOR_OPEN) || (st & AST_NOT_READY)) {
2057 ("aztcd: Disk Changed or Not Ready 2 - Unmount Disk!\n");
2058 end_request(CURRENT, 0);
2059 printk((st & AST_DOOR_OPEN) ?
2060 "aztcd: door open\n" :
2061 "aztcd: disk removed\n");
2062 if (azt_transfer_is_active) {
2063 azt_state = AZT_S_START;
2064 loop_ctl = 1; /* goto immediately */
2067 azt_state = AZT_S_IDLE;
2068 while (current_valid())
2069 end_request(CURRENT, 0);
2073 /* if (aztSendCmd(ACMD_SET_MODE)) RETURN("azt_poll 3");
2074 outb(0x01, DATA_PORT);
2078 if (aztSendCmd(ACMD_GET_STATUS))
2079 RETURN("azt_poll 4");
2082 azt_state = AZT_S_READ;
2090 if (azt_state != azt_state_old) {
2091 azt_state_old = azt_state;
2092 printk("AZT_S_READ\n");
2096 if ((st = aztStatus()) != -1) {
2097 if ((st & AST_DSK_CHG)
2098 || (st & AST_NOT_READY)) {
2101 azt_invalidate_buffers();
2103 ("aztcd: Disk Changed or Not Ready 3 - Unmount Disk!\n");
2104 end_request(CURRENT, 0);
2111 if ((st & AST_DOOR_OPEN) || (st & AST_NOT_READY)) {
2114 printk((st & AST_DOOR_OPEN) ?
2115 "aztcd: door open\n" :
2116 "aztcd: disk removed\n");
2117 if (azt_transfer_is_active) {
2118 azt_state = AZT_S_START;
2122 azt_state = AZT_S_IDLE;
2123 while (current_valid())
2124 end_request(CURRENT, 0);
2128 if (current_valid()) {
2129 struct azt_Play_msf msf;
2131 azt_next_bn = CURRENT->sector / 4;
2132 azt_hsg2msf(azt_next_bn, &msf.start);
2134 /* find out in which track we are */
2135 while (azt_msf2hsg(&msf.start) >
2136 azt_msf2hsg(&Toc[++i].trackTime)) {
2138 if (azt_msf2hsg(&msf.start) <
2139 azt_msf2hsg(&Toc[i].trackTime) -
2141 azt_read_count = AZT_BUF_SIZ; /*fast, because we read ahead */
2142 /*azt_read_count=CURRENT->nr_sectors; slow, no read ahead */
2143 } else /* don't read beyond end of track */
2144 #if AZT_MULTISESSION
2147 (azt_msf2hsg(&Toc[i].trackTime)
2149 azt_msf2hsg(&msf.start);
2150 if (azt_read_count < 0)
2152 if (azt_read_count > AZT_BUF_SIZ)
2156 ("aztcd: warning - trying to read beyond end of track\n");
2157 /* printk("%i %i %li %li\n",i,azt_read_count,azt_msf2hsg(&msf.start),azt_msf2hsg(&Toc[i].trackTime));
2161 azt_read_count = AZT_BUF_SIZ;
2166 msf.end.frame = azt_read_count; /*Mitsumi here reads 0xffffff sectors */
2169 ("---reading msf-address %x:%x:%x %x:%x:%x\n",
2170 msf.start.min, msf.start.sec,
2171 msf.start.frame, msf.end.min,
2172 msf.end.sec, msf.end.frame);
2174 ("azt_next_bn:%x azt_buf_in:%x azt_buf_out:%x azt_buf_bn:%x\n",
2175 azt_next_bn, azt_buf_in, azt_buf_out,
2176 azt_buf_bn[azt_buf_in]);
2178 if (azt_read_mode == AZT_MODE_2) {
2179 sendAztCmd(ACMD_PLAY_READ_RAW, &msf); /*XA disks in raw mode */
2181 sendAztCmd(ACMD_PLAY_READ, &msf); /*others in cooked mode */
2183 azt_state = AZT_S_DATA;
2184 AztTimeout = READ_TIMEOUT;
2186 azt_state = AZT_S_STOP;
2196 if (azt_state != azt_state_old) {
2197 azt_state_old = azt_state;
2198 printk("AZT_S_DATA\n");
2202 st = inb(STATUS_PORT) & AFL_STATUSorDATA;
2208 if (st != azt_st_old) {
2210 printk("---AFL_DATA st:%x\n", st);
2215 ("aztcd: Read of Block %d Failed, Maybe Audio Disk ? Giving up\n",
2217 if (azt_transfer_is_active) {
2221 if (current_valid())
2222 end_request(CURRENT, 0);
2225 azt_state = AZT_S_START;
2226 AztTimeout = READ_TIMEOUT;
2230 case AFL_STATUSorDATA:
2232 if (st != azt_st_old) {
2235 ("---AFL_STATUSorDATA st:%x\n",
2243 if (st != azt_st_old) {
2245 printk("---default: st:%x\n", st);
2249 if (!current_valid() && azt_buf_in == azt_buf_out) {
2250 azt_state = AZT_S_STOP;
2254 if (azt_read_count <= 0)
2256 ("aztcd: warning - try to read 0 frames\n");
2257 while (azt_read_count) { /*??? fast read ahead loop */
2258 azt_buf_bn[azt_buf_in] = -1;
2259 DTEN_LOW; /*??? unsolved problem, very
2260 seldom we get timeouts
2261 here, don't now the real
2262 reason. With my drive this
2263 sometimes also happens with
2264 Aztech's original driver under
2265 DOS. Is it a hardware bug?
2266 I tried to recover from such
2267 situations here. Zimmermann */
2268 if (aztTimeOutCount >= AZT_TIMEOUT) {
2270 ("read_count:%d CURRENT->nr_sectors:%ld azt_buf_in:%d\n",
2272 CURRENT->nr_sectors,
2275 ("azt_transfer_is_active:%x\n",
2276 azt_transfer_is_active);
2278 azt_state = AZT_S_STOP;
2280 end_request(CURRENT, 1); /*should we have here (1) or (0)? */
2282 if (azt_read_mode ==
2299 ("AZT_S_DATA; ---I've read data- read_count: %d\n",
2302 ("azt_next_bn:%d azt_buf_in:%d azt_buf_out:%d azt_buf_bn:%d\n",
2309 azt_buf_bn[azt_buf_in] =
2311 if (azt_buf_out == -1)
2320 if (!azt_transfer_is_active) {
2321 while (current_valid()) {
2323 if (CURRENT->nr_sectors ==
2325 end_request(CURRENT, 1);
2332 && (CURRENT->sector / 4 < azt_next_bn
2333 || CURRENT->sector / 4 >
2334 azt_next_bn + AZT_BUF_SIZ)) {
2335 azt_state = AZT_S_STOP;
2339 AztTimeout = READ_TIMEOUT;
2340 if (azt_read_count == 0) {
2341 azt_state = AZT_S_STOP;
2352 if (azt_state != azt_state_old) {
2353 azt_state_old = azt_state;
2354 printk("AZT_S_STOP\n");
2357 if (azt_read_count != 0)
2358 printk("aztcd: discard data=%x frames\n",
2360 while (azt_read_count != 0) {
2362 if (!(inb(STATUS_PORT) & AFL_DATA)) {
2363 if (azt_read_mode == AZT_MODE_2)
2365 i < CD_FRAMESIZE_RAW;
2370 i < CD_FRAMESIZE; i++)
2375 if (aztSendCmd(ACMD_GET_STATUS))
2376 RETURN("azt_poll 5");
2377 azt_state = AZT_S_STOPPING;
2381 case AZT_S_STOPPING:
2383 if (azt_state != azt_state_old) {
2384 azt_state_old = azt_state;
2385 printk("AZT_S_STOPPING\n");
2389 if ((st = aztStatus()) == -1 && AztTimeout)
2393 && ((st & AST_DSK_CHG)
2394 || (st & AST_NOT_READY))) {
2397 azt_invalidate_buffers();
2399 ("aztcd: Disk Changed or Not Ready 4 - Unmount Disk!\n");
2400 end_request(CURRENT, 0);
2404 printk("CURRENT_VALID %d azt_mode %d\n",
2405 current_valid(), azt_mode);
2408 if (current_valid()) {
2410 if (azt_mode == 1) {
2411 azt_state = AZT_S_READ;
2416 azt_state = AZT_S_MODE;
2422 azt_state = AZT_S_START;
2426 azt_state = AZT_S_IDLE;
2432 printk("aztcd: invalid state %d\n", azt_state);
2438 if (!AztTimeout--) {
2439 printk("aztcd: timeout in state %d\n", azt_state);
2440 azt_state = AZT_S_STOP;
2441 if (aztSendCmd(ACMD_STOP))
2442 RETURN("azt_poll 6");
2446 SET_TIMER(azt_poll, HZ / 100);
2450 /*###########################################################################
2451 * Miscellaneous support functions
2452 ###########################################################################
2454 static void azt_hsg2msf(long hsg, struct msf *msf)
2457 msf->min = hsg / 4500;
2459 msf->sec = hsg / 75;
2460 msf->frame = hsg % 75;
2463 printk("aztcd: Error hsg2msf address Minutes\n");
2465 printk("aztcd: Error hsg2msf address Seconds\n");
2466 if (msf->frame >= 75)
2467 printk("aztcd: Error hsg2msf address Frames\n");
2469 azt_bin2bcd(&msf->min); /* convert to BCD */
2470 azt_bin2bcd(&msf->sec);
2471 azt_bin2bcd(&msf->frame);
2474 static long azt_msf2hsg(struct msf *mp)
2476 return azt_bcd2bin(mp->frame) + azt_bcd2bin(mp->sec) * 75
2477 + azt_bcd2bin(mp->min) * 4500 - CD_MSF_OFFSET;
2480 static void azt_bin2bcd(unsigned char *p)
2489 static int azt_bcd2bin(unsigned char bcd)
2491 return (bcd >> 4) * 10 + (bcd & 0xF);
2494 MODULE_LICENSE("GPL");
2495 MODULE_ALIAS_BLOCKDEV_MAJOR(AZTECH_CDROM_MAJOR);