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