spelling: s/trough/through/
[linux-2.6.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.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 through 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
202 #include <linux/blkdev.h>
203
204 #undef DEBUG
205 #define STATISTICS              /* record times and frequencies of events */
206 #define AUTO_PROBE_MODULE
207 #define USE_INSW
208
209 #include "cm206.h"
210
211 /* This variable defines whether or not to probe for adapter base port 
212    address and interrupt request. It can be overridden by the boot 
213    parameter `auto'.
214 */
215 static int auto_probe = 1;      /* Yes, why not? */
216
217 static int cm206_base = CM206_BASE;
218 static int cm206_irq = CM206_IRQ;
219 #ifdef MODULE
220 static int cm206[2] = { 0, 0 }; /* for compatible `insmod' parameter passing */
221 #endif
222
223 MODULE_PARM(cm206_base, "i");   /* base */
224 MODULE_PARM(cm206_irq, "i");    /* irq */
225 MODULE_PARM(cm206, "1-2i");     /* base,irq or irq,base */
226 MODULE_PARM(auto_probe, "i");   /* auto probe base and irq */
227 MODULE_LICENSE("GPL");
228
229 #define POLLOOP 100             /* milliseconds */
230 #define READ_AHEAD 1            /* defines private buffer, waste! */
231 #define BACK_AHEAD 1            /* defines adapter-read ahead */
232 #define DATA_TIMEOUT (3*HZ)     /* measured in jiffies (10 ms) */
233 #define UART_TIMEOUT (5*HZ/100)
234 #define DSB_TIMEOUT (7*HZ)      /* time for the slowest command to finish */
235 #define UR_SIZE 4               /* uart receive buffer fifo size */
236
237 #define LINUX_BLOCK_SIZE 512    /* WHERE is this defined? */
238 #define RAW_SECTOR_SIZE 2352    /* ok, is also defined in cdrom.h */
239 #define ISO_SECTOR_SIZE 2048
240 #define BLOCKS_ISO (ISO_SECTOR_SIZE/LINUX_BLOCK_SIZE)   /* 4 */
241 #define CD_SYNC_HEAD 16         /* CD_SYNC + CD_HEAD */
242
243 #ifdef STATISTICS               /* keep track of errors in counters */
244 #define stats(i) { ++cd->stats[st_ ## i]; \
245                      cd->last_stat[st_ ## i] = cd->stat_counter++; \
246                  }
247 #else
248 #define stats(i) (void) 0;
249 #endif
250
251 #define Debug(a) {printk (KERN_DEBUG); printk a;}
252 #ifdef DEBUG
253 #define debug(a) Debug(a)
254 #else
255 #define debug(a) (void) 0;
256 #endif
257
258 typedef unsigned char uch;      /* 8-bits */
259 typedef unsigned short ush;     /* 16-bits */
260
261 struct toc_struct {             /* private copy of Table of Contents */
262         uch track, fsm[3], q0;
263 };
264
265 struct cm206_struct {
266         volatile ush intr_ds;   /* data status read on last interrupt */
267         volatile ush intr_ls;   /* uart line status read on last interrupt */
268         volatile uch ur[UR_SIZE];       /* uart receive buffer fifo */
269         volatile uch ur_w, ur_r;        /* write/read buffer index */
270         volatile uch dsb, cc;   /* drive status byte and condition (error) code */
271         int command;            /* command to be written to the uart */
272         int openfiles;
273         ush sector[READ_AHEAD * RAW_SECTOR_SIZE / 2];   /* buffered cd-sector */
274         int sector_first, sector_last;  /* range of these sectors */
275         wait_queue_head_t uart; /* wait queues for interrupt */
276         wait_queue_head_t data;
277         struct timer_list timer;        /* time-out */
278         char timed_out;
279         signed char max_sectors;        /* number of sectors that fit in adapter mem */
280         char wait_back;         /* we're waiting for a background-read */
281         char background;        /* is a read going on in the background? */
282         int adapter_first;      /* if so, that's the starting sector */
283         int adapter_last;
284         char fifo_overflowed;
285         uch disc_status[7];     /* result of get_disc_status command */
286 #ifdef STATISTICS
287         int stats[NR_STATS];
288         int last_stat[NR_STATS];        /* `time' at which stat was stat */
289         int stat_counter;
290 #endif
291         struct toc_struct toc[101];     /* The whole table of contents + lead-out */
292         uch q[10];              /* Last read q-channel info */
293         uch audio_status[5];    /* last read position on pause */
294         uch media_changed;      /* record if media changed */
295 };
296
297 #define DISC_STATUS cd->disc_status[0]
298 #define FIRST_TRACK cd->disc_status[1]
299 #define LAST_TRACK cd->disc_status[2]
300 #define PAUSED cd->audio_status[0]      /* misuse this memory byte! */
301 #define PLAY_TO cd->toc[0]      /* toc[0] records end-time in play */
302
303 static struct cm206_struct *cd; /* the main memory structure */
304 static struct request_queue *cm206_queue;
305 static DEFINE_SPINLOCK(cm206_lock);
306
307 /* First, we define some polling functions. These are actually
308    only being used in the initialization. */
309
310 static void send_command_polled(int command)
311 {
312         int loop = POLLOOP;
313         while (!(inw(r_line_status) & ls_transmitter_buffer_empty)
314                && loop > 0) {
315                 mdelay(1);      /* one millisec delay */
316                 --loop;
317         }
318         outw(command, r_uart_transmit);
319 }
320
321 static uch receive_echo_polled(void)
322 {
323         int loop = POLLOOP;
324         while (!(inw(r_line_status) & ls_receive_buffer_full) && loop > 0) {
325                 mdelay(1);
326                 --loop;
327         }
328         return ((uch) inw(r_uart_receive));
329 }
330
331 static uch send_receive_polled(int command)
332 {
333         send_command_polled(command);
334         return receive_echo_polled();
335 }
336
337 static inline void clear_ur(void)
338 {
339         if (cd->ur_r != cd->ur_w) {
340                 debug(("Deleting bytes from fifo:"));
341                 for (; cd->ur_r != cd->ur_w;
342                      cd->ur_r++, cd->ur_r %= UR_SIZE)
343                         debug((" 0x%x", cd->ur[cd->ur_r]));
344                 debug(("\n"));
345         }
346 }
347
348 static struct tasklet_struct cm206_tasklet;
349
350 /* The interrupt handler. When the cm260 generates an interrupt, very
351    much care has to be taken in reading out the registers in the right
352    order; in case of a receive_buffer_full interrupt, first the
353    uart_receive must be read, and then the line status again to
354    de-assert the interrupt line. It took me a couple of hours to find
355    this out:-( 
356
357    The function reset_cm206 appears to cause an interrupt, because
358    pulling up the INIT line clears both the uart-write-buffer /and/
359    the uart-write-buffer-empty mask. We call this a `lost interrupt,'
360    as there seems so reason for this to happen.
361 */
362
363 static irqreturn_t cm206_interrupt(int sig, void *dev_id, struct pt_regs *regs)
364 {
365         volatile ush fool;
366         cd->intr_ds = inw(r_data_status);       /* resets data_ready, data_error,
367                                                    crc_error, sync_error, toc_ready 
368                                                    interrupts */
369         cd->intr_ls = inw(r_line_status);       /* resets overrun bit */
370         debug(("Intr, 0x%x 0x%x, %d\n", cd->intr_ds, cd->intr_ls,
371                cd->background));
372         if (cd->intr_ls & ls_attention)
373                 stats(attention);
374         /* receive buffer full? */
375         if (cd->intr_ls & ls_receive_buffer_full) {
376                 cd->ur[cd->ur_w] = inb(r_uart_receive); /* get order right! */
377                 cd->intr_ls = inw(r_line_status);       /* resets rbf interrupt */
378                 debug(("receiving #%d: 0x%x\n", cd->ur_w,
379                        cd->ur[cd->ur_w]));
380                 cd->ur_w++;
381                 cd->ur_w %= UR_SIZE;
382                 if (cd->ur_w == cd->ur_r)
383                         debug(("cd->ur overflow!\n"));
384                 if (waitqueue_active(&cd->uart) && cd->background < 2) {
385                         del_timer(&cd->timer);
386                         wake_up_interruptible(&cd->uart);
387                 }
388         }
389         /* data ready in fifo? */
390         else if (cd->intr_ds & ds_data_ready) {
391                 if (cd->background)
392                         ++cd->adapter_last;
393                 if (waitqueue_active(&cd->data)
394                     && (cd->wait_back || !cd->background)) {
395                         del_timer(&cd->timer);
396                         wake_up_interruptible(&cd->data);
397                 }
398                 stats(data_ready);
399         }
400         /* ready to issue a write command? */
401         else if (cd->command && cd->intr_ls & ls_transmitter_buffer_empty) {
402                 outw(dc_normal | (inw(r_data_status) & 0x7f),
403                      r_data_control);
404                 outw(cd->command, r_uart_transmit);
405                 cd->command = 0;
406                 if (!cd->background)
407                         wake_up_interruptible(&cd->uart);
408         }
409         /* now treat errors (at least, identify them for debugging) */
410         else if (cd->intr_ds & ds_fifo_overflow) {
411                 debug(("Fifo overflow at sectors 0x%x\n",
412                        cd->sector_first));
413                 fool = inw(r_fifo_output_buffer);       /* de-assert the interrupt */
414                 cd->fifo_overflowed = 1;        /* signal one word less should be read */
415                 stats(fifo_overflow);
416         } else if (cd->intr_ds & ds_data_error) {
417                 debug(("Data error at sector 0x%x\n", cd->sector_first));
418                 stats(data_error);
419         } else if (cd->intr_ds & ds_crc_error) {
420                 debug(("CRC error at sector 0x%x\n", cd->sector_first));
421                 stats(crc_error);
422         } else if (cd->intr_ds & ds_sync_error) {
423                 debug(("Sync at sector 0x%x\n", cd->sector_first));
424                 stats(sync_error);
425         } else if (cd->intr_ds & ds_toc_ready) {
426                 /* do something appropriate */
427         }
428         /* couldn't see why this interrupt, maybe due to init */
429         else {
430                 outw(dc_normal | READ_AHEAD, r_data_control);
431                 stats(lost_intr);
432         }
433         if (cd->background
434             && (cd->adapter_last - cd->adapter_first == cd->max_sectors
435                 || cd->fifo_overflowed))
436                 tasklet_schedule(&cm206_tasklet);       /* issue a stop read command */
437         stats(interrupt);
438         return IRQ_HANDLED;
439 }
440
441 /* we have put the address of the wait queue in who */
442 static void cm206_timeout(unsigned long who)
443 {
444         cd->timed_out = 1;
445         debug(("Timing out\n"));
446         wake_up_interruptible((wait_queue_head_t *) who);
447 }
448
449 /* This function returns 1 if a timeout occurred, 0 if an interrupt
450    happened */
451 static int sleep_or_timeout(wait_queue_head_t * wait, int timeout)
452 {
453         cd->timed_out = 0;
454         init_timer(&cd->timer);
455         cd->timer.data = (unsigned long) wait;
456         cd->timer.expires = jiffies + timeout;
457         add_timer(&cd->timer);
458         debug(("going to sleep\n"));
459         interruptible_sleep_on(wait);
460         del_timer(&cd->timer);
461         if (cd->timed_out) {
462                 cd->timed_out = 0;
463                 return 1;
464         } else
465                 return 0;
466 }
467
468 static void send_command(int command)
469 {
470         debug(("Sending 0x%x\n", command));
471         if (!(inw(r_line_status) & ls_transmitter_buffer_empty)) {
472                 cd->command = command;
473                 cli();          /* don't interrupt before sleep */
474                 outw(dc_mask_sync_error | dc_no_stop_on_error |
475                      (inw(r_data_status) & 0x7f), r_data_control);
476                 /* interrupt routine sends command */
477                 if (sleep_or_timeout(&cd->uart, UART_TIMEOUT)) {
478                         debug(("Time out on write-buffer\n"));
479                         stats(write_timeout);
480                         outw(command, r_uart_transmit);
481                 }
482                 debug(("Write commmand delayed\n"));
483         } else
484                 outw(command, r_uart_transmit);
485 }
486
487 static uch receive_byte(int timeout)
488 {
489         uch ret;
490         cli();
491         debug(("cli\n"));
492         ret = cd->ur[cd->ur_r];
493         if (cd->ur_r != cd->ur_w) {
494                 sti();
495                 debug(("returning #%d: 0x%x\n", cd->ur_r,
496                        cd->ur[cd->ur_r]));
497                 cd->ur_r++;
498                 cd->ur_r %= UR_SIZE;
499                 return ret;
500         } else if (sleep_or_timeout(&cd->uart, timeout)) {      /* does sti() */
501                 debug(("Time out on receive-buffer\n"));
502 #ifdef STATISTICS
503                 if (timeout == UART_TIMEOUT)
504                         stats(receive_timeout)  /* no `;'! */
505                             else
506                         stats(dsb_timeout);
507 #endif
508                 return 0xda;
509         }
510         ret = cd->ur[cd->ur_r];
511         debug(("slept; returning #%d: 0x%x\n", cd->ur_r,
512                cd->ur[cd->ur_r]));
513         cd->ur_r++;
514         cd->ur_r %= UR_SIZE;
515         return ret;
516 }
517
518 static inline uch receive_echo(void)
519 {
520         return receive_byte(UART_TIMEOUT);
521 }
522
523 static inline uch send_receive(int command)
524 {
525         send_command(command);
526         return receive_echo();
527 }
528
529 static inline uch wait_dsb(void)
530 {
531         return receive_byte(DSB_TIMEOUT);
532 }
533
534 static int type_0_command(int command, int expect_dsb)
535 {
536         int e;
537         clear_ur();
538         if (command != (e = send_receive(command))) {
539                 debug(("command 0x%x echoed as 0x%x\n", command, e));
540                 stats(echo);
541                 return -1;
542         }
543         if (expect_dsb) {
544                 cd->dsb = wait_dsb();   /* wait for command to finish */
545         }
546         return 0;
547 }
548
549 static int type_1_command(int command, int bytes, uch * status)
550 {                               /* returns info */
551         int i;
552         if (type_0_command(command, 0))
553                 return -1;
554         for (i = 0; i < bytes; i++)
555                 status[i] = send_receive(c_gimme);
556         return 0;
557 }
558
559 /* This function resets the adapter card. We'd better not do this too
560  * often, because it tends to generate `lost interrupts.' */
561 static void reset_cm260(void)
562 {
563         outw(dc_normal | dc_initialize | READ_AHEAD, r_data_control);
564         udelay(10);             /* 3.3 mu sec minimum */
565         outw(dc_normal | READ_AHEAD, r_data_control);
566 }
567
568 /* fsm: frame-sec-min from linear address; one of many */
569 static void fsm(int lba, uch * fsm)
570 {
571         fsm[0] = lba % 75;
572         lba /= 75;
573         lba += 2;
574         fsm[1] = lba % 60;
575         fsm[2] = lba / 60;
576 }
577
578 static inline int fsm2lba(uch * fsm)
579 {
580         return fsm[0] + 75 * (fsm[1] - 2 + 60 * fsm[2]);
581 }
582
583 static inline int f_s_m2lba(uch f, uch s, uch m)
584 {
585         return f + 75 * (s - 2 + 60 * m);
586 }
587
588 static int start_read(int start)
589 {
590         uch read_sector[4] = { c_read_data, };
591         int i, e;
592
593         fsm(start, &read_sector[1]);
594         clear_ur();
595         for (i = 0; i < 4; i++)
596                 if (read_sector[i] != (e = send_receive(read_sector[i]))) {
597                         debug(("read_sector: %x echoes %x\n",
598                                read_sector[i], e));
599                         stats(echo);
600                         if (e == 0xff) {        /* this seems to happen often */
601                                 e = receive_echo();
602                                 debug(("Second try %x\n", e));
603                                 if (e != read_sector[i])
604                                         return -1;
605                         }
606                 }
607         return 0;
608 }
609
610 static int stop_read(void)
611 {
612         int e;
613         type_0_command(c_stop, 0);
614         if ((e = receive_echo()) != 0xff) {
615                 debug(("c_stop didn't send 0xff, but 0x%x\n", e));
616                 stats(stop_0xff);
617                 return -1;
618         }
619         return 0;
620 }
621
622 /* This function starts to read sectors in adapter memory, the
623    interrupt routine should stop the read. In fact, the bottom_half
624    routine takes care of this. Set a flag `background' in the cd
625    struct to indicate the process. */
626
627 static int read_background(int start, int reading)
628 {
629         if (cd->background)
630                 return -1;      /* can't do twice */
631         outw(dc_normal | BACK_AHEAD, r_data_control);
632         if (!reading && start_read(start))
633                 return -2;
634         cd->adapter_first = cd->adapter_last = start;
635         cd->background = 1;     /* flag a read is going on */
636         return 0;
637 }
638
639 #ifdef USE_INSW
640 #define transport_data insw
641 #else
642 /* this routine implements insw(,,). There was a time i had the
643    impression that there would be any difference in error-behaviour. */
644 void transport_data(int port, ush * dest, int count)
645 {
646         int i;
647         ush *d;
648         for (i = 0, d = dest; i < count; i++, d++)
649                 *d = inw(port);
650 }
651 #endif
652
653
654 #define MAX_TRIES 100
655 static int read_sector(int start)
656 {
657         int tries = 0;
658         if (cd->background) {
659                 cd->background = 0;
660                 cd->adapter_last = -1;  /* invalidate adapter memory */
661                 stop_read();
662         }
663         cd->fifo_overflowed = 0;
664         reset_cm260();          /* empty fifo etc. */
665         if (start_read(start))
666                 return -1;
667         do {
668                 if (sleep_or_timeout(&cd->data, DATA_TIMEOUT)) {
669                         debug(("Read timed out sector 0x%x\n", start));
670                         stats(read_timeout);
671                         stop_read();
672                         return -3;
673                 }
674                 tries++;
675         } while (cd->intr_ds & ds_fifo_empty && tries < MAX_TRIES);
676         if (tries > 1)
677                 debug(("Took me some tries\n"))
678                     else
679         if (tries == MAX_TRIES)
680                 debug(("MAX_TRIES tries for read sector\n"));
681         transport_data(r_fifo_output_buffer, cd->sector,
682                        READ_AHEAD * RAW_SECTOR_SIZE / 2);
683         if (read_background(start + READ_AHEAD, 1))
684                 stats(read_background);
685         cd->sector_first = start;
686         cd->sector_last = start + READ_AHEAD;
687         stats(read_restarted);
688         return 0;
689 }
690
691 /* The function of bottom-half is to send a stop command to the drive
692    This isn't easy because the routine is not `owned' by any process;
693    we can't go to sleep! The variable cd->background gives the status:
694    0 no read pending
695    1 a read is pending
696    2 c_stop waits for write_buffer_empty
697    3 c_stop waits for receive_buffer_full: echo
698    4 c_stop waits for receive_buffer_full: 0xff
699 */
700
701 static void cm206_tasklet_func(unsigned long ignore)
702 {
703         debug(("bh: %d\n", cd->background));
704         switch (cd->background) {
705         case 1:
706                 stats(bh);
707                 if (!(cd->intr_ls & ls_transmitter_buffer_empty)) {
708                         cd->command = c_stop;
709                         outw(dc_mask_sync_error | dc_no_stop_on_error |
710                              (inw(r_data_status) & 0x7f), r_data_control);
711                         cd->background = 2;
712                         break;  /* we'd better not time-out here! */
713                 } else
714                         outw(c_stop, r_uart_transmit);
715                 /* fall into case 2: */
716         case 2:
717                 /* the write has been satisfied by interrupt routine */
718                 cd->background = 3;
719                 break;
720         case 3:
721                 if (cd->ur_r != cd->ur_w) {
722                         if (cd->ur[cd->ur_r] != c_stop) {
723                                 debug(("cm206_bh: c_stop echoed 0x%x\n",
724                                        cd->ur[cd->ur_r]));
725                                 stats(echo);
726                         }
727                         cd->ur_r++;
728                         cd->ur_r %= UR_SIZE;
729                 }
730                 cd->background++;
731                 break;
732         case 4:
733                 if (cd->ur_r != cd->ur_w) {
734                         if (cd->ur[cd->ur_r] != 0xff) {
735                                 debug(("cm206_bh: c_stop reacted with 0x%x\n", cd->ur[cd->ur_r]));
736                                 stats(stop_0xff);
737                         }
738                         cd->ur_r++;
739                         cd->ur_r %= UR_SIZE;
740                 }
741                 cd->background = 0;
742         }
743 }
744
745 static DECLARE_TASKLET(cm206_tasklet, cm206_tasklet_func, 0);
746
747 /* This command clears the dsb_possible_media_change flag, so we must 
748  * retain it.
749  */
750 static 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 static 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         if (!cd->openfiles) {   /* reset only first time */
773                 cd->background = 0;
774                 reset_cm260();
775                 cd->adapter_last = -1;  /* invalidate adapter memory */
776                 cd->sector_last = -1;
777         }
778         ++cd->openfiles;
779         stats(open);
780         return 0;
781 }
782
783 static void cm206_release(struct cdrom_device_info *cdi)
784 {
785         if (cd->openfiles == 1) {
786                 if (cd->background) {
787                         cd->background = 0;
788                         stop_read();
789                 }
790                 cd->sector_last = -1;   /* Make our internal buffer invalid */
791                 FIRST_TRACK = 0;        /* No valid disc status */
792         }
793         --cd->openfiles;
794 }
795
796 /* Empty buffer empties $sectors$ sectors of the adapter card buffer,
797  * and then reads a sector in kernel memory.  */
798 static void empty_buffer(int sectors)
799 {
800         while (sectors >= 0) {
801                 transport_data(r_fifo_output_buffer,
802                                cd->sector + cd->fifo_overflowed,
803                                RAW_SECTOR_SIZE / 2 - cd->fifo_overflowed);
804                 --sectors;
805                 ++cd->adapter_first;    /* update the current adapter sector */
806                 cd->fifo_overflowed = 0;        /* reset overflow bit */
807                 stats(sector_transferred);
808         }
809         cd->sector_first = cd->adapter_first - 1;
810         cd->sector_last = cd->adapter_first;    /* update the buffer sector */
811 }
812
813 /* try_adapter. This function determines if the requested sector is
814    in adapter memory, or will appear there soon. Returns 0 upon
815    success */
816 static int try_adapter(int sector)
817 {
818         if (cd->adapter_first <= sector && sector < cd->adapter_last) {
819                 /* sector is in adapter memory */
820                 empty_buffer(sector - cd->adapter_first);
821                 return 0;
822         } else if (cd->background == 1 && cd->adapter_first <= sector
823                    && sector < cd->adapter_first + cd->max_sectors) {
824                 /* a read is going on, we can wait for it */
825                 cd->wait_back = 1;
826                 while (sector >= cd->adapter_last) {
827                         if (sleep_or_timeout(&cd->data, DATA_TIMEOUT)) {
828                                 debug(("Timed out during background wait: %d %d %d %d\n", sector, cd->adapter_last, cd->adapter_first, cd->background));
829                                 stats(back_read_timeout);
830                                 cd->wait_back = 0;
831                                 return -1;
832                         }
833                 }
834                 cd->wait_back = 0;
835                 empty_buffer(sector - cd->adapter_first);
836                 return 0;
837         } else
838                 return -2;
839 }
840
841 /* This is not a very smart implementation. We could optimize for 
842    consecutive block numbers. I'm not convinced this would really
843    bring down the processor load. */
844 static void do_cm206_request(request_queue_t * q)
845 {
846         long int i, cd_sec_no;
847         int quarter, error;
848         uch *source, *dest;
849         struct request *req;
850
851         while (1) {     /* repeat until all requests have been satisfied */
852                 req = elv_next_request(q);
853                 if (!req)
854                         return;
855
856                 if (req->cmd != READ) {
857                         debug(("Non-read command %d on cdrom\n", req->cmd));
858                         end_request(req, 0);
859                         continue;
860                 }
861                 spin_unlock_irq(q->queue_lock);
862                 error = 0;
863                 for (i = 0; i < req->nr_sectors; i++) {
864                         int e1, e2;
865                         cd_sec_no = (req->sector + i) / BLOCKS_ISO;     /* 4 times 512 bytes */
866                         quarter = (req->sector + i) % BLOCKS_ISO;
867                         dest = req->buffer + i * LINUX_BLOCK_SIZE;
868                         /* is already in buffer memory? */
869                         if (cd->sector_first <= cd_sec_no
870                             && cd_sec_no < cd->sector_last) {
871                                 source =
872                                     ((uch *) cd->sector) + 16 +
873                                     quarter * LINUX_BLOCK_SIZE +
874                                     (cd_sec_no -
875                                      cd->sector_first) * RAW_SECTOR_SIZE;
876                                 memcpy(dest, source, LINUX_BLOCK_SIZE);
877                         } else if (!(e1 = try_adapter(cd_sec_no)) ||
878                                    !(e2 = read_sector(cd_sec_no))) {
879                                 source =
880                                     ((uch *) cd->sector) + 16 +
881                                     quarter * LINUX_BLOCK_SIZE;
882                                 memcpy(dest, source, LINUX_BLOCK_SIZE);
883                         } else {
884                                 error = 1;
885                                 debug(("cm206_request: %d %d\n", e1, e2));
886                         }
887                 }
888                 spin_lock_irq(q->queue_lock);
889                 end_request(req, !error);
890         }
891 }
892
893 /* Audio support. I've tried very hard, but the cm206 drive doesn't 
894    seem to have a get_toc (table-of-contents) function, while i'm
895    pretty sure it must read the toc upon disc insertion. Therefore
896    this function has been implemented through a binary search 
897    strategy. All track starts that happen to be found are stored in
898    cd->toc[], for future use. 
899
900    I've spent a whole day on a bug that only shows under Workman---
901    I don't get it. Tried everything, nothing works. If workman asks
902    for track# 0xaa, it'll get the wrong time back. Any other program
903    receives the correct value. I'm stymied.
904 */
905
906 /* seek seeks to address lba. It does wait to arrive there. */
907 static void seek(int lba)
908 {
909         int i;
910         uch seek_command[4] = { c_seek, };
911
912         fsm(lba, &seek_command[1]);
913         for (i = 0; i < 4; i++)
914                 type_0_command(seek_command[i], 0);
915         cd->dsb = wait_dsb();
916 }
917
918 uch bcdbin(unsigned char bcd)
919 {                               /* stolen from mcd.c! */
920         return (bcd >> 4) * 10 + (bcd & 0xf);
921 }
922
923 static inline uch normalize_track(uch track)
924 {
925         if (track < 1)
926                 return 1;
927         if (track > LAST_TRACK)
928                 return LAST_TRACK + 1;
929         return track;
930 }
931
932 /* This function does a binary search for track start. It records all
933  * tracks seen in the process. Input $track$ must be between 1 and
934  * #-of-tracks+1.  Note that the start of the disc must be in toc[1].fsm. 
935  */
936 static int get_toc_lba(uch track)
937 {
938         int max = 74 * 60 * 75 - 150, min = fsm2lba(cd->toc[1].fsm);
939         int i, lba, l, old_lba = 0;
940         uch *q = cd->q;
941         uch ct;                 /* current track */
942         int binary = 0;
943         const int skip = 3 * 60 * 75;   /* 3 minutes */
944
945         for (i = track; i > 0; i--)
946                 if (cd->toc[i].track) {
947                         min = fsm2lba(cd->toc[i].fsm);
948                         break;
949                 }
950         lba = min + skip;
951         do {
952                 seek(lba);
953                 type_1_command(c_read_current_q, 10, q);
954                 ct = normalize_track(q[1]);
955                 if (!cd->toc[ct].track) {
956                         l = q[9] - bcdbin(q[5]) + 75 * (q[8] -
957                                                         bcdbin(q[4]) - 2 +
958                                                         60 * (q[7] -
959                                                               bcdbin(q
960                                                                      [3])));
961                         cd->toc[ct].track = q[1];       /* lead out still 0xaa */
962                         fsm(l, cd->toc[ct].fsm);
963                         cd->toc[ct].q0 = q[0];  /* contains adr and ctrl info */
964                         if (ct == track)
965                                 return l;
966                 }
967                 old_lba = lba;
968                 if (binary) {
969                         if (ct < track)
970                                 min = lba;
971                         else
972                                 max = lba;
973                         lba = (min + max) / 2;
974                 } else {
975                         if (ct < track)
976                                 lba += skip;
977                         else {
978                                 binary = 1;
979                                 max = lba;
980                                 min = lba - skip;
981                                 lba = (min + max) / 2;
982                         }
983                 }
984         } while (lba != old_lba);
985         return lba;
986 }
987
988 static void update_toc_entry(uch track)
989 {
990         track = normalize_track(track);
991         if (!cd->toc[track].track)
992                 get_toc_lba(track);
993 }
994
995 /* return 0 upon success */
996 static int read_toc_header(struct cdrom_tochdr *hp)
997 {
998         if (!FIRST_TRACK)
999                 get_disc_status();
1000         if (hp) {
1001                 int i;
1002                 hp->cdth_trk0 = FIRST_TRACK;
1003                 hp->cdth_trk1 = LAST_TRACK;
1004                 /* fill in first track position */
1005                 for (i = 0; i < 3; i++)
1006                         cd->toc[1].fsm[i] = cd->disc_status[3 + i];
1007                 update_toc_entry(LAST_TRACK + 1);       /* find most entries */
1008                 return 0;
1009         }
1010         return -1;
1011 }
1012
1013 static void play_from_to_msf(struct cdrom_msf *msfp)
1014 {
1015         uch play_command[] = { c_play,
1016                 msfp->cdmsf_frame0, msfp->cdmsf_sec0, msfp->cdmsf_min0,
1017                 msfp->cdmsf_frame1, msfp->cdmsf_sec1, msfp->cdmsf_min1, 2,
1018                     2
1019         };
1020         int i;
1021         for (i = 0; i < 9; i++)
1022                 type_0_command(play_command[i], 0);
1023         for (i = 0; i < 3; i++)
1024                 PLAY_TO.fsm[i] = play_command[i + 4];
1025         PLAY_TO.track = 0;      /* say no track end */
1026         cd->dsb = wait_dsb();
1027 }
1028
1029 static void play_from_to_track(int from, int to)
1030 {
1031         uch play_command[8] = { c_play, };
1032         int i;
1033
1034         if (from == 0) {        /* continue paused play */
1035                 for (i = 0; i < 3; i++) {
1036                         play_command[i + 1] = cd->audio_status[i + 2];
1037                         play_command[i + 4] = PLAY_TO.fsm[i];
1038                 }
1039         } else {
1040                 update_toc_entry(from);
1041                 update_toc_entry(to + 1);
1042                 for (i = 0; i < 3; i++) {
1043                         play_command[i + 1] = cd->toc[from].fsm[i];
1044                         PLAY_TO.fsm[i] = play_command[i + 4] =
1045                             cd->toc[to + 1].fsm[i];
1046                 }
1047                 PLAY_TO.track = to;
1048         }
1049         for (i = 0; i < 7; i++)
1050                 type_0_command(play_command[i], 0);
1051         for (i = 0; i < 2; i++)
1052                 type_0_command(0x2, 0); /* volume */
1053         cd->dsb = wait_dsb();
1054 }
1055
1056 static int get_current_q(struct cdrom_subchnl *qp)
1057 {
1058         int i;
1059         uch *q = cd->q;
1060         if (type_1_command(c_read_current_q, 10, q))
1061                 return 0;
1062 /*  q[0] = bcdbin(q[0]); Don't think so! */
1063         for (i = 2; i < 6; i++)
1064                 q[i] = bcdbin(q[i]);
1065         qp->cdsc_adr = q[0] & 0xf;
1066         qp->cdsc_ctrl = q[0] >> 4;      /* from mcd.c */
1067         qp->cdsc_trk = q[1];
1068         qp->cdsc_ind = q[2];
1069         if (qp->cdsc_format == CDROM_MSF) {
1070                 qp->cdsc_reladdr.msf.minute = q[3];
1071                 qp->cdsc_reladdr.msf.second = q[4];
1072                 qp->cdsc_reladdr.msf.frame = q[5];
1073                 qp->cdsc_absaddr.msf.minute = q[7];
1074                 qp->cdsc_absaddr.msf.second = q[8];
1075                 qp->cdsc_absaddr.msf.frame = q[9];
1076         } else {
1077                 qp->cdsc_reladdr.lba = f_s_m2lba(q[5], q[4], q[3]);
1078                 qp->cdsc_absaddr.lba = f_s_m2lba(q[9], q[8], q[7]);
1079         }
1080         get_drive_status();
1081         if (cd->dsb & dsb_play_in_progress)
1082                 qp->cdsc_audiostatus = CDROM_AUDIO_PLAY;
1083         else if (PAUSED)
1084                 qp->cdsc_audiostatus = CDROM_AUDIO_PAUSED;
1085         else
1086                 qp->cdsc_audiostatus = CDROM_AUDIO_NO_STATUS;
1087         return 0;
1088 }
1089
1090 static void invalidate_toc(void)
1091 {
1092         memset(cd->toc, 0, sizeof(cd->toc));
1093         memset(cd->disc_status, 0, sizeof(cd->disc_status));
1094 }
1095
1096 /* cdrom.c guarantees that cdte_format == CDROM_MSF */
1097 static void get_toc_entry(struct cdrom_tocentry *ep)
1098 {
1099         uch track = normalize_track(ep->cdte_track);
1100         update_toc_entry(track);
1101         ep->cdte_addr.msf.frame = cd->toc[track].fsm[0];
1102         ep->cdte_addr.msf.second = cd->toc[track].fsm[1];
1103         ep->cdte_addr.msf.minute = cd->toc[track].fsm[2];
1104         ep->cdte_adr = cd->toc[track].q0 & 0xf;
1105         ep->cdte_ctrl = cd->toc[track].q0 >> 4;
1106         ep->cdte_datamode = 0;
1107 }
1108
1109 /* Audio ioctl.  Ioctl commands connected to audio are in such an
1110  * idiosyncratic i/o format, that we leave these untouched. Return 0
1111  * upon success. Memory checking has been done by cdrom_ioctl(), the
1112  * calling function, as well as LBA/MSF sanitization.
1113 */
1114 static int cm206_audio_ioctl(struct cdrom_device_info *cdi, unsigned int cmd,
1115                              void *arg)
1116 {
1117         switch (cmd) {
1118         case CDROMREADTOCHDR:
1119                 return read_toc_header((struct cdrom_tochdr *) arg);
1120         case CDROMREADTOCENTRY:
1121                 get_toc_entry((struct cdrom_tocentry *) arg);
1122                 return 0;
1123         case CDROMPLAYMSF:
1124                 play_from_to_msf((struct cdrom_msf *) arg);
1125                 return 0;
1126         case CDROMPLAYTRKIND:   /* admittedly, not particularly beautiful */
1127                 play_from_to_track(((struct cdrom_ti *) arg)->cdti_trk0,
1128                                    ((struct cdrom_ti *) arg)->cdti_trk1);
1129                 return 0;
1130         case CDROMSTOP:
1131                 PAUSED = 0;
1132                 if (cd->dsb & dsb_play_in_progress)
1133                         return type_0_command(c_stop, 1);
1134                 else
1135                         return 0;
1136         case CDROMPAUSE:
1137                 get_drive_status();
1138                 if (cd->dsb & dsb_play_in_progress) {
1139                         type_0_command(c_stop, 1);
1140                         type_1_command(c_audio_status, 5,
1141                                        cd->audio_status);
1142                         PAUSED = 1;     /* say we're paused */
1143                 }
1144                 return 0;
1145         case CDROMRESUME:
1146                 if (PAUSED)
1147                         play_from_to_track(0, 0);
1148                 PAUSED = 0;
1149                 return 0;
1150         case CDROMSTART:
1151         case CDROMVOLCTRL:
1152                 return 0;
1153         case CDROMSUBCHNL:
1154                 return get_current_q((struct cdrom_subchnl *) arg);
1155         default:
1156                 return -EINVAL;
1157         }
1158 }
1159
1160 /* Ioctl. These ioctls are specific to the cm206 driver. I have made
1161    some driver statistics accessible through ioctl calls.
1162  */
1163
1164 static int cm206_ioctl(struct cdrom_device_info *cdi, unsigned int cmd,
1165                        unsigned long arg)
1166 {
1167         switch (cmd) {
1168 #ifdef STATISTICS
1169         case CM206CTL_GET_STAT:
1170                 if (arg >= NR_STATS)
1171                         return -EINVAL;
1172                 else
1173                         return cd->stats[arg];
1174         case CM206CTL_GET_LAST_STAT:
1175                 if (arg >= NR_STATS)
1176                         return -EINVAL;
1177                 else
1178                         return cd->last_stat[arg];
1179 #endif
1180         default:
1181                 debug(("Unknown ioctl call 0x%x\n", cmd));
1182                 return -EINVAL;
1183         }
1184 }
1185
1186 static int cm206_media_changed(struct cdrom_device_info *cdi, int disc_nr)
1187 {
1188         if (cd != NULL) {
1189                 int r;
1190                 get_drive_status();     /* ensure cd->media_changed OK */
1191                 r = cd->media_changed;
1192                 cd->media_changed = 0;  /* clear bit */
1193                 return r;
1194         } else
1195                 return -EIO;
1196 }
1197
1198 /* The new generic cdrom support. Routines should be concise, most of
1199    the logic should be in cdrom.c */
1200
1201
1202 /* controls tray movement */
1203 static int cm206_tray_move(struct cdrom_device_info *cdi, int position)
1204 {
1205         if (position) {         /* 1: eject */
1206                 type_0_command(c_open_tray, 1);
1207                 invalidate_toc();
1208         } else
1209                 type_0_command(c_close_tray, 1);        /* 0: close */
1210         return 0;
1211 }
1212
1213 /* gives current state of the drive */
1214 static int cm206_drive_status(struct cdrom_device_info *cdi, int slot_nr)
1215 {
1216         get_drive_status();
1217         if (cd->dsb & dsb_tray_not_closed)
1218                 return CDS_TRAY_OPEN;
1219         if (!(cd->dsb & dsb_disc_present))
1220                 return CDS_NO_DISC;
1221         if (cd->dsb & dsb_drive_not_ready)
1222                 return CDS_DRIVE_NOT_READY;
1223         return CDS_DISC_OK;
1224 }
1225
1226 /* locks or unlocks door lock==1: lock; return 0 upon success */
1227 static int cm206_lock_door(struct cdrom_device_info *cdi, int lock)
1228 {
1229         uch command = (lock) ? c_lock_tray : c_unlock_tray;
1230         type_0_command(command, 1);     /* wait and get dsb */
1231         /* the logic calculates the success, 0 means successful */
1232         return lock ^ ((cd->dsb & dsb_tray_locked) != 0);
1233 }
1234
1235 /* Although a session start should be in LBA format, we return it in 
1236    MSF format because it is slightly easier, and the new generic ioctl
1237    will take care of the necessary conversion. */
1238 static int cm206_get_last_session(struct cdrom_device_info *cdi,
1239                                   struct cdrom_multisession *mssp)
1240 {
1241         if (!FIRST_TRACK)
1242                 get_disc_status();
1243         if (mssp != NULL) {
1244                 if (DISC_STATUS & cds_multi_session) {  /* multi-session */
1245                         mssp->addr.msf.frame = cd->disc_status[3];
1246                         mssp->addr.msf.second = cd->disc_status[4];
1247                         mssp->addr.msf.minute = cd->disc_status[5];
1248                         mssp->addr_format = CDROM_MSF;
1249                         mssp->xa_flag = 1;
1250                 } else {
1251                         mssp->xa_flag = 0;
1252                 }
1253                 return 1;
1254         }
1255         return 0;
1256 }
1257
1258 static int cm206_get_upc(struct cdrom_device_info *cdi, struct cdrom_mcn *mcn)
1259 {
1260         uch upc[10];
1261         char *ret = mcn->medium_catalog_number;
1262         int i;
1263
1264         if (type_1_command(c_read_upc, 10, upc))
1265                 return -EIO;
1266         for (i = 0; i < 13; i++) {
1267                 int w = i / 2 + 1, r = i % 2;
1268                 if (r)
1269                         ret[i] = 0x30 | (upc[w] & 0x0f);
1270                 else
1271                         ret[i] = 0x30 | ((upc[w] >> 4) & 0x0f);
1272         }
1273         ret[13] = '\0';
1274         return 0;
1275 }
1276
1277 static int cm206_reset(struct cdrom_device_info *cdi)
1278 {
1279         stop_read();
1280         reset_cm260();
1281         outw(dc_normal | dc_break | READ_AHEAD, r_data_control);
1282         mdelay(1);              /* 750 musec minimum */
1283         outw(dc_normal | READ_AHEAD, r_data_control);
1284         cd->sector_last = -1;   /* flag no data buffered */
1285         cd->adapter_last = -1;
1286         invalidate_toc();
1287         return 0;
1288 }
1289
1290 static int cm206_select_speed(struct cdrom_device_info *cdi, int speed)
1291 {
1292         int r;
1293         switch (speed) {
1294         case 0:
1295                 r = type_0_command(c_auto_mode, 1);
1296                 break;
1297         case 1:
1298                 r = type_0_command(c_force_1x, 1);
1299                 break;
1300         case 2:
1301                 r = type_0_command(c_force_2x, 1);
1302                 break;
1303         default:
1304                 return -1;
1305         }
1306         if (r < 0)
1307                 return r;
1308         else
1309                 return 1;
1310 }
1311
1312 static struct cdrom_device_ops cm206_dops = {
1313         .open                   = cm206_open,
1314         .release                = cm206_release,
1315         .drive_status           = cm206_drive_status,
1316         .media_changed          = cm206_media_changed,
1317         .tray_move              = cm206_tray_move,
1318         .lock_door              = cm206_lock_door,
1319         .select_speed           = cm206_select_speed,
1320         .get_last_session       = cm206_get_last_session,
1321         .get_mcn                = cm206_get_upc,
1322         .reset                  = cm206_reset,
1323         .audio_ioctl            = cm206_audio_ioctl,
1324         .dev_ioctl              = cm206_ioctl,
1325         .capability             = CDC_CLOSE_TRAY | CDC_OPEN_TRAY | CDC_LOCK |
1326                                   CDC_MULTI_SESSION | CDC_MEDIA_CHANGED |
1327                                   CDC_MCN | CDC_PLAY_AUDIO | CDC_SELECT_SPEED |
1328                                   CDC_IOCTLS | CDC_DRIVE_STATUS,
1329         .n_minors               = 1,
1330 };
1331
1332
1333 static struct cdrom_device_info cm206_info = {
1334         .ops            = &cm206_dops,
1335         .speed          = 2,
1336         .capacity       = 1,
1337         .name           = "cm206",
1338 };
1339
1340 static int cm206_block_open(struct inode *inode, struct file *file)
1341 {
1342         return cdrom_open(&cm206_info, inode, file);
1343 }
1344
1345 static int cm206_block_release(struct inode *inode, struct file *file)
1346 {
1347         return cdrom_release(&cm206_info, file);
1348 }
1349
1350 static int cm206_block_ioctl(struct inode *inode, struct file *file,
1351                                 unsigned cmd, unsigned long arg)
1352 {
1353         return cdrom_ioctl(file, &cm206_info, inode, cmd, arg);
1354 }
1355
1356 static int cm206_block_media_changed(struct gendisk *disk)
1357 {
1358         return cdrom_media_changed(&cm206_info);
1359 }
1360
1361 static struct block_device_operations cm206_bdops =
1362 {
1363         .owner          = THIS_MODULE,
1364         .open           = cm206_block_open,
1365         .release        = cm206_block_release,
1366         .ioctl          = cm206_block_ioctl,
1367         .media_changed  = cm206_block_media_changed,
1368 };
1369
1370 static struct gendisk *cm206_gendisk;
1371
1372 /* This function probes for the adapter card. It returns the base
1373    address if it has found the adapter card. One can specify a base 
1374    port to probe specifically, or 0 which means span all possible
1375    bases. 
1376
1377    Linus says it is too dangerous to use writes for probing, so we
1378    stick with pure reads for a while. Hope that 8 possible ranges,
1379    request_region, 15 bits of one port and 6 of another make things
1380    likely enough to accept the region on the first hit...
1381  */
1382 static int __init probe_base_port(int base)
1383 {
1384         int b = 0x300, e = 0x370;       /* this is the range of start addresses */
1385         volatile int fool, i;
1386
1387         if (base)
1388                 b = e = base;
1389         for (base = b; base <= e; base += 0x10) {
1390                 if (!request_region(base, 0x10,"cm206"))
1391                         continue;
1392                 for (i = 0; i < 3; i++)
1393                         fool = inw(base + 2);   /* empty possibly uart_receive_buffer */
1394                 if ((inw(base + 6) & 0xffef) != 0x0001 ||       /* line_status */
1395                     (inw(base) & 0xad00) != 0)  { /* data status */
1396                         release_region(base,0x10);
1397                         continue;
1398                 }
1399                 return (base);
1400         }
1401         return 0;
1402 }
1403
1404 #if !defined(MODULE) || defined(AUTO_PROBE_MODULE)
1405 /* Probe for irq# nr. If nr==0, probe for all possible irq's. */
1406 static int __init probe_irq(int nr)
1407 {
1408         int irqs, irq;
1409         outw(dc_normal | READ_AHEAD, r_data_control);   /* disable irq-generation */
1410         sti();
1411         irqs = probe_irq_on();
1412         reset_cm260();          /* causes interrupt */
1413         udelay(100);            /* wait for it */
1414         irq = probe_irq_off(irqs);
1415         outw(dc_normal | READ_AHEAD, r_data_control);   /* services interrupt */
1416         if (nr && irq != nr && irq > 0)
1417                 return 0;       /* wrong interrupt happened */
1418         else
1419                 return irq;
1420 }
1421 #endif
1422
1423 int __init cm206_init(void)
1424 {
1425         uch e = 0;
1426         long int size = sizeof(struct cm206_struct);
1427         struct gendisk *disk;
1428
1429         printk(KERN_INFO "cm206 cdrom driver " REVISION);
1430         cm206_base = probe_base_port(auto_probe ? 0 : cm206_base);
1431         if (!cm206_base) {
1432                 printk(" can't find adapter!\n");
1433                 return -EIO;
1434         }
1435         printk(" adapter at 0x%x", cm206_base);
1436         cd = (struct cm206_struct *) kmalloc(size, GFP_KERNEL);
1437         if (!cd)
1438                goto out_base;
1439         /* Now we have found the adaptor card, try to reset it. As we have
1440          * found out earlier, this process generates an interrupt as well,
1441          * so we might just exploit that fact for irq probing! */
1442 #if !defined(MODULE) || defined(AUTO_PROBE_MODULE)
1443         cm206_irq = probe_irq(auto_probe ? 0 : cm206_irq);
1444         if (cm206_irq <= 0) {
1445                 printk("can't find IRQ!\n");
1446                 goto out_probe;
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                 goto out_probe;
1464         }
1465         e = send_receive_polled(c_gimme);
1466         printk(KERN_INFO "Firmware revision %d", e & dcf_revision_code);
1467         if (e & dcf_transfer_rate)
1468                 printk(" double");
1469         else
1470                 printk(" single");
1471         printk(" speed drive");
1472         if (e & dcf_motorized_tray)
1473                 printk(", motorized tray");
1474         if (request_irq(cm206_irq, cm206_interrupt, 0, "cm206", NULL)) {
1475                 printk("\nUnable to reserve IRQ---aborted\n");
1476                 goto out_probe;
1477         }
1478         printk(".\n");
1479
1480         if (register_blkdev(MAJOR_NR, "cm206"))
1481                 goto out_blkdev;
1482
1483         disk = alloc_disk(1);
1484         if (!disk)
1485                 goto out_disk;
1486         disk->major = MAJOR_NR;
1487         disk->first_minor = 0;
1488         sprintf(disk->disk_name, "cm206cd");
1489         disk->fops = &cm206_bdops;
1490         disk->flags = GENHD_FL_CD;
1491         cm206_gendisk = disk;
1492         if (register_cdrom(&cm206_info) != 0) {
1493                 printk(KERN_INFO "Cannot register for cdrom %d!\n", MAJOR_NR);
1494                 goto out_cdrom;
1495         }
1496         cm206_queue = blk_init_queue(do_cm206_request, &cm206_lock);
1497         if (!cm206_queue)
1498                 goto out_queue;
1499                 
1500         blk_queue_hardsect_size(cm206_queue, 2048);
1501         disk->queue = cm206_queue;
1502         add_disk(disk);
1503
1504         memset(cd, 0, sizeof(*cd));     /* give'm some reasonable value */
1505         cd->sector_last = -1;   /* flag no data buffered */
1506         cd->adapter_last = -1;
1507         init_timer(&cd->timer);
1508         cd->timer.function = cm206_timeout;
1509         cd->max_sectors = (inw(r_data_status) & ds_ram_size) ? 24 : 97;
1510         printk(KERN_INFO "%d kB adapter memory available, "
1511                " %ld bytes kernel memory used.\n", cd->max_sectors * 2,
1512                size);
1513         return 0;
1514
1515 out_queue:
1516         unregister_cdrom(&cm206_info);
1517 out_cdrom:
1518         put_disk(disk);
1519 out_disk:
1520         unregister_blkdev(MAJOR_NR, "cm206");
1521 out_blkdev:
1522         free_irq(cm206_irq, NULL);
1523 out_probe:
1524         kfree(cd);
1525 out_base:
1526         release_region(cm206_base, 16);
1527         return -EIO;
1528 }
1529
1530 #ifdef MODULE
1531
1532
1533 static void __init parse_options(void)
1534 {
1535         int i;
1536         for (i = 0; i < 2; i++) {
1537                 if (0x300 <= cm206[i] && i <= 0x370
1538                     && cm206[i] % 0x10 == 0) {
1539                         cm206_base = cm206[i];
1540                         auto_probe = 0;
1541                 } else if (3 <= cm206[i] && cm206[i] <= 15) {
1542                         cm206_irq = cm206[i];
1543                         auto_probe = 0;
1544                 }
1545         }
1546 }
1547
1548 static int __cm206_init(void)
1549 {
1550         parse_options();
1551 #if !defined(AUTO_PROBE_MODULE)
1552         auto_probe = 0;
1553 #endif
1554         return cm206_init();
1555 }
1556
1557 static void __exit cm206_exit(void)
1558 {
1559         del_gendisk(cm206_gendisk);
1560         put_disk(cm206_gendisk);
1561         if (unregister_cdrom(&cm206_info)) {
1562                 printk("Can't unregister cdrom cm206\n");
1563                 return;
1564         }
1565         if (unregister_blkdev(MAJOR_NR, "cm206")) {
1566                 printk("Can't unregister major cm206\n");
1567                 return;
1568         }
1569         blk_cleanup_queue(cm206_queue);
1570         free_irq(cm206_irq, NULL);
1571         kfree(cd);
1572         release_region(cm206_base, 16);
1573         printk(KERN_INFO "cm206 removed\n");
1574 }
1575
1576 module_init(__cm206_init);
1577 module_exit(cm206_exit);
1578
1579 #else                           /* !MODULE */
1580
1581 /* This setup function accepts either `auto' or numbers in the range
1582  * 3--11 (for irq) or 0x300--0x370 (for base port) or both. */
1583
1584 static int __init cm206_setup(char *s)
1585 {
1586         int i, p[4];
1587
1588         (void) get_options(s, ARRAY_SIZE(p), p);
1589
1590         if (!strcmp(s, "auto"))
1591                 auto_probe = 1;
1592         for (i = 1; i <= p[0]; i++) {
1593                 if (0x300 <= p[i] && i <= 0x370 && p[i] % 0x10 == 0) {
1594                         cm206_base = p[i];
1595                         auto_probe = 0;
1596                 } else if (3 <= p[i] && p[i] <= 15) {
1597                         cm206_irq = p[i];
1598                         auto_probe = 0;
1599                 }
1600         }
1601         return 1;
1602 }
1603
1604 __setup("cm206=", cm206_setup);
1605
1606 #endif                          /* !MODULE */
1607 MODULE_ALIAS_BLOCKDEV_MAJOR(CM206_CDROM_MAJOR);
1608
1609 /*
1610  * Local variables:
1611  * 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"
1612  * End:
1613  */