1 #define AZT_VERSION "2.60"
3 /* $Id: aztcd.c,v 2.60 1997/11/29 09:51:19 root Exp root $
4 linux/drivers/block/aztcd.c - Aztech CD268 CDROM driver
6 Copyright (C) 1994-98 Werner Zimmermann(Werner.Zimmermann@fht-esslingen.de)
8 based on Mitsumi CDROM driver by Martin Hariss and preworks by
9 Eberhard Moenkeberg; contains contributions by Joe Nardone and Robby
12 This program is free software; you can redistribute it and/or modify
13 it under the terms of the GNU General Public License as published by
14 the Free Software Foundation; either version 2, or (at your option)
17 This program is distributed in the hope that it will be useful,
18 but WITHOUT ANY WARRANTY; without even the implied warranty of
19 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 GNU General Public License for more details.
22 You should have received a copy of the GNU General Public License
23 along with this program; if not, write to the Free Software
24 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
27 V0.0 Adaption to Aztech CD268-01A Version 1.3
28 Version is PRE_ALPHA, unresolved points:
29 1. I use busy wait instead of timer wait in STEN_LOW,DTEN_LOW
30 thus driver causes CPU overhead and is very slow
31 2. could not find a way to stop the drive, when it is
32 in data read mode, therefore I had to set
33 msf.end.min/sec/frame to 0:0:1 (in azt_poll); so only one
34 frame can be read in sequence, this is also the reason for
35 3. getting 'timeout in state 4' messages, but nevertheless
37 W.Zimmermann, Oct. 31, 1994
38 V0.1 Version is ALPHA, problems #2 and #3 resolved.
39 W.Zimmermann, Nov. 3, 1994
40 V0.2 Modification to some comments, debugging aids for partial test
41 with Borland C under DOS eliminated. Timer interrupt wait
42 STEN_LOW_WAIT additionally to busy wait for STEN_LOW implemented;
43 use it only for the 'slow' commands (ACMD_GET_Q_CHANNEL, ACMD_
44 SEEK_TO_LEAD_IN), all other commands are so 'fast', that busy
45 waiting seems better to me than interrupt rescheduling.
46 Besides that, when used in the wrong place, STEN_LOW_WAIT causes
48 In function aztPlay command ACMD_PLAY_AUDIO added, should make
49 audio functions work. The Aztech drive needs different commands
50 to read data tracks and play audio tracks.
51 W.Zimmermann, Nov. 8, 1994
52 V0.3 Recognition of missing drive during boot up improved (speeded up).
53 W.Zimmermann, Nov. 13, 1994
54 V0.35 Rewrote the control mechanism in azt_poll (formerly mcd_poll)
55 including removal of all 'goto' commands. :-);
56 J. Nardone, Nov. 14, 1994
57 V0.4 Renamed variables and constants to 'azt' instead of 'mcd'; had
58 to make some "compatibility" defines in azt.h; please note,
59 that the source file was renamed to azt.c, the include file to
61 Speeded up drive recognition during init (will be a little bit
62 slower than before if no drive is installed!); suggested by
64 read_count declared volatile and set to AZT_BUF_SIZ to make
65 drive faster (now 300kB/sec, was 60kB/sec before, measured
66 by 'time dd if=/dev/cdrom of=/dev/null bs=2048 count=4096';
67 different AZT_BUF_SIZes were test, above 16 no further im-
68 provement seems to be possible; suggested by E.Moenkeberg.
69 W.Zimmermann, Nov. 18, 1994
70 V0.42 Included getAztStatus command in GetQChannelInfo() to allow
71 reading Q-channel info on audio disks, if drive is stopped,
72 and some other bug fixes in the audio stuff, suggested by
74 Added more ioctls (reading data in mode 1 and mode 2).
75 Completely removed the old azt_poll() routine.
76 Detection of ORCHID CDS-3110 in aztcd_init implemented.
77 Additional debugging aids (see the readme file).
78 W.Zimmermann, Dec. 9, 1994
79 V0.50 Autodetection of drives implemented.
80 W.Zimmermann, Dec. 12, 1994
81 V0.52 Prepared for including in the standard kernel, renamed most
82 variables to contain 'azt', included autoconf.h
83 W.Zimmermann, Dec. 16, 1994
84 V0.6 Version for being included in the standard Linux kernel.
85 Renamed source and header file to aztcd.c and aztcd.h
86 W.Zimmermann, Dec. 24, 1994
87 V0.7 Changed VERIFY_READ to VERIFY_WRITE in aztcd_ioctl, case
88 CDROMREADMODE1 and CDROMREADMODE2; bug fix in the ioctl,
89 which causes kernel crashes when playing audio, changed
90 include-files (config.h instead of autoconf.h, removed
92 W.Zimmermann, Jan. 8, 1995
93 V0.72 Some more modifications for adaption to the standard kernel.
94 W.Zimmermann, Jan. 16, 1995
95 V0.80 aztcd is now part of the standard kernel since version 1.1.83.
96 Modified the SET_TIMER and CLEAR_TIMER macros to comply with
98 W.Zimmermann, Jan. 21, 1995
99 V0.90 Included CDROMVOLCTRL, but with my Aztech drive I can only turn
100 the channels on and off. If it works better with your drive,
101 please mail me. Also implemented ACMD_CLOSE for CDROMSTART.
102 W.Zimmermann, Jan. 24, 1995
103 V1.00 Implemented close and lock tray commands. Patches supplied by
105 Added support for loadable MODULEs, so aztcd can now also be
106 loaded by insmod and removed by rmmod during run time
107 Werner Zimmermann, Mar. 24, 95
108 V1.10 Implemented soundcard configuration for Orchid CDS-3110 drives
109 connected to Soundwave32 cards. Release for LST 2.1.
111 Werner Zimmermann, May 8, 95
112 V1.20 Implemented limited support for DOSEMU0.60's cdrom.c. Now it works, but
113 sometimes DOSEMU may hang for 30 seconds or so. A fully functional ver-
114 sion needs an update of Dosemu0.60's cdrom.c, which will come with the
115 next revision of Dosemu.
116 Also Soundwave32 support now works.
117 Werner Zimmermann, May 22, 95
118 V1.30 Auto-eject feature. Inspired by Franc Racis (racis@psu.edu)
119 Werner Zimmermann, July 4, 95
120 V1.40 Started multisession support. Implementation copied from mcdx.c
121 by Heiko Schlittermann. Not tested yet.
122 Werner Zimmermann, July 15, 95
123 V1.50 Implementation of ioctl CDROMRESET, continued multisession, began
124 XA, but still untested. Heavy modifications to drive status de-
126 Werner Zimmermann, July 25, 95
127 V1.60 XA support now should work. Speeded up drive recognition in cases,
128 where no drive is installed.
129 Werner Zimmermann, August 8, 1995
130 V1.70 Multisession support now is completed, but there is still not
131 enough testing done. If you can test it, please contact me. For
132 details please read /usr/src/linux/Documentation/cdrom/aztcd
133 Werner Zimmermann, August 19, 1995
134 V1.80 Modification to suit the new kernel boot procedure introduced
135 with kernel 1.3.33. Will definitely not work with older kernels.
136 Programming done by Linus himself.
137 Werner Zimmermann, October 11, 1995
138 V1.90 Support for Conrad TXC drives, thank's to Jochen Kunz and Olaf Kaluza.
139 Werner Zimmermann, October 21, 1995
140 V2.00 Changed #include "blk.h" to <linux/blk.h> as the directory
141 structure was changed. README.aztcd is now /usr/src/docu-
142 mentation/cdrom/aztcd
143 Werner Zimmermann, November 10, 95
144 V2.10 Started to modify azt_poll to prevent reading beyond end of
146 Werner Zimmermann, December 3, 95
147 V2.20 Changed some comments
148 Werner Zimmermann, April 1, 96
149 V2.30 Implemented support for CyCDROM CR520, CR940, Code for CR520
150 delivered by H.Berger with preworks by E.Moenkeberg.
151 Werner Zimmermann, April 29, 96
152 V2.40 Reorganized the placement of functions in the source code file
153 to reflect the layered approach; did not actually change code
154 Werner Zimmermann, May 1, 96
155 V2.50 Heiko Eissfeldt suggested to remove some VERIFY_READs in
156 aztcd_ioctl; check_aztcd_media_change modified
157 Werner Zimmermann, May 16, 96
158 V2.60 Implemented Auto-Probing; made changes for kernel's 2.1.xx blocksize
159 Adaption to linux kernel > 2.1.0
160 Werner Zimmermann, Nov 29, 97
162 November 1999 -- Make kernel-parameter implementation work with 2.3.x
163 Removed init_module & cleanup_module in favor of
164 module_init & module_exit.
165 Torben Mathiasen <tmm@image.dk>
168 #include <linux/version.h>
170 #define MAJOR_NR AZTECH_CDROM_MAJOR
172 #include <linux/blk.h>
175 #include <linux/module.h>
176 #include <linux/errno.h>
177 #include <linux/sched.h>
178 #include <linux/mm.h>
179 #include <linux/timer.h>
180 #include <linux/fs.h>
181 #include <linux/kernel.h>
182 #include <linux/cdrom.h>
183 #include <linux/ioport.h>
184 #include <linux/string.h>
185 #include <linux/major.h>
186 #include <linux/devfs_fs_kernel.h>
188 #ifndef AZT_KERNEL_PRIOR_2_1
189 #include <linux/init.h>
192 #include <asm/system.h>
195 #ifdef AZT_KERNEL_PRIOR_2_1
196 #include <asm/segment.h>
198 #include <asm/uaccess.h>
199 static int aztcd_blocksizes
[1] = {2048};
203 /*###########################################################################
205 ###########################################################################
207 #define SET_TIMER(func, jifs) delay_timer.expires = jiffies + (jifs); \
208 delay_timer.function = (void *) (func); \
209 add_timer(&delay_timer);
211 #define CLEAR_TIMER del_timer(&delay_timer);
213 #define RETURNM(message,value) {printk("aztcd: Warning: %s failed\n",message);\
215 #define RETURN(message) {printk("aztcd: Warning: %s failed\n",message);\
218 /* Macros to switch the IDE-interface to the slave device and back to the master*/
219 #define SWITCH_IDE_SLAVE outb_p(0xa0,azt_port+6); \
220 outb_p(0x10,azt_port+6); \
221 outb_p(0x00,azt_port+7); \
222 outb_p(0x10,azt_port+6);
223 #define SWITCH_IDE_MASTER outb_p(0xa0,azt_port+6);
228 #define AZT_TEST1 /* <int-..> */
229 #define AZT_TEST2 /* do_aztcd_request */
230 #define AZT_TEST3 /* AZT_S_state */
231 #define AZT_TEST4 /* QUICK_LOOP-counter */
232 #define AZT_TEST5 /* port(1) state */
234 #define AZT_DEBUG_MULTISESSION
237 #define CURRENT_VALID \
238 (!QUEUE_EMPTY && MAJOR(CURRENT -> rq_dev) == MAJOR_NR && CURRENT -> cmd == READ \
239 && CURRENT -> sector != -1)
241 #define AFL_STATUSorDATA (AFL_STATUS | AFL_DATA)
242 #define AZT_BUF_SIZ 16
244 #define READ_TIMEOUT 3000
246 #define azt_port aztcd /*needed for the modutils*/
248 #ifndef AZT_KERNEL_PRIOR_2_1
249 #define memcpy_fromfs copy_from_user
250 #define memcpy_tofs copy_to_user
253 /*##########################################################################
255 ##########################################################################
258 { AZT_S_IDLE
, /* 0 */
264 AZT_S_STOPPING
/* 6 */
267 { AZT_MODE_0
, /*read mode for audio disks, not supported by Aztech firmware*/
268 AZT_MODE_1
, /*read mode for normal CD-ROMs*/
269 AZT_MODE_2
/*read mode for XA CD-ROMs*/
272 /*##########################################################################
274 ##########################################################################
276 static int aztPresent
= 0;
278 static volatile int azt_transfer_is_active
=0;
280 static char azt_buf
[CD_FRAMESIZE_RAW
*AZT_BUF_SIZ
];/*buffer for block size conversion*/
281 #if AZT_PRIVATE_IOCTLS
282 static char buf
[CD_FRAMESIZE_RAW
]; /*separate buffer for the ioctls*/
285 static volatile int azt_buf_bn
[AZT_BUF_SIZ
], azt_next_bn
;
286 static volatile int azt_buf_in
, azt_buf_out
= -1;
287 static volatile int azt_error
=0;
288 static int azt_open_count
=0;
289 static volatile enum azt_state_e azt_state
= AZT_S_IDLE
;
291 static volatile enum azt_state_e azt_state_old
= AZT_S_STOP
;
292 static volatile int azt_st_old
= 0;
294 static volatile enum azt_read_modes azt_read_mode
= AZT_MODE_1
;
296 static int azt_mode
= -1;
297 static volatile int azt_read_count
= 1;
299 static int azt_port
= AZT_BASE_ADDR
;
301 #ifndef AZT_KERNEL_PRIOR_2_1
302 MODULE_PARM(azt_port
, "i");
305 static int azt_port_auto
[16] = AZT_BASE_AUTO
;
307 static char azt_cont
= 0;
308 static char azt_init_end
= 0;
309 static char azt_auto_eject
= AZT_AUTO_EJECT
;
311 static int AztTimeout
, AztTries
;
312 static DECLARE_WAIT_QUEUE_HEAD(azt_waitq
);
313 static struct timer_list delay_timer
= { {NULL
, NULL
}, 0, 0, NULL
};
315 static struct azt_DiskInfo DiskInfo
;
316 static struct azt_Toc Toc
[MAX_TRACKS
];
317 static struct azt_Play_msf azt_Play
;
319 static int aztAudioStatus
= CDROM_AUDIO_NO_STATUS
;
320 static char aztDiskChanged
= 1;
321 static char aztTocUpToDate
= 0;
323 static unsigned char aztIndatum
;
324 static unsigned long aztTimeOutCount
;
325 static int aztCmd
= 0;
327 /*###########################################################################
329 ###########################################################################
331 /* CDROM Drive Low Level I/O Functions */
336 void statusAzt(void);
337 static void aztStatTimer(void);
339 /* CDROM Drive Command Functions */
340 static int aztSendCmd(int cmd
);
341 static int sendAztCmd(int cmd
, struct azt_Play_msf
*params
);
342 static int aztSeek(struct azt_Play_msf
*params
);
343 static int aztSetDiskType(int type
);
344 static int aztStatus(void);
345 static int getAztStatus(void);
346 static int aztPlay(struct azt_Play_msf
*arg
);
347 static void aztCloseDoor(void);
348 static void aztLockDoor(void);
349 static void aztUnlockDoor(void);
350 static int aztGetValue(unsigned char *result
);
351 static int aztGetQChannelInfo(struct azt_Toc
*qp
);
352 static int aztUpdateToc(void);
353 static int aztGetDiskInfo(void);
355 static int aztGetMultiDiskInfo(void);
357 static int aztGetToc(int multi
);
359 /* Kernel Interface Functions */
360 static int check_aztcd_media_change(kdev_t full_dev
);
361 static int aztcd_ioctl(struct inode
*ip
, struct file
*fp
, unsigned int cmd
, unsigned long arg
);
362 static void azt_transfer(void);
363 static void do_aztcd_request(request_queue_t
*);
364 static void azt_invalidate_buffers(void);
365 int aztcd_open(struct inode
*ip
, struct file
*fp
);
367 #ifdef AZT_KERNEL_PRIOR_2_1
368 static void aztcd_release(struct inode
* inode
, struct file
* file
);
370 static int aztcd_release(struct inode
* inode
, struct file
* file
);
373 int aztcd_init(void);
375 static struct block_device_operations azt_fops
= {
377 release
: aztcd_release
,
379 check_media_change
: check_aztcd_media_change
,
382 /* Aztcd State Machine: Controls Drive Operating State */
383 static void azt_poll(void);
385 /* Miscellaneous support functions */
386 static void azt_hsg2msf(long hsg
, struct msf
*msf
);
387 static long azt_msf2hsg(struct msf
*mp
);
388 static void azt_bin2bcd(unsigned char *p
);
389 static int azt_bcd2bin(unsigned char bcd
);
391 /*##########################################################################
392 CDROM Drive Low Level I/O Functions
393 ##########################################################################
395 /* Macros for the drive hardware interface handshake, these macros use
397 /* Wait for OP_OK = drive answers with AFL_OP_OK after receiving a command*/
398 # define OP_OK op_ok()
401 do { aztIndatum
=inb(DATA_PORT
);
403 if (aztTimeOutCount
>=AZT_TIMEOUT
)
404 { printk("aztcd: Error Wait OP_OK\n");
407 } while (aztIndatum
!=AFL_OP_OK
);
410 /* Wait for PA_OK = drive answers with AFL_PA_OK after receiving parameters*/
411 # define PA_OK pa_ok()
414 do { aztIndatum
=inb(DATA_PORT
);
416 if (aztTimeOutCount
>=AZT_TIMEOUT
)
417 { printk("aztcd: Error Wait PA_OK\n");
420 } while (aztIndatum
!=AFL_PA_OK
);
423 /* Wait for STEN=Low = handshake signal 'AFL_.._OK available or command executed*/
424 # define STEN_LOW sten_low()
427 do { aztIndatum
=inb(STATUS_PORT
);
429 if (aztTimeOutCount
>=AZT_TIMEOUT
)
430 { if (azt_init_end
) printk("aztcd: Error Wait STEN_LOW commands:%x\n",aztCmd
);
433 } while (aztIndatum
&AFL_STATUS
);
436 /* Wait for DTEN=Low = handshake signal 'Data available'*/
437 # define DTEN_LOW dten_low()
440 do { aztIndatum
=inb(STATUS_PORT
);
442 if (aztTimeOutCount
>=AZT_TIMEOUT
)
443 { printk("aztcd: Error Wait DTEN_OK\n");
446 } while (aztIndatum
&AFL_DATA
);
450 * Macro for timer wait on STEN=Low, should only be used for 'slow' commands;
451 * may cause kernel panic when used in the wrong place
453 #define STEN_LOW_WAIT statusAzt()
455 { AztTimeout
= AZT_STATUS_DELAY
;
456 SET_TIMER(aztStatTimer
, HZ
/100);
457 sleep_on(&azt_waitq
);
458 if (AztTimeout
<= 0) printk("aztcd: Error Wait STEN_LOW_WAIT command:%x\n",aztCmd
);
462 static void aztStatTimer(void)
463 { if (!(inb(STATUS_PORT
) & AFL_STATUS
))
464 { wake_up(&azt_waitq
);
469 { wake_up(&azt_waitq
);
470 printk("aztcd: Error aztStatTimer: Timeout\n");
473 SET_TIMER(aztStatTimer
, HZ
/100);
476 /*##########################################################################
477 CDROM Drive Command Functions
478 ##########################################################################
481 * Send a single command, return -1 on error, else 0
483 static int aztSendCmd(int cmd
)
484 { unsigned char data
;
488 printk("aztcd: Executing command %x\n",cmd
);
491 if ((azt_port
==0x1f0)||(azt_port
==0x170))
492 SWITCH_IDE_SLAVE
; /*switch IDE interface to slave configuration*/
495 outb(POLLED
,MODE_PORT
);
496 do { if (inb(STATUS_PORT
)&AFL_STATUS
) break;
497 inb(DATA_PORT
); /* if status left from last command, read and */
498 } while (1); /* discard it */
499 do { if (inb(STATUS_PORT
)&AFL_DATA
) break;
500 inb(DATA_PORT
); /* if data left from last command, read and */
501 } while (1); /* discard it */
502 for (retry
=0;retry
<AZT_RETRY_ATTEMPTS
;retry
++)
503 { outb((unsigned char) cmd
,CMD_PORT
);
507 { return 0;} /*OP_OK?*/
508 if (data
==AFL_OP_ERR
)
511 printk("### Error 1 aztcd: aztSendCmd %x Error Code %x\n",cmd
,data
);
514 if (retry
>=AZT_RETRY_ATTEMPTS
)
515 { printk("### Error 2 aztcd: aztSendCmd %x \n",cmd
);
518 RETURNM("aztSendCmd",-1);
522 * Send a play or read command to the drive, return -1 on error, else 0
524 static int sendAztCmd(int cmd
, struct azt_Play_msf
*params
)
525 { unsigned char data
;
529 printk("aztcd: play start=%02x:%02x:%02x end=%02x:%02x:%02x\n", \
530 params
->start
.min
, params
->start
.sec
, params
->start
.frame
, \
531 params
->end
.min
, params
->end
.sec
, params
->end
.frame
);
533 for (retry
=0;retry
<AZT_RETRY_ATTEMPTS
;retry
++)
535 outb(params
-> start
.min
,CMD_PORT
);
536 outb(params
-> start
.sec
,CMD_PORT
);
537 outb(params
-> start
.frame
,CMD_PORT
);
538 outb(params
-> end
.min
,CMD_PORT
);
539 outb(params
-> end
.sec
,CMD_PORT
);
540 outb(params
-> end
.frame
,CMD_PORT
);
544 { return 0;} /*PA_OK ?*/
545 if (data
==AFL_PA_ERR
)
548 printk("### Error 1 aztcd: sendAztCmd %x Error Code %x\n",cmd
,data
);
551 if (retry
>=AZT_RETRY_ATTEMPTS
)
552 { printk("### Error 2 aztcd: sendAztCmd %x\n ",cmd
);
555 RETURNM("sendAztCmd",-1);
559 * Send a seek command to the drive, return -1 on error, else 0
561 static int aztSeek(struct azt_Play_msf
*params
)
562 { unsigned char data
;
566 printk("aztcd: aztSeek %02x:%02x:%02x\n", \
567 params
->start
.min
, params
->start
.sec
, params
->start
.frame
);
569 for (retry
=0;retry
<AZT_RETRY_ATTEMPTS
;retry
++)
570 { aztSendCmd(ACMD_SEEK
);
571 outb(params
-> start
.min
,CMD_PORT
);
572 outb(params
-> start
.sec
,CMD_PORT
);
573 outb(params
-> start
.frame
,CMD_PORT
);
577 { return 0;} /*PA_OK ?*/
578 if (data
==AFL_PA_ERR
)
581 printk("### Error 1 aztcd: aztSeek\n");
584 if (retry
>=AZT_RETRY_ATTEMPTS
)
585 { printk("### Error 2 aztcd: aztSeek\n ");
588 RETURNM("aztSeek",-1);
591 /* Send a Set Disk Type command
592 does not seem to work with Aztech drives, behavior is completely indepen-
593 dent on which mode is set ???
595 static int aztSetDiskType(int type
)
596 { unsigned char data
;
600 printk("aztcd: set disk type command: type= %i\n",type
);
602 for (retry
=0;retry
<AZT_RETRY_ATTEMPTS
;retry
++)
603 { aztSendCmd(ACMD_SET_DISK_TYPE
);
607 if (data
==AFL_PA_OK
) /*PA_OK ?*/
608 { azt_read_mode
=type
;
611 if (data
==AFL_PA_ERR
)
614 printk("### Error 1 aztcd: aztSetDiskType %x Error Code %x\n",type
,data
);
617 if (retry
>=AZT_RETRY_ATTEMPTS
)
618 { printk("### Error 2 aztcd: aztSetDiskType %x\n ",type
);
621 RETURNM("aztSetDiskType",-1);
625 /* used in azt_poll to poll the status, expects another program to issue a
626 * ACMD_GET_STATUS directly before
628 static int aztStatus(void)
632 i = inb(STATUS_PORT) & AFL_STATUS; is STEN=0? ???
635 if (aztTimeOutCount
<AZT_TIMEOUT
)
636 { st
= inb(DATA_PORT
) & 0xFF;
640 RETURNM("aztStatus",-1);
644 * Get the drive status
646 static int getAztStatus(void)
649 if (aztSendCmd(ACMD_GET_STATUS
)) 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
))
656 { printk("aztcd: AST_CMD_CHECK error or no status available\n");
660 if (((st
&AST_MODE_BITS
)!=AST_BUSY
) && (aztAudioStatus
== CDROM_AUDIO_PLAY
))
661 /* XXX might be an error? look at q-channel? */
662 aztAudioStatus
= CDROM_AUDIO_COMPLETED
;
664 if ((st
& AST_DSK_CHG
)||(st
& AST_NOT_READY
))
665 { aztDiskChanged
= 1;
667 aztAudioStatus
= CDROM_AUDIO_NO_STATUS
;
674 * Send a 'Play' command and get the status. Use only from the top half.
676 static int aztPlay(struct azt_Play_msf
*arg
)
677 { if (sendAztCmd(ACMD_PLAY_AUDIO
, arg
) < 0) RETURNM("aztPlay",-1);
682 * Subroutines to automatically close the door (tray) and
683 * lock it closed when the cd is mounted. Leave the tray
684 * locking as an option
686 static void aztCloseDoor(void)
688 aztSendCmd(ACMD_CLOSE
);
693 static void aztLockDoor(void)
695 #if AZT_ALLOW_TRAY_LOCK
696 aztSendCmd(ACMD_LOCK
);
702 static void aztUnlockDoor(void)
704 #if AZT_ALLOW_TRAY_LOCK
705 aztSendCmd(ACMD_UNLOCK
);
712 * Read a value from the drive. Should return quickly, so a busy wait
713 * is used to avoid excessive rescheduling. The read command itself must
714 * be issued with aztSendCmd() directly before
716 static int aztGetValue(unsigned char *result
)
720 if (aztTimeOutCount
>=AZT_TIMEOUT
)
721 { printk("aztcd: aztGetValue timeout\n");
724 s
= inb(DATA_PORT
) & 0xFF;
725 *result
= (unsigned char) s
;
730 * Read the current Q-channel info. Also used for reading the
733 int aztGetQChannelInfo(struct azt_Toc
*qp
)
734 { unsigned char notUsed
;
738 printk("aztcd: starting aztGetQChannelInfo Time:%li\n",jiffies
);
740 if ((st
=getAztStatus())==-1) RETURNM("aztGetQChannelInfo 1",-1);
741 if (aztSendCmd(ACMD_GET_Q_CHANNEL
)) RETURNM("aztGetQChannelInfo 2",-1);
742 /*STEN_LOW_WAIT; ??? Dosemu0.60's cdrom.c does not like STEN_LOW_WAIT here*/
743 if (aztGetValue(¬Used
)) RETURNM("aztGetQChannelInfo 3",-1); /*??? Nullbyte einlesen*/
744 if ((st
&AST_MODE_BITS
)==AST_INITIAL
)
745 { qp
->ctrl_addr
=0; /* when audio stop ACMD_GET_Q_CHANNEL returns */
746 qp
->track
=0; /* only one byte with Aztech drives */
750 qp
->trackTime
.frame
=0;
753 qp
->diskTime
.frame
=0;
757 { if (aztGetValue(&qp
-> ctrl_addr
) < 0) RETURNM("aztGetQChannelInfo 4",-1);
758 if (aztGetValue(&qp
-> track
) < 0) RETURNM("aztGetQChannelInfo 4",-1);
759 if (aztGetValue(&qp
-> pointIndex
) < 0) RETURNM("aztGetQChannelInfo 4",-1);
760 if (aztGetValue(&qp
-> trackTime
.min
) < 0) RETURNM("aztGetQChannelInfo 4",-1);
761 if (aztGetValue(&qp
-> trackTime
.sec
) < 0) RETURNM("aztGetQChannelInfo 4",-1);
762 if (aztGetValue(&qp
-> trackTime
.frame
) < 0) RETURNM("aztGetQChannelInfo 4",-1);
763 if (aztGetValue(¬Used
) < 0) RETURNM("aztGetQChannelInfo 4",-1);
764 if (aztGetValue(&qp
-> diskTime
.min
) < 0) RETURNM("aztGetQChannelInfo 4",-1);
765 if (aztGetValue(&qp
-> diskTime
.sec
) < 0) RETURNM("aztGetQChannelInfo 4",-1);
766 if (aztGetValue(&qp
-> diskTime
.frame
) < 0) RETURNM("aztGetQChannelInfo 4",-1);
769 printk("aztcd: exiting aztGetQChannelInfo Time:%li\n",jiffies
);
775 * Read the table of contents (TOC) and TOC header if necessary
777 static int aztUpdateToc()
781 printk("aztcd: starting aztUpdateToc Time:%li\n",jiffies
);
786 if (aztGetDiskInfo() < 0)
789 if (aztGetToc(0) < 0)
792 /*audio disk detection
793 with my Aztech drive there is no audio status bit, so I use the copy
794 protection bit of the first track. If this track is copy protected
795 (copy bit = 0), I assume, it's an audio disk. Strange, but works ??? */
796 if (!(Toc
[DiskInfo
.first
].ctrl_addr
& 0x40))
802 if (! DiskInfo
.audio
)
803 { azt_Play
.start
.min
= 0; /*XA detection only seems to work*/
804 azt_Play
.start
.sec
= 2; /*when we play a track*/
805 azt_Play
.start
.frame
= 0;
806 azt_Play
.end
.min
= 0;
807 azt_Play
.end
.sec
= 0;
808 azt_Play
.end
.frame
= 1;
809 if (sendAztCmd(ACMD_PLAY_READ
, &azt_Play
)) return -1;
811 for (st
=0;st
<CD_FRAMESIZE
;st
++) inb(DATA_PORT
);
813 DiskInfo
.xa
= getAztStatus() & AST_MODE
;
815 { printk("aztcd: XA support experimental - mail results to Werner.Zimmermann@fht-esslingen.de\n");
818 /*multisession detection
819 support for multisession CDs is done automatically with Aztech drives,
820 we don't have to take care about TOC redirection; if we want the isofs
821 to take care about redirection, we have to set AZT_MULTISESSION to 1*/
825 { aztGetMultiDiskInfo(); /*here Disk.Info.multi is set*/
829 { DiskInfo
.lastSession
.min
= Toc
[DiskInfo
.next
].diskTime
.min
;
830 DiskInfo
.lastSession
.sec
= Toc
[DiskInfo
.next
].diskTime
.sec
;
831 DiskInfo
.lastSession
.frame
= Toc
[DiskInfo
.next
].diskTime
.frame
;
832 printk("aztcd: Multisession support experimental\n");
835 { DiskInfo
.lastSession
.min
= Toc
[DiskInfo
.first
].diskTime
.min
;
836 DiskInfo
.lastSession
.sec
= Toc
[DiskInfo
.first
].diskTime
.sec
;
837 DiskInfo
.lastSession
.frame
= Toc
[DiskInfo
.first
].diskTime
.frame
;
842 printk("aztcd: exiting aztUpdateToc Time:%li\n",jiffies
);
848 /* Read the table of contents header, i.e. no. of tracks and start of first
851 static int aztGetDiskInfo()
854 struct azt_Toc qInfo
;
857 printk("aztcd: starting aztGetDiskInfo Time:%li\n",jiffies
);
859 if (aztSendCmd(ACMD_SEEK_TO_LEADIN
)) RETURNM("aztGetDiskInfo 1",-1);
862 for (limit
=300;limit
>0;limit
--)
863 { if (aztGetQChannelInfo(&qInfo
)<0) RETURNM("aztGetDiskInfo 2",-1);
864 if (qInfo
.pointIndex
==0xA0) /*Number of FirstTrack*/
865 { DiskInfo
.first
= qInfo
.diskTime
.min
;
866 DiskInfo
.first
= azt_bcd2bin(DiskInfo
.first
);
869 if (qInfo
.pointIndex
==0xA1) /*Number of LastTrack*/
870 { DiskInfo
.last
= qInfo
.diskTime
.min
;
871 DiskInfo
.last
= azt_bcd2bin(DiskInfo
.last
);
874 if (qInfo
.pointIndex
==0xA2) /*DiskLength*/
875 { DiskInfo
.diskLength
.min
=qInfo
.diskTime
.min
;
876 DiskInfo
.diskLength
.sec
=qInfo
.diskTime
.sec
;
877 DiskInfo
.diskLength
.frame
=qInfo
.diskTime
.frame
;
880 if ((qInfo
.pointIndex
==DiskInfo
.first
)&&(test
&0x01)) /*StartTime of First Track*/
881 { DiskInfo
.firstTrack
.min
=qInfo
.diskTime
.min
;
882 DiskInfo
.firstTrack
.sec
=qInfo
.diskTime
.sec
;
883 DiskInfo
.firstTrack
.frame
=qInfo
.diskTime
.frame
;
886 if (test
==0x0F) break;
889 printk ("aztcd: exiting aztGetDiskInfo Time:%li\n",jiffies
);
890 printk("Disk Info: first %d last %d length %02X:%02X.%02X dez first %02X:%02X.%02X dez\n",
893 DiskInfo
.diskLength
.min
,
894 DiskInfo
.diskLength
.sec
,
895 DiskInfo
.diskLength
.frame
,
896 DiskInfo
.firstTrack
.min
,
897 DiskInfo
.firstTrack
.sec
,
898 DiskInfo
.firstTrack
.frame
);
900 if (test
!=0x0F) return -1;
906 * Get Multisession Disk Info
908 static int aztGetMultiDiskInfo(void)
911 struct azt_Toc qInfo
;
914 printk("aztcd: starting aztGetMultiDiskInfo\n");
917 do { azt_Play
.start
.min
= Toc
[DiskInfo
.last
+1].diskTime
.min
;
918 azt_Play
.start
.sec
= Toc
[DiskInfo
.last
+1].diskTime
.sec
;
919 azt_Play
.start
.frame
= Toc
[DiskInfo
.last
+1].diskTime
.frame
;
922 for (limit
=30;limit
>0;limit
--) /*Seek for LeadIn of next session*/
923 { if (aztSeek(&azt_Play
)) RETURNM("aztGetMultiDiskInfo 1",-1);
924 if (aztGetQChannelInfo(&qInfo
)<0) RETURNM("aztGetMultiDiskInfo 2",-1);
925 if ((qInfo
.track
==0)&&(qInfo
.pointIndex
)) break; /*LeadIn found*/
926 if ((azt_Play
.start
.sec
+=10) > 59)
927 { azt_Play
.start
.sec
=0;
928 azt_Play
.start
.min
++;
931 if (!limit
) break; /*Check, if a leadin track was found, if not we're
932 at the end of the disk*/
933 #ifdef AZT_DEBUG_MULTISESSION
934 printk("leadin found track %d pointIndex %x limit %d\n",qInfo
.track
,qInfo
.pointIndex
,limit
);
936 for (limit
=300;limit
>0;limit
--)
937 { if (++azt_Play
.start
.frame
>74)
938 { azt_Play
.start
.frame
=0;
939 if (azt_Play
.start
.sec
> 59)
940 { azt_Play
.start
.sec
=0;
941 azt_Play
.start
.min
++;
944 if (aztSeek(&azt_Play
)) RETURNM("aztGetMultiDiskInfo 3",-1);
945 if (aztGetQChannelInfo(&qInfo
)<0) RETURNM("aztGetMultiDiskInfo 4",-1);
946 if (qInfo
.pointIndex
==0xA0) /*Number of NextTrack*/
947 { DiskInfo
.next
= qInfo
.diskTime
.min
;
948 DiskInfo
.next
= azt_bcd2bin(DiskInfo
.next
);
951 if (qInfo
.pointIndex
==0xA1) /*Number of LastTrack*/
952 { DiskInfo
.last
= qInfo
.diskTime
.min
;
953 DiskInfo
.last
= azt_bcd2bin(DiskInfo
.last
);
956 if (qInfo
.pointIndex
==0xA2) /*DiskLength*/
957 { DiskInfo
.diskLength
.min
=qInfo
.diskTime
.min
;
958 DiskInfo
.diskLength
.sec
=qInfo
.diskTime
.sec
;
959 DiskInfo
.diskLength
.frame
=qInfo
.diskTime
.frame
;
962 if ((qInfo
.pointIndex
==DiskInfo
.next
)&&(test
&0x01)) /*StartTime of Next Track*/
963 { DiskInfo
.nextSession
.min
=qInfo
.diskTime
.min
;
964 DiskInfo
.nextSession
.sec
=qInfo
.diskTime
.sec
;
965 DiskInfo
.nextSession
.frame
=qInfo
.diskTime
.frame
;
968 if (test
==0x0F) break;
970 #ifdef AZT_DEBUG_MULTISESSION
971 printk ("MultiDisk Info: first %d next %d last %d length %02x:%02x.%02x dez first %02x:%02x.%02x dez next %02x:%02x.%02x dez\n",
975 DiskInfo
.diskLength
.min
,
976 DiskInfo
.diskLength
.sec
,
977 DiskInfo
.diskLength
.frame
,
978 DiskInfo
.firstTrack
.min
,
979 DiskInfo
.firstTrack
.sec
,
980 DiskInfo
.firstTrack
.frame
,
981 DiskInfo
.nextSession
.min
,
982 DiskInfo
.nextSession
.sec
,
983 DiskInfo
.nextSession
.frame
);
988 DiskInfo
.multi
=1; /*found TOC of more than one session*/
993 printk ("aztcd: exiting aztGetMultiDiskInfo Time:%li\n",jiffies
);
1000 * Read the table of contents (TOC)
1002 static int aztGetToc(int multi
)
1005 struct azt_Toc qInfo
;
1008 printk("aztcd: starting aztGetToc Time:%li\n",jiffies
);
1011 { for (i
= 0; i
< MAX_TRACKS
; i
++)
1012 Toc
[i
].pointIndex
= 0;
1013 i
= DiskInfo
.last
+ 3;
1016 { for (i
= DiskInfo
.next
; i
< MAX_TRACKS
; i
++)
1017 Toc
[i
].pointIndex
= 0;
1018 i
= DiskInfo
.last
+ 4 - DiskInfo
.next
;
1021 /*Is there a good reason to stop motor before TOC read?
1022 if (aztSendCmd(ACMD_STOP)) RETURNM("aztGetToc 1",-1);
1028 if (aztSendCmd(ACMD_SEEK_TO_LEADIN
)) RETURNM("aztGetToc 2",-1);
1031 for (limit
= 300; limit
> 0; limit
--)
1033 { if (++azt_Play
.start
.sec
> 59)
1034 { azt_Play
.start
.sec
=0;
1035 azt_Play
.start
.min
++;
1037 if (aztSeek(&azt_Play
)) RETURNM("aztGetToc 3",-1);
1039 if (aztGetQChannelInfo(&qInfo
) < 0)
1042 px
= azt_bcd2bin(qInfo
.pointIndex
);
1044 if (px
> 0 && px
< MAX_TRACKS
&& qInfo
.track
== 0)
1045 if (Toc
[px
].pointIndex
== 0)
1054 Toc
[DiskInfo
.last
+ 1].diskTime
= DiskInfo
.diskLength
;
1055 Toc
[DiskInfo
.last
].trackTime
= DiskInfo
.diskLength
;
1057 #ifdef AZT_DEBUG_MULTISESSION
1058 printk("aztcd: exiting aztGetToc\n");
1059 for (i
= 1; i
<= DiskInfo
.last
+1; i
++)
1060 printk("i = %2d ctl-adr = %02X track %2d px %02X %02X:%02X.%02X dez %02X:%02X.%02X dez\n",
1061 i
, Toc
[i
].ctrl_addr
, Toc
[i
].track
, Toc
[i
].pointIndex
,
1062 Toc
[i
].trackTime
.min
, Toc
[i
].trackTime
.sec
, Toc
[i
].trackTime
.frame
,
1063 Toc
[i
].diskTime
.min
, Toc
[i
].diskTime
.sec
, Toc
[i
].diskTime
.frame
);
1064 for (i
= 100; i
< 103; i
++)
1065 printk("i = %2d ctl-adr = %02X track %2d px %02X %02X:%02X.%02X dez %02X:%02X.%02X dez\n",
1066 i
, Toc
[i
].ctrl_addr
, Toc
[i
].track
, Toc
[i
].pointIndex
,
1067 Toc
[i
].trackTime
.min
, Toc
[i
].trackTime
.sec
, Toc
[i
].trackTime
.frame
,
1068 Toc
[i
].diskTime
.min
, Toc
[i
].diskTime
.sec
, Toc
[i
].diskTime
.frame
);
1071 return limit
> 0 ? 0 : -1;
1075 /*##########################################################################
1076 Kernel Interface Functions
1077 ##########################################################################
1081 static int __init
aztcd_setup(char *str
)
1085 (void)get_options(str
, ARRAY_SIZE(ints
), ints
);
1094 __setup("aztcd=", aztcd_setup
);
1096 #endif /* !MODULE */
1099 * Checking if the media has been changed
1101 static int check_aztcd_media_change(kdev_t full_dev
)
1102 { if (aztDiskChanged
) /* disk changed */
1107 return 0; /* no change */
1111 * Kernel IO-controls
1113 static int aztcd_ioctl(struct inode
*ip
, struct file
*fp
, unsigned int cmd
, unsigned long arg
)
1115 struct azt_Toc qInfo
;
1117 struct cdrom_tochdr tocHdr
;
1118 struct cdrom_msf msf
;
1119 struct cdrom_tocentry entry
;
1120 struct azt_Toc
*tocPtr
;
1121 struct cdrom_subchnl subchnl
;
1122 struct cdrom_volctrl volctrl
;
1125 printk("aztcd: starting aztcd_ioctl - Command:%x Time: %li\n",cmd
, jiffies
);
1126 printk("aztcd Status %x\n", getAztStatus());
1128 if (!ip
) RETURNM("aztcd_ioctl 1",-EINVAL
);
1129 if (getAztStatus()<0) RETURNM("aztcd_ioctl 2", -EIO
);
1130 if ((!aztTocUpToDate
)||(aztDiskChanged
))
1131 { if ((i
=aztUpdateToc())<0) RETURNM("aztcd_ioctl 3", i
); /* error reading TOC */
1136 case CDROMSTART
: /* Spin up the drive. Don't know, what to do,
1137 at least close the tray */
1138 #if AZT_PRIVATE_IOCTLS
1139 if (aztSendCmd(ACMD_CLOSE
)) RETURNM("aztcd_ioctl 4",-1);
1143 case CDROMSTOP
: /* Spin down the drive */
1144 if (aztSendCmd(ACMD_STOP
)) RETURNM("aztcd_ioctl 5",-1);
1146 /* should we do anything if it fails? */
1147 aztAudioStatus
= CDROM_AUDIO_NO_STATUS
;
1149 case CDROMPAUSE
: /* Pause the drive */
1150 if (aztAudioStatus
!= CDROM_AUDIO_PLAY
) return -EINVAL
;
1152 if (aztGetQChannelInfo(&qInfo
) < 0)
1153 { /* didn't get q channel info */
1154 aztAudioStatus
= CDROM_AUDIO_NO_STATUS
;
1155 RETURNM("aztcd_ioctl 7",0);
1157 azt_Play
.start
= qInfo
.diskTime
; /* remember restart point */
1159 if (aztSendCmd(ACMD_PAUSE
)) RETURNM("aztcd_ioctl 8",-1);
1161 aztAudioStatus
= CDROM_AUDIO_PAUSED
;
1163 case CDROMRESUME
: /* Play it again, Sam */
1164 if (aztAudioStatus
!= CDROM_AUDIO_PAUSED
) return -EINVAL
;
1165 /* restart the drive at the saved position. */
1166 i
= aztPlay(&azt_Play
);
1168 { aztAudioStatus
= CDROM_AUDIO_ERROR
;
1171 aztAudioStatus
= CDROM_AUDIO_PLAY
;
1173 case CDROMMULTISESSION
: /*multisession support -- experimental*/
1174 { struct cdrom_multisession ms
;
1176 printk("aztcd ioctl MULTISESSION\n");
1178 st
= verify_area(VERIFY_WRITE
, (void*) arg
, sizeof(struct cdrom_multisession
));
1180 memcpy_fromfs(&ms
, (void*) arg
, sizeof(struct cdrom_multisession
));
1181 if (ms
.addr_format
== CDROM_MSF
)
1182 { ms
.addr
.msf
.minute
= azt_bcd2bin(DiskInfo
.lastSession
.min
);
1183 ms
.addr
.msf
.second
= azt_bcd2bin(DiskInfo
.lastSession
.sec
);
1184 ms
.addr
.msf
.frame
= azt_bcd2bin(DiskInfo
.lastSession
.frame
);
1186 else if (ms
.addr_format
== CDROM_LBA
)
1187 ms
.addr
.lba
= azt_msf2hsg(&DiskInfo
.lastSession
);
1190 ms
.xa_flag
= DiskInfo
.xa
;
1191 memcpy_tofs((void*) arg
, &ms
, sizeof(struct cdrom_multisession
));
1193 if (ms
.addr_format
== CDROM_MSF
)
1194 printk("aztcd multisession xa:%d, msf:%02x:%02x.%02x [%02x:%02x.%02x])\n",
1195 ms
.xa_flag
, ms
.addr
.msf
.minute
, ms
.addr
.msf
.second
,
1196 ms
.addr
.msf
.frame
, DiskInfo
.lastSession
.min
,
1197 DiskInfo
.lastSession
.sec
, DiskInfo
.lastSession
.frame
);
1199 printk("aztcd multisession %d, lba:0x%08x [%02x:%02x.%02x])\n",
1200 ms
.xa_flag
, ms
.addr
.lba
, DiskInfo
.lastSession
.min
,
1201 DiskInfo
.lastSession
.sec
, DiskInfo
.lastSession
.frame
);
1205 case CDROMPLAYTRKIND
: /* Play a track. This currently ignores index. */
1206 st
= verify_area(VERIFY_READ
, (void *) arg
, sizeof ti
);
1208 memcpy_fromfs(&ti
, (void *) arg
, sizeof ti
);
1209 if (ti
.cdti_trk0
< DiskInfo
.first
1210 || ti
.cdti_trk0
> DiskInfo
.last
1211 || ti
.cdti_trk1
< ti
.cdti_trk0
)
1214 if (ti
.cdti_trk1
> DiskInfo
.last
)
1215 ti
.cdti_trk1
= DiskInfo
.last
;
1216 azt_Play
.start
= Toc
[ti
.cdti_trk0
].diskTime
;
1217 azt_Play
.end
= Toc
[ti
.cdti_trk1
+ 1].diskTime
;
1219 printk("aztcd play: %02x:%02x.%02x to %02x:%02x.%02x\n",
1220 azt_Play
.start
.min
, azt_Play
.start
.sec
, azt_Play
.start
.frame
,
1221 azt_Play
.end
.min
, azt_Play
.end
.sec
, azt_Play
.end
.frame
);
1223 i
= aztPlay(&azt_Play
);
1225 { aztAudioStatus
= CDROM_AUDIO_ERROR
;
1228 aztAudioStatus
= CDROM_AUDIO_PLAY
;
1230 case CDROMPLAYMSF
: /* Play starting at the given MSF address. */
1231 /* if (aztAudioStatus == CDROM_AUDIO_PLAY)
1232 { if (aztSendCmd(ACMD_STOP)) RETURNM("aztcd_ioctl 9",-1);
1234 aztAudioStatus = CDROM_AUDIO_NO_STATUS;
1237 st
= verify_area(VERIFY_READ
, (void *) arg
, sizeof msf
);
1239 memcpy_fromfs(&msf
, (void *) arg
, sizeof msf
);
1240 /* convert to bcd */
1241 azt_bin2bcd(&msf
.cdmsf_min0
);
1242 azt_bin2bcd(&msf
.cdmsf_sec0
);
1243 azt_bin2bcd(&msf
.cdmsf_frame0
);
1244 azt_bin2bcd(&msf
.cdmsf_min1
);
1245 azt_bin2bcd(&msf
.cdmsf_sec1
);
1246 azt_bin2bcd(&msf
.cdmsf_frame1
);
1247 azt_Play
.start
.min
= msf
.cdmsf_min0
;
1248 azt_Play
.start
.sec
= msf
.cdmsf_sec0
;
1249 azt_Play
.start
.frame
= msf
.cdmsf_frame0
;
1250 azt_Play
.end
.min
= msf
.cdmsf_min1
;
1251 azt_Play
.end
.sec
= msf
.cdmsf_sec1
;
1252 azt_Play
.end
.frame
= msf
.cdmsf_frame1
;
1254 printk("aztcd play: %02x:%02x.%02x to %02x:%02x.%02x\n",
1255 azt_Play
.start
.min
, azt_Play
.start
.sec
, azt_Play
.start
.frame
,
1256 azt_Play
.end
.min
, azt_Play
.end
.sec
, azt_Play
.end
.frame
);
1258 i
= aztPlay(&azt_Play
);
1260 { aztAudioStatus
= CDROM_AUDIO_ERROR
;
1263 aztAudioStatus
= CDROM_AUDIO_PLAY
;
1266 case CDROMREADTOCHDR
: /* Read the table of contents header */
1267 st
= verify_area(VERIFY_WRITE
, (void *) arg
, sizeof tocHdr
);
1269 tocHdr
.cdth_trk0
= DiskInfo
.first
;
1270 tocHdr
.cdth_trk1
= DiskInfo
.last
;
1271 memcpy_tofs((void *) arg
, &tocHdr
, sizeof tocHdr
);
1273 case CDROMREADTOCENTRY
: /* Read an entry in the table of contents */
1274 st
= verify_area(VERIFY_WRITE
, (void *) arg
, sizeof entry
);
1276 memcpy_fromfs(&entry
, (void *) arg
, sizeof entry
);
1277 if ((!aztTocUpToDate
)||aztDiskChanged
) aztUpdateToc();
1278 if (entry
.cdte_track
== CDROM_LEADOUT
)
1279 tocPtr
= &Toc
[DiskInfo
.last
+ 1];
1280 else if (entry
.cdte_track
> DiskInfo
.last
1281 || entry
.cdte_track
< DiskInfo
.first
)
1285 tocPtr
= &Toc
[entry
.cdte_track
];
1286 entry
.cdte_adr
= tocPtr
-> ctrl_addr
;
1287 entry
.cdte_ctrl
= tocPtr
-> ctrl_addr
>> 4;
1288 if (entry
.cdte_format
== CDROM_LBA
)
1289 entry
.cdte_addr
.lba
= azt_msf2hsg(&tocPtr
-> diskTime
);
1290 else if (entry
.cdte_format
== CDROM_MSF
)
1291 { entry
.cdte_addr
.msf
.minute
= azt_bcd2bin(tocPtr
-> diskTime
.min
);
1292 entry
.cdte_addr
.msf
.second
= azt_bcd2bin(tocPtr
-> diskTime
.sec
);
1293 entry
.cdte_addr
.msf
.frame
= azt_bcd2bin(tocPtr
-> diskTime
.frame
);
1298 memcpy_tofs((void *) arg
, &entry
, sizeof entry
);
1300 case CDROMSUBCHNL
: /* Get subchannel info */
1301 st
= verify_area(VERIFY_WRITE
, (void *) arg
, sizeof(struct cdrom_subchnl
));
1304 printk("aztcd: exiting aztcd_ioctl - Error 1 - Command:%x\n",cmd
);
1308 memcpy_fromfs(&subchnl
, (void *) arg
, sizeof (struct cdrom_subchnl
));
1309 if (aztGetQChannelInfo(&qInfo
) < 0)
1312 printk("aztcd: exiting aztcd_ioctl - Error 3 - Command:%x\n",cmd
);
1316 subchnl
.cdsc_audiostatus
= aztAudioStatus
;
1317 subchnl
.cdsc_adr
= qInfo
.ctrl_addr
;
1318 subchnl
.cdsc_ctrl
= qInfo
.ctrl_addr
>> 4;
1319 subchnl
.cdsc_trk
= azt_bcd2bin(qInfo
.track
);
1320 subchnl
.cdsc_ind
= azt_bcd2bin(qInfo
.pointIndex
);
1321 if (subchnl
.cdsc_format
== CDROM_LBA
)
1322 { subchnl
.cdsc_absaddr
.lba
= azt_msf2hsg(&qInfo
.diskTime
);
1323 subchnl
.cdsc_reladdr
.lba
= azt_msf2hsg(&qInfo
.trackTime
);
1326 { subchnl
.cdsc_format
= CDROM_MSF
;
1327 subchnl
.cdsc_absaddr
.msf
.minute
= azt_bcd2bin(qInfo
.diskTime
.min
);
1328 subchnl
.cdsc_absaddr
.msf
.second
= azt_bcd2bin(qInfo
.diskTime
.sec
);
1329 subchnl
.cdsc_absaddr
.msf
.frame
= azt_bcd2bin(qInfo
.diskTime
.frame
);
1330 subchnl
.cdsc_reladdr
.msf
.minute
= azt_bcd2bin(qInfo
.trackTime
.min
);
1331 subchnl
.cdsc_reladdr
.msf
.second
= azt_bcd2bin(qInfo
.trackTime
.sec
);
1332 subchnl
.cdsc_reladdr
.msf
.frame
= azt_bcd2bin(qInfo
.trackTime
.frame
);
1334 memcpy_tofs((void *) arg
, &subchnl
, sizeof (struct cdrom_subchnl
));
1336 case CDROMVOLCTRL
: /* Volume control
1337 * With my Aztech CD268-01A volume control does not work, I can only
1338 turn the channels on (any value !=0) or off (value==0). Maybe it
1339 works better with your drive */
1340 st
=verify_area(VERIFY_READ
,(void *) arg
, sizeof(volctrl
));
1341 if (st
) return (st
);
1342 memcpy_fromfs(&volctrl
,(char *) arg
,sizeof(volctrl
));
1343 azt_Play
.start
.min
= 0x21;
1344 azt_Play
.start
.sec
= 0x84;
1345 azt_Play
.start
.frame
= volctrl
.channel0
;
1346 azt_Play
.end
.min
= volctrl
.channel1
;
1347 azt_Play
.end
.sec
= volctrl
.channel2
;
1348 azt_Play
.end
.frame
= volctrl
.channel3
;
1349 sendAztCmd(ACMD_SET_VOLUME
, &azt_Play
);
1353 aztUnlockDoor(); /* Assume user knows what they're doing */
1354 /* all drives can at least stop! */
1355 if (aztAudioStatus
== CDROM_AUDIO_PLAY
)
1356 { if (aztSendCmd(ACMD_STOP
)) RETURNM("azt_ioctl 10",-1);
1359 if (aztSendCmd(ACMD_EJECT
)) RETURNM("azt_ioctl 11",-1);
1361 aztAudioStatus
= CDROM_AUDIO_NO_STATUS
;
1364 azt_auto_eject
= (char) arg
;
1367 outb(ACMD_SOFT_RESET
,CMD_PORT
); /*send reset*/
1369 if (inb(DATA_PORT
)!=AFL_OP_OK
) /*OP_OK?*/
1370 { printk("aztcd: AZTECH CD-ROM drive does not respond\n");
1373 /*Take care, the following code is not compatible with other CD-ROM drivers,
1374 use it at your own risk with cdplay.c. Set AZT_PRIVATE_IOCTLS to 0 in aztcd.h,
1375 if you do not want to use it!
1377 #if AZT_PRIVATE_IOCTLS
1378 case CDROMREADCOOKED
: /*read data in mode 1 (2048 Bytes)*/
1379 case CDROMREADRAW
: /*read data in mode 2 (2336 Bytes)*/
1380 { st
= verify_area(VERIFY_WRITE
, (void *) arg
, sizeof buf
);
1382 memcpy_fromfs(&msf
, (void *) arg
, sizeof msf
);
1383 /* convert to bcd */
1384 azt_bin2bcd(&msf
.cdmsf_min0
);
1385 azt_bin2bcd(&msf
.cdmsf_sec0
);
1386 azt_bin2bcd(&msf
.cdmsf_frame0
);
1389 msf
.cdmsf_frame1
=1; /*read only one frame*/
1390 azt_Play
.start
.min
= msf
.cdmsf_min0
;
1391 azt_Play
.start
.sec
= msf
.cdmsf_sec0
;
1392 azt_Play
.start
.frame
= msf
.cdmsf_frame0
;
1393 azt_Play
.end
.min
= msf
.cdmsf_min1
;
1394 azt_Play
.end
.sec
= msf
.cdmsf_sec1
;
1395 azt_Play
.end
.frame
= msf
.cdmsf_frame1
;
1396 if (cmd
==CDROMREADRAW
)
1398 { return -1; /*XA Disks can't be read raw*/
1401 { if (sendAztCmd(ACMD_PLAY_READ_RAW
, &azt_Play
)) return -1;
1403 insb(DATA_PORT
,buf
,CD_FRAMESIZE_RAW
);
1404 memcpy_tofs((void *) arg
, &buf
, CD_FRAMESIZE_RAW
);
1407 else /*CDROMREADCOOKED*/
1408 { if (sendAztCmd(ACMD_PLAY_READ
, &azt_Play
)) return -1;
1410 insb(DATA_PORT
,buf
,CD_FRAMESIZE
);
1411 memcpy_tofs((void *) arg
, &buf
, CD_FRAMESIZE
);
1415 case CDROMSEEK
: /*seek msf address*/
1416 st
= verify_area(VERIFY_READ
, (void *) arg
, sizeof msf
);
1418 memcpy_fromfs(&msf
, (void *) arg
, sizeof msf
);
1419 /* convert to bcd */
1420 azt_bin2bcd(&msf
.cdmsf_min0
);
1421 azt_bin2bcd(&msf
.cdmsf_sec0
);
1422 azt_bin2bcd(&msf
.cdmsf_frame0
);
1423 azt_Play
.start
.min
= msf
.cdmsf_min0
;
1424 azt_Play
.start
.sec
= msf
.cdmsf_sec0
;
1425 azt_Play
.start
.frame
= msf
.cdmsf_frame0
;
1426 if (aztSeek(&azt_Play
)) return -1;
1428 #endif /*end of incompatible code*/
1429 case CDROMREADMODE1
: /*set read data in mode 1*/
1430 return aztSetDiskType(AZT_MODE_1
);
1431 case CDROMREADMODE2
: /*set read data in mode 2*/
1432 return aztSetDiskType(AZT_MODE_2
);
1437 printk("aztcd: exiting aztcd_ioctl Command:%x Time:%li\n",cmd
,jiffies
);
1443 * Take care of the different block sizes between cdrom and Linux.
1444 * When Linux gets variable block sizes this will probably go away.
1446 static void azt_transfer(void)
1449 printk("aztcd: executing azt_transfer Time:%li\n",jiffies
);
1451 if (CURRENT_VALID
) {
1452 while (CURRENT
-> nr_sectors
) {
1453 int bn
= CURRENT
-> sector
/ 4;
1455 for (i
= 0; i
< AZT_BUF_SIZ
&& azt_buf_bn
[i
] != bn
; ++i
)
1457 if (i
< AZT_BUF_SIZ
) {
1458 int offs
= (i
* 4 + (CURRENT
-> sector
& 3)) * 512;
1459 int nr_sectors
= 4 - (CURRENT
-> sector
& 3);
1460 if (azt_buf_out
!= i
) {
1462 if (azt_buf_bn
[i
] != bn
) {
1467 if (nr_sectors
> CURRENT
-> nr_sectors
)
1468 nr_sectors
= CURRENT
-> nr_sectors
;
1469 memcpy(CURRENT
-> buffer
, azt_buf
+ offs
, nr_sectors
* 512);
1470 CURRENT
-> nr_sectors
-= nr_sectors
;
1471 CURRENT
-> sector
+= nr_sectors
;
1472 CURRENT
-> buffer
+= nr_sectors
* 512;
1481 static void do_aztcd_request(request_queue_t
* q
)
1484 printk(" do_aztcd_request(%ld+%ld) Time:%li\n", CURRENT
-> sector
, CURRENT
-> nr_sectors
,jiffies
);
1487 { printk("aztcd: Error, tried to mount an Audio CD\n");
1491 azt_transfer_is_active
= 1;
1492 while (CURRENT_VALID
) {
1494 if (!buffer_locked(CURRENT
->bh
))
1495 panic(DEVICE_NAME
": block not locked");
1498 if (CURRENT
-> nr_sectors
== 0) {
1501 azt_buf_out
= -1; /* Want to read a block not in buffer */
1502 if (azt_state
== AZT_S_IDLE
) {
1503 if ((!aztTocUpToDate
)||aztDiskChanged
) {
1504 if (aztUpdateToc() < 0) {
1505 while (CURRENT_VALID
)
1510 azt_state
= AZT_S_START
;
1512 SET_TIMER(azt_poll
, HZ
/100);
1517 azt_transfer_is_active
= 0;
1519 printk("azt_next_bn:%x azt_buf_in:%x azt_buf_out:%x azt_buf_bn:%x\n", \
1520 azt_next_bn
, azt_buf_in
, azt_buf_out
, azt_buf_bn
[azt_buf_in
]);
1521 printk(" do_aztcd_request ends Time:%li\n",jiffies
);
1526 static void azt_invalidate_buffers(void)
1530 printk("aztcd: executing azt_invalidate_buffers\n");
1532 for (i
= 0; i
< AZT_BUF_SIZ
; ++i
)
1538 * Open the device special file. Check that a disk is in.
1540 int aztcd_open(struct inode
*ip
, struct file
*fp
)
1544 printk("aztcd: starting aztcd_open\n");
1547 if (aztPresent
== 0)
1548 return -ENXIO
; /* no hardware */
1552 if (!azt_open_count
&& azt_state
== AZT_S_IDLE
)
1553 { azt_invalidate_buffers();
1555 st
= getAztStatus(); /* check drive status */
1556 if (st
== -1) goto err_out
; /* drive doesn't respond */
1558 if (st
& AST_DOOR_OPEN
)
1559 { /* close door, then get the status again. */
1560 printk("aztcd: Door Open?\n");
1562 st
= getAztStatus();
1565 if ((st
& AST_NOT_READY
) || (st
& AST_DSK_CHG
)) /*no disk in drive or changed*/
1566 { printk("aztcd: Disk Changed or No Disk in Drive?\n");
1569 if (aztUpdateToc()) goto err_out
;
1576 printk("aztcd: exiting aztcd_open\n");
1587 * On close, we flush all azt blocks from the buffer cache.
1589 #ifdef AZT_KERNEL_PRIOR_2_1
1590 static void aztcd_release(struct inode
* inode
, struct file
* file
)
1592 static int aztcd_release(struct inode
* inode
, struct file
* file
)
1596 printk("aztcd: executing aztcd_release\n");
1597 printk("inode: %p, inode->i_rdev: %x file: %p\n",inode
,inode
->i_rdev
,file
);
1600 if (!--azt_open_count
) {
1601 azt_invalidate_buffers();
1604 aztSendCmd(ACMD_EJECT
);
1607 #ifdef AZT_KERNEL_PRIOR_2_1
1617 * Test for presence of drive and initialize it. Called at boot time.
1620 int __init
aztcd_init(void)
1621 { long int count
, max_count
;
1622 unsigned char result
[50];
1627 { printk("aztcd: no Aztech CD-ROM Initialization");
1631 printk("aztcd: AZTECH, ORCHID, OKANO, WEARNES, TXC, CyDROM CD-ROM Driver\n");
1632 printk("aztcd: (C) 1994-98 W.Zimmermann\n");
1634 { printk("aztcd: KernelVersion=%s DriverVersion=%s For IDE/ATAPI-drives use ide-cd.c\n",UTS_RELEASE
,AZT_VERSION
);
1637 printk("aztcd: DriverVersion=%s BaseAddress=0x%x For IDE/ATAPI-drives use ide-cd.c\n",AZT_VERSION
,azt_port
);
1638 printk("aztcd: If you have problems, read /usr/src/linux/Documentation/cdrom/aztcd\n");
1641 #ifdef AZT_SW32 /*CDROM connected to Soundwave32 card*/
1642 if ((0xFF00 & inw(AZT_SW32_ID_REG
)) != 0x4500)
1643 { printk("aztcd: no Soundwave32 card detected at base:%x init:%x config:%x id:%x\n",
1644 AZT_SW32_BASE_ADDR
,AZT_SW32_INIT
,AZT_SW32_CONFIG_REG
,AZT_SW32_ID_REG
);
1648 { printk(KERN_INFO
"aztcd: Soundwave32 card detected at %x Version %x\n",
1649 AZT_SW32_BASE_ADDR
, inw(AZT_SW32_ID_REG
));
1650 outw(AZT_SW32_INIT
,AZT_SW32_CONFIG_REG
);
1651 for (count
=0;count
<10000;count
++); /*delay a bit*/
1655 /* check for presence of drive */
1657 if (azt_port
== -1) /* autoprobing */
1658 { for (i
=0;(azt_port_auto
[i
]!=0)&&(i
<16);i
++)
1659 { azt_port
= azt_port_auto
[i
];
1660 printk("aztcd: Autoprobing BaseAddress=0x%x \n",azt_port
);
1661 st
= check_region(azt_port
, 4); /*proprietary interfaces need 4 bytes*/
1664 outb(POLLED
,MODE_PORT
);
1667 outb(ACMD_GET_VERSION
,CMD_PORT
); /*Try to get version info*/
1670 do { aztIndatum
=inb(STATUS_PORT
);
1672 if (aztTimeOutCount
>=AZT_FAST_TIMEOUT
) break;
1673 } while (aztIndatum
&AFL_STATUS
);
1674 if (inb(DATA_PORT
)==AFL_OP_OK
)
1677 if ((azt_port_auto
[i
]==0)||(i
==16))
1678 { printk("aztcd: no AZTECH CD-ROM drive found\n");
1682 else /* no autoprobing */
1683 { if ((azt_port
==0x1f0)||(azt_port
==0x170))
1684 st
= check_region(azt_port
, 8); /*IDE-interfaces need 8 bytes*/
1686 st
= check_region(azt_port
, 4); /*proprietary interfaces need 4 bytes*/
1688 { printk("aztcd: conflict, I/O port (%X) already used\n",azt_port
);
1692 if ((azt_port
==0x1f0)||(azt_port
==0x170))
1693 SWITCH_IDE_SLAVE
; /*switch IDE interface to slave configuration*/
1695 outb(POLLED
,MODE_PORT
);
1698 outb(ACMD_GET_VERSION
,CMD_PORT
); /*Try to get version info*/
1701 do { aztIndatum
=inb(STATUS_PORT
);
1703 if (aztTimeOutCount
>=AZT_FAST_TIMEOUT
) break;
1704 } while (aztIndatum
&AFL_STATUS
);
1706 if (inb(DATA_PORT
)!=AFL_OP_OK
) /*OP_OK? If not, reset and try again*/
1710 { printk("aztcd: no AZTECH CD-ROM drive found-Try boot parameter aztcd=<BaseAddress>,0x79\n");
1719 { printk("aztcd: drive reset - please wait\n");
1720 for (count
=0;count
<50;count
++)
1721 { inb(STATUS_PORT
); /*removing all data from earlier tries*/
1724 outb(POLLED
,MODE_PORT
);
1727 getAztStatus(); /*trap errors*/
1728 outb(ACMD_SOFT_RESET
,CMD_PORT
); /*send reset*/
1730 if (inb(DATA_PORT
)!=AFL_OP_OK
) /*OP_OK?*/
1731 { printk("aztcd: no AZTECH CD-ROM drive found\n");
1735 for (count
= 0; count
< AZT_TIMEOUT
; count
++)
1736 barrier(); /* Stop gcc 2.96 being smart */
1738 if ((st
=getAztStatus())==-1)
1739 { printk("aztcd: Drive Status Error Status=%x\n",st
);
1743 printk("aztcd: Status = %x\n",st
);
1745 outb(POLLED
,MODE_PORT
);
1748 outb(ACMD_GET_VERSION
,CMD_PORT
); /*GetVersion*/
1757 result
[0]=inb(DATA_PORT
); /*reading in a null byte???*/
1758 for (count
=1;count
<50;count
++) /*Reading version string*/
1759 { aztTimeOutCount
=0; /*here we must implement STEN_LOW differently*/
1760 do { aztIndatum
=inb(STATUS_PORT
);/*because we want to exit by timeout*/
1762 if (aztTimeOutCount
>=AZT_FAST_TIMEOUT
) break;
1763 } while (aztIndatum
&AFL_STATUS
);
1764 if (aztTimeOutCount
>=AZT_FAST_TIMEOUT
) break; /*all chars read?*/
1765 result
[count
]=inb(DATA_PORT
);
1767 if (count
>30) max_count
=30; /*print max.30 chars of the version string*/
1768 else max_count
=count
;
1769 printk(KERN_INFO
"aztcd: FirmwareVersion=");
1770 for (count
=1;count
<max_count
;count
++) printk("%c",result
[count
]);
1773 if ((result
[1]=='A')&&(result
[2]=='Z')&&(result
[3]=='T'))
1774 { printk("AZTECH drive detected\n"); /*AZTECH*/
1776 else if ((result
[2]=='C')&&(result
[3]=='D')&&(result
[4]=='D'))
1777 { printk("ORCHID or WEARNES drive detected\n"); /*ORCHID or WEARNES*/
1779 else if ((result
[1]==0x03)&&(result
[2]=='5'))
1780 { printk("TXC or CyCDROM drive detected\n"); /*Conrad TXC, CyCDROM*/
1782 else /*OTHERS or none*/
1783 { printk("\nunknown drive or firmware version detected\n");
1784 printk("aztcd may not run stable, if you want to try anyhow,\n");
1785 printk("boot with: aztcd=<BaseAddress>,0x79\n");
1786 if ((azt_cont
!=0x79))
1787 { printk("aztcd: FirmwareVersion=");
1788 for (count
=1;count
<5;count
++) printk("%c",result
[count
]);
1790 printk("Aborted\n");
1794 devfs_register (NULL
, "aztcd", DEVFS_FL_DEFAULT
, MAJOR_NR
, 0,
1795 S_IFBLK
| S_IRUGO
| S_IWUGO
, &azt_fops
, NULL
);
1796 if (devfs_register_blkdev(MAJOR_NR
, "aztcd", &azt_fops
) != 0)
1798 printk("aztcd: Unable to get major %d for Aztech CD-ROM\n",
1802 blk_init_queue(BLK_DEFAULT_QUEUE(MAJOR_NR
), DEVICE_REQUEST
);
1803 #ifndef AZT_KERNEL_PRIOR_2_1
1804 blksize_size
[MAJOR_NR
] = aztcd_blocksizes
;
1806 read_ahead
[MAJOR_NR
] = 4;
1807 register_disk(NULL
, MKDEV(MAJOR_NR
,0), 1, &azt_fops
, 0);
1809 if ((azt_port
==0x1f0)||(azt_port
==0x170))
1810 request_region(azt_port
, 8, "aztcd"); /*IDE-interface*/
1812 request_region(azt_port
, 4, "aztcd"); /*proprietary interface*/
1814 azt_invalidate_buffers();
1820 void __exit
aztcd_exit(void)
1822 devfs_unregister(devfs_find_handle(NULL
, "aztcd", 0, 0, DEVFS_SPECIAL_BLK
,
1824 if ((devfs_unregister_blkdev(MAJOR_NR
, "aztcd") == -EINVAL
))
1825 { printk("What's that: can't unregister aztcd\n");
1828 blk_cleanup_queue(BLK_DEFAULT_QUEUE(MAJOR_NR
));
1829 if ((azt_port
==0x1f0)||(azt_port
==0x170))
1830 { SWITCH_IDE_MASTER
;
1831 release_region(azt_port
,8); /*IDE-interface*/
1834 release_region(azt_port
,4); /*proprietary interface*/
1835 printk(KERN_INFO
"aztcd module released.\n");
1839 module_init(aztcd_init
);
1841 module_exit(aztcd_exit
);
1843 /*##########################################################################
1844 Aztcd State Machine: Controls Drive Operating State
1845 ##########################################################################
1847 static void azt_poll(void)
1854 if (aztSendCmd(ACMD_GET_ERROR
)) RETURN("azt_poll 1");
1856 azt_error
=inb(DATA_PORT
)&0xFF;
1857 printk("aztcd: I/O error 0x%02x\n", azt_error
);
1858 azt_invalidate_buffers();
1859 #ifdef WARN_IF_READ_FAILURE
1861 printk("aztcd: Read of Block %d Failed - Maybe Audio Disk?\n", azt_next_bn
);
1864 printk("aztcd: Read of Block %d Failed, Maybe Audio Disk? Giving up\n", azt_next_bn
);
1865 if (azt_transfer_is_active
) {
1874 azt_state
= AZT_S_STOP
;
1879 loop_ctl
= 0; /* each case must flip this back to 1 if we want
1880 to come back up here */
1881 switch (azt_state
) {
1885 if (azt_state
!=azt_state_old
) {
1886 azt_state_old
=azt_state
;
1887 printk("AZT_S_IDLE\n");
1894 if (azt_state
!=azt_state_old
) {
1895 azt_state_old
=azt_state
;
1896 printk("AZT_S_START\n");
1899 if(aztSendCmd(ACMD_GET_STATUS
)) RETURN("azt_poll 2"); /*result will be checked by aztStatus() */
1900 azt_state
= azt_mode
== 1 ? AZT_S_READ
: AZT_S_MODE
;
1906 if (azt_state
!=azt_state_old
) {
1907 azt_state_old
=azt_state
;
1908 printk("AZT_S_MODE\n");
1912 if ((st
= aztStatus()) != -1) {
1913 if ((st
& AST_DSK_CHG
)||(st
& AST_NOT_READY
)) {
1916 azt_invalidate_buffers();
1918 printk("aztcd: Disk Changed or Not Ready 1 - Unmount Disk!\n");
1924 if ((st
& AST_DOOR_OPEN
)||(st
& AST_NOT_READY
)) {
1927 printk("aztcd: Disk Changed or Not Ready 2 - Unmount Disk!\n");
1929 printk((st
& AST_DOOR_OPEN
) ? "aztcd: door open\n" : "aztcd: disk removed\n");
1930 if (azt_transfer_is_active
) {
1931 azt_state
= AZT_S_START
;
1932 loop_ctl
= 1; /* goto immediately */
1935 azt_state
= AZT_S_IDLE
;
1936 while (CURRENT_VALID
)
1941 /* if (aztSendCmd(ACMD_SET_MODE)) RETURN("azt_poll 3");
1942 outb(0x01, DATA_PORT);
1945 */ if (aztSendCmd(ACMD_GET_STATUS
)) RETURN("azt_poll 4");
1948 azt_state
= AZT_S_READ
;
1956 if (azt_state
!=azt_state_old
) {
1957 azt_state_old
=azt_state
;
1958 printk("AZT_S_READ\n");
1962 if ((st
= aztStatus()) != -1) {
1963 if ((st
& AST_DSK_CHG
)||(st
& AST_NOT_READY
)) {
1966 azt_invalidate_buffers();
1967 printk("aztcd: Disk Changed or Not Ready 3 - Unmount Disk!\n");
1974 if ((st
& AST_DOOR_OPEN
)||(st
& AST_NOT_READY
)) {
1977 printk((st
& AST_DOOR_OPEN
) ? "aztcd: door open\n" : "aztcd: disk removed\n");
1978 if (azt_transfer_is_active
) {
1979 azt_state
= AZT_S_START
;
1983 azt_state
= AZT_S_IDLE
;
1984 while (CURRENT_VALID
)
1989 if (CURRENT_VALID
) {
1990 struct azt_Play_msf msf
;
1992 azt_next_bn
= CURRENT
-> sector
/ 4;
1993 azt_hsg2msf(azt_next_bn
, &msf
.start
);
1995 /* find out in which track we are */
1996 while (azt_msf2hsg(&msf
.start
)>azt_msf2hsg(&Toc
[++i
].trackTime
)) {};
1997 if (azt_msf2hsg(&msf
.start
)<azt_msf2hsg(&Toc
[i
].trackTime
)-AZT_BUF_SIZ
)
1998 { azt_read_count
=AZT_BUF_SIZ
; /*fast, because we read ahead*/
1999 /*azt_read_count=CURRENT->nr_sectors; slow, no read ahead*/
2001 else /* don't read beyond end of track */
2002 #if AZT_MULTISESSION
2003 { azt_read_count
=(azt_msf2hsg(&Toc
[i
].trackTime
)/4)*4-azt_msf2hsg(&msf
.start
);
2004 if (azt_read_count
< 0) azt_read_count
=0;
2005 if (azt_read_count
> AZT_BUF_SIZ
) azt_read_count
=AZT_BUF_SIZ
;
2006 printk("aztcd: warning - trying to read beyond end of track\n");
2007 /* printk("%i %i %li %li\n",i,azt_read_count,azt_msf2hsg(&msf.start),azt_msf2hsg(&Toc[i].trackTime));
2010 { azt_read_count
=AZT_BUF_SIZ
;
2015 msf
.end
.frame
= azt_read_count
;/*Mitsumi here reads 0xffffff sectors*/
2017 printk("---reading msf-address %x:%x:%x %x:%x:%x\n",msf
.start
.min
,msf
.start
.sec
,msf
.start
.frame
,msf
.end
.min
,msf
.end
.sec
,msf
.end
.frame
);
2018 printk("azt_next_bn:%x azt_buf_in:%x azt_buf_out:%x azt_buf_bn:%x\n", \
2019 azt_next_bn
, azt_buf_in
, azt_buf_out
, azt_buf_bn
[azt_buf_in
]);
2021 if (azt_read_mode
==AZT_MODE_2
)
2022 { sendAztCmd(ACMD_PLAY_READ_RAW
, &msf
); /*XA disks in raw mode*/
2025 { sendAztCmd(ACMD_PLAY_READ
, &msf
); /*others in cooked mode*/
2027 azt_state
= AZT_S_DATA
;
2028 AztTimeout
= READ_TIMEOUT
;
2030 azt_state
= AZT_S_STOP
;
2040 if (azt_state
!=azt_state_old
) {
2041 azt_state_old
=azt_state
;
2042 printk("AZT_S_DATA\n");
2046 st
= inb(STATUS_PORT
) & AFL_STATUSorDATA
;
2052 if (st
!=azt_st_old
) {
2054 printk("---AFL_DATA st:%x\n",st
);
2058 printk("aztcd: Read of Block %d Failed, Maybe Audio Disk ? Giving up\n", azt_next_bn
);
2059 if (azt_transfer_is_active
) {
2067 azt_state
= AZT_S_START
;
2068 AztTimeout
= READ_TIMEOUT
;
2072 case AFL_STATUSorDATA
:
2074 if (st
!=azt_st_old
) {
2076 printk("---AFL_STATUSorDATA st:%x\n",st
);
2083 if (st
!=azt_st_old
) {
2085 printk("---default: st:%x\n",st
);
2089 if (!CURRENT_VALID
&& azt_buf_in
== azt_buf_out
) {
2090 azt_state
= AZT_S_STOP
;
2094 if (azt_read_count
<=0)
2095 printk("aztcd: warning - try to read 0 frames\n");
2096 while (azt_read_count
) /*??? fast read ahead loop*/
2097 { azt_buf_bn
[azt_buf_in
] = -1;
2098 DTEN_LOW
; /*??? unsolved problem, very
2099 seldom we get timeouts
2100 here, don't now the real
2101 reason. With my drive this
2102 sometimes also happens with
2103 Aztech's original driver under
2104 DOS. Is it a hardware bug?
2105 I tried to recover from such
2106 situations here. Zimmermann*/
2107 if (aztTimeOutCount
>=AZT_TIMEOUT
)
2108 { printk("read_count:%d CURRENT->nr_sectors:%ld azt_buf_in:%d\n", azt_read_count
,CURRENT
->nr_sectors
,azt_buf_in
);
2109 printk("azt_transfer_is_active:%x\n",azt_transfer_is_active
);
2111 azt_state
= AZT_S_STOP
;
2113 end_request(1); /*should we have here (1) or (0)? */
2116 { if (azt_read_mode
==AZT_MODE_2
)
2117 { insb(DATA_PORT
, azt_buf
+ CD_FRAMESIZE_RAW
* azt_buf_in
, CD_FRAMESIZE_RAW
);
2120 { insb(DATA_PORT
, azt_buf
+ CD_FRAMESIZE
* azt_buf_in
, CD_FRAMESIZE
);
2124 printk("AZT_S_DATA; ---I've read data- read_count: %d\n",azt_read_count
);
2125 printk("azt_next_bn:%d azt_buf_in:%d azt_buf_out:%d azt_buf_bn:%d\n", \
2126 azt_next_bn
, azt_buf_in
, azt_buf_out
, azt_buf_bn
[azt_buf_in
]);
2128 azt_buf_bn
[azt_buf_in
] = azt_next_bn
++;
2129 if (azt_buf_out
== -1)
2130 azt_buf_out
= azt_buf_in
;
2131 azt_buf_in
= azt_buf_in
+ 1 == AZT_BUF_SIZ
? 0 : azt_buf_in
+ 1;
2134 if (!azt_transfer_is_active
) {
2135 while (CURRENT_VALID
) {
2137 if (CURRENT
-> nr_sectors
== 0)
2145 && (CURRENT
-> sector
/ 4 < azt_next_bn
||
2146 CURRENT
-> sector
/ 4 > azt_next_bn
+ AZT_BUF_SIZ
)) {
2147 azt_state
= AZT_S_STOP
;
2151 AztTimeout
= READ_TIMEOUT
;
2152 if (azt_read_count
==0) {
2153 azt_state
= AZT_S_STOP
;
2164 if (azt_state
!=azt_state_old
) {
2165 azt_state_old
=azt_state
;
2166 printk("AZT_S_STOP\n");
2169 if (azt_read_count
!=0) printk("aztcd: discard data=%x frames\n",azt_read_count
);
2170 while (azt_read_count
!=0) {
2172 if ( !(inb(STATUS_PORT
) & AFL_DATA
) ) {
2173 if (azt_read_mode
==AZT_MODE_2
)
2174 for (i
=0; i
<CD_FRAMESIZE_RAW
; i
++) inb(DATA_PORT
);
2176 for (i
=0; i
<CD_FRAMESIZE
; i
++) inb(DATA_PORT
);
2180 if (aztSendCmd(ACMD_GET_STATUS
)) RETURN("azt_poll 5");
2181 azt_state
= AZT_S_STOPPING
;
2185 case AZT_S_STOPPING
:
2187 if (azt_state
!=azt_state_old
) {
2188 azt_state_old
=azt_state
;
2189 printk("AZT_S_STOPPING\n");
2193 if ((st
= aztStatus()) == -1 && AztTimeout
)
2196 if ((st
!= -1) && ((st
& AST_DSK_CHG
)||(st
& AST_NOT_READY
))) {
2199 azt_invalidate_buffers();
2200 printk("aztcd: Disk Changed or Not Ready 4 - Unmount Disk!\n");
2206 printk("CURRENT_VALID %d azt_mode %d\n",
2207 CURRENT_VALID
, azt_mode
);
2210 if (CURRENT_VALID
) {
2212 if (azt_mode
== 1) {
2213 azt_state
= AZT_S_READ
;
2218 azt_state
= AZT_S_MODE
;
2224 azt_state
= AZT_S_START
;
2228 azt_state
= AZT_S_IDLE
;
2234 printk("aztcd: invalid state %d\n", azt_state
);
2241 { printk("aztcd: timeout in state %d\n", azt_state
);
2242 azt_state
= AZT_S_STOP
;
2243 if (aztSendCmd(ACMD_STOP
)) RETURN("azt_poll 6");
2247 SET_TIMER(azt_poll
, HZ
/100);
2251 /*###########################################################################
2252 * Miscellaneous support functions
2253 ###########################################################################
2255 static void azt_hsg2msf(long hsg
, struct msf
*msf
)
2257 msf
-> min
= hsg
/ 4500;
2259 msf
-> sec
= hsg
/ 75;
2260 msf
-> frame
= hsg
% 75;
2262 if (msf
->min
>=70) printk("aztcd: Error hsg2msf address Minutes\n");
2263 if (msf
->sec
>=60) printk("aztcd: Error hsg2msf address Seconds\n");
2264 if (msf
->frame
>=75) printk("aztcd: Error hsg2msf address Frames\n");
2266 azt_bin2bcd(&msf
-> min
); /* convert to BCD */
2267 azt_bin2bcd(&msf
-> sec
);
2268 azt_bin2bcd(&msf
-> frame
);
2271 static long azt_msf2hsg(struct msf
*mp
)
2272 { return azt_bcd2bin(mp
-> frame
) + azt_bcd2bin(mp
-> sec
) * 75
2273 + azt_bcd2bin(mp
-> min
) * 4500 - CD_MSF_OFFSET
;
2276 static void azt_bin2bcd(unsigned char *p
)
2284 static int azt_bcd2bin(unsigned char bcd
)
2285 { return (bcd
>> 4) * 10 + (bcd
& 0xF);