File: /usr/src/linux/drivers/cdrom/cm206.c

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     
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     
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     
330     uch send_receive_polled(int command)
331     {
332     	send_command_polled(command);
333     	return receive_echo_polled();
334     }
335     
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     
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 */
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 */
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     
464     void cm206_delay(int nr_jiffies)
465     {
466     	DECLARE_WAIT_QUEUE_HEAD(wait);
467     	sleep_or_timeout(&wait, nr_jiffies);
468     }
469     
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     
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     
520     inline uch receive_echo(void)
521     {
522     	return receive_byte(UART_TIMEOUT);
523     }
524     
525     inline uch send_receive(int command)
526     {
527     	send_command(command);
528     	return receive_echo();
529     }
530     
531     inline uch wait_dsb(void)
532     {
533     	return receive_byte(DSB_TIMEOUT);
534     }
535     
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     
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.' */
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 */
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     
580     inline int fsm2lba(uch * fsm)
581     {
582     	return fsm[0] + 75 * (fsm[1] - 2 + 60 * fsm[2]);
583     }
584     
585     inline int f_s_m2lba(uch f, uch s, uch m)
586     {
587     	return f + 75 * (s - 2 + 60 * m);
588     }
589     
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     
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     
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. */
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
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     
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      */
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     
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     /* The new open. The real opening strategy is defined in cdrom.c. */
769     
770     static int cm206_open(struct cdrom_device_info *cdi, int purpose)
771     {
772     	MOD_INC_USE_COUNT;
773     	if (!cd->openfiles) {	/* reset only first time */
774     		cd->background = 0;
775     		reset_cm260();
776     		cd->adapter_last = -1;	/* invalidate adapter memory */
777     		cd->sector_last = -1;
778     	}
779     	++cd->openfiles;
780     	stats(open);
781     	return 0;
782     }
783     
784     static void cm206_release(struct cdrom_device_info *cdi)
785     {
786     	if (cd->openfiles == 1) {
787     		if (cd->background) {
788     			cd->background = 0;
789     			stop_read();
790     		}
791     		cd->sector_last = -1;	/* Make our internal buffer invalid */
792     		FIRST_TRACK = 0;	/* No valid disc status */
793     	}
794     	--cd->openfiles;
795     	MOD_DEC_USE_COUNT;
796     }
797     
798     /* Empty buffer empties $sectors$ sectors of the adapter card buffer,
799      * and then reads a sector in kernel memory.  */
800     void empty_buffer(int sectors)
801     {
802     	while (sectors >= 0) {
803     		transport_data(r_fifo_output_buffer,
804     			       cd->sector + cd->fifo_overflowed,
805     			       RAW_SECTOR_SIZE / 2 - cd->fifo_overflowed);
806     		--sectors;
807     		++cd->adapter_first;	/* update the current adapter sector */
808     		cd->fifo_overflowed = 0;	/* reset overflow bit */
809     		stats(sector_transferred);
810     	}
811     	cd->sector_first = cd->adapter_first - 1;
812     	cd->sector_last = cd->adapter_first;	/* update the buffer sector */
813     }
814     
815     /* try_adapter. This function determines if the requested sector is
816        in adapter memory, or will appear there soon. Returns 0 upon
817        success */
818     int try_adapter(int sector)
819     {
820     	if (cd->adapter_first <= sector && sector < cd->adapter_last) {
821     		/* sector is in adapter memory */
822     		empty_buffer(sector - cd->adapter_first);
823     		return 0;
824     	} else if (cd->background == 1 && cd->adapter_first <= sector
825     		   && sector < cd->adapter_first + cd->max_sectors) {
826     		/* a read is going on, we can wait for it */
827     		cd->wait_back = 1;
828     		while (sector >= cd->adapter_last) {
829     			if (sleep_or_timeout(&cd->data, DATA_TIMEOUT)) {
830     				debug(("Timed out during background wait: %d %d %d %d\n", sector, cd->adapter_last, cd->adapter_first, cd->background));
831     				stats(back_read_timeout);
832     				cd->wait_back = 0;
833     				return -1;
834     			}
835     		}
836     		cd->wait_back = 0;
837     		empty_buffer(sector - cd->adapter_first);
838     		return 0;
839     	} else
840     		return -2;
841     }
842     
843     /* This is not a very smart implementation. We could optimize for 
844        consecutive block numbers. I'm not convinced this would really
845        bring down the processor load. */
846     static void do_cm206_request(request_queue_t * q)
847     {
848     	long int i, cd_sec_no;
849     	int quarter, error;
850     	uch *source, *dest;
851     
852     	while (1) {		/* repeat until all requests have been satisfied */
853     		INIT_REQUEST;
854     		if (QUEUE_EMPTY || CURRENT->rq_status == RQ_INACTIVE)
855     			return;
856     		if (CURRENT->cmd != READ) {
857     			debug(("Non-read command %d on cdrom\n",
858     			       CURRENT->cmd));
859     			end_request(0);
860     			continue;
861     		}
862     		spin_unlock_irq(&io_request_lock);
863     		error = 0;
864     		for (i = 0; i < CURRENT->nr_sectors; i++) {
865     			int e1, e2;
866     			cd_sec_no = (CURRENT->sector + i) / BLOCKS_ISO;	/* 4 times 512 bytes */
867     			quarter = (CURRENT->sector + i) % BLOCKS_ISO;
868     			dest = CURRENT->buffer + i * LINUX_BLOCK_SIZE;
869     			/* is already in buffer memory? */
870     			if (cd->sector_first <= cd_sec_no
871     			    && cd_sec_no < cd->sector_last) {
872     				source =
873     				    ((uch *) cd->sector) + 16 +
874     				    quarter * LINUX_BLOCK_SIZE +
875     				    (cd_sec_no -
876     				     cd->sector_first) * RAW_SECTOR_SIZE;
877     				memcpy(dest, source, LINUX_BLOCK_SIZE);
878     			} else if (!(e1 = try_adapter(cd_sec_no)) ||
879     				   !(e2 = read_sector(cd_sec_no))) {
880     				source =
881     				    ((uch *) cd->sector) + 16 +
882     				    quarter * LINUX_BLOCK_SIZE;
883     				memcpy(dest, source, LINUX_BLOCK_SIZE);
884     			} else {
885     				error = 1;
886     				debug(("cm206_request: %d %d\n", e1, e2));
887     			}
888     		}
889     		spin_lock_irq(&io_request_lock);
890     		end_request(!error);
891     	}
892     }
893     
894     /* Audio support. I've tried very hard, but the cm206 drive doesn't 
895        seem to have a get_toc (table-of-contents) function, while i'm
896        pretty sure it must read the toc upon disc insertion. Therefore
897        this function has been implemented through a binary search 
898        strategy. All track starts that happen to be found are stored in
899        cd->toc[], for future use. 
900     
901        I've spent a whole day on a bug that only shows under Workman---
902        I don't get it. Tried everything, nothing works. If workman asks
903        for track# 0xaa, it'll get the wrong time back. Any other program
904        receives the correct value. I'm stymied.
905     */
906     
907     /* seek seeks to address lba. It does wait to arrive there. */
908     void seek(int lba)
909     {
910     	int i;
911     	uch seek_command[4] = { c_seek, };
912     
913     	fsm(lba, &seek_command[1]);
914     	for (i = 0; i < 4; i++)
915     		type_0_command(seek_command[i], 0);
916     	cd->dsb = wait_dsb();
917     }
918     
919     uch bcdbin(unsigned char bcd)
920     {				/* stolen from mcd.c! */
921     	return (bcd >> 4) * 10 + (bcd & 0xf);
922     }
923     
924     inline uch normalize_track(uch track)
925     {
926     	if (track < 1)
927     		return 1;
928     	if (track > LAST_TRACK)
929     		return LAST_TRACK + 1;
930     	return track;
931     }
932     
933     /* This function does a binary search for track start. It records all
934      * tracks seen in the process. Input $track$ must be between 1 and
935      * #-of-tracks+1.  Note that the start of the disc must be in toc[1].fsm. 
936      */
937     int get_toc_lba(uch track)
938     {
939     	int max = 74 * 60 * 75 - 150, min = fsm2lba(cd->toc[1].fsm);
940     	int i, lba, l, old_lba = 0;
941     	uch *q = cd->q;
942     	uch ct;			/* current track */
943     	int binary = 0;
944     	const int skip = 3 * 60 * 75;	/* 3 minutes */
945     
946     	for (i = track; i > 0; i--)
947     		if (cd->toc[i].track) {
948     			min = fsm2lba(cd->toc[i].fsm);
949     			break;
950     		}
951     	lba = min + skip;
952     	do {
953     		seek(lba);
954     		type_1_command(c_read_current_q, 10, q);
955     		ct = normalize_track(q[1]);
956     		if (!cd->toc[ct].track) {
957     			l = q[9] - bcdbin(q[5]) + 75 * (q[8] -
958     							bcdbin(q[4]) - 2 +
959     							60 * (q[7] -
960     							      bcdbin(q
961     								     [3])));
962     			cd->toc[ct].track = q[1];	/* lead out still 0xaa */
963     			fsm(l, cd->toc[ct].fsm);
964     			cd->toc[ct].q0 = q[0];	/* contains adr and ctrl info */
965     			if (ct == track)
966     				return l;
967     		}
968     		old_lba = lba;
969     		if (binary) {
970     			if (ct < track)
971     				min = lba;
972     			else
973     				max = lba;
974     			lba = (min + max) / 2;
975     		} else {
976     			if (ct < track)
977     				lba += skip;
978     			else {
979     				binary = 1;
980     				max = lba;
981     				min = lba - skip;
982     				lba = (min + max) / 2;
983     			}
984     		}
985     	} while (lba != old_lba);
986     	return lba;
987     }
988     
989     void update_toc_entry(uch track)
990     {
991     	track = normalize_track(track);
992     	if (!cd->toc[track].track)
993     		get_toc_lba(track);
994     }
995     
996     /* return 0 upon success */
997     int read_toc_header(struct cdrom_tochdr *hp)
998     {
999     	if (!FIRST_TRACK)
1000     		get_disc_status();
1001     	if (hp) {
1002     		int i;
1003     		hp->cdth_trk0 = FIRST_TRACK;
1004     		hp->cdth_trk1 = LAST_TRACK;
1005     		/* fill in first track position */
1006     		for (i = 0; i < 3; i++)
1007     			cd->toc[1].fsm[i] = cd->disc_status[3 + i];
1008     		update_toc_entry(LAST_TRACK + 1);	/* find most entries */
1009     		return 0;
1010     	}
1011     	return -1;
1012     }
1013     
1014     void play_from_to_msf(struct cdrom_msf *msfp)
1015     {
1016     	uch play_command[] = { c_play,
1017     		msfp->cdmsf_frame0, msfp->cdmsf_sec0, msfp->cdmsf_min0,
1018     		msfp->cdmsf_frame1, msfp->cdmsf_sec1, msfp->cdmsf_min1, 2,
1019     		    2
1020     	};
1021     	int i;
1022     	for (i = 0; i < 9; i++)
1023     		type_0_command(play_command[i], 0);
1024     	for (i = 0; i < 3; i++)
1025     		PLAY_TO.fsm[i] = play_command[i + 4];
1026     	PLAY_TO.track = 0;	/* say no track end */
1027     	cd->dsb = wait_dsb();
1028     }
1029     
1030     void play_from_to_track(int from, int to)
1031     {
1032     	uch play_command[8] = { c_play, };
1033     	int i;
1034     
1035     	if (from == 0) {	/* continue paused play */
1036     		for (i = 0; i < 3; i++) {
1037     			play_command[i + 1] = cd->audio_status[i + 2];
1038     			play_command[i + 4] = PLAY_TO.fsm[i];
1039     		}
1040     	} else {
1041     		update_toc_entry(from);
1042     		update_toc_entry(to + 1);
1043     		for (i = 0; i < 3; i++) {
1044     			play_command[i + 1] = cd->toc[from].fsm[i];
1045     			PLAY_TO.fsm[i] = play_command[i + 4] =
1046     			    cd->toc[to + 1].fsm[i];
1047     		}
1048     		PLAY_TO.track = to;
1049     	}
1050     	for (i = 0; i < 7; i++)
1051     		type_0_command(play_command[i], 0);
1052     	for (i = 0; i < 2; i++)
1053     		type_0_command(0x2, 0);	/* volume */
1054     	cd->dsb = wait_dsb();
1055     }
1056     
1057     int get_current_q(struct cdrom_subchnl *qp)
1058     {
1059     	int i;
1060     	uch *q = cd->q;
1061     	if (type_1_command(c_read_current_q, 10, q))
1062     		return 0;
1063     /*  q[0] = bcdbin(q[0]); Don't think so! */
1064     	for (i = 2; i < 6; i++)
1065     		q[i] = bcdbin(q[i]);
1066     	qp->cdsc_adr = q[0] & 0xf;
1067     	qp->cdsc_ctrl = q[0] >> 4;	/* from mcd.c */
1068     	qp->cdsc_trk = q[1];
1069     	qp->cdsc_ind = q[2];
1070     	if (qp->cdsc_format == CDROM_MSF) {
1071     		qp->cdsc_reladdr.msf.minute = q[3];
1072     		qp->cdsc_reladdr.msf.second = q[4];
1073     		qp->cdsc_reladdr.msf.frame = q[5];
1074     		qp->cdsc_absaddr.msf.minute = q[7];
1075     		qp->cdsc_absaddr.msf.second = q[8];
1076     		qp->cdsc_absaddr.msf.frame = q[9];
1077     	} else {
1078     		qp->cdsc_reladdr.lba = f_s_m2lba(q[5], q[4], q[3]);
1079     		qp->cdsc_absaddr.lba = f_s_m2lba(q[9], q[8], q[7]);
1080     	}
1081     	get_drive_status();
1082     	if (cd->dsb & dsb_play_in_progress)
1083     		qp->cdsc_audiostatus = CDROM_AUDIO_PLAY;
1084     	else if (PAUSED)
1085     		qp->cdsc_audiostatus = CDROM_AUDIO_PAUSED;
1086     	else
1087     		qp->cdsc_audiostatus = CDROM_AUDIO_NO_STATUS;
1088     	return 0;
1089     }
1090     
1091     void invalidate_toc(void)
1092     {
1093     	memset(cd->toc, 0, sizeof(cd->toc));
1094     	memset(cd->disc_status, 0, sizeof(cd->disc_status));
1095     }
1096     
1097     /* cdrom.c guarantees that cdte_format == CDROM_MSF */
1098     void get_toc_entry(struct cdrom_tocentry *ep)
1099     {
1100     	uch track = normalize_track(ep->cdte_track);
1101     	update_toc_entry(track);
1102     	ep->cdte_addr.msf.frame = cd->toc[track].fsm[0];
1103     	ep->cdte_addr.msf.second = cd->toc[track].fsm[1];
1104     	ep->cdte_addr.msf.minute = cd->toc[track].fsm[2];
1105     	ep->cdte_adr = cd->toc[track].q0 & 0xf;
1106     	ep->cdte_ctrl = cd->toc[track].q0 >> 4;
1107     	ep->cdte_datamode = 0;
1108     }
1109     
1110     /* Audio ioctl.  Ioctl commands connected to audio are in such an
1111      * idiosyncratic i/o format, that we leave these untouched. Return 0
1112      * upon success. Memory checking has been done by cdrom_ioctl(), the
1113      * calling function, as well as LBA/MSF sanitization.
1114     */
1115     int cm206_audio_ioctl(struct cdrom_device_info *cdi, unsigned int cmd,
1116     		      void *arg)
1117     {
1118     	switch (cmd) {
1119     	case CDROMREADTOCHDR:
1120     		return read_toc_header((struct cdrom_tochdr *) arg);
1121     	case CDROMREADTOCENTRY:
1122     		get_toc_entry((struct cdrom_tocentry *) arg);
1123     		return 0;
1124     	case CDROMPLAYMSF:
1125     		play_from_to_msf((struct cdrom_msf *) arg);
1126     		return 0;
1127     	case CDROMPLAYTRKIND:	/* admittedly, not particularly beautiful */
1128     		play_from_to_track(((struct cdrom_ti *) arg)->cdti_trk0,
1129     				   ((struct cdrom_ti *) arg)->cdti_trk1);
1130     		return 0;
1131     	case CDROMSTOP:
1132     		PAUSED = 0;
1133     		if (cd->dsb & dsb_play_in_progress)
1134     			return type_0_command(c_stop, 1);
1135     		else
1136     			return 0;
1137     	case CDROMPAUSE:
1138     		get_drive_status();
1139     		if (cd->dsb & dsb_play_in_progress) {
1140     			type_0_command(c_stop, 1);
1141     			type_1_command(c_audio_status, 5,
1142     				       cd->audio_status);
1143     			PAUSED = 1;	/* say we're paused */
1144     		}
1145     		return 0;
1146     	case CDROMRESUME:
1147     		if (PAUSED)
1148     			play_from_to_track(0, 0);
1149     		PAUSED = 0;
1150     		return 0;
1151     	case CDROMSTART:
1152     	case CDROMVOLCTRL:
1153     		return 0;
1154     	case CDROMSUBCHNL:
1155     		return get_current_q((struct cdrom_subchnl *) arg);
1156     	default:
1157     		return -EINVAL;
1158     	}
1159     }
1160     
1161     /* Ioctl. These ioctls are specific to the cm206 driver. I have made
1162        some driver statistics accessible through ioctl calls.
1163      */
1164     
1165     static int cm206_ioctl(struct cdrom_device_info *cdi, unsigned int cmd,
1166     		       unsigned long arg)
1167     {
1168     	switch (cmd) {
1169     #ifdef STATISTICS
1170     	case CM206CTL_GET_STAT:
1171     		if (arg >= NR_STATS)
1172     			return -EINVAL;
1173     		else
1174     			return cd->stats[arg];
1175     	case CM206CTL_GET_LAST_STAT:
1176     		if (arg >= NR_STATS)
1177     			return -EINVAL;
1178     		else
1179     			return cd->last_stat[arg];
1180     #endif
1181     	default:
1182     		debug(("Unknown ioctl call 0x%x\n", cmd));
1183     		return -EINVAL;
1184     	}
1185     }
1186     
1187     int cm206_media_changed(struct cdrom_device_info *cdi, int disc_nr)
1188     {
1189     	if (cd != NULL) {
1190     		int r;
1191     		get_drive_status();	/* ensure cd->media_changed OK */
1192     		r = cd->media_changed;
1193     		cd->media_changed = 0;	/* clear bit */
1194     		return r;
1195     	} else
1196     		return -EIO;
1197     }
1198     
1199     /* The new generic cdrom support. Routines should be concise, most of
1200        the logic should be in cdrom.c */
1201     
1202     /* returns number of times device is in use */
1203     int cm206_open_files(struct cdrom_device_info *cdi)
1204     {
1205     	if (cd)
1206     		return cd->openfiles;
1207     	return -1;
1208     }
1209     
1210     /* controls tray movement */
1211     int cm206_tray_move(struct cdrom_device_info *cdi, int position)
1212     {
1213     	if (position) {		/* 1: eject */
1214     		type_0_command(c_open_tray, 1);
1215     		invalidate_toc();
1216     	} else
1217     		type_0_command(c_close_tray, 1);	/* 0: close */
1218     	return 0;
1219     }
1220     
1221     /* gives current state of the drive */
1222     int cm206_drive_status(struct cdrom_device_info *cdi, int slot_nr)
1223     {
1224     	get_drive_status();
1225     	if (cd->dsb & dsb_tray_not_closed)
1226     		return CDS_TRAY_OPEN;
1227     	if (!(cd->dsb & dsb_disc_present))
1228     		return CDS_NO_DISC;
1229     	if (cd->dsb & dsb_drive_not_ready)
1230     		return CDS_DRIVE_NOT_READY;
1231     	return CDS_DISC_OK;
1232     }
1233     
1234     /* locks or unlocks door lock==1: lock; return 0 upon success */
1235     int cm206_lock_door(struct cdrom_device_info *cdi, int lock)
1236     {
1237     	uch command = (lock) ? c_lock_tray : c_unlock_tray;
1238     	type_0_command(command, 1);	/* wait and get dsb */
1239     	/* the logic calculates the success, 0 means successful */
1240     	return lock ^ ((cd->dsb & dsb_tray_locked) != 0);
1241     }
1242     
1243     /* Although a session start should be in LBA format, we return it in 
1244        MSF format because it is slightly easier, and the new generic ioctl
1245        will take care of the necessary conversion. */
1246     int cm206_get_last_session(struct cdrom_device_info *cdi,
1247     			   struct cdrom_multisession *mssp)
1248     {
1249     	if (!FIRST_TRACK)
1250     		get_disc_status();
1251     	if (mssp != NULL) {
1252     		if (DISC_STATUS & cds_multi_session) {	/* multi-session */
1253     			mssp->addr.msf.frame = cd->disc_status[3];
1254     			mssp->addr.msf.second = cd->disc_status[4];
1255     			mssp->addr.msf.minute = cd->disc_status[5];
1256     			mssp->addr_format = CDROM_MSF;
1257     			mssp->xa_flag = 1;
1258     		} else {
1259     			mssp->xa_flag = 0;
1260     		}
1261     		return 1;
1262     	}
1263     	return 0;
1264     }
1265     
1266     int cm206_get_upc(struct cdrom_device_info *cdi, struct cdrom_mcn *mcn)
1267     {
1268     	uch upc[10];
1269     	char *ret = mcn->medium_catalog_number;
1270     	int i;
1271     
1272     	if (type_1_command(c_read_upc, 10, upc))
1273     		return -EIO;
1274     	for (i = 0; i < 13; i++) {
1275     		int w = i / 2 + 1, r = i % 2;
1276     		if (r)
1277     			ret[i] = 0x30 | (upc[w] & 0x0f);
1278     		else
1279     			ret[i] = 0x30 | ((upc[w] >> 4) & 0x0f);
1280     	}
1281     	ret[13] = '\0';
1282     	return 0;
1283     }
1284     
1285     int cm206_reset(struct cdrom_device_info *cdi)
1286     {
1287     	stop_read();
1288     	reset_cm260();
1289     	outw(dc_normal | dc_break | READ_AHEAD, r_data_control);
1290     	mdelay(1);		/* 750 musec minimum */
1291     	outw(dc_normal | READ_AHEAD, r_data_control);
1292     	cd->sector_last = -1;	/* flag no data buffered */
1293     	cd->adapter_last = -1;
1294     	invalidate_toc();
1295     	return 0;
1296     }
1297     
1298     int cm206_select_speed(struct cdrom_device_info *cdi, int speed)
1299     {
1300     	int r;
1301     	switch (speed) {
1302     	case 0:
1303     		r = type_0_command(c_auto_mode, 1);
1304     		break;
1305     	case 1:
1306     		r = type_0_command(c_force_1x, 1);
1307     		break;
1308     	case 2:
1309     		r = type_0_command(c_force_2x, 1);
1310     		break;
1311     	default:
1312     		return -1;
1313     	}
1314     	if (r < 0)
1315     		return r;
1316     	else
1317     		return 1;
1318     }
1319     
1320     static struct cdrom_device_ops cm206_dops = {
1321     	open:cm206_open,
1322     	release:cm206_release,
1323     	drive_status:cm206_drive_status,
1324     	media_changed:cm206_media_changed,
1325     	tray_move:cm206_tray_move,
1326     	lock_door:cm206_lock_door,
1327     	select_speed:cm206_select_speed,
1328     	get_last_session:cm206_get_last_session,
1329     	get_mcn:cm206_get_upc,
1330     	reset:cm206_reset,
1331     	audio_ioctl:cm206_audio_ioctl,
1332     	dev_ioctl:cm206_ioctl,
1333     	capability:CDC_CLOSE_TRAY | CDC_OPEN_TRAY | CDC_LOCK |
1334     	    CDC_MULTI_SESSION | CDC_MEDIA_CHANGED |
1335     	    CDC_MCN | CDC_PLAY_AUDIO | CDC_SELECT_SPEED |
1336     	    CDC_IOCTLS | CDC_DRIVE_STATUS,
1337     	n_minors:1,
1338     };
1339     
1340     
1341     static struct cdrom_device_info cm206_info = {
1342     	ops:&cm206_dops,
1343     	speed:2,
1344     	capacity:1,
1345     	name:"cm206",
1346     };
1347     
1348     /* This routine gets called during initialization if things go wrong,
1349      * can be used in cleanup_module as well. */
1350     static void cleanup(int level)
1351     {
1352     	switch (level) {
1353     	case 4:
1354     		if (unregister_cdrom(&cm206_info)) {
1355     			printk("Can't unregister cdrom cm206\n");
1356     			return;
1357     		}
1358     		if (devfs_unregister_blkdev(MAJOR_NR, "cm206")) {
1359     			printk("Can't unregister major cm206\n");
1360     			return;
1361     		}
1362     		blk_cleanup_queue(BLK_DEFAULT_QUEUE(MAJOR_NR));
1363     	case 3:
1364     		free_irq(cm206_irq, NULL);
1365     	case 2:
1366     	case 1:
1367     		kfree(cd);
1368     		release_region(cm206_base, 16);
1369     	default:;
1370     	}
1371     }
1372     
1373     /* This function probes for the adapter card. It returns the base
1374        address if it has found the adapter card. One can specify a base 
1375        port to probe specifically, or 0 which means span all possible
1376        bases. 
1377     
1378        Linus says it is too dangerous to use writes for probing, so we
1379        stick with pure reads for a while. Hope that 8 possible ranges,
1380        check_region, 15 bits of one port and 6 of another make things
1381        likely enough to accept the region on the first hit...
1382      */
1383     int __init probe_base_port(int base)
1384     {
1385     	int b = 0x300, e = 0x370;	/* this is the range of start addresses */
1386     	volatile int fool, i;
1387     
1388     	if (base)
1389     		b = e = base;
1390     	for (base = b; base <= e; base += 0x10) {
1391     		if (check_region(base, 0x10))
1392     			continue;
1393     		for (i = 0; i < 3; i++)
1394     			fool = inw(base + 2);	/* empty possibly uart_receive_buffer */
1395     		if ((inw(base + 6) & 0xffef) != 0x0001 ||	/* line_status */
1396     		    (inw(base) & 0xad00) != 0)	/* data status */
1397     			continue;
1398     		return (base);
1399     	}
1400     	return 0;
1401     }
1402     
1403     #if !defined(MODULE) || defined(AUTO_PROBE_MODULE)
1404     /* Probe for irq# nr. If nr==0, probe for all possible irq's. */
1405     int __init probe_irq(int nr)
1406     {
1407     	int irqs, irq;
1408     	outw(dc_normal | READ_AHEAD, r_data_control);	/* disable irq-generation */
1409     	sti();
1410     	irqs = probe_irq_on();
1411     	reset_cm260();		/* causes interrupt */
1412     	udelay(100);		/* wait for it */
1413     	irq = probe_irq_off(irqs);
1414     	outw(dc_normal | READ_AHEAD, r_data_control);	/* services interrupt */
1415     	if (nr && irq != nr && irq > 0)
1416     		return 0;	/* wrong interrupt happened */
1417     	else
1418     		return irq;
1419     }
1420     #endif
1421     
1422     int __init cm206_init(void)
1423     {
1424     	uch e = 0;
1425     	long int size = sizeof(struct cm206_struct);
1426     
1427     	printk(KERN_INFO "cm206 cdrom driver " REVISION);
1428     	cm206_base = probe_base_port(auto_probe ? 0 : cm206_base);
1429     	if (!cm206_base) {
1430     		printk(" can't find adapter!\n");
1431     		return -EIO;
1432     	}
1433     	printk(" adapter at 0x%x", cm206_base);
1434     	request_region(cm206_base, 16, "cm206");
1435     	cd = (struct cm206_struct *) kmalloc(size, GFP_KERNEL);
1436     	if (!cd)
1437     		return -EIO;
1438     	/* Now we have found the adaptor card, try to reset it. As we have
1439     	 * found out earlier, this process generates an interrupt as well,
1440     	 * so we might just exploit that fact for irq probing! */
1441     #if !defined(MODULE) || defined(AUTO_PROBE_MODULE)
1442     	cm206_irq = probe_irq(auto_probe ? 0 : cm206_irq);
1443     	if (cm206_irq <= 0) {
1444     		printk("can't find IRQ!\n");
1445     		cleanup(1);
1446     		return -EIO;
1447     	} else
1448     		printk(" IRQ %d found\n", cm206_irq);
1449     #else
1450     	cli();
1451     	reset_cm260();
1452     	/* Now, the problem here is that reset_cm260 can generate an
1453     	   interrupt. It seems that this can cause a kernel oops some time
1454     	   later. So we wait a while and `service' this interrupt. */
1455     	mdelay(1);
1456     	outw(dc_normal | READ_AHEAD, r_data_control);
1457     	sti();
1458     	printk(" using IRQ %d\n", cm206_irq);
1459     #endif
1460     	if (send_receive_polled(c_drive_configuration) !=
1461     	    c_drive_configuration) {
1462     		printk(KERN_INFO " drive not there\n");
1463     		cleanup(1);
1464     		return -EIO;
1465     	}
1466     	e = send_receive_polled(c_gimme);
1467     	printk(KERN_INFO "Firmware revision %d", e & dcf_revision_code);
1468     	if (e & dcf_transfer_rate)
1469     		printk(" double");
1470     	else
1471     		printk(" single");
1472     	printk(" speed drive");
1473     	if (e & dcf_motorized_tray)
1474     		printk(", motorized tray");
1475     	if (request_irq(cm206_irq, cm206_interrupt, 0, "cm206", NULL)) {
1476     		printk("\nUnable to reserve IRQ---aborted\n");
1477     		cleanup(2);
1478     		return -EIO;
1479     	}
1480     	printk(".\n");
1481     	if (devfs_register_blkdev(MAJOR_NR, "cm206", &cdrom_fops) != 0) {
1482     		printk(KERN_INFO "Cannot register for major %d!\n",
1483     		       MAJOR_NR);
1484     		cleanup(3);
1485     		return -EIO;
1486     	}
1487     	cm206_info.dev = MKDEV(MAJOR_NR, 0);
1488     	if (register_cdrom(&cm206_info) != 0) {
1489     		printk(KERN_INFO "Cannot register for cdrom %d!\n",
1490     		       MAJOR_NR);
1491     		cleanup(3);
1492     		return -EIO;
1493     	}
1494     	blk_init_queue(BLK_DEFAULT_QUEUE(MAJOR_NR), DEVICE_REQUEST);
1495     	blksize_size[MAJOR_NR] = cm206_blocksizes;
1496     	read_ahead[MAJOR_NR] = 16;	/* reads ahead what? */
1497     	init_bh(CM206_BH, cm206_bh);
1498     
1499     	memset(cd, 0, sizeof(*cd));	/* give'm some reasonable value */
1500     	cd->sector_last = -1;	/* flag no data buffered */
1501     	cd->adapter_last = -1;
1502     	cd->timer.function = cm206_timeout;
1503     	cd->max_sectors = (inw(r_data_status) & ds_ram_size) ? 24 : 97;
1504     	printk(KERN_INFO "%d kB adapter memory available, "
1505     	       " %ld bytes kernel memory used.\n", cd->max_sectors * 2,
1506     	       size);
1507     	return 0;
1508     }
1509     
1510     #ifdef MODULE
1511     
1512     
1513     static void __init parse_options(void)
1514     {
1515     	int i;
1516     	for (i = 0; i < 2; i++) {
1517     		if (0x300 <= cm206[i] && i <= 0x370
1518     		    && cm206[i] % 0x10 == 0) {
1519     			cm206_base = cm206[i];
1520     			auto_probe = 0;
1521     		} else if (3 <= cm206[i] && cm206[i] <= 15) {
1522     			cm206_irq = cm206[i];
1523     			auto_probe = 0;
1524     		}
1525     	}
1526     }
1527     
1528     int __cm206_init(void)
1529     {
1530     	parse_options();
1531     #if !defined(AUTO_PROBE_MODULE)
1532     	auto_probe = 0;
1533     #endif
1534     	return cm206_init();
1535     }
1536     
1537     void __exit cm206_exit(void)
1538     {
1539     	cleanup(4);
1540     	printk(KERN_INFO "cm206 removed\n");
1541     }
1542     
1543     module_init(__cm206_init);
1544     module_exit(cm206_exit);
1545     
1546     #else				/* !MODULE */
1547     
1548     /* This setup function accepts either `auto' or numbers in the range
1549      * 3--11 (for irq) or 0x300--0x370 (for base port) or both. */
1550     
1551     static int __init cm206_setup(char *s)
1552     {
1553     	int i, p[4];
1554     
1555     	(void) get_options(s, ARRAY_SIZE(p), p);
1556     
1557     	if (!strcmp(s, "auto"))
1558     		auto_probe = 1;
1559     	for (i = 1; i <= p[0]; i++) {
1560     		if (0x300 <= p[i] && i <= 0x370 && p[i] % 0x10 == 0) {
1561     			cm206_base = p[i];
1562     			auto_probe = 0;
1563     		} else if (3 <= p[i] && p[i] <= 15) {
1564     			cm206_irq = p[i];
1565     			auto_probe = 0;
1566     		}
1567     	}
1568     	return 1;
1569     }
1570     
1571     __setup("cm206=", cm206_setup);
1572     
1573     #endif				/* !MODULE */
1574     
1575     
1576     /*
1577      * Local variables:
1578      * 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"
1579      * End:
1580      */
1581