1 /* cm206.c. A linux-driver for the cm206 cdrom player with cm260 adapter card.
2    Copyright (c) 1995--1997 David A. van Leeuwen.
3    $Id: cm206.c,v 1.5 1997/12/26 11:02:51 david Exp $
4 
5      This program is free software; you can redistribute it and/or modify
6      it under the terms of the GNU General Public License as published by
7      the Free Software Foundation; either version 2 of the License, or
8      (at your option) any later version.
9 
10      This program is distributed in the hope that it will be useful,
11      but WITHOUT ANY WARRANTY; without even the implied warranty of
12      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13      GNU General Public License for more details.
14 
15      You should have received a copy of the GNU General Public License
16      along with this program; if not, write to the Free Software
17      Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18 
19 History:
20  Started 25 jan 1994. Waiting for documentation...
21  22 feb 1995: 0.1a first reasonably safe polling driver.
22 	      Two major bugs, one in read_sector and one in
23 	      do_cm206_request, happened to cancel!
24  25 feb 1995: 0.2a first reasonable interrupt driven version of above.
25               uart writes are still done in polling mode.
26  25 feb 1995: 0.21a writes also in interrupt mode, still some
27 	      small bugs to be found... Larger buffer.
28   2 mrt 1995: 0.22 Bug found (cd-> nowhere, interrupt was called in
29               initialization), read_ahead of 16. Timeouts implemented.
30 	      unclear if they do something...
31   7 mrt 1995: 0.23 Start of background read-ahead.
32  18 mrt 1995: 0.24 Working background read-ahead. (still problems)
33  26 mrt 1995: 0.25 Multi-session ioctl added (kernel v1.2).
34               Statistics implemented, though separate stats206.h.
35 	      Accessible trough ioctl 0x1000 (just a number).
36 	      Hard to choose between v1.2 development and 1.1.75.
37 	      Bottom-half doesn't work with 1.2...
38 	      0.25a: fixed... typo. Still problems...
39   1 apr 1995: 0.26 Module support added. Most bugs found. Use kernel 1.2.n.
40   5 apr 1995: 0.27 Auto-probe for the adapter card base address.
41               Auto-probe for the adaptor card irq line.
42   7 apr 1995: 0.28 Added lilo setup support for base address and irq.
43               Use major number 32 (not in this source), officially
44 	      assigned to this driver.
45   9 apr 1995: 0.29 Added very limited audio support. Toc_header, stop, pause,
46               resume, eject. Play_track ignores track info, because we can't
47 	      read a table-of-contents entry. Toc_entry is implemented
48 	      as a `placebo' function: always returns start of disc.
49   3 may 1995: 0.30 Audio support completed. The get_toc_entry function
50               is implemented as a binary search.
51  15 may 1995: 0.31 More work on audio stuff. Workman is not easy to
52               satisfy; changed binary search into linear search.
53 	      Auto-probe for base address somewhat relaxed.
54   1 jun 1995: 0.32 Removed probe_irq_on/off for module version.
55  10 jun 1995: 0.33 Workman still behaves funny, but you should be
56               able to eject and substitute another disc.
57 
58  An adaptation of 0.33 is included in linux-1.3.7 by Eberhard Moenkeberg
59 
60  18 jul 1995: 0.34 Patch by Heiko Eissfeldt included, mainly considering
61               verify_area's in the ioctls. Some bugs introduced by
62 	      EM considering the base port and irq fixed.
63 
64  18 dec 1995: 0.35 Add some code for error checking... no luck...
65 
66  We jump to reach our goal: version 1.0 in the next stable linux kernel.
67 
68  19 mar 1996: 0.95 Different implementation of CDROM_GET_UPC, on
69 	      request of Thomas Quinot.
70  25 mar 1996: 0.96 Interpretation of opening with O_WRONLY or O_RDWR:
71 	      open only for ioctl operation, e.g., for operation of
72 	      tray etc.
73  4 apr 1996:  0.97 First implementation of layer between VFS and cdrom
74               driver, a generic interface. Much of the functionality
75 	      of cm206_open() and cm206_ioctl() is transferred to a
76 	      new file cdrom.c and its header ucdrom.h.
77 
78 	      Upgrade to Linux kernel 1.3.78.
79 
80  11 apr 1996  0.98 Upgrade to Linux kernel 1.3.85
81               More code moved to cdrom.c
82 
83  	      0.99 Some more small changes to decrease number
84  	      of oopses at module load;
85 
86  27 jul 1996  0.100 Many hours of debugging, kernel change from 1.2.13
87 	      to 2.0.7 seems to have introduced some weird behavior
88 	      in (interruptible_)sleep_on(&cd->data): the process
89 	      seems to be woken without any explicit wake_up in my own
90 	      code. Patch to try 100x in case such untriggered wake_up's
91 	      occur.
92 
93  28 jul 1996  0.101 Rewriting of the code that receives the command echo,
94 	      using a fifo to store echoed bytes.
95 
96  	      Branch from 0.99:
97 
98  	      0.99.1.0 Update to kernel release 2.0.10 dev_t -> kdev_t
99  	      (emoenke) various typos found by others.  extra
100  	      module-load oops protection.
101 
102  	      0.99.1.1 Initialization constant cdrom_dops.speed
103  	      changed from float (2.0) to int (2); Cli()-sti() pair
104  	      around cm260_reset() in module initialization code.
105 
106  	      0.99.1.2 Changes literally as proposed by Scott Snyder
107  	      <snyder@d0sgif.fnal.gov> for the 2.1 kernel line, which
108  	      have to do mainly with the poor minor support i had. The
109  	      major new concept is to change a cdrom driver's
110  	      operations struct from the capabilities struct. This
111  	      reflects the fact that there is one major for a driver,
112  	      whilst there can be many minors whith completely
113  	      different capabilities.
114 
115 	      0.99.1.3 More changes for operations/info separation.
116 
117 	      0.99.1.4 Added speed selection (someone had to do this
118 	      first).
119 
120   23 jan 1997 0.99.1.5 MODULE_PARMS call added.
121 
122   23 jan 1997 0.100.1.2--0.100.1.5 following similar lines as
123   	      0.99.1.1--0.99.1.5. I get too many complaints about the
124 	      drive making read errors. What't wrong with the 2.0+
125 	      kernel line? Why get i (and othe cm206 owners) weird
126 	      results? Why were things good in the good old 1.1--1.2
127 	      era? Why don't i throw away the drive?
128 
129  2 feb 1997   0.102 Added `volatile' to values in cm206_struct. Seems to
130  	      reduce many of the problems. Rewrote polling routines
131 	      to use fixed delays between polls.
132 	      0.103 Changed printk behavior.
133 	      0.104 Added a 0.100 -> 0.100.1.1 change
134 
135 11 feb 1997   0.105 Allow auto_probe during module load, disable
136               with module option "auto_probe=0". Moved some debugging
137 	      statements to lower priority. Implemented select_speed()
138 	      function.
139 
140 13 feb 1997   1.0 Final version for 2.0 kernel line.
141 
142 	      All following changes will be for the 2.1 kernel line.
143 
144 15 feb 1997   1.1 Keep up with kernel 2.1.26, merge in changes from
145               cdrom.c 0.100.1.1--1.0. Add some more MODULE_PARMS.
146 
147 14 sep 1997   1.2 Upgrade to Linux 2.1.55.  Added blksize_size[], patch
148               sent by James Bottomley <James.Bottomley@columbiasc.ncr.com>.
149 
150 21 dec 1997   1.4 Upgrade to Linux 2.1.72.
151 
152 24 jan 1998   Removed the cm206_disc_status() function, as it was now dead
153               code.  The Uniform CDROM driver now provides this functionality.
154 
155 9 Nov. 1999   Make kernel-parameter implementation work with 2.3.x
156 	      Removed init_module & cleanup_module in favor of
157 	      module_init & module_exit.
158 	      Torben Mathiasen <tmm@image.dk>
159  *
160  * Parts of the code are based upon lmscd.c written by Kai Petzke,
161  * sbpcd.c written by Eberhard Moenkeberg, and mcd.c by Martin
162  * Harriss, but any off-the-shelf dynamic programming algorithm won't
163  * be able to find them.
164  *
165  * The cm206 drive interface and the cm260 adapter card seem to be
166  * sufficiently different from their cm205/cm250 counterparts
167  * in order to write a complete new driver.
168  *
169  * I call all routines connected to the Linux kernel something
170  * with `cm206' in it, as this stuff is too series-dependent.
171  *
172  * Currently, my limited knowledge is based on:
173  * - The Linux Kernel Hacker's guide, v. 0.5, by Michael K. Johnson
174  * - Linux Kernel Programmierung, by Michael Beck and others
175  * - Philips/LMS cm206 and cm226 product specification
176  * - Philips/LMS cm260 product specification
177  *
178  * David van Leeuwen, david@tm.tno.nl.  */
179 #define REVISION "$Revision: 1.5 $"
180 
181 #include <linux/module.h>
182 
183 #include <linux/errno.h>	/* These include what we really need */
184 #include <linux/delay.h>
185 #include <linux/string.h>
186 #include <linux/sched.h>
187 #include <linux/interrupt.h>
188 #include <linux/timer.h>
189 #include <linux/cdrom.h>
190 #include <linux/devfs_fs_kernel.h>
191 #include <linux/ioport.h>
192 #include <linux/mm.h>
193 #include <linux/slab.h>
194 #include <linux/init.h>
195 
196 /* #include <linux/ucdrom.h> */
197 
198 #include <asm/io.h>
199 
200 #define MAJOR_NR CM206_CDROM_MAJOR
201 #include <linux/blk.h>
202 
203 #undef DEBUG
204 #define STATISTICS		/* record times and frequencies of events */
205 #define AUTO_PROBE_MODULE
206 #define USE_INSW
207 
208 #include "cm206.h"
209 
210 /* This variable defines whether or not to probe for adapter base port
211    address and interrupt request. It can be overridden by the boot
212    parameter `auto'.
213 */
214 static int auto_probe = 1;	/* Yes, why not? */
215 
216 static int cm206_base = CM206_BASE;
217 static int cm206_irq = CM206_IRQ;
218 #ifdef MODULE
219 static int cm206[2] = { 0, 0 };	/* for compatible `insmod' parameter passing */
220 #endif
221 
222 MODULE_PARM(cm206_base, "i");	/* base */
223 MODULE_PARM(cm206_irq, "i");	/* irq */
224 MODULE_PARM(cm206, "1-2i");	/* base,irq or irq,base */
225 MODULE_PARM(auto_probe, "i");	/* auto probe base and irq */
226 MODULE_LICENSE("GPL");
227 
228 #define POLLOOP 100		/* milliseconds */
229 #define READ_AHEAD 1		/* defines private buffer, waste! */
230 #define BACK_AHEAD 1		/* defines adapter-read ahead */
231 #define DATA_TIMEOUT (3*HZ)	/* measured in jiffies (10 ms) */
232 #define UART_TIMEOUT (5*HZ/100)
233 #define DSB_TIMEOUT (7*HZ)	/* time for the slowest command to finish */
234 #define UR_SIZE 4		/* uart receive buffer fifo size */
235 
236 #define LINUX_BLOCK_SIZE 512	/* WHERE is this defined? */
237 #define RAW_SECTOR_SIZE 2352	/* ok, is also defined in cdrom.h */
238 #define ISO_SECTOR_SIZE 2048
239 #define BLOCKS_ISO (ISO_SECTOR_SIZE/LINUX_BLOCK_SIZE)	/* 4 */
240 #define CD_SYNC_HEAD 16		/* CD_SYNC + CD_HEAD */
241 
242 #ifdef STATISTICS		/* keep track of errors in counters */
243 #define stats(i) { ++cd->stats[st_ ## i]; \
244 		     cd->last_stat[st_ ## i] = cd->stat_counter++; \
245 		 }
246 #else
247 #define stats(i) (void) 0;
248 #endif
249 
250 #define Debug(a) {printk (KERN_DEBUG); printk a;}
251 #ifdef DEBUG
252 #define debug(a) Debug(a)
253 #else
254 #define debug(a) (void) 0;
255 #endif
256 
257 typedef unsigned char uch;	/* 8-bits */
258 typedef unsigned short ush;	/* 16-bits */
259 
260 struct toc_struct {		/* private copy of Table of Contents */
261 	uch track, fsm[3], q0;
262 };
263 
264 static int cm206_blocksizes[1] = { 2048 };
265 
266 struct cm206_struct {
267 	volatile ush intr_ds;	/* data status read on last interrupt */
268 	volatile ush intr_ls;	/* uart line status read on last interrupt */
269 	volatile uch ur[UR_SIZE];	/* uart receive buffer fifo */
270 	volatile uch ur_w, ur_r;	/* write/read buffer index */
271 	volatile uch dsb, cc;	/* drive status byte and condition (error) code */
272 	int command;		/* command to be written to the uart */
273 	int openfiles;
274 	ush sector[READ_AHEAD * RAW_SECTOR_SIZE / 2];	/* buffered cd-sector */
275 	int sector_first, sector_last;	/* range of these sectors */
276 	wait_queue_head_t uart;	/* wait queues for interrupt */
277 	wait_queue_head_t data;
278 	struct timer_list timer;	/* time-out */
279 	char timed_out;
280 	signed char max_sectors;	/* number of sectors that fit in adapter mem */
281 	char wait_back;		/* we're waiting for a background-read */
282 	char background;	/* is a read going on in the background? */
283 	int adapter_first;	/* if so, that's the starting sector */
284 	int adapter_last;
285 	char fifo_overflowed;
286 	uch disc_status[7];	/* result of get_disc_status command */
287 #ifdef STATISTICS
288 	int stats[NR_STATS];
289 	int last_stat[NR_STATS];	/* `time' at which stat was stat */
290 	int stat_counter;
291 #endif
292 	struct toc_struct toc[101];	/* The whole table of contents + lead-out */
293 	uch q[10];		/* Last read q-channel info */
294 	uch audio_status[5];	/* last read position on pause */
295 	uch media_changed;	/* record if media changed */
296 };
297 
298 #define DISC_STATUS cd->disc_status[0]
299 #define FIRST_TRACK cd->disc_status[1]
300 #define LAST_TRACK cd->disc_status[2]
301 #define PAUSED cd->audio_status[0]	/* misuse this memory byte! */
302 #define PLAY_TO cd->toc[0]	/* toc[0] records end-time in play */
303 
304 static struct cm206_struct *cd;	/* the main memory structure */
305 
306 /* First, we define some polling functions. These are actually
307    only being used in the initialization. */
308 
send_command_polled(int command)309 void send_command_polled(int command)
310 {
311 	int loop = POLLOOP;
312 	while (!(inw(r_line_status) & ls_transmitter_buffer_empty)
313 	       && loop > 0) {
314 		mdelay(1);	/* one millisec delay */
315 		--loop;
316 	}
317 	outw(command, r_uart_transmit);
318 }
319 
receive_echo_polled(void)320 uch receive_echo_polled(void)
321 {
322 	int loop = POLLOOP;
323 	while (!(inw(r_line_status) & ls_receive_buffer_full) && loop > 0) {
324 		mdelay(1);
325 		--loop;
326 	}
327 	return ((uch) inw(r_uart_receive));
328 }
329 
send_receive_polled(int command)330 uch send_receive_polled(int command)
331 {
332 	send_command_polled(command);
333 	return receive_echo_polled();
334 }
335 
clear_ur(void)336 inline void clear_ur(void)
337 {
338 	if (cd->ur_r != cd->ur_w) {
339 		debug(("Deleting bytes from fifo:"));
340 		for (; cd->ur_r != cd->ur_w;
341 		     cd->ur_r++, cd->ur_r %= UR_SIZE)
342 			debug((" 0x%x", cd->ur[cd->ur_r]));
343 		debug(("\n"));
344 	}
345 }
346 
347 /* The interrupt handler. When the cm260 generates an interrupt, very
348    much care has to be taken in reading out the registers in the right
349    order; in case of a receive_buffer_full interrupt, first the
350    uart_receive must be read, and then the line status again to
351    de-assert the interrupt line. It took me a couple of hours to find
352    this out:-(
353 
354    The function reset_cm206 appears to cause an interrupt, because
355    pulling up the INIT line clears both the uart-write-buffer /and/
356    the uart-write-buffer-empty mask. We call this a `lost interrupt,'
357    as there seems so reason for this to happen.
358 */
359 
cm206_interrupt(int sig,void * dev_id,struct pt_regs * regs)360 static void cm206_interrupt(int sig, void *dev_id, struct pt_regs *regs)
361 /* you rang? */
362 {
363 	volatile ush fool;
364 	cd->intr_ds = inw(r_data_status);	/* resets data_ready, data_error,
365 						   crc_error, sync_error, toc_ready
366 						   interrupts */
367 	cd->intr_ls = inw(r_line_status);	/* resets overrun bit */
368 	debug(("Intr, 0x%x 0x%x, %d\n", cd->intr_ds, cd->intr_ls,
369 	       cd->background));
370 	if (cd->intr_ls & ls_attention)
371 		stats(attention);
372 	/* receive buffer full? */
373 	if (cd->intr_ls & ls_receive_buffer_full) {
374 		cd->ur[cd->ur_w] = inb(r_uart_receive);	/* get order right! */
375 		cd->intr_ls = inw(r_line_status);	/* resets rbf interrupt */
376 		debug(("receiving #%d: 0x%x\n", cd->ur_w,
377 		       cd->ur[cd->ur_w]));
378 		cd->ur_w++;
379 		cd->ur_w %= UR_SIZE;
380 		if (cd->ur_w == cd->ur_r)
381 			debug(("cd->ur overflow!\n"));
382 		if (waitqueue_active(&cd->uart) && cd->background < 2) {
383 			del_timer(&cd->timer);
384 			wake_up_interruptible(&cd->uart);
385 		}
386 	}
387 	/* data ready in fifo? */
388 	else if (cd->intr_ds & ds_data_ready) {
389 		if (cd->background)
390 			++cd->adapter_last;
391 		if (waitqueue_active(&cd->data)
392 		    && (cd->wait_back || !cd->background)) {
393 			del_timer(&cd->timer);
394 			wake_up_interruptible(&cd->data);
395 		}
396 		stats(data_ready);
397 	}
398 	/* ready to issue a write command? */
399 	else if (cd->command && cd->intr_ls & ls_transmitter_buffer_empty) {
400 		outw(dc_normal | (inw(r_data_status) & 0x7f),
401 		     r_data_control);
402 		outw(cd->command, r_uart_transmit);
403 		cd->command = 0;
404 		if (!cd->background)
405 			wake_up_interruptible(&cd->uart);
406 	}
407 	/* now treat errors (at least, identify them for debugging) */
408 	else if (cd->intr_ds & ds_fifo_overflow) {
409 		debug(("Fifo overflow at sectors 0x%x\n",
410 		       cd->sector_first));
411 		fool = inw(r_fifo_output_buffer);	/* de-assert the interrupt */
412 		cd->fifo_overflowed = 1;	/* signal one word less should be read */
413 		stats(fifo_overflow);
414 	} else if (cd->intr_ds & ds_data_error) {
415 		debug(("Data error at sector 0x%x\n", cd->sector_first));
416 		stats(data_error);
417 	} else if (cd->intr_ds & ds_crc_error) {
418 		debug(("CRC error at sector 0x%x\n", cd->sector_first));
419 		stats(crc_error);
420 	} else if (cd->intr_ds & ds_sync_error) {
421 		debug(("Sync at sector 0x%x\n", cd->sector_first));
422 		stats(sync_error);
423 	} else if (cd->intr_ds & ds_toc_ready) {
424 		/* do something appropriate */
425 	}
426 	/* couldn't see why this interrupt, maybe due to init */
427 	else {
428 		outw(dc_normal | READ_AHEAD, r_data_control);
429 		stats(lost_intr);
430 	}
431 	if (cd->background
432 	    && (cd->adapter_last - cd->adapter_first == cd->max_sectors
433 		|| cd->fifo_overflowed))
434 		mark_bh(CM206_BH);	/* issue a stop read command */
435 	stats(interrupt);
436 }
437 
438 /* we have put the address of the wait queue in who */
cm206_timeout(unsigned long who)439 void cm206_timeout(unsigned long who)
440 {
441 	cd->timed_out = 1;
442 	debug(("Timing out\n"));
443 	wake_up_interruptible((wait_queue_head_t *) who);
444 }
445 
446 /* This function returns 1 if a timeout occurred, 0 if an interrupt
447    happened */
sleep_or_timeout(wait_queue_head_t * wait,int timeout)448 int sleep_or_timeout(wait_queue_head_t * wait, int timeout)
449 {
450 	cd->timed_out = 0;
451 	cd->timer.data = (unsigned long) wait;
452 	cd->timer.expires = jiffies + timeout;
453 	add_timer(&cd->timer);
454 	debug(("going to sleep\n"));
455 	interruptible_sleep_on(wait);
456 	del_timer(&cd->timer);
457 	if (cd->timed_out) {
458 		cd->timed_out = 0;
459 		return 1;
460 	} else
461 		return 0;
462 }
463 
cm206_delay(int nr_jiffies)464 void cm206_delay(int nr_jiffies)
465 {
466 	DECLARE_WAIT_QUEUE_HEAD(wait);
467 	sleep_or_timeout(&wait, nr_jiffies);
468 }
469 
send_command(int command)470 void send_command(int command)
471 {
472 	debug(("Sending 0x%x\n", command));
473 	if (!(inw(r_line_status) & ls_transmitter_buffer_empty)) {
474 		cd->command = command;
475 		cli();		/* don't interrupt before sleep */
476 		outw(dc_mask_sync_error | dc_no_stop_on_error |
477 		     (inw(r_data_status) & 0x7f), r_data_control);
478 		/* interrupt routine sends command */
479 		if (sleep_or_timeout(&cd->uart, UART_TIMEOUT)) {
480 			debug(("Time out on write-buffer\n"));
481 			stats(write_timeout);
482 			outw(command, r_uart_transmit);
483 		}
484 		debug(("Write commmand delayed\n"));
485 	} else
486 		outw(command, r_uart_transmit);
487 }
488 
receive_byte(int timeout)489 uch receive_byte(int timeout)
490 {
491 	uch ret;
492 	cli();
493 	debug(("cli\n"));
494 	ret = cd->ur[cd->ur_r];
495 	if (cd->ur_r != cd->ur_w) {
496 		sti();
497 		debug(("returning #%d: 0x%x\n", cd->ur_r,
498 		       cd->ur[cd->ur_r]));
499 		cd->ur_r++;
500 		cd->ur_r %= UR_SIZE;
501 		return ret;
502 	} else if (sleep_or_timeout(&cd->uart, timeout)) {	/* does sti() */
503 		debug(("Time out on receive-buffer\n"));
504 #ifdef STATISTICS
505 		if (timeout == UART_TIMEOUT)
506 			stats(receive_timeout)	/* no `;'! */
507 			    else
508 			stats(dsb_timeout);
509 #endif
510 		return 0xda;
511 	}
512 	ret = cd->ur[cd->ur_r];
513 	debug(("slept; returning #%d: 0x%x\n", cd->ur_r,
514 	       cd->ur[cd->ur_r]));
515 	cd->ur_r++;
516 	cd->ur_r %= UR_SIZE;
517 	return ret;
518 }
519 
receive_echo(void)520 inline uch receive_echo(void)
521 {
522 	return receive_byte(UART_TIMEOUT);
523 }
524 
send_receive(int command)525 inline uch send_receive(int command)
526 {
527 	send_command(command);
528 	return receive_echo();
529 }
530 
wait_dsb(void)531 inline uch wait_dsb(void)
532 {
533 	return receive_byte(DSB_TIMEOUT);
534 }
535 
type_0_command(int command,int expect_dsb)536 int type_0_command(int command, int expect_dsb)
537 {
538 	int e;
539 	clear_ur();
540 	if (command != (e = send_receive(command))) {
541 		debug(("command 0x%x echoed as 0x%x\n", command, e));
542 		stats(echo);
543 		return -1;
544 	}
545 	if (expect_dsb) {
546 		cd->dsb = wait_dsb();	/* wait for command to finish */
547 	}
548 	return 0;
549 }
550 
type_1_command(int command,int bytes,uch * status)551 int type_1_command(int command, int bytes, uch * status)
552 {				/* returns info */
553 	int i;
554 	if (type_0_command(command, 0))
555 		return -1;
556 	for (i = 0; i < bytes; i++)
557 		status[i] = send_receive(c_gimme);
558 	return 0;
559 }
560 
561 /* This function resets the adapter card. We'd better not do this too
562  * often, because it tends to generate `lost interrupts.' */
reset_cm260(void)563 void reset_cm260(void)
564 {
565 	outw(dc_normal | dc_initialize | READ_AHEAD, r_data_control);
566 	udelay(10);		/* 3.3 mu sec minimum */
567 	outw(dc_normal | READ_AHEAD, r_data_control);
568 }
569 
570 /* fsm: frame-sec-min from linear address; one of many */
fsm(int lba,uch * fsm)571 void fsm(int lba, uch * fsm)
572 {
573 	fsm[0] = lba % 75;
574 	lba /= 75;
575 	lba += 2;
576 	fsm[1] = lba % 60;
577 	fsm[2] = lba / 60;
578 }
579 
fsm2lba(uch * fsm)580 inline int fsm2lba(uch * fsm)
581 {
582 	return fsm[0] + 75 * (fsm[1] - 2 + 60 * fsm[2]);
583 }
584 
f_s_m2lba(uch f,uch s,uch m)585 inline int f_s_m2lba(uch f, uch s, uch m)
586 {
587 	return f + 75 * (s - 2 + 60 * m);
588 }
589 
start_read(int start)590 int start_read(int start)
591 {
592 	uch read_sector[4] = { c_read_data, };
593 	int i, e;
594 
595 	fsm(start, &read_sector[1]);
596 	clear_ur();
597 	for (i = 0; i < 4; i++)
598 		if (read_sector[i] != (e = send_receive(read_sector[i]))) {
599 			debug(("read_sector: %x echoes %x\n",
600 			       read_sector[i], e));
601 			stats(echo);
602 			if (e == 0xff) {	/* this seems to happen often */
603 				e = receive_echo();
604 				debug(("Second try %x\n", e));
605 				if (e != read_sector[i])
606 					return -1;
607 			}
608 		}
609 	return 0;
610 }
611 
stop_read(void)612 int stop_read(void)
613 {
614 	int e;
615 	type_0_command(c_stop, 0);
616 	if ((e = receive_echo()) != 0xff) {
617 		debug(("c_stop didn't send 0xff, but 0x%x\n", e));
618 		stats(stop_0xff);
619 		return -1;
620 	}
621 	return 0;
622 }
623 
624 /* This function starts to read sectors in adapter memory, the
625    interrupt routine should stop the read. In fact, the bottom_half
626    routine takes care of this. Set a flag `background' in the cd
627    struct to indicate the process. */
628 
read_background(int start,int reading)629 int read_background(int start, int reading)
630 {
631 	if (cd->background)
632 		return -1;	/* can't do twice */
633 	outw(dc_normal | BACK_AHEAD, r_data_control);
634 	if (!reading && start_read(start))
635 		return -2;
636 	cd->adapter_first = cd->adapter_last = start;
637 	cd->background = 1;	/* flag a read is going on */
638 	return 0;
639 }
640 
641 #ifdef USE_INSW
642 #define transport_data insw
643 #else
644 /* this routine implements insw(,,). There was a time i had the
645    impression that there would be any difference in error-behaviour. */
transport_data(int port,ush * dest,int count)646 void transport_data(int port, ush * dest, int count)
647 {
648 	int i;
649 	ush *d;
650 	for (i = 0, d = dest; i < count; i++, d++)
651 		*d = inw(port);
652 }
653 #endif
654 
655 
656 #define MAX_TRIES 100
read_sector(int start)657 int read_sector(int start)
658 {
659 	int tries = 0;
660 	if (cd->background) {
661 		cd->background = 0;
662 		cd->adapter_last = -1;	/* invalidate adapter memory */
663 		stop_read();
664 	}
665 	cd->fifo_overflowed = 0;
666 	reset_cm260();		/* empty fifo etc. */
667 	if (start_read(start))
668 		return -1;
669 	do {
670 		if (sleep_or_timeout(&cd->data, DATA_TIMEOUT)) {
671 			debug(("Read timed out sector 0x%x\n", start));
672 			stats(read_timeout);
673 			stop_read();
674 			return -3;
675 		}
676 		tries++;
677 	} while (cd->intr_ds & ds_fifo_empty && tries < MAX_TRIES);
678 	if (tries > 1)
679 		debug(("Took me some tries\n"))
680 		    else
681 	if (tries == MAX_TRIES)
682 		debug(("MAX_TRIES tries for read sector\n"));
683 	transport_data(r_fifo_output_buffer, cd->sector,
684 		       READ_AHEAD * RAW_SECTOR_SIZE / 2);
685 	if (read_background(start + READ_AHEAD, 1))
686 		stats(read_background);
687 	cd->sector_first = start;
688 	cd->sector_last = start + READ_AHEAD;
689 	stats(read_restarted);
690 	return 0;
691 }
692 
693 /* The function of bottom-half is to send a stop command to the drive
694    This isn't easy because the routine is not `owned' by any process;
695    we can't go to sleep! The variable cd->background gives the status:
696    0 no read pending
697    1 a read is pending
698    2 c_stop waits for write_buffer_empty
699    3 c_stop waits for receive_buffer_full: echo
700    4 c_stop waits for receive_buffer_full: 0xff
701 */
702 
cm206_bh(void)703 void cm206_bh(void)
704 {
705 	debug(("bh: %d\n", cd->background));
706 	switch (cd->background) {
707 	case 1:
708 		stats(bh);
709 		if (!(cd->intr_ls & ls_transmitter_buffer_empty)) {
710 			cd->command = c_stop;
711 			outw(dc_mask_sync_error | dc_no_stop_on_error |
712 			     (inw(r_data_status) & 0x7f), r_data_control);
713 			cd->background = 2;
714 			break;	/* we'd better not time-out here! */
715 		} else
716 			outw(c_stop, r_uart_transmit);
717 		/* fall into case 2: */
718 	case 2:
719 		/* the write has been satisfied by interrupt routine */
720 		cd->background = 3;
721 		break;
722 	case 3:
723 		if (cd->ur_r != cd->ur_w) {
724 			if (cd->ur[cd->ur_r] != c_stop) {
725 				debug(("cm206_bh: c_stop echoed 0x%x\n",
726 				       cd->ur[cd->ur_r]));
727 				stats(echo);
728 			}
729 			cd->ur_r++;
730 			cd->ur_r %= UR_SIZE;
731 		}
732 		cd->background++;
733 		break;
734 	case 4:
735 		if (cd->ur_r != cd->ur_w) {
736 			if (cd->ur[cd->ur_r] != 0xff) {
737 				debug(("cm206_bh: c_stop reacted with 0x%x\n", cd->ur[cd->ur_r]));
738 				stats(stop_0xff);
739 			}
740 			cd->ur_r++;
741 			cd->ur_r %= UR_SIZE;
742 		}
743 		cd->background = 0;
744 	}
745 }
746 
747 /* This command clears the dsb_possible_media_change flag, so we must
748  * retain it.
749  */
get_drive_status(void)750 void get_drive_status(void)
751 {
752 	uch status[2];
753 	type_1_command(c_drive_status, 2, status);	/* this might be done faster */
754 	cd->dsb = status[0];
755 	cd->cc = status[1];
756 	cd->media_changed |=
757 	    !!(cd->dsb & (dsb_possible_media_change |
758 			  dsb_drive_not_ready | dsb_tray_not_closed));
759 }
760 
get_disc_status(void)761 void get_disc_status(void)
762 {
763 	if (type_1_command(c_disc_status, 7, cd->disc_status)) {
764 		debug(("get_disc_status: error\n"));
765 	}
766 }
767 
768 struct block_device_operations cm206_bdops =
769 {
770 	owner:			THIS_MODULE,
771 	open:			cdrom_open,
772 	release:		cdrom_release,
773 	ioctl:			cdrom_ioctl,
774 	check_media_change:	cdrom_media_changed,
775 };
776 
777 /* The new open. The real opening strategy is defined in cdrom.c. */
778 
cm206_open(struct cdrom_device_info * cdi,int purpose)779 static int cm206_open(struct cdrom_device_info *cdi, int purpose)
780 {
781 	if (!cd->openfiles) {	/* reset only first time */
782 		cd->background = 0;
783 		reset_cm260();
784 		cd->adapter_last = -1;	/* invalidate adapter memory */
785 		cd->sector_last = -1;
786 	}
787 	++cd->openfiles;
788 	stats(open);
789 	return 0;
790 }
791 
cm206_release(struct cdrom_device_info * cdi)792 static void cm206_release(struct cdrom_device_info *cdi)
793 {
794 	if (cd->openfiles == 1) {
795 		if (cd->background) {
796 			cd->background = 0;
797 			stop_read();
798 		}
799 		cd->sector_last = -1;	/* Make our internal buffer invalid */
800 		FIRST_TRACK = 0;	/* No valid disc status */
801 	}
802 	--cd->openfiles;
803 }
804 
805 /* Empty buffer empties $sectors$ sectors of the adapter card buffer,
806  * and then reads a sector in kernel memory.  */
empty_buffer(int sectors)807 void empty_buffer(int sectors)
808 {
809 	while (sectors >= 0) {
810 		transport_data(r_fifo_output_buffer,
811 			       cd->sector + cd->fifo_overflowed,
812 			       RAW_SECTOR_SIZE / 2 - cd->fifo_overflowed);
813 		--sectors;
814 		++cd->adapter_first;	/* update the current adapter sector */
815 		cd->fifo_overflowed = 0;	/* reset overflow bit */
816 		stats(sector_transferred);
817 	}
818 	cd->sector_first = cd->adapter_first - 1;
819 	cd->sector_last = cd->adapter_first;	/* update the buffer sector */
820 }
821 
822 /* try_adapter. This function determines if the requested sector is
823    in adapter memory, or will appear there soon. Returns 0 upon
824    success */
try_adapter(int sector)825 int try_adapter(int sector)
826 {
827 	if (cd->adapter_first <= sector && sector < cd->adapter_last) {
828 		/* sector is in adapter memory */
829 		empty_buffer(sector - cd->adapter_first);
830 		return 0;
831 	} else if (cd->background == 1 && cd->adapter_first <= sector
832 		   && sector < cd->adapter_first + cd->max_sectors) {
833 		/* a read is going on, we can wait for it */
834 		cd->wait_back = 1;
835 		while (sector >= cd->adapter_last) {
836 			if (sleep_or_timeout(&cd->data, DATA_TIMEOUT)) {
837 				debug(("Timed out during background wait: %d %d %d %d\n", sector, cd->adapter_last, cd->adapter_first, cd->background));
838 				stats(back_read_timeout);
839 				cd->wait_back = 0;
840 				return -1;
841 			}
842 		}
843 		cd->wait_back = 0;
844 		empty_buffer(sector - cd->adapter_first);
845 		return 0;
846 	} else
847 		return -2;
848 }
849 
850 /* This is not a very smart implementation. We could optimize for
851    consecutive block numbers. I'm not convinced this would really
852    bring down the processor load. */
do_cm206_request(request_queue_t * q)853 static void do_cm206_request(request_queue_t * q)
854 {
855 	long int i, cd_sec_no;
856 	int quarter, error;
857 	uch *source, *dest;
858 
859 	while (1) {		/* repeat until all requests have been satisfied */
860 		INIT_REQUEST;
861 		if (QUEUE_EMPTY || CURRENT->rq_status == RQ_INACTIVE)
862 			return;
863 		if (CURRENT->cmd != READ) {
864 			debug(("Non-read command %d on cdrom\n",
865 			       CURRENT->cmd));
866 			end_request(0);
867 			continue;
868 		}
869 		spin_unlock_irq(&io_request_lock);
870 		error = 0;
871 		for (i = 0; i < CURRENT->nr_sectors; i++) {
872 			int e1, e2;
873 			cd_sec_no = (CURRENT->sector + i) / BLOCKS_ISO;	/* 4 times 512 bytes */
874 			quarter = (CURRENT->sector + i) % BLOCKS_ISO;
875 			dest = CURRENT->buffer + i * LINUX_BLOCK_SIZE;
876 			/* is already in buffer memory? */
877 			if (cd->sector_first <= cd_sec_no
878 			    && cd_sec_no < cd->sector_last) {
879 				source =
880 				    ((uch *) cd->sector) + 16 +
881 				    quarter * LINUX_BLOCK_SIZE +
882 				    (cd_sec_no -
883 				     cd->sector_first) * RAW_SECTOR_SIZE;
884 				memcpy(dest, source, LINUX_BLOCK_SIZE);
885 			} else if (!(e1 = try_adapter(cd_sec_no)) ||
886 				   !(e2 = read_sector(cd_sec_no))) {
887 				source =
888 				    ((uch *) cd->sector) + 16 +
889 				    quarter * LINUX_BLOCK_SIZE;
890 				memcpy(dest, source, LINUX_BLOCK_SIZE);
891 			} else {
892 				error = 1;
893 				debug(("cm206_request: %d %d\n", e1, e2));
894 			}
895 		}
896 		spin_lock_irq(&io_request_lock);
897 		end_request(!error);
898 	}
899 }
900 
901 /* Audio support. I've tried very hard, but the cm206 drive doesn't
902    seem to have a get_toc (table-of-contents) function, while i'm
903    pretty sure it must read the toc upon disc insertion. Therefore
904    this function has been implemented through a binary search
905    strategy. All track starts that happen to be found are stored in
906    cd->toc[], for future use.
907 
908    I've spent a whole day on a bug that only shows under Workman---
909    I don't get it. Tried everything, nothing works. If workman asks
910    for track# 0xaa, it'll get the wrong time back. Any other program
911    receives the correct value. I'm stymied.
912 */
913 
914 /* seek seeks to address lba. It does wait to arrive there. */
seek(int lba)915 void seek(int lba)
916 {
917 	int i;
918 	uch seek_command[4] = { c_seek, };
919 
920 	fsm(lba, &seek_command[1]);
921 	for (i = 0; i < 4; i++)
922 		type_0_command(seek_command[i], 0);
923 	cd->dsb = wait_dsb();
924 }
925 
bcdbin(unsigned char bcd)926 uch bcdbin(unsigned char bcd)
927 {				/* stolen from mcd.c! */
928 	return (bcd >> 4) * 10 + (bcd & 0xf);
929 }
930 
normalize_track(uch track)931 inline uch normalize_track(uch track)
932 {
933 	if (track < 1)
934 		return 1;
935 	if (track > LAST_TRACK)
936 		return LAST_TRACK + 1;
937 	return track;
938 }
939 
940 /* This function does a binary search for track start. It records all
941  * tracks seen in the process. Input $track$ must be between 1 and
942  * #-of-tracks+1.  Note that the start of the disc must be in toc[1].fsm.
943  */
get_toc_lba(uch track)944 int get_toc_lba(uch track)
945 {
946 	int max = 74 * 60 * 75 - 150, min = fsm2lba(cd->toc[1].fsm);
947 	int i, lba, l, old_lba = 0;
948 	uch *q = cd->q;
949 	uch ct;			/* current track */
950 	int binary = 0;
951 	const int skip = 3 * 60 * 75;	/* 3 minutes */
952 
953 	for (i = track; i > 0; i--)
954 		if (cd->toc[i].track) {
955 			min = fsm2lba(cd->toc[i].fsm);
956 			break;
957 		}
958 	lba = min + skip;
959 	do {
960 		seek(lba);
961 		type_1_command(c_read_current_q, 10, q);
962 		ct = normalize_track(q[1]);
963 		if (!cd->toc[ct].track) {
964 			l = q[9] - bcdbin(q[5]) + 75 * (q[8] -
965 							bcdbin(q[4]) - 2 +
966 							60 * (q[7] -
967 							      bcdbin(q
968 								     [3])));
969 			cd->toc[ct].track = q[1];	/* lead out still 0xaa */
970 			fsm(l, cd->toc[ct].fsm);
971 			cd->toc[ct].q0 = q[0];	/* contains adr and ctrl info */
972 			if (ct == track)
973 				return l;
974 		}
975 		old_lba = lba;
976 		if (binary) {
977 			if (ct < track)
978 				min = lba;
979 			else
980 				max = lba;
981 			lba = (min + max) / 2;
982 		} else {
983 			if (ct < track)
984 				lba += skip;
985 			else {
986 				binary = 1;
987 				max = lba;
988 				min = lba - skip;
989 				lba = (min + max) / 2;
990 			}
991 		}
992 	} while (lba != old_lba);
993 	return lba;
994 }
995 
update_toc_entry(uch track)996 void update_toc_entry(uch track)
997 {
998 	track = normalize_track(track);
999 	if (!cd->toc[track].track)
1000 		get_toc_lba(track);
1001 }
1002 
1003 /* return 0 upon success */
read_toc_header(struct cdrom_tochdr * hp)1004 int read_toc_header(struct cdrom_tochdr *hp)
1005 {
1006 	if (!FIRST_TRACK)
1007 		get_disc_status();
1008 	if (hp) {
1009 		int i;
1010 		hp->cdth_trk0 = FIRST_TRACK;
1011 		hp->cdth_trk1 = LAST_TRACK;
1012 		/* fill in first track position */
1013 		for (i = 0; i < 3; i++)
1014 			cd->toc[1].fsm[i] = cd->disc_status[3 + i];
1015 		update_toc_entry(LAST_TRACK + 1);	/* find most entries */
1016 		return 0;
1017 	}
1018 	return -1;
1019 }
1020 
play_from_to_msf(struct cdrom_msf * msfp)1021 void play_from_to_msf(struct cdrom_msf *msfp)
1022 {
1023 	uch play_command[] = { c_play,
1024 		msfp->cdmsf_frame0, msfp->cdmsf_sec0, msfp->cdmsf_min0,
1025 		msfp->cdmsf_frame1, msfp->cdmsf_sec1, msfp->cdmsf_min1, 2,
1026 		    2
1027 	};
1028 	int i;
1029 	for (i = 0; i < 9; i++)
1030 		type_0_command(play_command[i], 0);
1031 	for (i = 0; i < 3; i++)
1032 		PLAY_TO.fsm[i] = play_command[i + 4];
1033 	PLAY_TO.track = 0;	/* say no track end */
1034 	cd->dsb = wait_dsb();
1035 }
1036 
play_from_to_track(int from,int to)1037 void play_from_to_track(int from, int to)
1038 {
1039 	uch play_command[8] = { c_play, };
1040 	int i;
1041 
1042 	if (from == 0) {	/* continue paused play */
1043 		for (i = 0; i < 3; i++) {
1044 			play_command[i + 1] = cd->audio_status[i + 2];
1045 			play_command[i + 4] = PLAY_TO.fsm[i];
1046 		}
1047 	} else {
1048 		update_toc_entry(from);
1049 		update_toc_entry(to + 1);
1050 		for (i = 0; i < 3; i++) {
1051 			play_command[i + 1] = cd->toc[from].fsm[i];
1052 			PLAY_TO.fsm[i] = play_command[i + 4] =
1053 			    cd->toc[to + 1].fsm[i];
1054 		}
1055 		PLAY_TO.track = to;
1056 	}
1057 	for (i = 0; i < 7; i++)
1058 		type_0_command(play_command[i], 0);
1059 	for (i = 0; i < 2; i++)
1060 		type_0_command(0x2, 0);	/* volume */
1061 	cd->dsb = wait_dsb();
1062 }
1063 
get_current_q(struct cdrom_subchnl * qp)1064 int get_current_q(struct cdrom_subchnl *qp)
1065 {
1066 	int i;
1067 	uch *q = cd->q;
1068 	if (type_1_command(c_read_current_q, 10, q))
1069 		return 0;
1070 /*  q[0] = bcdbin(q[0]); Don't think so! */
1071 	for (i = 2; i < 6; i++)
1072 		q[i] = bcdbin(q[i]);
1073 	qp->cdsc_adr = q[0] & 0xf;
1074 	qp->cdsc_ctrl = q[0] >> 4;	/* from mcd.c */
1075 	qp->cdsc_trk = q[1];
1076 	qp->cdsc_ind = q[2];
1077 	if (qp->cdsc_format == CDROM_MSF) {
1078 		qp->cdsc_reladdr.msf.minute = q[3];
1079 		qp->cdsc_reladdr.msf.second = q[4];
1080 		qp->cdsc_reladdr.msf.frame = q[5];
1081 		qp->cdsc_absaddr.msf.minute = q[7];
1082 		qp->cdsc_absaddr.msf.second = q[8];
1083 		qp->cdsc_absaddr.msf.frame = q[9];
1084 	} else {
1085 		qp->cdsc_reladdr.lba = f_s_m2lba(q[5], q[4], q[3]);
1086 		qp->cdsc_absaddr.lba = f_s_m2lba(q[9], q[8], q[7]);
1087 	}
1088 	get_drive_status();
1089 	if (cd->dsb & dsb_play_in_progress)
1090 		qp->cdsc_audiostatus = CDROM_AUDIO_PLAY;
1091 	else if (PAUSED)
1092 		qp->cdsc_audiostatus = CDROM_AUDIO_PAUSED;
1093 	else
1094 		qp->cdsc_audiostatus = CDROM_AUDIO_NO_STATUS;
1095 	return 0;
1096 }
1097 
invalidate_toc(void)1098 void invalidate_toc(void)
1099 {
1100 	memset(cd->toc, 0, sizeof(cd->toc));
1101 	memset(cd->disc_status, 0, sizeof(cd->disc_status));
1102 }
1103 
1104 /* cdrom.c guarantees that cdte_format == CDROM_MSF */
get_toc_entry(struct cdrom_tocentry * ep)1105 void get_toc_entry(struct cdrom_tocentry *ep)
1106 {
1107 	uch track = normalize_track(ep->cdte_track);
1108 	update_toc_entry(track);
1109 	ep->cdte_addr.msf.frame = cd->toc[track].fsm[0];
1110 	ep->cdte_addr.msf.second = cd->toc[track].fsm[1];
1111 	ep->cdte_addr.msf.minute = cd->toc[track].fsm[2];
1112 	ep->cdte_adr = cd->toc[track].q0 & 0xf;
1113 	ep->cdte_ctrl = cd->toc[track].q0 >> 4;
1114 	ep->cdte_datamode = 0;
1115 }
1116 
1117 /* Audio ioctl.  Ioctl commands connected to audio are in such an
1118  * idiosyncratic i/o format, that we leave these untouched. Return 0
1119  * upon success. Memory checking has been done by cdrom_ioctl(), the
1120  * calling function, as well as LBA/MSF sanitization.
1121 */
cm206_audio_ioctl(struct cdrom_device_info * cdi,unsigned int cmd,void * arg)1122 int cm206_audio_ioctl(struct cdrom_device_info *cdi, unsigned int cmd,
1123 		      void *arg)
1124 {
1125 	switch (cmd) {
1126 	case CDROMREADTOCHDR:
1127 		return read_toc_header((struct cdrom_tochdr *) arg);
1128 	case CDROMREADTOCENTRY:
1129 		get_toc_entry((struct cdrom_tocentry *) arg);
1130 		return 0;
1131 	case CDROMPLAYMSF:
1132 		play_from_to_msf((struct cdrom_msf *) arg);
1133 		return 0;
1134 	case CDROMPLAYTRKIND:	/* admittedly, not particularly beautiful */
1135 		play_from_to_track(((struct cdrom_ti *) arg)->cdti_trk0,
1136 				   ((struct cdrom_ti *) arg)->cdti_trk1);
1137 		return 0;
1138 	case CDROMSTOP:
1139 		PAUSED = 0;
1140 		if (cd->dsb & dsb_play_in_progress)
1141 			return type_0_command(c_stop, 1);
1142 		else
1143 			return 0;
1144 	case CDROMPAUSE:
1145 		get_drive_status();
1146 		if (cd->dsb & dsb_play_in_progress) {
1147 			type_0_command(c_stop, 1);
1148 			type_1_command(c_audio_status, 5,
1149 				       cd->audio_status);
1150 			PAUSED = 1;	/* say we're paused */
1151 		}
1152 		return 0;
1153 	case CDROMRESUME:
1154 		if (PAUSED)
1155 			play_from_to_track(0, 0);
1156 		PAUSED = 0;
1157 		return 0;
1158 	case CDROMSTART:
1159 	case CDROMVOLCTRL:
1160 		return 0;
1161 	case CDROMSUBCHNL:
1162 		return get_current_q((struct cdrom_subchnl *) arg);
1163 	default:
1164 		return -EINVAL;
1165 	}
1166 }
1167 
1168 /* Ioctl. These ioctls are specific to the cm206 driver. I have made
1169    some driver statistics accessible through ioctl calls.
1170  */
1171 
cm206_ioctl(struct cdrom_device_info * cdi,unsigned int cmd,unsigned long arg)1172 static int cm206_ioctl(struct cdrom_device_info *cdi, unsigned int cmd,
1173 		       unsigned long arg)
1174 {
1175 	switch (cmd) {
1176 #ifdef STATISTICS
1177 	case CM206CTL_GET_STAT:
1178 		if (arg >= NR_STATS)
1179 			return -EINVAL;
1180 		else
1181 			return cd->stats[arg];
1182 	case CM206CTL_GET_LAST_STAT:
1183 		if (arg >= NR_STATS)
1184 			return -EINVAL;
1185 		else
1186 			return cd->last_stat[arg];
1187 #endif
1188 	default:
1189 		debug(("Unknown ioctl call 0x%x\n", cmd));
1190 		return -EINVAL;
1191 	}
1192 }
1193 
cm206_media_changed(struct cdrom_device_info * cdi,int disc_nr)1194 int cm206_media_changed(struct cdrom_device_info *cdi, int disc_nr)
1195 {
1196 	if (cd != NULL) {
1197 		int r;
1198 		get_drive_status();	/* ensure cd->media_changed OK */
1199 		r = cd->media_changed;
1200 		cd->media_changed = 0;	/* clear bit */
1201 		return r;
1202 	} else
1203 		return -EIO;
1204 }
1205 
1206 /* The new generic cdrom support. Routines should be concise, most of
1207    the logic should be in cdrom.c */
1208 
1209 /* returns number of times device is in use */
cm206_open_files(struct cdrom_device_info * cdi)1210 int cm206_open_files(struct cdrom_device_info *cdi)
1211 {
1212 	if (cd)
1213 		return cd->openfiles;
1214 	return -1;
1215 }
1216 
1217 /* controls tray movement */
cm206_tray_move(struct cdrom_device_info * cdi,int position)1218 int cm206_tray_move(struct cdrom_device_info *cdi, int position)
1219 {
1220 	if (position) {		/* 1: eject */
1221 		type_0_command(c_open_tray, 1);
1222 		invalidate_toc();
1223 	} else
1224 		type_0_command(c_close_tray, 1);	/* 0: close */
1225 	return 0;
1226 }
1227 
1228 /* gives current state of the drive */
cm206_drive_status(struct cdrom_device_info * cdi,int slot_nr)1229 int cm206_drive_status(struct cdrom_device_info *cdi, int slot_nr)
1230 {
1231 	get_drive_status();
1232 	if (cd->dsb & dsb_tray_not_closed)
1233 		return CDS_TRAY_OPEN;
1234 	if (!(cd->dsb & dsb_disc_present))
1235 		return CDS_NO_DISC;
1236 	if (cd->dsb & dsb_drive_not_ready)
1237 		return CDS_DRIVE_NOT_READY;
1238 	return CDS_DISC_OK;
1239 }
1240 
1241 /* locks or unlocks door lock==1: lock; return 0 upon success */
cm206_lock_door(struct cdrom_device_info * cdi,int lock)1242 int cm206_lock_door(struct cdrom_device_info *cdi, int lock)
1243 {
1244 	uch command = (lock) ? c_lock_tray : c_unlock_tray;
1245 	type_0_command(command, 1);	/* wait and get dsb */
1246 	/* the logic calculates the success, 0 means successful */
1247 	return lock ^ ((cd->dsb & dsb_tray_locked) != 0);
1248 }
1249 
1250 /* Although a session start should be in LBA format, we return it in
1251    MSF format because it is slightly easier, and the new generic ioctl
1252    will take care of the necessary conversion. */
cm206_get_last_session(struct cdrom_device_info * cdi,struct cdrom_multisession * mssp)1253 int cm206_get_last_session(struct cdrom_device_info *cdi,
1254 			   struct cdrom_multisession *mssp)
1255 {
1256 	if (!FIRST_TRACK)
1257 		get_disc_status();
1258 	if (mssp != NULL) {
1259 		if (DISC_STATUS & cds_multi_session) {	/* multi-session */
1260 			mssp->addr.msf.frame = cd->disc_status[3];
1261 			mssp->addr.msf.second = cd->disc_status[4];
1262 			mssp->addr.msf.minute = cd->disc_status[5];
1263 			mssp->addr_format = CDROM_MSF;
1264 			mssp->xa_flag = 1;
1265 		} else {
1266 			mssp->xa_flag = 0;
1267 		}
1268 		return 1;
1269 	}
1270 	return 0;
1271 }
1272 
cm206_get_upc(struct cdrom_device_info * cdi,struct cdrom_mcn * mcn)1273 int cm206_get_upc(struct cdrom_device_info *cdi, struct cdrom_mcn *mcn)
1274 {
1275 	uch upc[10];
1276 	char *ret = mcn->medium_catalog_number;
1277 	int i;
1278 
1279 	if (type_1_command(c_read_upc, 10, upc))
1280 		return -EIO;
1281 	for (i = 0; i < 13; i++) {
1282 		int w = i / 2 + 1, r = i % 2;
1283 		if (r)
1284 			ret[i] = 0x30 | (upc[w] & 0x0f);
1285 		else
1286 			ret[i] = 0x30 | ((upc[w] >> 4) & 0x0f);
1287 	}
1288 	ret[13] = '\0';
1289 	return 0;
1290 }
1291 
cm206_reset(struct cdrom_device_info * cdi)1292 int cm206_reset(struct cdrom_device_info *cdi)
1293 {
1294 	stop_read();
1295 	reset_cm260();
1296 	outw(dc_normal | dc_break | READ_AHEAD, r_data_control);
1297 	mdelay(1);		/* 750 musec minimum */
1298 	outw(dc_normal | READ_AHEAD, r_data_control);
1299 	cd->sector_last = -1;	/* flag no data buffered */
1300 	cd->adapter_last = -1;
1301 	invalidate_toc();
1302 	return 0;
1303 }
1304 
cm206_select_speed(struct cdrom_device_info * cdi,int speed)1305 int cm206_select_speed(struct cdrom_device_info *cdi, int speed)
1306 {
1307 	int r;
1308 	switch (speed) {
1309 	case 0:
1310 		r = type_0_command(c_auto_mode, 1);
1311 		break;
1312 	case 1:
1313 		r = type_0_command(c_force_1x, 1);
1314 		break;
1315 	case 2:
1316 		r = type_0_command(c_force_2x, 1);
1317 		break;
1318 	default:
1319 		return -1;
1320 	}
1321 	if (r < 0)
1322 		return r;
1323 	else
1324 		return 1;
1325 }
1326 
1327 static struct cdrom_device_ops cm206_dops = {
1328 	open:cm206_open,
1329 	release:cm206_release,
1330 	drive_status:cm206_drive_status,
1331 	media_changed:cm206_media_changed,
1332 	tray_move:cm206_tray_move,
1333 	lock_door:cm206_lock_door,
1334 	select_speed:cm206_select_speed,
1335 	get_last_session:cm206_get_last_session,
1336 	get_mcn:cm206_get_upc,
1337 	reset:cm206_reset,
1338 	audio_ioctl:cm206_audio_ioctl,
1339 	dev_ioctl:cm206_ioctl,
1340 	capability:CDC_CLOSE_TRAY | CDC_OPEN_TRAY | CDC_LOCK |
1341 	    CDC_MULTI_SESSION | CDC_MEDIA_CHANGED |
1342 	    CDC_MCN | CDC_PLAY_AUDIO | CDC_SELECT_SPEED |
1343 	    CDC_IOCTLS | CDC_DRIVE_STATUS,
1344 	n_minors:1,
1345 };
1346 
1347 
1348 static struct cdrom_device_info cm206_info = {
1349 	ops:&cm206_dops,
1350 	speed:2,
1351 	capacity:1,
1352 	name:"cm206",
1353 };
1354 
1355 /* This routine gets called during initialization if things go wrong,
1356  * can be used in cleanup_module as well. */
cleanup(int level)1357 static void cleanup(int level)
1358 {
1359 	switch (level) {
1360 	case 4:
1361 		if (unregister_cdrom(&cm206_info)) {
1362 			printk("Can't unregister cdrom cm206\n");
1363 			return;
1364 		}
1365 		if (devfs_unregister_blkdev(MAJOR_NR, "cm206")) {
1366 			printk("Can't unregister major cm206\n");
1367 			return;
1368 		}
1369 		blk_cleanup_queue(BLK_DEFAULT_QUEUE(MAJOR_NR));
1370 	case 3:
1371 		free_irq(cm206_irq, NULL);
1372 	case 2:
1373 	case 1:
1374 		kfree(cd);
1375 		release_region(cm206_base, 16);
1376 	default:;
1377 	}
1378 }
1379 
1380 /* This function probes for the adapter card. It returns the base
1381    address if it has found the adapter card. One can specify a base
1382    port to probe specifically, or 0 which means span all possible
1383    bases.
1384 
1385    Linus says it is too dangerous to use writes for probing, so we
1386    stick with pure reads for a while. Hope that 8 possible ranges,
1387    check_region, 15 bits of one port and 6 of another make things
1388    likely enough to accept the region on the first hit...
1389  */
probe_base_port(int base)1390 int __init probe_base_port(int base)
1391 {
1392 	int b = 0x300, e = 0x370;	/* this is the range of start addresses */
1393 	volatile int fool, i;
1394 
1395 	if (base)
1396 		b = e = base;
1397 	for (base = b; base <= e; base += 0x10) {
1398 		if (check_region(base, 0x10))
1399 			continue;
1400 		for (i = 0; i < 3; i++)
1401 			fool = inw(base + 2);	/* empty possibly uart_receive_buffer */
1402 		if ((inw(base + 6) & 0xffef) != 0x0001 ||	/* line_status */
1403 		    (inw(base) & 0xad00) != 0)	/* data status */
1404 			continue;
1405 		return (base);
1406 	}
1407 	return 0;
1408 }
1409 
1410 #if !defined(MODULE) || defined(AUTO_PROBE_MODULE)
1411 /* Probe for irq# nr. If nr==0, probe for all possible irq's. */
probe_irq(int nr)1412 int __init probe_irq(int nr)
1413 {
1414 	int irqs, irq;
1415 	outw(dc_normal | READ_AHEAD, r_data_control);	/* disable irq-generation */
1416 	sti();
1417 	irqs = probe_irq_on();
1418 	reset_cm260();		/* causes interrupt */
1419 	udelay(100);		/* wait for it */
1420 	irq = probe_irq_off(irqs);
1421 	outw(dc_normal | READ_AHEAD, r_data_control);	/* services interrupt */
1422 	if (nr && irq != nr && irq > 0)
1423 		return 0;	/* wrong interrupt happened */
1424 	else
1425 		return irq;
1426 }
1427 #endif
1428 
cm206_init(void)1429 int __init cm206_init(void)
1430 {
1431 	uch e = 0;
1432 	long int size = sizeof(struct cm206_struct);
1433 
1434 	printk(KERN_INFO "cm206 cdrom driver " REVISION);
1435 	cm206_base = probe_base_port(auto_probe ? 0 : cm206_base);
1436 	if (!cm206_base) {
1437 		printk(" can't find adapter!\n");
1438 		return -EIO;
1439 	}
1440 	printk(" adapter at 0x%x", cm206_base);
1441 	request_region(cm206_base, 16, "cm206");
1442 	cd = (struct cm206_struct *) kmalloc(size, GFP_KERNEL);
1443 	if (!cd)
1444 		return -EIO;
1445 	/* Now we have found the adaptor card, try to reset it. As we have
1446 	 * found out earlier, this process generates an interrupt as well,
1447 	 * so we might just exploit that fact for irq probing! */
1448 #if !defined(MODULE) || defined(AUTO_PROBE_MODULE)
1449 	cm206_irq = probe_irq(auto_probe ? 0 : cm206_irq);
1450 	if (cm206_irq <= 0) {
1451 		printk("can't find IRQ!\n");
1452 		cleanup(1);
1453 		return -EIO;
1454 	} else
1455 		printk(" IRQ %d found\n", cm206_irq);
1456 #else
1457 	cli();
1458 	reset_cm260();
1459 	/* Now, the problem here is that reset_cm260 can generate an
1460 	   interrupt. It seems that this can cause a kernel oops some time
1461 	   later. So we wait a while and `service' this interrupt. */
1462 	mdelay(1);
1463 	outw(dc_normal | READ_AHEAD, r_data_control);
1464 	sti();
1465 	printk(" using IRQ %d\n", cm206_irq);
1466 #endif
1467 	if (send_receive_polled(c_drive_configuration) !=
1468 	    c_drive_configuration) {
1469 		printk(KERN_INFO " drive not there\n");
1470 		cleanup(1);
1471 		return -EIO;
1472 	}
1473 	e = send_receive_polled(c_gimme);
1474 	printk(KERN_INFO "Firmware revision %d", e & dcf_revision_code);
1475 	if (e & dcf_transfer_rate)
1476 		printk(" double");
1477 	else
1478 		printk(" single");
1479 	printk(" speed drive");
1480 	if (e & dcf_motorized_tray)
1481 		printk(", motorized tray");
1482 	if (request_irq(cm206_irq, cm206_interrupt, 0, "cm206", NULL)) {
1483 		printk("\nUnable to reserve IRQ---aborted\n");
1484 		cleanup(2);
1485 		return -EIO;
1486 	}
1487 	printk(".\n");
1488 	if (devfs_register_blkdev(MAJOR_NR, "cm206", &cm206_bdops) != 0) {
1489 		printk(KERN_INFO "Cannot register for major %d!\n",
1490 		       MAJOR_NR);
1491 		cleanup(3);
1492 		return -EIO;
1493 	}
1494 	cm206_info.dev = MKDEV(MAJOR_NR, 0);
1495 	if (register_cdrom(&cm206_info) != 0) {
1496 		printk(KERN_INFO "Cannot register for cdrom %d!\n",
1497 		       MAJOR_NR);
1498 		cleanup(3);
1499 		return -EIO;
1500 	}
1501 	devfs_plain_cdrom(&cm206_info, &cm206_bdops);
1502 	blk_init_queue(BLK_DEFAULT_QUEUE(MAJOR_NR), DEVICE_REQUEST);
1503 	blksize_size[MAJOR_NR] = cm206_blocksizes;
1504 	read_ahead[MAJOR_NR] = 16;	/* reads ahead what? */
1505 	init_bh(CM206_BH, cm206_bh);
1506 
1507 	memset(cd, 0, sizeof(*cd));	/* give'm some reasonable value */
1508 	cd->sector_last = -1;	/* flag no data buffered */
1509 	cd->adapter_last = -1;
1510 	cd->timer.function = cm206_timeout;
1511 	cd->max_sectors = (inw(r_data_status) & ds_ram_size) ? 24 : 97;
1512 	printk(KERN_INFO "%d kB adapter memory available, "
1513 	       " %ld bytes kernel memory used.\n", cd->max_sectors * 2,
1514 	       size);
1515 	return 0;
1516 }
1517 
1518 #ifdef MODULE
1519 
1520 
parse_options(void)1521 static void __init parse_options(void)
1522 {
1523 	int i;
1524 	for (i = 0; i < 2; i++) {
1525 		if (0x300 <= cm206[i] && i <= 0x370
1526 		    && cm206[i] % 0x10 == 0) {
1527 			cm206_base = cm206[i];
1528 			auto_probe = 0;
1529 		} else if (3 <= cm206[i] && cm206[i] <= 15) {
1530 			cm206_irq = cm206[i];
1531 			auto_probe = 0;
1532 		}
1533 	}
1534 }
1535 
__cm206_init(void)1536 int __cm206_init(void)
1537 {
1538 	parse_options();
1539 #if !defined(AUTO_PROBE_MODULE)
1540 	auto_probe = 0;
1541 #endif
1542 	return cm206_init();
1543 }
1544 
cm206_exit(void)1545 void __exit cm206_exit(void)
1546 {
1547 	cleanup(4);
1548 	printk(KERN_INFO "cm206 removed\n");
1549 }
1550 
1551 module_init(__cm206_init);
1552 module_exit(cm206_exit);
1553 
1554 #else				/* !MODULE */
1555 
1556 /* This setup function accepts either `auto' or numbers in the range
1557  * 3--11 (for irq) or 0x300--0x370 (for base port) or both. */
1558 
cm206_setup(char * s)1559 static int __init cm206_setup(char *s)
1560 {
1561 	int i, p[4];
1562 
1563 	(void) get_options(s, ARRAY_SIZE(p), p);
1564 
1565 	if (!strcmp(s, "auto"))
1566 		auto_probe = 1;
1567 	for (i = 1; i <= p[0]; i++) {
1568 		if (0x300 <= p[i] && i <= 0x370 && p[i] % 0x10 == 0) {
1569 			cm206_base = p[i];
1570 			auto_probe = 0;
1571 		} else if (3 <= p[i] && p[i] <= 15) {
1572 			cm206_irq = p[i];
1573 			auto_probe = 0;
1574 		}
1575 	}
1576 	return 1;
1577 }
1578 
1579 __setup("cm206=", cm206_setup);
1580 
1581 #endif				/* !MODULE */
1582 
1583 
1584 /*
1585  * Local variables:
1586  * compile-command: "gcc -D__KERNEL__ -I/usr/src/linux/include -Wall -Wstrict-prototypes -O2 -fomit-frame-pointer -pipe -fno-strength-reduce -m486 -DMODULE -DMODVERSIONS -include /usr/src/linux/include/linux/modversions.h  -c -o cm206.o cm206.c"
1587  * End:
1588  */
1589