]> nv-tegra.nvidia Code Review - linux-2.6.git/blob - drivers/cdrom/cm206.c
[NETFILTER] x_table.c: sem2mutex
[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 static int cm206_media_changed(struct cdrom_device_info *cdi, int disc_nr)
1161 {
1162         if (cd != NULL) {
1163                 int r;
1164                 get_drive_status();     /* ensure cd->media_changed OK */
1165                 r = cd->media_changed;
1166                 cd->media_changed = 0;  /* clear bit */
1167                 return r;
1168         } else
1169                 return -EIO;
1170 }
1171
1172 /* The new generic cdrom support. Routines should be concise, most of
1173    the logic should be in cdrom.c */
1174
1175
1176 /* controls tray movement */
1177 static int cm206_tray_move(struct cdrom_device_info *cdi, int position)
1178 {
1179         if (position) {         /* 1: eject */
1180                 type_0_command(c_open_tray, 1);
1181                 invalidate_toc();
1182         } else
1183                 type_0_command(c_close_tray, 1);        /* 0: close */
1184         return 0;
1185 }
1186
1187 /* gives current state of the drive */
1188 static int cm206_drive_status(struct cdrom_device_info *cdi, int slot_nr)
1189 {
1190         get_drive_status();
1191         if (cd->dsb & dsb_tray_not_closed)
1192                 return CDS_TRAY_OPEN;
1193         if (!(cd->dsb & dsb_disc_present))
1194                 return CDS_NO_DISC;
1195         if (cd->dsb & dsb_drive_not_ready)
1196                 return CDS_DRIVE_NOT_READY;
1197         return CDS_DISC_OK;
1198 }
1199
1200 /* locks or unlocks door lock==1: lock; return 0 upon success */
1201 static int cm206_lock_door(struct cdrom_device_info *cdi, int lock)
1202 {
1203         uch command = (lock) ? c_lock_tray : c_unlock_tray;
1204         type_0_command(command, 1);     /* wait and get dsb */
1205         /* the logic calculates the success, 0 means successful */
1206         return lock ^ ((cd->dsb & dsb_tray_locked) != 0);
1207 }
1208
1209 /* Although a session start should be in LBA format, we return it in 
1210    MSF format because it is slightly easier, and the new generic ioctl
1211    will take care of the necessary conversion. */
1212 static int cm206_get_last_session(struct cdrom_device_info *cdi,
1213                                   struct cdrom_multisession *mssp)
1214 {
1215         if (!FIRST_TRACK)
1216                 get_disc_status();
1217         if (mssp != NULL) {
1218                 if (DISC_STATUS & cds_multi_session) {  /* multi-session */
1219                         mssp->addr.msf.frame = cd->disc_status[3];
1220                         mssp->addr.msf.second = cd->disc_status[4];
1221                         mssp->addr.msf.minute = cd->disc_status[5];
1222                         mssp->addr_format = CDROM_MSF;
1223                         mssp->xa_flag = 1;
1224                 } else {
1225                         mssp->xa_flag = 0;
1226                 }
1227                 return 1;
1228         }
1229         return 0;
1230 }
1231
1232 static int cm206_get_upc(struct cdrom_device_info *cdi, struct cdrom_mcn *mcn)
1233 {
1234         uch upc[10];
1235         char *ret = mcn->medium_catalog_number;
1236         int i;
1237
1238         if (type_1_command(c_read_upc, 10, upc))
1239                 return -EIO;
1240         for (i = 0; i < 13; i++) {
1241                 int w = i / 2 + 1, r = i % 2;
1242                 if (r)
1243                         ret[i] = 0x30 | (upc[w] & 0x0f);
1244                 else
1245                         ret[i] = 0x30 | ((upc[w] >> 4) & 0x0f);
1246         }
1247         ret[13] = '\0';
1248         return 0;
1249 }
1250
1251 static int cm206_reset(struct cdrom_device_info *cdi)
1252 {
1253         stop_read();
1254         reset_cm260();
1255         outw(dc_normal | dc_break | READ_AHEAD, r_data_control);
1256         mdelay(1);              /* 750 musec minimum */
1257         outw(dc_normal | READ_AHEAD, r_data_control);
1258         cd->sector_last = -1;   /* flag no data buffered */
1259         cd->adapter_last = -1;
1260         invalidate_toc();
1261         return 0;
1262 }
1263
1264 static int cm206_select_speed(struct cdrom_device_info *cdi, int speed)
1265 {
1266         int r;
1267         switch (speed) {
1268         case 0:
1269                 r = type_0_command(c_auto_mode, 1);
1270                 break;
1271         case 1:
1272                 r = type_0_command(c_force_1x, 1);
1273                 break;
1274         case 2:
1275                 r = type_0_command(c_force_2x, 1);
1276                 break;
1277         default:
1278                 return -1;
1279         }
1280         if (r < 0)
1281                 return r;
1282         else
1283                 return 1;
1284 }
1285
1286 static struct cdrom_device_ops cm206_dops = {
1287         .open                   = cm206_open,
1288         .release                = cm206_release,
1289         .drive_status           = cm206_drive_status,
1290         .media_changed          = cm206_media_changed,
1291         .tray_move              = cm206_tray_move,
1292         .lock_door              = cm206_lock_door,
1293         .select_speed           = cm206_select_speed,
1294         .get_last_session       = cm206_get_last_session,
1295         .get_mcn                = cm206_get_upc,
1296         .reset                  = cm206_reset,
1297         .audio_ioctl            = cm206_audio_ioctl,
1298         .capability             = CDC_CLOSE_TRAY | CDC_OPEN_TRAY | CDC_LOCK |
1299                                   CDC_MULTI_SESSION | CDC_MEDIA_CHANGED |
1300                                   CDC_MCN | CDC_PLAY_AUDIO | CDC_SELECT_SPEED |
1301                                   CDC_DRIVE_STATUS,
1302         .n_minors               = 1,
1303 };
1304
1305
1306 static struct cdrom_device_info cm206_info = {
1307         .ops            = &cm206_dops,
1308         .speed          = 2,
1309         .capacity       = 1,
1310         .name           = "cm206",
1311 };
1312
1313 static int cm206_block_open(struct inode *inode, struct file *file)
1314 {
1315         return cdrom_open(&cm206_info, inode, file);
1316 }
1317
1318 static int cm206_block_release(struct inode *inode, struct file *file)
1319 {
1320         return cdrom_release(&cm206_info, file);
1321 }
1322
1323 static int cm206_block_ioctl(struct inode *inode, struct file *file,
1324                                 unsigned cmd, unsigned long arg)
1325 {
1326         switch (cmd) {
1327 #ifdef STATISTICS
1328         case CM206CTL_GET_STAT:
1329                 if (arg >= NR_STATS)
1330                         return -EINVAL;
1331                 return cd->stats[arg];
1332         case CM206CTL_GET_LAST_STAT:
1333                 if (arg >= NR_STATS)
1334                         return -EINVAL;
1335                 return cd->last_stat[arg];
1336 #endif
1337         default:
1338                 break;
1339         }
1340
1341         return cdrom_ioctl(file, &cm206_info, inode, cmd, arg);
1342 }
1343
1344 static int cm206_block_media_changed(struct gendisk *disk)
1345 {
1346         return cdrom_media_changed(&cm206_info);
1347 }
1348
1349 static struct block_device_operations cm206_bdops =
1350 {
1351         .owner          = THIS_MODULE,
1352         .open           = cm206_block_open,
1353         .release        = cm206_block_release,
1354         .ioctl          = cm206_block_ioctl,
1355         .media_changed  = cm206_block_media_changed,
1356 };
1357
1358 static struct gendisk *cm206_gendisk;
1359
1360 /* This function probes for the adapter card. It returns the base
1361    address if it has found the adapter card. One can specify a base 
1362    port to probe specifically, or 0 which means span all possible
1363    bases. 
1364
1365    Linus says it is too dangerous to use writes for probing, so we
1366    stick with pure reads for a while. Hope that 8 possible ranges,
1367    request_region, 15 bits of one port and 6 of another make things
1368    likely enough to accept the region on the first hit...
1369  */
1370 static int __init probe_base_port(int base)
1371 {
1372         int b = 0x300, e = 0x370;       /* this is the range of start addresses */
1373         volatile int fool, i;
1374
1375         if (base)
1376                 b = e = base;
1377         for (base = b; base <= e; base += 0x10) {
1378                 if (!request_region(base, 0x10,"cm206"))
1379                         continue;
1380                 for (i = 0; i < 3; i++)
1381                         fool = inw(base + 2);   /* empty possibly uart_receive_buffer */
1382                 if ((inw(base + 6) & 0xffef) != 0x0001 ||       /* line_status */
1383                     (inw(base) & 0xad00) != 0)  { /* data status */
1384                         release_region(base,0x10);
1385                         continue;
1386                 }
1387                 return (base);
1388         }
1389         return 0;
1390 }
1391
1392 #if !defined(MODULE) || defined(AUTO_PROBE_MODULE)
1393 /* Probe for irq# nr. If nr==0, probe for all possible irq's. */
1394 static int __init probe_irq(int nr)
1395 {
1396         int irqs, irq;
1397         outw(dc_normal | READ_AHEAD, r_data_control);   /* disable irq-generation */
1398         sti();
1399         irqs = probe_irq_on();
1400         reset_cm260();          /* causes interrupt */
1401         udelay(100);            /* wait for it */
1402         irq = probe_irq_off(irqs);
1403         outw(dc_normal | READ_AHEAD, r_data_control);   /* services interrupt */
1404         if (nr && irq != nr && irq > 0)
1405                 return 0;       /* wrong interrupt happened */
1406         else
1407                 return irq;
1408 }
1409 #endif
1410
1411 int __init cm206_init(void)
1412 {
1413         uch e = 0;
1414         long int size = sizeof(struct cm206_struct);
1415         struct gendisk *disk;
1416
1417         printk(KERN_INFO "cm206 cdrom driver " REVISION);
1418         cm206_base = probe_base_port(auto_probe ? 0 : cm206_base);
1419         if (!cm206_base) {
1420                 printk(" can't find adapter!\n");
1421                 return -EIO;
1422         }
1423         printk(" adapter at 0x%x", cm206_base);
1424         cd = (struct cm206_struct *) kmalloc(size, GFP_KERNEL);
1425         if (!cd)
1426                goto out_base;
1427         /* Now we have found the adaptor card, try to reset it. As we have
1428          * found out earlier, this process generates an interrupt as well,
1429          * so we might just exploit that fact for irq probing! */
1430 #if !defined(MODULE) || defined(AUTO_PROBE_MODULE)
1431         cm206_irq = probe_irq(auto_probe ? 0 : cm206_irq);
1432         if (cm206_irq <= 0) {
1433                 printk("can't find IRQ!\n");
1434                 goto out_probe;
1435         } else
1436                 printk(" IRQ %d found\n", cm206_irq);
1437 #else
1438         cli();
1439         reset_cm260();
1440         /* Now, the problem here is that reset_cm260 can generate an
1441            interrupt. It seems that this can cause a kernel oops some time
1442            later. So we wait a while and `service' this interrupt. */
1443         mdelay(1);
1444         outw(dc_normal | READ_AHEAD, r_data_control);
1445         sti();
1446         printk(" using IRQ %d\n", cm206_irq);
1447 #endif
1448         if (send_receive_polled(c_drive_configuration) !=
1449             c_drive_configuration) {
1450                 printk(KERN_INFO " drive not there\n");
1451                 goto out_probe;
1452         }
1453         e = send_receive_polled(c_gimme);
1454         printk(KERN_INFO "Firmware revision %d", e & dcf_revision_code);
1455         if (e & dcf_transfer_rate)
1456                 printk(" double");
1457         else
1458                 printk(" single");
1459         printk(" speed drive");
1460         if (e & dcf_motorized_tray)
1461                 printk(", motorized tray");
1462         if (request_irq(cm206_irq, cm206_interrupt, 0, "cm206", NULL)) {
1463                 printk("\nUnable to reserve IRQ---aborted\n");
1464                 goto out_probe;
1465         }
1466         printk(".\n");
1467
1468         if (register_blkdev(MAJOR_NR, "cm206"))
1469                 goto out_blkdev;
1470
1471         disk = alloc_disk(1);
1472         if (!disk)
1473                 goto out_disk;
1474         disk->major = MAJOR_NR;
1475         disk->first_minor = 0;
1476         sprintf(disk->disk_name, "cm206cd");
1477         disk->fops = &cm206_bdops;
1478         disk->flags = GENHD_FL_CD;
1479         cm206_gendisk = disk;
1480         if (register_cdrom(&cm206_info) != 0) {
1481                 printk(KERN_INFO "Cannot register for cdrom %d!\n", MAJOR_NR);
1482                 goto out_cdrom;
1483         }
1484         cm206_queue = blk_init_queue(do_cm206_request, &cm206_lock);
1485         if (!cm206_queue)
1486                 goto out_queue;
1487                 
1488         blk_queue_hardsect_size(cm206_queue, 2048);
1489         disk->queue = cm206_queue;
1490         add_disk(disk);
1491
1492         memset(cd, 0, sizeof(*cd));     /* give'm some reasonable value */
1493         cd->sector_last = -1;   /* flag no data buffered */
1494         cd->adapter_last = -1;
1495         init_timer(&cd->timer);
1496         cd->timer.function = cm206_timeout;
1497         cd->max_sectors = (inw(r_data_status) & ds_ram_size) ? 24 : 97;
1498         printk(KERN_INFO "%d kB adapter memory available, "
1499                " %ld bytes kernel memory used.\n", cd->max_sectors * 2,
1500                size);
1501         return 0;
1502
1503 out_queue:
1504         unregister_cdrom(&cm206_info);
1505 out_cdrom:
1506         put_disk(disk);
1507 out_disk:
1508         unregister_blkdev(MAJOR_NR, "cm206");
1509 out_blkdev:
1510         free_irq(cm206_irq, NULL);
1511 out_probe:
1512         kfree(cd);
1513 out_base:
1514         release_region(cm206_base, 16);
1515         return -EIO;
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 static 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 static void __exit cm206_exit(void)
1546 {
1547         del_gendisk(cm206_gendisk);
1548         put_disk(cm206_gendisk);
1549         if (unregister_cdrom(&cm206_info)) {
1550                 printk("Can't unregister cdrom cm206\n");
1551                 return;
1552         }
1553         if (unregister_blkdev(MAJOR_NR, "cm206")) {
1554                 printk("Can't unregister major cm206\n");
1555                 return;
1556         }
1557         blk_cleanup_queue(cm206_queue);
1558         free_irq(cm206_irq, NULL);
1559         kfree(cd);
1560         release_region(cm206_base, 16);
1561         printk(KERN_INFO "cm206 removed\n");
1562 }
1563
1564 module_init(__cm206_init);
1565 module_exit(cm206_exit);
1566
1567 #else                           /* !MODULE */
1568
1569 /* This setup function accepts either `auto' or numbers in the range
1570  * 3--11 (for irq) or 0x300--0x370 (for base port) or both. */
1571
1572 static int __init cm206_setup(char *s)
1573 {
1574         int i, p[4];
1575
1576         (void) get_options(s, ARRAY_SIZE(p), p);
1577
1578         if (!strcmp(s, "auto"))
1579                 auto_probe = 1;
1580         for (i = 1; i <= p[0]; i++) {
1581                 if (0x300 <= p[i] && i <= 0x370 && p[i] % 0x10 == 0) {
1582                         cm206_base = p[i];
1583                         auto_probe = 0;
1584                 } else if (3 <= p[i] && p[i] <= 15) {
1585                         cm206_irq = p[i];
1586                         auto_probe = 0;
1587                 }
1588         }
1589         return 1;
1590 }
1591
1592 __setup("cm206=", cm206_setup);
1593
1594 #endif                          /* !MODULE */
1595 MODULE_ALIAS_BLOCKDEV_MAJOR(CM206_CDROM_MAJOR);
1596
1597 /*
1598  * Local variables:
1599  * 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"
1600  * End:
1601  */