import of ftp.dlink.com/GPL/DSMG-600_reB/ppclinux.tar.gz
[linux-2.4.21-pre4.git] / 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.1.1.1 2005/04/11 02:50:17 jack 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.1.1.1 $"
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 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
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
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.  */
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 */
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. */
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. */
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
926 uch bcdbin(unsigned char bcd)
927 {                               /* stolen from mcd.c! */
928         return (bcd >> 4) * 10 + (bcd & 0xf);
929 }
930
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  */
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
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 */
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
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
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
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
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 */
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 */
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
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
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 */
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 */
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 */
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 */
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. */
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
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
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
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. */
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  */
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. */
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
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
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
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
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
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  */