1 #define AZT_VERSION "2.60"
2
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
5
6 Copyright (C) 1994-98 Werner Zimmermann(Werner.Zimmermann@fht-esslingen.de)
7
8 based on Mitsumi CDROM driver by Martin Hariss and preworks by
9 Eberhard Moenkeberg; contains contributions by Joe Nardone and Robby
10 Schirmer.
11
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)
15 any later version.
16
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.
21
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.
25
26 HISTORY
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
36 it works
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
47 kernel panic.
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
60 azt.h
61 Speeded up drive recognition during init (will be a little bit
62 slower than before if no drive is installed!); suggested by
63 Robby Schirmer.
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
73 Robby Schirmer.
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
91 delay.h)
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
97 the new timer scheme.
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
104 Frank Racis
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.
110 (still experimental)
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-
125 tection.
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
145 tracks.
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
161
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>
166 */
167
168 #include <linux/version.h>
169
170 #define MAJOR_NR AZTECH_CDROM_MAJOR
171
172 #include <linux/blk.h>
173 #include "aztcd.h"
174
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>
187
188 #include <linux/init.h>
189
190 #include <asm/system.h>
191 #include <asm/io.h>
192
193 #include <asm/uaccess.h>
194 static int aztcd_blocksizes[1] = { 2048 };
195
196
197 /*###########################################################################
198 Defines
199 ###########################################################################
200 */
201 #define SET_TIMER(func, jifs) delay_timer.expires = jiffies + (jifs); \
202 delay_timer.function = (void *) (func); \
203 add_timer(&delay_timer);
204
205 #define CLEAR_TIMER del_timer(&delay_timer);
206
207 #define RETURNM(message,value) {printk("aztcd: Warning: %s failed\n",message);\
208 return value;}
209 #define RETURN(message) {printk("aztcd: Warning: %s failed\n",message);\
210 return;}
211
212 /* Macros to switch the IDE-interface to the slave device and back to the master*/
213 #define SWITCH_IDE_SLAVE outb_p(0xa0,azt_port+6); \
214 outb_p(0x10,azt_port+6); \
215 outb_p(0x00,azt_port+7); \
216 outb_p(0x10,azt_port+6);
217 #define SWITCH_IDE_MASTER outb_p(0xa0,azt_port+6);
218
219
220 #if 0
221 #define AZT_TEST
222 #define AZT_TEST1 /* <int-..> */
223 #define AZT_TEST2 /* do_aztcd_request */
224 #define AZT_TEST3 /* AZT_S_state */
225 #define AZT_TEST4 /* QUICK_LOOP-counter */
226 #define AZT_TEST5 /* port(1) state */
227 #define AZT_DEBUG
228 #define AZT_DEBUG_MULTISESSION
229 #endif
230
231 #define CURRENT_VALID \
232 (!QUEUE_EMPTY && MAJOR(CURRENT -> rq_dev) == MAJOR_NR && CURRENT -> cmd == READ \
233 && CURRENT -> sector != -1)
234
235 #define AFL_STATUSorDATA (AFL_STATUS | AFL_DATA)
236 #define AZT_BUF_SIZ 16
237
238 #define READ_TIMEOUT 3000
239
240 #define azt_port aztcd /*needed for the modutils */
241
242 /*##########################################################################
243 Type Definitions
244 ##########################################################################
245 */
246 enum azt_state_e { AZT_S_IDLE, /* 0 */
247 AZT_S_START, /* 1 */
248 AZT_S_MODE, /* 2 */
249 AZT_S_READ, /* 3 */
250 AZT_S_DATA, /* 4 */
251 AZT_S_STOP, /* 5 */
252 AZT_S_STOPPING /* 6 */
253 };
254 enum azt_read_modes { AZT_MODE_0, /*read mode for audio disks, not supported by Aztech firmware */
255 AZT_MODE_1, /*read mode for normal CD-ROMs */
256 AZT_MODE_2 /*read mode for XA CD-ROMs */
257 };
258
259 /*##########################################################################
260 Global Variables
261 ##########################################################################
262 */
263 static int aztPresent = 0;
264
265 static volatile int azt_transfer_is_active = 0;
266
267 static char azt_buf[CD_FRAMESIZE_RAW * AZT_BUF_SIZ]; /*buffer for block size conversion */
268 #if AZT_PRIVATE_IOCTLS
269 static char buf[CD_FRAMESIZE_RAW]; /*separate buffer for the ioctls */
270 #endif
271
272 static volatile int azt_buf_bn[AZT_BUF_SIZ], azt_next_bn;
273 static volatile int azt_buf_in, azt_buf_out = -1;
274 static volatile int azt_error = 0;
275 static int azt_open_count = 0;
276 static volatile enum azt_state_e azt_state = AZT_S_IDLE;
277 #ifdef AZT_TEST3
278 static volatile enum azt_state_e azt_state_old = AZT_S_STOP;
279 static volatile int azt_st_old = 0;
280 #endif
281 static volatile enum azt_read_modes azt_read_mode = AZT_MODE_1;
282
283 static int azt_mode = -1;
284 static volatile int azt_read_count = 1;
285
286 static int azt_port = AZT_BASE_ADDR;
287
288 MODULE_PARM(azt_port, "i");
289
290 static int azt_port_auto[16] = AZT_BASE_AUTO;
291
292 static char azt_cont = 0;
293 static char azt_init_end = 0;
294 static char azt_auto_eject = AZT_AUTO_EJECT;
295
296 static int AztTimeout, AztTries;
297 static DECLARE_WAIT_QUEUE_HEAD(azt_waitq);
298 static struct timer_list delay_timer;
299
300 static struct azt_DiskInfo DiskInfo;
301 static struct azt_Toc Toc[MAX_TRACKS];
302 static struct azt_Play_msf azt_Play;
303
304 static int aztAudioStatus = CDROM_AUDIO_NO_STATUS;
305 static char aztDiskChanged = 1;
306 static char aztTocUpToDate = 0;
307
308 static unsigned char aztIndatum;
309 static unsigned long aztTimeOutCount;
310 static int aztCmd = 0;
311
312 /*###########################################################################
313 Function Prototypes
314 ###########################################################################
315 */
316 /* CDROM Drive Low Level I/O Functions */
317 void op_ok(void);
318 void pa_ok(void);
319 void sten_low(void);
320 void dten_low(void);
321 void statusAzt(void);
322 static void aztStatTimer(void);
323
324 /* CDROM Drive Command Functions */
325 static int aztSendCmd(int cmd);
326 static int sendAztCmd(int cmd, struct azt_Play_msf *params);
327 static int aztSeek(struct azt_Play_msf *params);
328 static int aztSetDiskType(int type);
329 static int aztStatus(void);
330 static int getAztStatus(void);
331 static int aztPlay(struct azt_Play_msf *arg);
332 static void aztCloseDoor(void);
333 static void aztLockDoor(void);
334 static void aztUnlockDoor(void);
335 static int aztGetValue(unsigned char *result);
336 static int aztGetQChannelInfo(struct azt_Toc *qp);
337 static int aztUpdateToc(void);
338 static int aztGetDiskInfo(void);
339 #if AZT_MULTISESSION
340 static int aztGetMultiDiskInfo(void);
341 #endif
342 static int aztGetToc(int multi);
343
344 /* Kernel Interface Functions */
345 static int check_aztcd_media_change(kdev_t full_dev);
346 static int aztcd_ioctl(struct inode *ip, struct file *fp, unsigned int cmd,
347 unsigned long arg);
348 static void azt_transfer(void);
349 static void do_aztcd_request(request_queue_t *);
350 static void azt_invalidate_buffers(void);
351 int aztcd_open(struct inode *ip, struct file *fp);
352
353 static int aztcd_release(struct inode *inode, struct file *file);
354
355 int aztcd_init(void);
356
357 static struct block_device_operations azt_fops = {
358 owner:THIS_MODULE,
359 open:aztcd_open,
360 release:aztcd_release,
361 ioctl:aztcd_ioctl,
362 check_media_change:check_aztcd_media_change,
363 };
364
365 /* Aztcd State Machine: Controls Drive Operating State */
366 static void azt_poll(void);
367
368 /* Miscellaneous support functions */
369 static void azt_hsg2msf(long hsg, struct msf *msf);
370 static long azt_msf2hsg(struct msf *mp);
371 static void azt_bin2bcd(unsigned char *p);
372 static int azt_bcd2bin(unsigned char bcd);
373
374 /*##########################################################################
375 CDROM Drive Low Level I/O Functions
376 ##########################################################################
377 */
378 /* Macros for the drive hardware interface handshake, these macros use
379 busy waiting */
380 /* Wait for OP_OK = drive answers with AFL_OP_OK after receiving a command*/
381 # define OP_OK op_ok()
op_ok(void)382 void op_ok(void)
383 {
384 aztTimeOutCount = 0;
385 do {
386 aztIndatum = inb(DATA_PORT);
387 aztTimeOutCount++;
388 if (aztTimeOutCount >= AZT_TIMEOUT) {
389 printk("aztcd: Error Wait OP_OK\n");
390 break;
391 }
392 } while (aztIndatum != AFL_OP_OK);
393 }
394
395 /* Wait for PA_OK = drive answers with AFL_PA_OK after receiving parameters*/
396 # define PA_OK pa_ok()
pa_ok(void)397 void pa_ok(void)
398 {
399 aztTimeOutCount = 0;
400 do {
401 aztIndatum = inb(DATA_PORT);
402 aztTimeOutCount++;
403 if (aztTimeOutCount >= AZT_TIMEOUT) {
404 printk("aztcd: Error Wait PA_OK\n");
405 break;
406 }
407 } while (aztIndatum != AFL_PA_OK);
408 }
409
410 /* Wait for STEN=Low = handshake signal 'AFL_.._OK available or command executed*/
411 # define STEN_LOW sten_low()
sten_low(void)412 void sten_low(void)
413 {
414 aztTimeOutCount = 0;
415 do {
416 aztIndatum = inb(STATUS_PORT);
417 aztTimeOutCount++;
418 if (aztTimeOutCount >= AZT_TIMEOUT) {
419 if (azt_init_end)
420 printk
421 ("aztcd: Error Wait STEN_LOW commands:%x\n",
422 aztCmd);
423 break;
424 }
425 } while (aztIndatum & AFL_STATUS);
426 }
427
428 /* Wait for DTEN=Low = handshake signal 'Data available'*/
429 # define DTEN_LOW dten_low()
dten_low(void)430 void dten_low(void)
431 {
432 aztTimeOutCount = 0;
433 do {
434 aztIndatum = inb(STATUS_PORT);
435 aztTimeOutCount++;
436 if (aztTimeOutCount >= AZT_TIMEOUT) {
437 printk("aztcd: Error Wait DTEN_OK\n");
438 break;
439 }
440 } while (aztIndatum & AFL_DATA);
441 }
442
443 /*
444 * Macro for timer wait on STEN=Low, should only be used for 'slow' commands;
445 * may cause kernel panic when used in the wrong place
446 */
447 #define STEN_LOW_WAIT statusAzt()
statusAzt(void)448 void statusAzt(void)
449 {
450 AztTimeout = AZT_STATUS_DELAY;
451 SET_TIMER(aztStatTimer, HZ / 100);
452 sleep_on(&azt_waitq);
453 if (AztTimeout <= 0)
454 printk("aztcd: Error Wait STEN_LOW_WAIT command:%x\n",
455 aztCmd);
456 return;
457 }
458
aztStatTimer(void)459 static void aztStatTimer(void)
460 {
461 if (!(inb(STATUS_PORT) & AFL_STATUS)) {
462 wake_up(&azt_waitq);
463 return;
464 }
465 AztTimeout--;
466 if (AztTimeout <= 0) {
467 wake_up(&azt_waitq);
468 printk("aztcd: Error aztStatTimer: Timeout\n");
469 return;
470 }
471 SET_TIMER(aztStatTimer, HZ / 100);
472 }
473
474 /*##########################################################################
475 CDROM Drive Command Functions
476 ##########################################################################
477 */
478 /*
479 * Send a single command, return -1 on error, else 0
480 */
aztSendCmd(int cmd)481 static int aztSendCmd(int cmd)
482 {
483 unsigned char data;
484 int retry;
485
486 #ifdef AZT_DEBUG
487 printk("aztcd: Executing command %x\n", cmd);
488 #endif
489
490 if ((azt_port == 0x1f0) || (azt_port == 0x170))
491 SWITCH_IDE_SLAVE; /*switch IDE interface to slave configuration */
492
493 aztCmd = cmd;
494 outb(POLLED, MODE_PORT);
495 do {
496 if (inb(STATUS_PORT) & AFL_STATUS)
497 break;
498 inb(DATA_PORT); /* if status left from last command, read and */
499 } while (1); /* discard it */
500 do {
501 if (inb(STATUS_PORT) & AFL_DATA)
502 break;
503 inb(DATA_PORT); /* if data left from last command, read and */
504 } while (1); /* discard it */
505 for (retry = 0; retry < AZT_RETRY_ATTEMPTS; retry++) {
506 outb((unsigned char) cmd, CMD_PORT);
507 STEN_LOW;
508 data = inb(DATA_PORT);
509 if (data == AFL_OP_OK) {
510 return 0;
511 } /*OP_OK? */
512 if (data == AFL_OP_ERR) {
513 STEN_LOW;
514 data = inb(DATA_PORT);
515 printk
516 ("### Error 1 aztcd: aztSendCmd %x Error Code %x\n",
517 cmd, data);
518 }
519 }
520 if (retry >= AZT_RETRY_ATTEMPTS) {
521 printk("### Error 2 aztcd: aztSendCmd %x \n", cmd);
522 azt_error = 0xA5;
523 }
524 RETURNM("aztSendCmd", -1);
525 }
526
527 /*
528 * Send a play or read command to the drive, return -1 on error, else 0
529 */
sendAztCmd(int cmd,struct azt_Play_msf * params)530 static int sendAztCmd(int cmd, struct azt_Play_msf *params)
531 {
532 unsigned char data;
533 int retry;
534
535 #ifdef AZT_DEBUG
536 printk("aztcd: play start=%02x:%02x:%02x end=%02x:%02x:%02x\n",
537 params->start.min, params->start.sec, params->start.frame,
538 params->end.min, params->end.sec, params->end.frame);
539 #endif
540 for (retry = 0; retry < AZT_RETRY_ATTEMPTS; retry++) {
541 aztSendCmd(cmd);
542 outb(params->start.min, CMD_PORT);
543 outb(params->start.sec, CMD_PORT);
544 outb(params->start.frame, CMD_PORT);
545 outb(params->end.min, CMD_PORT);
546 outb(params->end.sec, CMD_PORT);
547 outb(params->end.frame, CMD_PORT);
548 STEN_LOW;
549 data = inb(DATA_PORT);
550 if (data == AFL_PA_OK) {
551 return 0;
552 } /*PA_OK ? */
553 if (data == AFL_PA_ERR) {
554 STEN_LOW;
555 data = inb(DATA_PORT);
556 printk
557 ("### Error 1 aztcd: sendAztCmd %x Error Code %x\n",
558 cmd, data);
559 }
560 }
561 if (retry >= AZT_RETRY_ATTEMPTS) {
562 printk("### Error 2 aztcd: sendAztCmd %x\n ", cmd);
563 azt_error = 0xA5;
564 }
565 RETURNM("sendAztCmd", -1);
566 }
567
568 /*
569 * Send a seek command to the drive, return -1 on error, else 0
570 */
aztSeek(struct azt_Play_msf * params)571 static int aztSeek(struct azt_Play_msf *params)
572 {
573 unsigned char data;
574 int retry;
575
576 #ifdef AZT_DEBUG
577 printk("aztcd: aztSeek %02x:%02x:%02x\n",
578 params->start.min, params->start.sec, params->start.frame);
579 #endif
580 for (retry = 0; retry < AZT_RETRY_ATTEMPTS; retry++) {
581 aztSendCmd(ACMD_SEEK);
582 outb(params->start.min, CMD_PORT);
583 outb(params->start.sec, CMD_PORT);
584 outb(params->start.frame, CMD_PORT);
585 STEN_LOW;
586 data = inb(DATA_PORT);
587 if (data == AFL_PA_OK) {
588 return 0;
589 } /*PA_OK ? */
590 if (data == AFL_PA_ERR) {
591 STEN_LOW;
592 data = inb(DATA_PORT);
593 printk("### Error 1 aztcd: aztSeek\n");
594 }
595 }
596 if (retry >= AZT_RETRY_ATTEMPTS) {
597 printk("### Error 2 aztcd: aztSeek\n ");
598 azt_error = 0xA5;
599 }
600 RETURNM("aztSeek", -1);
601 }
602
603 /* Send a Set Disk Type command
604 does not seem to work with Aztech drives, behavior is completely indepen-
605 dent on which mode is set ???
606 */
aztSetDiskType(int type)607 static int aztSetDiskType(int type)
608 {
609 unsigned char data;
610 int retry;
611
612 #ifdef AZT_DEBUG
613 printk("aztcd: set disk type command: type= %i\n", type);
614 #endif
615 for (retry = 0; retry < AZT_RETRY_ATTEMPTS; retry++) {
616 aztSendCmd(ACMD_SET_DISK_TYPE);
617 outb(type, CMD_PORT);
618 STEN_LOW;
619 data = inb(DATA_PORT);
620 if (data == AFL_PA_OK) { /*PA_OK ? */
621 azt_read_mode = type;
622 return 0;
623 }
624 if (data == AFL_PA_ERR) {
625 STEN_LOW;
626 data = inb(DATA_PORT);
627 printk
628 ("### Error 1 aztcd: aztSetDiskType %x Error Code %x\n",
629 type, data);
630 }
631 }
632 if (retry >= AZT_RETRY_ATTEMPTS) {
633 printk("### Error 2 aztcd: aztSetDiskType %x\n ", type);
634 azt_error = 0xA5;
635 }
636 RETURNM("aztSetDiskType", -1);
637 }
638
639
640 /* used in azt_poll to poll the status, expects another program to issue a
641 * ACMD_GET_STATUS directly before
642 */
aztStatus(void)643 static int aztStatus(void)
644 {
645 int st;
646 /* int i;
647
648 i = inb(STATUS_PORT) & AFL_STATUS; is STEN=0? ???
649 if (!i)
650 */ STEN_LOW;
651 if (aztTimeOutCount < AZT_TIMEOUT) {
652 st = inb(DATA_PORT) & 0xFF;
653 return st;
654 } else
655 RETURNM("aztStatus", -1);
656 }
657
658 /*
659 * Get the drive status
660 */
getAztStatus(void)661 static int getAztStatus(void)
662 {
663 int st;
664
665 if (aztSendCmd(ACMD_GET_STATUS))
666 RETURNM("getAztStatus 1", -1);
667 STEN_LOW;
668 st = inb(DATA_PORT) & 0xFF;
669 #ifdef AZT_DEBUG
670 printk("aztcd: Status = %x\n", st);
671 #endif
672 if ((st == 0xFF) || (st & AST_CMD_CHECK)) {
673 printk
674 ("aztcd: AST_CMD_CHECK error or no status available\n");
675 return -1;
676 }
677
678 if (((st & AST_MODE_BITS) != AST_BUSY)
679 && (aztAudioStatus == CDROM_AUDIO_PLAY))
680 /* XXX might be an error? look at q-channel? */
681 aztAudioStatus = CDROM_AUDIO_COMPLETED;
682
683 if ((st & AST_DSK_CHG) || (st & AST_NOT_READY)) {
684 aztDiskChanged = 1;
685 aztTocUpToDate = 0;
686 aztAudioStatus = CDROM_AUDIO_NO_STATUS;
687 }
688 return st;
689 }
690
691
692 /*
693 * Send a 'Play' command and get the status. Use only from the top half.
694 */
aztPlay(struct azt_Play_msf * arg)695 static int aztPlay(struct azt_Play_msf *arg)
696 {
697 if (sendAztCmd(ACMD_PLAY_AUDIO, arg) < 0)
698 RETURNM("aztPlay", -1);
699 return 0;
700 }
701
702 /*
703 * Subroutines to automatically close the door (tray) and
704 * lock it closed when the cd is mounted. Leave the tray
705 * locking as an option
706 */
aztCloseDoor(void)707 static void aztCloseDoor(void)
708 {
709 aztSendCmd(ACMD_CLOSE);
710 STEN_LOW;
711 return;
712 }
713
aztLockDoor(void)714 static void aztLockDoor(void)
715 {
716 #if AZT_ALLOW_TRAY_LOCK
717 aztSendCmd(ACMD_LOCK);
718 STEN_LOW;
719 #endif
720 return;
721 }
722
aztUnlockDoor(void)723 static void aztUnlockDoor(void)
724 {
725 #if AZT_ALLOW_TRAY_LOCK
726 aztSendCmd(ACMD_UNLOCK);
727 STEN_LOW;
728 #endif
729 return;
730 }
731
732 /*
733 * Read a value from the drive. Should return quickly, so a busy wait
734 * is used to avoid excessive rescheduling. The read command itself must
735 * be issued with aztSendCmd() directly before
736 */
aztGetValue(unsigned char * result)737 static int aztGetValue(unsigned char *result)
738 {
739 int s;
740
741 STEN_LOW;
742 if (aztTimeOutCount >= AZT_TIMEOUT) {
743 printk("aztcd: aztGetValue timeout\n");
744 return -1;
745 }
746 s = inb(DATA_PORT) & 0xFF;
747 *result = (unsigned char) s;
748 return 0;
749 }
750
751 /*
752 * Read the current Q-channel info. Also used for reading the
753 * table of contents.
754 */
aztGetQChannelInfo(struct azt_Toc * qp)755 int aztGetQChannelInfo(struct azt_Toc *qp)
756 {
757 unsigned char notUsed;
758 int st;
759
760 #ifdef AZT_DEBUG
761 printk("aztcd: starting aztGetQChannelInfo Time:%li\n", jiffies);
762 #endif
763 if ((st = getAztStatus()) == -1)
764 RETURNM("aztGetQChannelInfo 1", -1);
765 if (aztSendCmd(ACMD_GET_Q_CHANNEL))
766 RETURNM("aztGetQChannelInfo 2", -1);
767 /*STEN_LOW_WAIT; ??? Dosemu0.60's cdrom.c does not like STEN_LOW_WAIT here */
768 if (aztGetValue(¬Used))
769 RETURNM("aztGetQChannelInfo 3", -1); /*??? Nullbyte einlesen */
770 if ((st & AST_MODE_BITS) == AST_INITIAL) {
771 qp->ctrl_addr = 0; /* when audio stop ACMD_GET_Q_CHANNEL returns */
772 qp->track = 0; /* only one byte with Aztech drives */
773 qp->pointIndex = 0;
774 qp->trackTime.min = 0;
775 qp->trackTime.sec = 0;
776 qp->trackTime.frame = 0;
777 qp->diskTime.min = 0;
778 qp->diskTime.sec = 0;
779 qp->diskTime.frame = 0;
780 return 0;
781 } else {
782 if (aztGetValue(&qp->ctrl_addr) < 0)
783 RETURNM("aztGetQChannelInfo 4", -1);
784 if (aztGetValue(&qp->track) < 0)
785 RETURNM("aztGetQChannelInfo 4", -1);
786 if (aztGetValue(&qp->pointIndex) < 0)
787 RETURNM("aztGetQChannelInfo 4", -1);
788 if (aztGetValue(&qp->trackTime.min) < 0)
789 RETURNM("aztGetQChannelInfo 4", -1);
790 if (aztGetValue(&qp->trackTime.sec) < 0)
791 RETURNM("aztGetQChannelInfo 4", -1);
792 if (aztGetValue(&qp->trackTime.frame) < 0)
793 RETURNM("aztGetQChannelInfo 4", -1);
794 if (aztGetValue(¬Used) < 0)
795 RETURNM("aztGetQChannelInfo 4", -1);
796 if (aztGetValue(&qp->diskTime.min) < 0)
797 RETURNM("aztGetQChannelInfo 4", -1);
798 if (aztGetValue(&qp->diskTime.sec) < 0)
799 RETURNM("aztGetQChannelInfo 4", -1);
800 if (aztGetValue(&qp->diskTime.frame) < 0)
801 RETURNM("aztGetQChannelInfo 4", -1);
802 }
803 #ifdef AZT_DEBUG
804 printk("aztcd: exiting aztGetQChannelInfo Time:%li\n", jiffies);
805 #endif
806 return 0;
807 }
808
809 /*
810 * Read the table of contents (TOC) and TOC header if necessary
811 */
aztUpdateToc()812 static int aztUpdateToc()
813 {
814 int st;
815
816 #ifdef AZT_DEBUG
817 printk("aztcd: starting aztUpdateToc Time:%li\n", jiffies);
818 #endif
819 if (aztTocUpToDate)
820 return 0;
821
822 if (aztGetDiskInfo() < 0)
823 return -EIO;
824
825 if (aztGetToc(0) < 0)
826 return -EIO;
827
828 /*audio disk detection
829 with my Aztech drive there is no audio status bit, so I use the copy
830 protection bit of the first track. If this track is copy protected
831 (copy bit = 0), I assume, it's an audio disk. Strange, but works ??? */
832 if (!(Toc[DiskInfo.first].ctrl_addr & 0x40))
833 DiskInfo.audio = 1;
834 else
835 DiskInfo.audio = 0;
836
837 /* XA detection */
838 if (!DiskInfo.audio) {
839 azt_Play.start.min = 0; /*XA detection only seems to work */
840 azt_Play.start.sec = 2; /*when we play a track */
841 azt_Play.start.frame = 0;
842 azt_Play.end.min = 0;
843 azt_Play.end.sec = 0;
844 azt_Play.end.frame = 1;
845 if (sendAztCmd(ACMD_PLAY_READ, &azt_Play))
846 return -1;
847 DTEN_LOW;
848 for (st = 0; st < CD_FRAMESIZE; st++)
849 inb(DATA_PORT);
850 }
851 DiskInfo.xa = getAztStatus() & AST_MODE;
852 if (DiskInfo.xa) {
853 printk
854 ("aztcd: XA support experimental - mail results to Werner.Zimmermann@fht-esslingen.de\n");
855 }
856
857 /*multisession detection
858 support for multisession CDs is done automatically with Aztech drives,
859 we don't have to take care about TOC redirection; if we want the isofs
860 to take care about redirection, we have to set AZT_MULTISESSION to 1 */
861 DiskInfo.multi = 0;
862 #if AZT_MULTISESSION
863 if (DiskInfo.xa) {
864 aztGetMultiDiskInfo(); /*here Disk.Info.multi is set */
865 }
866 #endif
867 if (DiskInfo.multi) {
868 DiskInfo.lastSession.min = Toc[DiskInfo.next].diskTime.min;
869 DiskInfo.lastSession.sec = Toc[DiskInfo.next].diskTime.sec;
870 DiskInfo.lastSession.frame =
871 Toc[DiskInfo.next].diskTime.frame;
872 printk("aztcd: Multisession support experimental\n");
873 } else {
874 DiskInfo.lastSession.min =
875 Toc[DiskInfo.first].diskTime.min;
876 DiskInfo.lastSession.sec =
877 Toc[DiskInfo.first].diskTime.sec;
878 DiskInfo.lastSession.frame =
879 Toc[DiskInfo.first].diskTime.frame;
880 }
881
882 aztTocUpToDate = 1;
883 #ifdef AZT_DEBUG
884 printk("aztcd: exiting aztUpdateToc Time:%li\n", jiffies);
885 #endif
886 return 0;
887 }
888
889
890 /* Read the table of contents header, i.e. no. of tracks and start of first
891 * track
892 */
aztGetDiskInfo()893 static int aztGetDiskInfo()
894 {
895 int limit;
896 unsigned char test;
897 struct azt_Toc qInfo;
898
899 #ifdef AZT_DEBUG
900 printk("aztcd: starting aztGetDiskInfo Time:%li\n", jiffies);
901 #endif
902 if (aztSendCmd(ACMD_SEEK_TO_LEADIN))
903 RETURNM("aztGetDiskInfo 1", -1);
904 STEN_LOW_WAIT;
905 test = 0;
906 for (limit = 300; limit > 0; limit--) {
907 if (aztGetQChannelInfo(&qInfo) < 0)
908 RETURNM("aztGetDiskInfo 2", -1);
909 if (qInfo.pointIndex == 0xA0) { /*Number of FirstTrack */
910 DiskInfo.first = qInfo.diskTime.min;
911 DiskInfo.first = azt_bcd2bin(DiskInfo.first);
912 test = test | 0x01;
913 }
914 if (qInfo.pointIndex == 0xA1) { /*Number of LastTrack */
915 DiskInfo.last = qInfo.diskTime.min;
916 DiskInfo.last = azt_bcd2bin(DiskInfo.last);
917 test = test | 0x02;
918 }
919 if (qInfo.pointIndex == 0xA2) { /*DiskLength */
920 DiskInfo.diskLength.min = qInfo.diskTime.min;
921 DiskInfo.diskLength.sec = qInfo.diskTime.sec;
922 DiskInfo.diskLength.frame = qInfo.diskTime.frame;
923 test = test | 0x04;
924 }
925 if ((qInfo.pointIndex == DiskInfo.first) && (test & 0x01)) { /*StartTime of First Track */
926 DiskInfo.firstTrack.min = qInfo.diskTime.min;
927 DiskInfo.firstTrack.sec = qInfo.diskTime.sec;
928 DiskInfo.firstTrack.frame = qInfo.diskTime.frame;
929 test = test | 0x08;
930 }
931 if (test == 0x0F)
932 break;
933 }
934 #ifdef AZT_DEBUG
935 printk("aztcd: exiting aztGetDiskInfo Time:%li\n", jiffies);
936 printk
937 ("Disk Info: first %d last %d length %02X:%02X.%02X dez first %02X:%02X.%02X dez\n",
938 DiskInfo.first, DiskInfo.last, DiskInfo.diskLength.min,
939 DiskInfo.diskLength.sec, DiskInfo.diskLength.frame,
940 DiskInfo.firstTrack.min, DiskInfo.firstTrack.sec,
941 DiskInfo.firstTrack.frame);
942 #endif
943 if (test != 0x0F)
944 return -1;
945 return 0;
946 }
947
948 #if AZT_MULTISESSION
949 /*
950 * Get Multisession Disk Info
951 */
aztGetMultiDiskInfo(void)952 static int aztGetMultiDiskInfo(void)
953 {
954 int limit, k = 5;
955 unsigned char test;
956 struct azt_Toc qInfo;
957
958 #ifdef AZT_DEBUG
959 printk("aztcd: starting aztGetMultiDiskInfo\n");
960 #endif
961
962 do {
963 azt_Play.start.min = Toc[DiskInfo.last + 1].diskTime.min;
964 azt_Play.start.sec = Toc[DiskInfo.last + 1].diskTime.sec;
965 azt_Play.start.frame =
966 Toc[DiskInfo.last + 1].diskTime.frame;
967 test = 0;
968
969 for (limit = 30; limit > 0; limit--) { /*Seek for LeadIn of next session */
970 if (aztSeek(&azt_Play))
971 RETURNM("aztGetMultiDiskInfo 1", -1);
972 if (aztGetQChannelInfo(&qInfo) < 0)
973 RETURNM("aztGetMultiDiskInfo 2", -1);
974 if ((qInfo.track == 0) && (qInfo.pointIndex))
975 break; /*LeadIn found */
976 if ((azt_Play.start.sec += 10) > 59) {
977 azt_Play.start.sec = 0;
978 azt_Play.start.min++;
979 }
980 }
981 if (!limit)
982 break; /*Check, if a leadin track was found, if not we're
983 at the end of the disk */
984 #ifdef AZT_DEBUG_MULTISESSION
985 printk("leadin found track %d pointIndex %x limit %d\n",
986 qInfo.track, qInfo.pointIndex, limit);
987 #endif
988 for (limit = 300; limit > 0; limit--) {
989 if (++azt_Play.start.frame > 74) {
990 azt_Play.start.frame = 0;
991 if (azt_Play.start.sec > 59) {
992 azt_Play.start.sec = 0;
993 azt_Play.start.min++;
994 }
995 }
996 if (aztSeek(&azt_Play))
997 RETURNM("aztGetMultiDiskInfo 3", -1);
998 if (aztGetQChannelInfo(&qInfo) < 0)
999 RETURNM("aztGetMultiDiskInfo 4", -1);
1000 if (qInfo.pointIndex == 0xA0) { /*Number of NextTrack */
1001 DiskInfo.next = qInfo.diskTime.min;
1002 DiskInfo.next = azt_bcd2bin(DiskInfo.next);
1003 test = test | 0x01;
1004 }
1005 if (qInfo.pointIndex == 0xA1) { /*Number of LastTrack */
1006 DiskInfo.last = qInfo.diskTime.min;
1007 DiskInfo.last = azt_bcd2bin(DiskInfo.last);
1008 test = test | 0x02;
1009 }
1010 if (qInfo.pointIndex == 0xA2) { /*DiskLength */
1011 DiskInfo.diskLength.min =
1012 qInfo.diskTime.min;
1013 DiskInfo.diskLength.sec =
1014 qInfo.diskTime.sec;
1015 DiskInfo.diskLength.frame =
1016 qInfo.diskTime.frame;
1017 test = test | 0x04;
1018 }
1019 if ((qInfo.pointIndex == DiskInfo.next) && (test & 0x01)) { /*StartTime of Next Track */
1020 DiskInfo.nextSession.min =
1021 qInfo.diskTime.min;
1022 DiskInfo.nextSession.sec =
1023 qInfo.diskTime.sec;
1024 DiskInfo.nextSession.frame =
1025 qInfo.diskTime.frame;
1026 test = test | 0x08;
1027 }
1028 if (test == 0x0F)
1029 break;
1030 }
1031 #ifdef AZT_DEBUG_MULTISESSION
1032 printk
1033 ("MultiDisk Info: first %d next %d last %d length %02x:%02x.%02x dez first %02x:%02x.%02x dez next %02x:%02x.%02x dez\n",
1034 DiskInfo.first, DiskInfo.next, DiskInfo.last,
1035 DiskInfo.diskLength.min, DiskInfo.diskLength.sec,
1036 DiskInfo.diskLength.frame, DiskInfo.firstTrack.min,
1037 DiskInfo.firstTrack.sec, DiskInfo.firstTrack.frame,
1038 DiskInfo.nextSession.min, DiskInfo.nextSession.sec,
1039 DiskInfo.nextSession.frame);
1040 #endif
1041 if (test != 0x0F)
1042 break;
1043 else
1044 DiskInfo.multi = 1; /*found TOC of more than one session */
1045 aztGetToc(1);
1046 } while (--k);
1047
1048 #ifdef AZT_DEBUG
1049 printk("aztcd: exiting aztGetMultiDiskInfo Time:%li\n", jiffies);
1050 #endif
1051 return 0;
1052 }
1053 #endif
1054
1055 /*
1056 * Read the table of contents (TOC)
1057 */
aztGetToc(int multi)1058 static int aztGetToc(int multi)
1059 {
1060 int i, px;
1061 int limit;
1062 struct azt_Toc qInfo;
1063
1064 #ifdef AZT_DEBUG
1065 printk("aztcd: starting aztGetToc Time:%li\n", jiffies);
1066 #endif
1067 if (!multi) {
1068 for (i = 0; i < MAX_TRACKS; i++)
1069 Toc[i].pointIndex = 0;
1070 i = DiskInfo.last + 3;
1071 } else {
1072 for (i = DiskInfo.next; i < MAX_TRACKS; i++)
1073 Toc[i].pointIndex = 0;
1074 i = DiskInfo.last + 4 - DiskInfo.next;
1075 }
1076
1077 /*Is there a good reason to stop motor before TOC read?
1078 if (aztSendCmd(ACMD_STOP)) RETURNM("aztGetToc 1",-1);
1079 STEN_LOW_WAIT;
1080 */
1081
1082 if (!multi) {
1083 azt_mode = 0x05;
1084 if (aztSendCmd(ACMD_SEEK_TO_LEADIN))
1085 RETURNM("aztGetToc 2", -1);
1086 STEN_LOW_WAIT;
1087 }
1088 for (limit = 300; limit > 0; limit--) {
1089 if (multi) {
1090 if (++azt_Play.start.sec > 59) {
1091 azt_Play.start.sec = 0;
1092 azt_Play.start.min++;
1093 }
1094 if (aztSeek(&azt_Play))
1095 RETURNM("aztGetToc 3", -1);
1096 }
1097 if (aztGetQChannelInfo(&qInfo) < 0)
1098 break;
1099
1100 px = azt_bcd2bin(qInfo.pointIndex);
1101
1102 if (px > 0 && px < MAX_TRACKS && qInfo.track == 0)
1103 if (Toc[px].pointIndex == 0) {
1104 Toc[px] = qInfo;
1105 i--;
1106 }
1107
1108 if (i <= 0)
1109 break;
1110 }
1111
1112 Toc[DiskInfo.last + 1].diskTime = DiskInfo.diskLength;
1113 Toc[DiskInfo.last].trackTime = DiskInfo.diskLength;
1114
1115 #ifdef AZT_DEBUG_MULTISESSION
1116 printk("aztcd: exiting aztGetToc\n");
1117 for (i = 1; i <= DiskInfo.last + 1; i++)
1118 printk
1119 ("i = %2d ctl-adr = %02X track %2d px %02X %02X:%02X.%02X dez %02X:%02X.%02X dez\n",
1120 i, Toc[i].ctrl_addr, Toc[i].track, Toc[i].pointIndex,
1121 Toc[i].trackTime.min, Toc[i].trackTime.sec,
1122 Toc[i].trackTime.frame, Toc[i].diskTime.min,
1123 Toc[i].diskTime.sec, Toc[i].diskTime.frame);
1124 for (i = 100; i < 103; i++)
1125 printk
1126 ("i = %2d ctl-adr = %02X track %2d px %02X %02X:%02X.%02X dez %02X:%02X.%02X dez\n",
1127 i, Toc[i].ctrl_addr, Toc[i].track, Toc[i].pointIndex,
1128 Toc[i].trackTime.min, Toc[i].trackTime.sec,
1129 Toc[i].trackTime.frame, Toc[i].diskTime.min,
1130 Toc[i].diskTime.sec, Toc[i].diskTime.frame);
1131 #endif
1132
1133 return limit > 0 ? 0 : -1;
1134 }
1135
1136
1137 /*##########################################################################
1138 Kernel Interface Functions
1139 ##########################################################################
1140 */
1141
1142 #ifndef MODULE
aztcd_setup(char * str)1143 static int __init aztcd_setup(char *str)
1144 {
1145 int ints[4];
1146
1147 (void) get_options(str, ARRAY_SIZE(ints), ints);
1148
1149 if (ints[0] > 0)
1150 azt_port = ints[1];
1151 if (ints[1] > 1)
1152 azt_cont = ints[2];
1153 return 1;
1154 }
1155
1156 __setup("aztcd=", aztcd_setup);
1157
1158 #endif /* !MODULE */
1159
1160 /*
1161 * Checking if the media has been changed
1162 */
check_aztcd_media_change(kdev_t full_dev)1163 static int check_aztcd_media_change(kdev_t full_dev)
1164 {
1165 if (aztDiskChanged) { /* disk changed */
1166 aztDiskChanged = 0;
1167 return 1;
1168 } else
1169 return 0; /* no change */
1170 }
1171
1172 /*
1173 * Kernel IO-controls
1174 */
aztcd_ioctl(struct inode * ip,struct file * fp,unsigned int cmd,unsigned long arg)1175 static int aztcd_ioctl(struct inode *ip, struct file *fp, unsigned int cmd,
1176 unsigned long arg)
1177 {
1178 int i;
1179 struct azt_Toc qInfo;
1180 struct cdrom_ti ti;
1181 struct cdrom_tochdr tocHdr;
1182 struct cdrom_msf msf;
1183 struct cdrom_tocentry entry;
1184 struct azt_Toc *tocPtr;
1185 struct cdrom_subchnl subchnl;
1186 struct cdrom_volctrl volctrl;
1187
1188 #ifdef AZT_DEBUG
1189 printk("aztcd: starting aztcd_ioctl - Command:%x Time: %li\n",
1190 cmd, jiffies);
1191 printk("aztcd Status %x\n", getAztStatus());
1192 #endif
1193 if (!ip)
1194 RETURNM("aztcd_ioctl 1", -EINVAL);
1195 if (getAztStatus() < 0)
1196 RETURNM("aztcd_ioctl 2", -EIO);
1197 if ((!aztTocUpToDate) || (aztDiskChanged)) {
1198 if ((i = aztUpdateToc()) < 0)
1199 RETURNM("aztcd_ioctl 3", i); /* error reading TOC */
1200 }
1201
1202 switch (cmd) {
1203 case CDROMSTART: /* Spin up the drive. Don't know, what to do,
1204 at least close the tray */
1205 #if AZT_PRIVATE_IOCTLS
1206 if (aztSendCmd(ACMD_CLOSE))
1207 RETURNM("aztcd_ioctl 4", -1);
1208 STEN_LOW_WAIT;
1209 #endif
1210 break;
1211 case CDROMSTOP: /* Spin down the drive */
1212 if (aztSendCmd(ACMD_STOP))
1213 RETURNM("aztcd_ioctl 5", -1);
1214 STEN_LOW_WAIT;
1215 /* should we do anything if it fails? */
1216 aztAudioStatus = CDROM_AUDIO_NO_STATUS;
1217 break;
1218 case CDROMPAUSE: /* Pause the drive */
1219 if (aztAudioStatus != CDROM_AUDIO_PLAY)
1220 return -EINVAL;
1221
1222 if (aztGetQChannelInfo(&qInfo) < 0) { /* didn't get q channel info */
1223 aztAudioStatus = CDROM_AUDIO_NO_STATUS;
1224 RETURNM("aztcd_ioctl 7", 0);
1225 }
1226 azt_Play.start = qInfo.diskTime; /* remember restart point */
1227
1228 if (aztSendCmd(ACMD_PAUSE))
1229 RETURNM("aztcd_ioctl 8", -1);
1230 STEN_LOW_WAIT;
1231 aztAudioStatus = CDROM_AUDIO_PAUSED;
1232 break;
1233 case CDROMRESUME: /* Play it again, Sam */
1234 if (aztAudioStatus != CDROM_AUDIO_PAUSED)
1235 return -EINVAL;
1236 /* restart the drive at the saved position. */
1237 i = aztPlay(&azt_Play);
1238 if (i < 0) {
1239 aztAudioStatus = CDROM_AUDIO_ERROR;
1240 return -EIO;
1241 }
1242 aztAudioStatus = CDROM_AUDIO_PLAY;
1243 break;
1244 case CDROMMULTISESSION: /*multisession support -- experimental */
1245 {
1246 struct cdrom_multisession ms;
1247 #ifdef AZT_DEBUG
1248 printk("aztcd ioctl MULTISESSION\n");
1249 #endif
1250 if (copy_from_user
1251 (&ms, (void *) arg,
1252 sizeof(struct cdrom_multisession)))
1253 return -EFAULT;
1254 if (ms.addr_format == CDROM_MSF) {
1255 ms.addr.msf.minute =
1256 azt_bcd2bin(DiskInfo.lastSession.min);
1257 ms.addr.msf.second =
1258 azt_bcd2bin(DiskInfo.lastSession.sec);
1259 ms.addr.msf.frame =
1260 azt_bcd2bin(DiskInfo.lastSession.
1261 frame);
1262 } else if (ms.addr_format == CDROM_LBA)
1263 ms.addr.lba =
1264 azt_msf2hsg(&DiskInfo.lastSession);
1265 else
1266 return -EINVAL;
1267 ms.xa_flag = DiskInfo.xa;
1268 if (copy_to_user
1269 ((void *) arg, &ms,
1270 sizeof(struct cdrom_multisession)))
1271 return -EFAULT;
1272 #ifdef AZT_DEBUG
1273 if (ms.addr_format == CDROM_MSF)
1274 printk
1275 ("aztcd multisession xa:%d, msf:%02x:%02x.%02x [%02x:%02x.%02x])\n",
1276 ms.xa_flag, ms.addr.msf.minute,
1277 ms.addr.msf.second, ms.addr.msf.frame,
1278 DiskInfo.lastSession.min,
1279 DiskInfo.lastSession.sec,
1280 DiskInfo.lastSession.frame);
1281 else
1282 printk
1283 ("aztcd multisession %d, lba:0x%08x [%02x:%02x.%02x])\n",
1284 ms.xa_flag, ms.addr.lba,
1285 DiskInfo.lastSession.min,
1286 DiskInfo.lastSession.sec,
1287 DiskInfo.lastSession.frame);
1288 #endif
1289 return 0;
1290 }
1291 case CDROMPLAYTRKIND: /* Play a track. This currently ignores index. */
1292 if (copy_from_user(&ti, (void *) arg, sizeof ti))
1293 return -EFAULT;
1294 if (ti.cdti_trk0 < DiskInfo.first
1295 || ti.cdti_trk0 > DiskInfo.last
1296 || ti.cdti_trk1 < ti.cdti_trk0) {
1297 return -EINVAL;
1298 }
1299 if (ti.cdti_trk1 > DiskInfo.last)
1300 ti.cdti_trk1 = DiskInfo.last;
1301 azt_Play.start = Toc[ti.cdti_trk0].diskTime;
1302 azt_Play.end = Toc[ti.cdti_trk1 + 1].diskTime;
1303 #ifdef AZT_DEBUG
1304 printk("aztcd play: %02x:%02x.%02x to %02x:%02x.%02x\n",
1305 azt_Play.start.min, azt_Play.start.sec,
1306 azt_Play.start.frame, azt_Play.end.min,
1307 azt_Play.end.sec, azt_Play.end.frame);
1308 #endif
1309 i = aztPlay(&azt_Play);
1310 if (i < 0) {
1311 aztAudioStatus = CDROM_AUDIO_ERROR;
1312 return -EIO;
1313 }
1314 aztAudioStatus = CDROM_AUDIO_PLAY;
1315 break;
1316 case CDROMPLAYMSF: /* Play starting at the given MSF address. */
1317 /* if (aztAudioStatus == CDROM_AUDIO_PLAY)
1318 { if (aztSendCmd(ACMD_STOP)) RETURNM("aztcd_ioctl 9",-1);
1319 STEN_LOW;
1320 aztAudioStatus = CDROM_AUDIO_NO_STATUS;
1321 }
1322 */
1323 if (copy_from_user(&msf, (void *) arg, sizeof msf))
1324 return -EFAULT;
1325 /* convert to bcd */
1326 azt_bin2bcd(&msf.cdmsf_min0);
1327 azt_bin2bcd(&msf.cdmsf_sec0);
1328 azt_bin2bcd(&msf.cdmsf_frame0);
1329 azt_bin2bcd(&msf.cdmsf_min1);
1330 azt_bin2bcd(&msf.cdmsf_sec1);
1331 azt_bin2bcd(&msf.cdmsf_frame1);
1332 azt_Play.start.min = msf.cdmsf_min0;
1333 azt_Play.start.sec = msf.cdmsf_sec0;
1334 azt_Play.start.frame = msf.cdmsf_frame0;
1335 azt_Play.end.min = msf.cdmsf_min1;
1336 azt_Play.end.sec = msf.cdmsf_sec1;
1337 azt_Play.end.frame = msf.cdmsf_frame1;
1338 #ifdef AZT_DEBUG
1339 printk("aztcd play: %02x:%02x.%02x to %02x:%02x.%02x\n",
1340 azt_Play.start.min, azt_Play.start.sec,
1341 azt_Play.start.frame, azt_Play.end.min,
1342 azt_Play.end.sec, azt_Play.end.frame);
1343 #endif
1344 i = aztPlay(&azt_Play);
1345 if (i < 0) {
1346 aztAudioStatus = CDROM_AUDIO_ERROR;
1347 return -EIO;
1348 }
1349 aztAudioStatus = CDROM_AUDIO_PLAY;
1350 break;
1351
1352 case CDROMREADTOCHDR: /* Read the table of contents header */
1353 tocHdr.cdth_trk0 = DiskInfo.first;
1354 tocHdr.cdth_trk1 = DiskInfo.last;
1355 if (copy_to_user((void *) arg, &tocHdr, sizeof tocHdr))
1356 return -EFAULT;
1357 break;
1358 case CDROMREADTOCENTRY: /* Read an entry in the table of contents */
1359 if (copy_from_user(&entry, (void *) arg, sizeof entry))
1360 return -EFAULT;
1361 if ((!aztTocUpToDate) || aztDiskChanged)
1362 aztUpdateToc();
1363 if (entry.cdte_track == CDROM_LEADOUT)
1364 tocPtr = &Toc[DiskInfo.last + 1];
1365 else if (entry.cdte_track > DiskInfo.last
1366 || entry.cdte_track < DiskInfo.first) {
1367 return -EINVAL;
1368 } else
1369 tocPtr = &Toc[entry.cdte_track];
1370 entry.cdte_adr = tocPtr->ctrl_addr;
1371 entry.cdte_ctrl = tocPtr->ctrl_addr >> 4;
1372 if (entry.cdte_format == CDROM_LBA)
1373 entry.cdte_addr.lba =
1374 azt_msf2hsg(&tocPtr->diskTime);
1375 else if (entry.cdte_format == CDROM_MSF) {
1376 entry.cdte_addr.msf.minute =
1377 azt_bcd2bin(tocPtr->diskTime.min);
1378 entry.cdte_addr.msf.second =
1379 azt_bcd2bin(tocPtr->diskTime.sec);
1380 entry.cdte_addr.msf.frame =
1381 azt_bcd2bin(tocPtr->diskTime.frame);
1382 } else {
1383 return -EINVAL;
1384 }
1385 if (copy_to_user((void *) arg, &entry, sizeof entry))
1386 return -EFAULT;
1387 break;
1388 case CDROMSUBCHNL: /* Get subchannel info */
1389 if (copy_from_user
1390 (&subchnl, (void *) arg, sizeof(struct cdrom_subchnl)))
1391 return -EFAULT;
1392 if (aztGetQChannelInfo(&qInfo) < 0) {
1393 #ifdef AZT_DEBUG
1394 printk
1395 ("aztcd: exiting aztcd_ioctl - Error 3 - Command:%x\n",
1396 cmd);
1397 #endif
1398 return -EIO;
1399 }
1400 subchnl.cdsc_audiostatus = aztAudioStatus;
1401 subchnl.cdsc_adr = qInfo.ctrl_addr;
1402 subchnl.cdsc_ctrl = qInfo.ctrl_addr >> 4;
1403 subchnl.cdsc_trk = azt_bcd2bin(qInfo.track);
1404 subchnl.cdsc_ind = azt_bcd2bin(qInfo.pointIndex);
1405 if (subchnl.cdsc_format == CDROM_LBA) {
1406 subchnl.cdsc_absaddr.lba =
1407 azt_msf2hsg(&qInfo.diskTime);
1408 subchnl.cdsc_reladdr.lba =
1409 azt_msf2hsg(&qInfo.trackTime);
1410 } else { /*default */
1411 subchnl.cdsc_format = CDROM_MSF;
1412 subchnl.cdsc_absaddr.msf.minute =
1413 azt_bcd2bin(qInfo.diskTime.min);
1414 subchnl.cdsc_absaddr.msf.second =
1415 azt_bcd2bin(qInfo.diskTime.sec);
1416 subchnl.cdsc_absaddr.msf.frame =
1417 azt_bcd2bin(qInfo.diskTime.frame);
1418 subchnl.cdsc_reladdr.msf.minute =
1419 azt_bcd2bin(qInfo.trackTime.min);
1420 subchnl.cdsc_reladdr.msf.second =
1421 azt_bcd2bin(qInfo.trackTime.sec);
1422 subchnl.cdsc_reladdr.msf.frame =
1423 azt_bcd2bin(qInfo.trackTime.frame);
1424 }
1425 if (copy_to_user
1426 ((void *) arg, &subchnl, sizeof(struct cdrom_subchnl)))
1427 return -EFAULT;
1428 break;
1429 case CDROMVOLCTRL: /* Volume control
1430 * With my Aztech CD268-01A volume control does not work, I can only
1431 turn the channels on (any value !=0) or off (value==0). Maybe it
1432 works better with your drive */
1433 if (copy_from_user
1434 (&volctrl, (char *) arg, sizeof(volctrl)))
1435 return -EFAULT;
1436 azt_Play.start.min = 0x21;
1437 azt_Play.start.sec = 0x84;
1438 azt_Play.start.frame = volctrl.channel0;
1439 azt_Play.end.min = volctrl.channel1;
1440 azt_Play.end.sec = volctrl.channel2;
1441 azt_Play.end.frame = volctrl.channel3;
1442 sendAztCmd(ACMD_SET_VOLUME, &azt_Play);
1443 STEN_LOW_WAIT;
1444 break;
1445 case CDROMEJECT:
1446 aztUnlockDoor(); /* Assume user knows what they're doing */
1447 /* all drives can at least stop! */
1448 if (aztAudioStatus == CDROM_AUDIO_PLAY) {
1449 if (aztSendCmd(ACMD_STOP))
1450 RETURNM("azt_ioctl 10", -1);
1451 STEN_LOW_WAIT;
1452 }
1453 if (aztSendCmd(ACMD_EJECT))
1454 RETURNM("azt_ioctl 11", -1);
1455 STEN_LOW_WAIT;
1456 aztAudioStatus = CDROM_AUDIO_NO_STATUS;
1457 break;
1458 case CDROMEJECT_SW:
1459 azt_auto_eject = (char) arg;
1460 break;
1461 case CDROMRESET:
1462 outb(ACMD_SOFT_RESET, CMD_PORT); /*send reset */
1463 STEN_LOW;
1464 if (inb(DATA_PORT) != AFL_OP_OK) { /*OP_OK? */
1465 printk
1466 ("aztcd: AZTECH CD-ROM drive does not respond\n");
1467 }
1468 break;
1469 /*Take care, the following code is not compatible with other CD-ROM drivers,
1470 use it at your own risk with cdplay.c. Set AZT_PRIVATE_IOCTLS to 0 in aztcd.h,
1471 if you do not want to use it!
1472 */
1473 #if AZT_PRIVATE_IOCTLS
1474 case CDROMREADCOOKED: /*read data in mode 1 (2048 Bytes) */
1475 case CDROMREADRAW: /*read data in mode 2 (2336 Bytes) */
1476 {
1477 if (copy_from_user(&msf, (void *) arg, sizeof msf))
1478 return -EFAULT;
1479 /* convert to bcd */
1480 azt_bin2bcd(&msf.cdmsf_min0);
1481 azt_bin2bcd(&msf.cdmsf_sec0);
1482 azt_bin2bcd(&msf.cdmsf_frame0);
1483 msf.cdmsf_min1 = 0;
1484 msf.cdmsf_sec1 = 0;
1485 msf.cdmsf_frame1 = 1; /*read only one frame */
1486 azt_Play.start.min = msf.cdmsf_min0;
1487 azt_Play.start.sec = msf.cdmsf_sec0;
1488 azt_Play.start.frame = msf.cdmsf_frame0;
1489 azt_Play.end.min = msf.cdmsf_min1;
1490 azt_Play.end.sec = msf.cdmsf_sec1;
1491 azt_Play.end.frame = msf.cdmsf_frame1;
1492 if (cmd == CDROMREADRAW) {
1493 if (DiskInfo.xa) {
1494 return -1; /*XA Disks can't be read raw */
1495 } else {
1496 if (sendAztCmd
1497 (ACMD_PLAY_READ_RAW,
1498 &azt_Play))
1499 return -1;
1500 DTEN_LOW;
1501 insb(DATA_PORT, buf,
1502 CD_FRAMESIZE_RAW);
1503 if (copy_to_user
1504 ((void *) arg, &buf,
1505 CD_FRAMESIZE_RAW))
1506 return -EFAULT;
1507 }
1508 } else
1509 /*CDROMREADCOOKED*/ {
1510 if (sendAztCmd(ACMD_PLAY_READ, &azt_Play))
1511 return -1;
1512 DTEN_LOW;
1513 insb(DATA_PORT, buf, CD_FRAMESIZE);
1514 if (copy_to_user
1515 ((void *) arg, &buf, CD_FRAMESIZE))
1516 return -EFAULT;
1517 }
1518 }
1519 break;
1520 case CDROMSEEK: /*seek msf address */
1521 if (copy_from_user(&msf, (void *) arg, sizeof msf))
1522 return -EFAULT;
1523 /* convert to bcd */
1524 azt_bin2bcd(&msf.cdmsf_min0);
1525 azt_bin2bcd(&msf.cdmsf_sec0);
1526 azt_bin2bcd(&msf.cdmsf_frame0);
1527 azt_Play.start.min = msf.cdmsf_min0;
1528 azt_Play.start.sec = msf.cdmsf_sec0;
1529 azt_Play.start.frame = msf.cdmsf_frame0;
1530 if (aztSeek(&azt_Play))
1531 return -1;
1532 break;
1533 #endif /*end of incompatible code */
1534 case CDROMREADMODE1: /*set read data in mode 1 */
1535 return aztSetDiskType(AZT_MODE_1);
1536 case CDROMREADMODE2: /*set read data in mode 2 */
1537 return aztSetDiskType(AZT_MODE_2);
1538 default:
1539 return -EINVAL;
1540 }
1541 #ifdef AZT_DEBUG
1542 printk("aztcd: exiting aztcd_ioctl Command:%x Time:%li\n", cmd,
1543 jiffies);
1544 #endif
1545 return 0;
1546 }
1547
1548 /*
1549 * Take care of the different block sizes between cdrom and Linux.
1550 * When Linux gets variable block sizes this will probably go away.
1551 */
azt_transfer(void)1552 static void azt_transfer(void)
1553 {
1554 #ifdef AZT_TEST
1555 printk("aztcd: executing azt_transfer Time:%li\n", jiffies);
1556 #endif
1557 if (CURRENT_VALID) {
1558 while (CURRENT->nr_sectors) {
1559 int bn = CURRENT->sector / 4;
1560 int i;
1561 for (i = 0; i < AZT_BUF_SIZ && azt_buf_bn[i] != bn;
1562 ++i);
1563 if (i < AZT_BUF_SIZ) {
1564 int offs =
1565 (i * 4 + (CURRENT->sector & 3)) * 512;
1566 int nr_sectors = 4 - (CURRENT->sector & 3);
1567 if (azt_buf_out != i) {
1568 azt_buf_out = i;
1569 if (azt_buf_bn[i] != bn) {
1570 azt_buf_out = -1;
1571 continue;
1572 }
1573 }
1574 if (nr_sectors > CURRENT->nr_sectors)
1575 nr_sectors = CURRENT->nr_sectors;
1576 memcpy(CURRENT->buffer, azt_buf + offs,
1577 nr_sectors * 512);
1578 CURRENT->nr_sectors -= nr_sectors;
1579 CURRENT->sector += nr_sectors;
1580 CURRENT->buffer += nr_sectors * 512;
1581 } else {
1582 azt_buf_out = -1;
1583 break;
1584 }
1585 }
1586 }
1587 }
1588
do_aztcd_request(request_queue_t * q)1589 static void do_aztcd_request(request_queue_t * q)
1590 {
1591 #ifdef AZT_TEST
1592 printk(" do_aztcd_request(%ld+%ld) Time:%li\n", CURRENT->sector,
1593 CURRENT->nr_sectors, jiffies);
1594 #endif
1595 if (DiskInfo.audio) {
1596 printk("aztcd: Error, tried to mount an Audio CD\n");
1597 end_request(0);
1598 return;
1599 }
1600 azt_transfer_is_active = 1;
1601 while (CURRENT_VALID) {
1602 if (CURRENT->bh) {
1603 if (!buffer_locked(CURRENT->bh))
1604 panic(DEVICE_NAME ": block not locked");
1605 }
1606 azt_transfer();
1607 if (CURRENT->nr_sectors == 0) {
1608 end_request(1);
1609 } else {
1610 azt_buf_out = -1; /* Want to read a block not in buffer */
1611 if (azt_state == AZT_S_IDLE) {
1612 if ((!aztTocUpToDate) || aztDiskChanged) {
1613 if (aztUpdateToc() < 0) {
1614 while (CURRENT_VALID)
1615 end_request(0);
1616 break;
1617 }
1618 }
1619 azt_state = AZT_S_START;
1620 AztTries = 5;
1621 SET_TIMER(azt_poll, HZ / 100);
1622 }
1623 break;
1624 }
1625 }
1626 azt_transfer_is_active = 0;
1627 #ifdef AZT_TEST2
1628 printk
1629 ("azt_next_bn:%x azt_buf_in:%x azt_buf_out:%x azt_buf_bn:%x\n",
1630 azt_next_bn, azt_buf_in, azt_buf_out, azt_buf_bn[azt_buf_in]);
1631 printk(" do_aztcd_request ends Time:%li\n", jiffies);
1632 #endif
1633 }
1634
1635
azt_invalidate_buffers(void)1636 static void azt_invalidate_buffers(void)
1637 {
1638 int i;
1639
1640 #ifdef AZT_DEBUG
1641 printk("aztcd: executing azt_invalidate_buffers\n");
1642 #endif
1643 for (i = 0; i < AZT_BUF_SIZ; ++i)
1644 azt_buf_bn[i] = -1;
1645 azt_buf_out = -1;
1646 }
1647
1648 /*
1649 * Open the device special file. Check that a disk is in.
1650 */
aztcd_open(struct inode * ip,struct file * fp)1651 int aztcd_open(struct inode *ip, struct file *fp)
1652 {
1653 int st;
1654
1655 #ifdef AZT_DEBUG
1656 printk("aztcd: starting aztcd_open\n");
1657 #endif
1658
1659 if (aztPresent == 0)
1660 return -ENXIO; /* no hardware */
1661
1662 if (!azt_open_count && azt_state == AZT_S_IDLE) {
1663 azt_invalidate_buffers();
1664
1665 st = getAztStatus(); /* check drive status */
1666 if (st == -1)
1667 goto err_out; /* drive doesn't respond */
1668
1669 if (st & AST_DOOR_OPEN) { /* close door, then get the status again. */
1670 printk("aztcd: Door Open?\n");
1671 aztCloseDoor();
1672 st = getAztStatus();
1673 }
1674
1675 if ((st & AST_NOT_READY) || (st & AST_DSK_CHG)) { /*no disk in drive or changed */
1676 printk
1677 ("aztcd: Disk Changed or No Disk in Drive?\n");
1678 aztTocUpToDate = 0;
1679 }
1680 if (aztUpdateToc())
1681 goto err_out;
1682
1683 }
1684 ++azt_open_count;
1685 aztLockDoor();
1686
1687 #ifdef AZT_DEBUG
1688 printk("aztcd: exiting aztcd_open\n");
1689 #endif
1690 return 0;
1691
1692 err_out:
1693 return -EIO;
1694 }
1695
1696
1697 /*
1698 * On close, we flush all azt blocks from the buffer cache.
1699 */
aztcd_release(struct inode * inode,struct file * file)1700 static int aztcd_release(struct inode *inode, struct file *file)
1701 {
1702 #ifdef AZT_DEBUG
1703 printk("aztcd: executing aztcd_release\n");
1704 printk("inode: %p, inode->i_rdev: %x file: %p\n", inode,
1705 inode->i_rdev, file);
1706 #endif
1707 if (!--azt_open_count) {
1708 azt_invalidate_buffers();
1709 aztUnlockDoor();
1710 if (azt_auto_eject)
1711 aztSendCmd(ACMD_EJECT);
1712 CLEAR_TIMER;
1713 }
1714 return 0;
1715 }
1716
1717
1718
1719 /*
1720 * Test for presence of drive and initialize it. Called at boot time.
1721 */
1722
aztcd_init(void)1723 int __init aztcd_init(void)
1724 {
1725 long int count, max_count;
1726 unsigned char result[50];
1727 int st;
1728 int i = 0;
1729
1730 if (azt_port == 0) {
1731 printk("aztcd: no Aztech CD-ROM Initialization");
1732 return -EIO;
1733 }
1734
1735 printk
1736 ("aztcd: AZTECH, ORCHID, OKANO, WEARNES, TXC, CyDROM CD-ROM Driver\n");
1737 printk("aztcd: (C) 1994-98 W.Zimmermann\n");
1738 if (azt_port == -1) {
1739 printk
1740 ("aztcd: KernelVersion=%s DriverVersion=%s For IDE/ATAPI-drives use ide-cd.c\n",
1741 UTS_RELEASE, AZT_VERSION);
1742 } else
1743 printk
1744 ("aztcd: DriverVersion=%s BaseAddress=0x%x For IDE/ATAPI-drives use ide-cd.c\n",
1745 AZT_VERSION, azt_port);
1746 printk
1747 ("aztcd: If you have problems, read /usr/src/linux/Documentation/cdrom/aztcd\n");
1748
1749
1750 #ifdef AZT_SW32 /*CDROM connected to Soundwave32 card */
1751 if ((0xFF00 & inw(AZT_SW32_ID_REG)) != 0x4500) {
1752 printk
1753 ("aztcd: no Soundwave32 card detected at base:%x init:%x config:%x id:%x\n",
1754 AZT_SW32_BASE_ADDR, AZT_SW32_INIT,
1755 AZT_SW32_CONFIG_REG, AZT_SW32_ID_REG);
1756 return -EIO;
1757 } else {
1758 printk(KERN_INFO
1759 "aztcd: Soundwave32 card detected at %x Version %x\n",
1760 AZT_SW32_BASE_ADDR, inw(AZT_SW32_ID_REG));
1761 outw(AZT_SW32_INIT, AZT_SW32_CONFIG_REG);
1762 for (count = 0; count < 10000; count++); /*delay a bit */
1763 }
1764 #endif
1765
1766 /* check for presence of drive */
1767
1768 if (azt_port == -1) { /* autoprobing */
1769 for (i = 0; (azt_port_auto[i] != 0) && (i < 16); i++) {
1770 azt_port = azt_port_auto[i];
1771 printk("aztcd: Autoprobing BaseAddress=0x%x \n",
1772 azt_port);
1773 st = check_region(azt_port, 4); /*proprietary interfaces need 4 bytes */
1774 if (st)
1775 continue;
1776
1777 outb(POLLED, MODE_PORT);
1778 inb(CMD_PORT);
1779 inb(CMD_PORT);
1780 outb(ACMD_GET_VERSION, CMD_PORT); /*Try to get version info */
1781
1782 aztTimeOutCount = 0;
1783 do {
1784 aztIndatum = inb(STATUS_PORT);
1785 aztTimeOutCount++;
1786 if (aztTimeOutCount >= AZT_FAST_TIMEOUT)
1787 break;
1788 } while (aztIndatum & AFL_STATUS);
1789 if (inb(DATA_PORT) == AFL_OP_OK)
1790 break;
1791 }
1792 if ((azt_port_auto[i] == 0) || (i == 16)) {
1793 printk("aztcd: no AZTECH CD-ROM drive found\n");
1794 return -EIO;
1795 }
1796 } else { /* no autoprobing */
1797 if ((azt_port == 0x1f0) || (azt_port == 0x170))
1798 st = check_region(azt_port, 8); /*IDE-interfaces need 8 bytes */
1799 else
1800 st = check_region(azt_port, 4); /*proprietary interfaces need 4 bytes */
1801 if (st) {
1802 printk
1803 ("aztcd: conflict, I/O port (%X) already used\n",
1804 azt_port);
1805 return -EIO;
1806 }
1807
1808 if ((azt_port == 0x1f0) || (azt_port == 0x170))
1809 SWITCH_IDE_SLAVE; /*switch IDE interface to slave configuration */
1810
1811 outb(POLLED, MODE_PORT);
1812 inb(CMD_PORT);
1813 inb(CMD_PORT);
1814 outb(ACMD_GET_VERSION, CMD_PORT); /*Try to get version info */
1815
1816 aztTimeOutCount = 0;
1817 do {
1818 aztIndatum = inb(STATUS_PORT);
1819 aztTimeOutCount++;
1820 if (aztTimeOutCount >= AZT_FAST_TIMEOUT)
1821 break;
1822 } while (aztIndatum & AFL_STATUS);
1823
1824 if (inb(DATA_PORT) != AFL_OP_OK) { /*OP_OK? If not, reset and try again */
1825 #ifndef MODULE
1826 if (azt_cont != 0x79) {
1827 printk
1828 ("aztcd: no AZTECH CD-ROM drive found-Try boot parameter aztcd=<BaseAddress>,0x79\n");
1829 return -EIO;
1830 }
1831 #else
1832 if (0) {
1833 }
1834 #endif
1835 else {
1836 printk
1837 ("aztcd: drive reset - please wait\n");
1838 for (count = 0; count < 50; count++) {
1839 inb(STATUS_PORT); /*removing all data from earlier tries */
1840 inb(DATA_PORT);
1841 }
1842 outb(POLLED, MODE_PORT);
1843 inb(CMD_PORT);
1844 inb(CMD_PORT);
1845 getAztStatus(); /*trap errors */
1846 outb(ACMD_SOFT_RESET, CMD_PORT); /*send reset */
1847 STEN_LOW;
1848 if (inb(DATA_PORT) != AFL_OP_OK) { /*OP_OK? */
1849 printk
1850 ("aztcd: no AZTECH CD-ROM drive found\n");
1851 return -EIO;
1852 }
1853
1854 for (count = 0; count < AZT_TIMEOUT;
1855 count++)
1856 barrier(); /* Stop gcc 2.96 being smart */
1857
1858 if ((st = getAztStatus()) == -1) {
1859 printk
1860 ("aztcd: Drive Status Error Status=%x\n",
1861 st);
1862 return -EIO;
1863 }
1864 #ifdef AZT_DEBUG
1865 printk("aztcd: Status = %x\n", st);
1866 #endif
1867 outb(POLLED, MODE_PORT);
1868 inb(CMD_PORT);
1869 inb(CMD_PORT);
1870 outb(ACMD_GET_VERSION, CMD_PORT); /*GetVersion */
1871 STEN_LOW;
1872 OP_OK;
1873 }
1874 }
1875 }
1876
1877 azt_init_end = 1;
1878 STEN_LOW;
1879 result[0] = inb(DATA_PORT); /*reading in a null byte??? */
1880 for (count = 1; count < 50; count++) { /*Reading version string */
1881 aztTimeOutCount = 0; /*here we must implement STEN_LOW differently */
1882 do {
1883 aztIndatum = inb(STATUS_PORT); /*because we want to exit by timeout */
1884 aztTimeOutCount++;
1885 if (aztTimeOutCount >= AZT_FAST_TIMEOUT)
1886 break;
1887 } while (aztIndatum & AFL_STATUS);
1888 if (aztTimeOutCount >= AZT_FAST_TIMEOUT)
1889 break; /*all chars read? */
1890 result[count] = inb(DATA_PORT);
1891 }
1892 if (count > 30)
1893 max_count = 30; /*print max.30 chars of the version string */
1894 else
1895 max_count = count;
1896 printk(KERN_INFO "aztcd: FirmwareVersion=");
1897 for (count = 1; count < max_count; count++)
1898 printk("%c", result[count]);
1899 printk("<<>> ");
1900
1901 if ((result[1] == 'A') && (result[2] == 'Z') && (result[3] == 'T')) {
1902 printk("AZTECH drive detected\n");
1903 /*AZTECH*/}
1904 else if ((result[2] == 'C') && (result[3] == 'D')
1905 && (result[4] == 'D')) {
1906 printk("ORCHID or WEARNES drive detected\n"); /*ORCHID or WEARNES */
1907 } else if ((result[1] == 0x03) && (result[2] == '5')) {
1908 printk("TXC or CyCDROM drive detected\n"); /*Conrad TXC, CyCDROM */
1909 } else { /*OTHERS or none */
1910 printk("\nunknown drive or firmware version detected\n");
1911 printk
1912 ("aztcd may not run stable, if you want to try anyhow,\n");
1913 printk("boot with: aztcd=<BaseAddress>,0x79\n");
1914 if ((azt_cont != 0x79)) {
1915 printk("aztcd: FirmwareVersion=");
1916 for (count = 1; count < 5; count++)
1917 printk("%c", result[count]);
1918 printk("<<>> ");
1919 printk("Aborted\n");
1920 return -EIO;
1921 }
1922 }
1923 devfs_register(NULL, "aztcd", DEVFS_FL_DEFAULT, MAJOR_NR, 0,
1924 S_IFBLK | S_IRUGO | S_IWUGO, &azt_fops, NULL);
1925 if (devfs_register_blkdev(MAJOR_NR, "aztcd", &azt_fops) != 0) {
1926 printk("aztcd: Unable to get major %d for Aztech CD-ROM\n",
1927 MAJOR_NR);
1928 return -EIO;
1929 }
1930 blk_init_queue(BLK_DEFAULT_QUEUE(MAJOR_NR), DEVICE_REQUEST);
1931 blksize_size[MAJOR_NR] = aztcd_blocksizes;
1932 read_ahead[MAJOR_NR] = 4;
1933 register_disk(NULL, MKDEV(MAJOR_NR, 0), 1, &azt_fops, 0);
1934
1935 if ((azt_port == 0x1f0) || (azt_port == 0x170))
1936 request_region(azt_port, 8, "aztcd"); /*IDE-interface */
1937 else
1938 request_region(azt_port, 4, "aztcd"); /*proprietary interface */
1939
1940 azt_invalidate_buffers();
1941 aztPresent = 1;
1942 aztCloseDoor();
1943 return (0);
1944 }
1945
aztcd_exit(void)1946 void __exit aztcd_exit(void)
1947 {
1948 devfs_unregister(devfs_find_handle
1949 (NULL, "aztcd", 0, 0, DEVFS_SPECIAL_BLK, 0));
1950 if ((devfs_unregister_blkdev(MAJOR_NR, "aztcd") == -EINVAL)) {
1951 printk("What's that: can't unregister aztcd\n");
1952 return;
1953 }
1954 blk_cleanup_queue(BLK_DEFAULT_QUEUE(MAJOR_NR));
1955 if ((azt_port == 0x1f0) || (azt_port == 0x170)) {
1956 SWITCH_IDE_MASTER;
1957 release_region(azt_port, 8); /*IDE-interface */
1958 } else
1959 release_region(azt_port, 4); /*proprietary interface */
1960 printk(KERN_INFO "aztcd module released.\n");
1961 }
1962
1963 #ifdef MODULE
1964 module_init(aztcd_init);
1965 #endif
1966 module_exit(aztcd_exit);
1967
1968 /*##########################################################################
1969 Aztcd State Machine: Controls Drive Operating State
1970 ##########################################################################
1971 */
azt_poll(void)1972 static void azt_poll(void)
1973 {
1974 int st = 0;
1975 int loop_ctl = 1;
1976 int skip = 0;
1977
1978 if (azt_error) {
1979 if (aztSendCmd(ACMD_GET_ERROR))
1980 RETURN("azt_poll 1");
1981 STEN_LOW;
1982 azt_error = inb(DATA_PORT) & 0xFF;
1983 printk("aztcd: I/O error 0x%02x\n", azt_error);
1984 azt_invalidate_buffers();
1985 #ifdef WARN_IF_READ_FAILURE
1986 if (AztTries == 5)
1987 printk
1988 ("aztcd: Read of Block %d Failed - Maybe Audio Disk?\n",
1989 azt_next_bn);
1990 #endif
1991 if (!AztTries--) {
1992 printk
1993 ("aztcd: Read of Block %d Failed, Maybe Audio Disk? Giving up\n",
1994 azt_next_bn);
1995 if (azt_transfer_is_active) {
1996 AztTries = 0;
1997 loop_ctl = 0;
1998 }
1999 if (CURRENT_VALID)
2000 end_request(0);
2001 AztTries = 5;
2002 }
2003 azt_error = 0;
2004 azt_state = AZT_S_STOP;
2005 }
2006
2007 while (loop_ctl) {
2008 loop_ctl = 0; /* each case must flip this back to 1 if we want
2009 to come back up here */
2010 switch (azt_state) {
2011
2012 case AZT_S_IDLE:
2013 #ifdef AZT_TEST3
2014 if (azt_state != azt_state_old) {
2015 azt_state_old = azt_state;
2016 printk("AZT_S_IDLE\n");
2017 }
2018 #endif
2019 return;
2020
2021 case AZT_S_START:
2022 #ifdef AZT_TEST3
2023 if (azt_state != azt_state_old) {
2024 azt_state_old = azt_state;
2025 printk("AZT_S_START\n");
2026 }
2027 #endif
2028 if (aztSendCmd(ACMD_GET_STATUS))
2029 RETURN("azt_poll 2"); /*result will be checked by aztStatus() */
2030 azt_state =
2031 azt_mode == 1 ? AZT_S_READ : AZT_S_MODE;
2032 AztTimeout = 3000;
2033 break;
2034
2035 case AZT_S_MODE:
2036 #ifdef AZT_TEST3
2037 if (azt_state != azt_state_old) {
2038 azt_state_old = azt_state;
2039 printk("AZT_S_MODE\n");
2040 }
2041 #endif
2042 if (!skip) {
2043 if ((st = aztStatus()) != -1) {
2044 if ((st & AST_DSK_CHG)
2045 || (st & AST_NOT_READY)) {
2046 aztDiskChanged = 1;
2047 aztTocUpToDate = 0;
2048 azt_invalidate_buffers();
2049 end_request(0);
2050 printk
2051 ("aztcd: Disk Changed or Not Ready 1 - Unmount Disk!\n");
2052 }
2053 } else
2054 break;
2055 }
2056 skip = 0;
2057
2058 if ((st & AST_DOOR_OPEN) || (st & AST_NOT_READY)) {
2059 aztDiskChanged = 1;
2060 aztTocUpToDate = 0;
2061 printk
2062 ("aztcd: Disk Changed or Not Ready 2 - Unmount Disk!\n");
2063 end_request(0);
2064 printk((st & AST_DOOR_OPEN) ?
2065 "aztcd: door open\n" :
2066 "aztcd: disk removed\n");
2067 if (azt_transfer_is_active) {
2068 azt_state = AZT_S_START;
2069 loop_ctl = 1; /* goto immediately */
2070 break;
2071 }
2072 azt_state = AZT_S_IDLE;
2073 while (CURRENT_VALID)
2074 end_request(0);
2075 return;
2076 }
2077
2078 /* if (aztSendCmd(ACMD_SET_MODE)) RETURN("azt_poll 3");
2079 outb(0x01, DATA_PORT);
2080 PA_OK;
2081 STEN_LOW;
2082 */
2083 if (aztSendCmd(ACMD_GET_STATUS))
2084 RETURN("azt_poll 4");
2085 STEN_LOW;
2086 azt_mode = 1;
2087 azt_state = AZT_S_READ;
2088 AztTimeout = 3000;
2089
2090 break;
2091
2092
2093 case AZT_S_READ:
2094 #ifdef AZT_TEST3
2095 if (azt_state != azt_state_old) {
2096 azt_state_old = azt_state;
2097 printk("AZT_S_READ\n");
2098 }
2099 #endif
2100 if (!skip) {
2101 if ((st = aztStatus()) != -1) {
2102 if ((st & AST_DSK_CHG)
2103 || (st & AST_NOT_READY)) {
2104 aztDiskChanged = 1;
2105 aztTocUpToDate = 0;
2106 azt_invalidate_buffers();
2107 printk
2108 ("aztcd: Disk Changed or Not Ready 3 - Unmount Disk!\n");
2109 end_request(0);
2110 }
2111 } else
2112 break;
2113 }
2114
2115 skip = 0;
2116 if ((st & AST_DOOR_OPEN) || (st & AST_NOT_READY)) {
2117 aztDiskChanged = 1;
2118 aztTocUpToDate = 0;
2119 printk((st & AST_DOOR_OPEN) ?
2120 "aztcd: door open\n" :
2121 "aztcd: disk removed\n");
2122 if (azt_transfer_is_active) {
2123 azt_state = AZT_S_START;
2124 loop_ctl = 1;
2125 break;
2126 }
2127 azt_state = AZT_S_IDLE;
2128 while (CURRENT_VALID)
2129 end_request(0);
2130 return;
2131 }
2132
2133 if (CURRENT_VALID) {
2134 struct azt_Play_msf msf;
2135 int i;
2136 azt_next_bn = CURRENT->sector / 4;
2137 azt_hsg2msf(azt_next_bn, &msf.start);
2138 i = 0;
2139 /* find out in which track we are */
2140 while (azt_msf2hsg(&msf.start) >
2141 azt_msf2hsg(&Toc[++i].trackTime)) {
2142 };
2143 if (azt_msf2hsg(&msf.start) <
2144 azt_msf2hsg(&Toc[i].trackTime) -
2145 AZT_BUF_SIZ) {
2146 azt_read_count = AZT_BUF_SIZ; /*fast, because we read ahead */
2147 /*azt_read_count=CURRENT->nr_sectors; slow, no read ahead */
2148 } else /* don't read beyond end of track */
2149 #if AZT_MULTISESSION
2150 {
2151 azt_read_count =
2152 (azt_msf2hsg(&Toc[i].trackTime)
2153 / 4) * 4 -
2154 azt_msf2hsg(&msf.start);
2155 if (azt_read_count < 0)
2156 azt_read_count = 0;
2157 if (azt_read_count > AZT_BUF_SIZ)
2158 azt_read_count =
2159 AZT_BUF_SIZ;
2160 printk
2161 ("aztcd: warning - trying to read beyond end of track\n");
2162 /* printk("%i %i %li %li\n",i,azt_read_count,azt_msf2hsg(&msf.start),azt_msf2hsg(&Toc[i].trackTime));
2163 */ }
2164 #else
2165 {
2166 azt_read_count = AZT_BUF_SIZ;
2167 }
2168 #endif
2169 msf.end.min = 0;
2170 msf.end.sec = 0;
2171 msf.end.frame = azt_read_count; /*Mitsumi here reads 0xffffff sectors */
2172 #ifdef AZT_TEST3
2173 printk
2174 ("---reading msf-address %x:%x:%x %x:%x:%x\n",
2175 msf.start.min, msf.start.sec,
2176 msf.start.frame, msf.end.min,
2177 msf.end.sec, msf.end.frame);
2178 printk
2179 ("azt_next_bn:%x azt_buf_in:%x azt_buf_out:%x azt_buf_bn:%x\n",
2180 azt_next_bn, azt_buf_in, azt_buf_out,
2181 azt_buf_bn[azt_buf_in]);
2182 #endif
2183 if (azt_read_mode == AZT_MODE_2) {
2184 sendAztCmd(ACMD_PLAY_READ_RAW, &msf); /*XA disks in raw mode */
2185 } else {
2186 sendAztCmd(ACMD_PLAY_READ, &msf); /*others in cooked mode */
2187 }
2188 azt_state = AZT_S_DATA;
2189 AztTimeout = READ_TIMEOUT;
2190 } else {
2191 azt_state = AZT_S_STOP;
2192 loop_ctl = 1;
2193 break;
2194 }
2195
2196 break;
2197
2198
2199 case AZT_S_DATA:
2200 #ifdef AZT_TEST3
2201 if (azt_state != azt_state_old) {
2202 azt_state_old = azt_state;
2203 printk("AZT_S_DATA\n");
2204 }
2205 #endif
2206
2207 st = inb(STATUS_PORT) & AFL_STATUSorDATA;
2208
2209 switch (st) {
2210
2211 case AFL_DATA:
2212 #ifdef AZT_TEST3
2213 if (st != azt_st_old) {
2214 azt_st_old = st;
2215 printk("---AFL_DATA st:%x\n", st);
2216 }
2217 #endif
2218 if (!AztTries--) {
2219 printk
2220 ("aztcd: Read of Block %d Failed, Maybe Audio Disk ? Giving up\n",
2221 azt_next_bn);
2222 if (azt_transfer_is_active) {
2223 AztTries = 0;
2224 break;
2225 }
2226 if (CURRENT_VALID)
2227 end_request(0);
2228 AztTries = 5;
2229 }
2230 azt_state = AZT_S_START;
2231 AztTimeout = READ_TIMEOUT;
2232 loop_ctl = 1;
2233 break;
2234
2235 case AFL_STATUSorDATA:
2236 #ifdef AZT_TEST3
2237 if (st != azt_st_old) {
2238 azt_st_old = st;
2239 printk
2240 ("---AFL_STATUSorDATA st:%x\n",
2241 st);
2242 }
2243 #endif
2244 break;
2245
2246 default:
2247 #ifdef AZT_TEST3
2248 if (st != azt_st_old) {
2249 azt_st_old = st;
2250 printk("---default: st:%x\n", st);
2251 }
2252 #endif
2253 AztTries = 5;
2254 if (!CURRENT_VALID
2255 && azt_buf_in == azt_buf_out) {
2256 azt_state = AZT_S_STOP;
2257 loop_ctl = 1;
2258 break;
2259 }
2260 if (azt_read_count <= 0)
2261 printk
2262 ("aztcd: warning - try to read 0 frames\n");
2263 while (azt_read_count) { /*??? fast read ahead loop */
2264 azt_buf_bn[azt_buf_in] = -1;
2265 DTEN_LOW; /*??? unsolved problem, very
2266 seldom we get timeouts
2267 here, don't now the real
2268 reason. With my drive this
2269 sometimes also happens with
2270 Aztech's original driver under
2271 DOS. Is it a hardware bug?
2272 I tried to recover from such
2273 situations here. Zimmermann */
2274 if (aztTimeOutCount >= AZT_TIMEOUT) {
2275 printk
2276 ("read_count:%d CURRENT->nr_sectors:%ld azt_buf_in:%d\n",
2277 azt_read_count,
2278 CURRENT->nr_sectors,
2279 azt_buf_in);
2280 printk
2281 ("azt_transfer_is_active:%x\n",
2282 azt_transfer_is_active);
2283 azt_read_count = 0;
2284 azt_state = AZT_S_STOP;
2285 loop_ctl = 1;
2286 end_request(1); /*should we have here (1) or (0)? */
2287 } else {
2288 if (azt_read_mode ==
2289 AZT_MODE_2) {
2290 insb(DATA_PORT,
2291 azt_buf +
2292 CD_FRAMESIZE_RAW
2293 * azt_buf_in,
2294 CD_FRAMESIZE_RAW);
2295 } else {
2296 insb(DATA_PORT,
2297 azt_buf +
2298 CD_FRAMESIZE *
2299 azt_buf_in,
2300 CD_FRAMESIZE);
2301 }
2302 azt_read_count--;
2303 #ifdef AZT_TEST3
2304 printk
2305 ("AZT_S_DATA; ---I've read data- read_count: %d\n",
2306 azt_read_count);
2307 printk
2308 ("azt_next_bn:%d azt_buf_in:%d azt_buf_out:%d azt_buf_bn:%d\n",
2309 azt_next_bn,
2310 azt_buf_in,
2311 azt_buf_out,
2312 azt_buf_bn
2313 [azt_buf_in]);
2314 #endif
2315 azt_buf_bn[azt_buf_in] =
2316 azt_next_bn++;
2317 if (azt_buf_out == -1)
2318 azt_buf_out =
2319 azt_buf_in;
2320 azt_buf_in =
2321 azt_buf_in + 1 ==
2322 AZT_BUF_SIZ ? 0 :
2323 azt_buf_in + 1;
2324 }
2325 }
2326 if (!azt_transfer_is_active) {
2327 while (CURRENT_VALID) {
2328 azt_transfer();
2329 if (CURRENT->nr_sectors ==
2330 0)
2331 end_request(1);
2332 else
2333 break;
2334 }
2335 }
2336
2337 if (CURRENT_VALID
2338 && (CURRENT->sector / 4 < azt_next_bn
2339 || CURRENT->sector / 4 >
2340 azt_next_bn + AZT_BUF_SIZ)) {
2341 azt_state = AZT_S_STOP;
2342 loop_ctl = 1;
2343 break;
2344 }
2345 AztTimeout = READ_TIMEOUT;
2346 if (azt_read_count == 0) {
2347 azt_state = AZT_S_STOP;
2348 loop_ctl = 1;
2349 break;
2350 }
2351 break;
2352 }
2353 break;
2354
2355
2356 case AZT_S_STOP:
2357 #ifdef AZT_TEST3
2358 if (azt_state != azt_state_old) {
2359 azt_state_old = azt_state;
2360 printk("AZT_S_STOP\n");
2361 }
2362 #endif
2363 if (azt_read_count != 0)
2364 printk("aztcd: discard data=%x frames\n",
2365 azt_read_count);
2366 while (azt_read_count != 0) {
2367 int i;
2368 if (!(inb(STATUS_PORT) & AFL_DATA)) {
2369 if (azt_read_mode == AZT_MODE_2)
2370 for (i = 0;
2371 i < CD_FRAMESIZE_RAW;
2372 i++)
2373 inb(DATA_PORT);
2374 else
2375 for (i = 0;
2376 i < CD_FRAMESIZE; i++)
2377 inb(DATA_PORT);
2378 }
2379 azt_read_count--;
2380 }
2381 if (aztSendCmd(ACMD_GET_STATUS))
2382 RETURN("azt_poll 5");
2383 azt_state = AZT_S_STOPPING;
2384 AztTimeout = 1000;
2385 break;
2386
2387 case AZT_S_STOPPING:
2388 #ifdef AZT_TEST3
2389 if (azt_state != azt_state_old) {
2390 azt_state_old = azt_state;
2391 printk("AZT_S_STOPPING\n");
2392 }
2393 #endif
2394
2395 if ((st = aztStatus()) == -1 && AztTimeout)
2396 break;
2397
2398 if ((st != -1)
2399 && ((st & AST_DSK_CHG)
2400 || (st & AST_NOT_READY))) {
2401 aztDiskChanged = 1;
2402 aztTocUpToDate = 0;
2403 azt_invalidate_buffers();
2404 printk
2405 ("aztcd: Disk Changed or Not Ready 4 - Unmount Disk!\n");
2406 end_request(0);
2407 }
2408
2409 #ifdef AZT_TEST3
2410 printk("CURRENT_VALID %d azt_mode %d\n",
2411 CURRENT_VALID, azt_mode);
2412 #endif
2413
2414 if (CURRENT_VALID) {
2415 if (st != -1) {
2416 if (azt_mode == 1) {
2417 azt_state = AZT_S_READ;
2418 loop_ctl = 1;
2419 skip = 1;
2420 break;
2421 } else {
2422 azt_state = AZT_S_MODE;
2423 loop_ctl = 1;
2424 skip = 1;
2425 break;
2426 }
2427 } else {
2428 azt_state = AZT_S_START;
2429 AztTimeout = 1;
2430 }
2431 } else {
2432 azt_state = AZT_S_IDLE;
2433 return;
2434 }
2435 break;
2436
2437 default:
2438 printk("aztcd: invalid state %d\n", azt_state);
2439 return;
2440 } /* case */
2441 } /* while */
2442
2443
2444 if (!AztTimeout--) {
2445 printk("aztcd: timeout in state %d\n", azt_state);
2446 azt_state = AZT_S_STOP;
2447 if (aztSendCmd(ACMD_STOP))
2448 RETURN("azt_poll 6");
2449 STEN_LOW_WAIT;
2450 };
2451
2452 SET_TIMER(azt_poll, HZ / 100);
2453 }
2454
2455
2456 /*###########################################################################
2457 * Miscellaneous support functions
2458 ###########################################################################
2459 */
azt_hsg2msf(long hsg,struct msf * msf)2460 static void azt_hsg2msf(long hsg, struct msf *msf)
2461 {
2462 hsg += 150;
2463 msf->min = hsg / 4500;
2464 hsg %= 4500;
2465 msf->sec = hsg / 75;
2466 msf->frame = hsg % 75;
2467 #ifdef AZT_DEBUG
2468 if (msf->min >= 70)
2469 printk("aztcd: Error hsg2msf address Minutes\n");
2470 if (msf->sec >= 60)
2471 printk("aztcd: Error hsg2msf address Seconds\n");
2472 if (msf->frame >= 75)
2473 printk("aztcd: Error hsg2msf address Frames\n");
2474 #endif
2475 azt_bin2bcd(&msf->min); /* convert to BCD */
2476 azt_bin2bcd(&msf->sec);
2477 azt_bin2bcd(&msf->frame);
2478 }
2479
azt_msf2hsg(struct msf * mp)2480 static long azt_msf2hsg(struct msf *mp)
2481 {
2482 return azt_bcd2bin(mp->frame) + azt_bcd2bin(mp->sec) * 75
2483 + azt_bcd2bin(mp->min) * 4500 - CD_MSF_OFFSET;
2484 }
2485
azt_bin2bcd(unsigned char * p)2486 static void azt_bin2bcd(unsigned char *p)
2487 {
2488 int u, t;
2489
2490 u = *p % 10;
2491 t = *p / 10;
2492 *p = u | (t << 4);
2493 }
2494
azt_bcd2bin(unsigned char bcd)2495 static int azt_bcd2bin(unsigned char bcd)
2496 {
2497 return (bcd >> 4) * 10 + (bcd & 0xF);
2498 }
2499
2500 MODULE_LICENSE("GPL");
2501 EXPORT_NO_SYMBOLS;
2502