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(&notUsed))
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(&notUsed) < 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