ftp://ftp.kernel.org/pub/linux/kernel/v2.6/linux-2.6.6.tar.bz2
[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 trough ioctl 0x1000 (just a number).
36               Hard to choose between v1.2 development and 1.1.75.
37               Bottom-half doesn't work with 1.2...
38               0.25a: fixed... typo. Still problems...
39   1 apr 1995: 0.26 Module support added. Most bugs found. Use kernel 1.2.n.
40   5 apr 1995: 0.27 Auto-probe for the adapter card base address.
41               Auto-probe for the adaptor card irq line.
42   7 apr 1995: 0.28 Added lilo setup support for base address and irq.
43               Use major number 32 (not in this source), officially
44               assigned to this driver.
45   9 apr 1995: 0.29 Added very limited audio support. Toc_header, stop, pause,
46               resume, eject. Play_track ignores track info, because we can't 
47               read a table-of-contents entry. Toc_entry is implemented
48               as a `placebo' function: always returns start of disc. 
49   3 may 1995: 0.30 Audio support completed. The get_toc_entry function
50               is implemented as a binary search. 
51  15 may 1995: 0.31 More work on audio stuff. Workman is not easy to 
52               satisfy; changed binary search into linear search.
53               Auto-probe for base address somewhat relaxed.
54   1 jun 1995: 0.32 Removed probe_irq_on/off for module version.
55  10 jun 1995: 0.33 Workman still behaves funny, but you should be
56               able to eject and substitute another disc.
57
58  An adaptation of 0.33 is included in linux-1.3.7 by Eberhard Moenkeberg
59
60  18 jul 1995: 0.34 Patch by Heiko Eissfeldt included, mainly considering 
61               verify_area's in the ioctls. Some bugs introduced by 
62               EM considering the base port and irq fixed. 
63
64  18 dec 1995: 0.35 Add some code for error checking... no luck...
65
66  We jump to reach our goal: version 1.0 in the next stable linux kernel.
67
68  19 mar 1996: 0.95 Different implementation of CDROM_GET_UPC, on
69               request of Thomas Quinot. 
70  25 mar 1996: 0.96 Interpretation of opening with O_WRONLY or O_RDWR:
71               open only for ioctl operation, e.g., for operation of
72               tray etc.
73  4 apr 1996:  0.97 First implementation of layer between VFS and cdrom
74               driver, a generic interface. Much of the functionality
75               of cm206_open() and cm206_ioctl() is transferred to a
76               new file cdrom.c and its header ucdrom.h. 
77
78               Upgrade to Linux kernel 1.3.78. 
79
80  11 apr 1996  0.98 Upgrade to Linux kernel 1.3.85
81               More code moved to cdrom.c
82  
83               0.99 Some more small changes to decrease number
84               of oopses at module load; 
85  
86  27 jul 1996  0.100 Many hours of debugging, kernel change from 1.2.13
87               to 2.0.7 seems to have introduced some weird behavior
88               in (interruptible_)sleep_on(&cd->data): the process
89               seems to be woken without any explicit wake_up in my own
90               code. Patch to try 100x in case such untriggered wake_up's 
91               occur. 
92
93  28 jul 1996  0.101 Rewriting of the code that receives the command echo,
94               using a fifo to store echoed bytes. 
95
96               Branch from 0.99:
97  
98               0.99.1.0 Update to kernel release 2.0.10 dev_t -> kdev_t
99               (emoenke) various typos found by others.  extra
100               module-load oops protection.
101  
102               0.99.1.1 Initialization constant cdrom_dops.speed
103               changed from float (2.0) to int (2); Cli()-sti() pair
104               around cm260_reset() in module initialization code.
105  
106               0.99.1.2 Changes literally as proposed by Scott Snyder
107               <snyder@d0sgif.fnal.gov> for the 2.1 kernel line, which
108               have to do mainly with the poor minor support i had. The
109               major new concept is to change a cdrom driver's
110               operations struct from the capabilities struct. This
111               reflects the fact that there is one major for a driver,
112               whilst there can be many minors whith completely
113               different capabilities.
114
115               0.99.1.3 More changes for operations/info separation.
116
117               0.99.1.4 Added speed selection (someone had to do this
118               first).
119
120   23 jan 1997 0.99.1.5 MODULE_PARMS call added.
121
122   23 jan 1997 0.100.1.2--0.100.1.5 following similar lines as 
123               0.99.1.1--0.99.1.5. I get too many complaints about the
124               drive making read errors. What't wrong with the 2.0+
125               kernel line? Why get i (and othe cm206 owners) weird
126               results? Why were things good in the good old 1.1--1.2 
127               era? Why don't i throw away the drive?
128
129  2 feb 1997   0.102 Added `volatile' to values in cm206_struct. Seems to 
130               reduce many of the problems. Rewrote polling routines
131               to use fixed delays between polls. 
132               0.103 Changed printk behavior. 
133               0.104 Added a 0.100 -> 0.100.1.1 change
134
135 11 feb 1997   0.105 Allow auto_probe during module load, disable
136               with module option "auto_probe=0". Moved some debugging
137               statements to lower priority. Implemented select_speed()
138               function. 
139
140 13 feb 1997   1.0 Final version for 2.0 kernel line. 
141
142               All following changes will be for the 2.1 kernel line. 
143
144 15 feb 1997   1.1 Keep up with kernel 2.1.26, merge in changes from 
145               cdrom.c 0.100.1.1--1.0. Add some more MODULE_PARMS. 
146
147 14 sep 1997   1.2 Upgrade to Linux 2.1.55.  Added blksize_size[], patch
148               sent by James Bottomley <James.Bottomley@columbiasc.ncr.com>.
149
150 21 dec 1997   1.4 Upgrade to Linux 2.1.72.  
151
152 24 jan 1998   Removed the cm206_disc_status() function, as it was now dead
153               code.  The Uniform CDROM driver now provides this functionality.
154               
155 9 Nov. 1999   Make kernel-parameter implementation work with 2.3.x 
156               Removed init_module & cleanup_module in favor of 
157               module_init & module_exit.
158               Torben Mathiasen <tmm@image.dk>
159  * 
160  * Parts of the code are based upon lmscd.c written by Kai Petzke,
161  * sbpcd.c written by Eberhard Moenkeberg, and mcd.c by Martin
162  * Harriss, but any off-the-shelf dynamic programming algorithm won't
163  * be able to find them.
164  *
165  * The cm206 drive interface and the cm260 adapter card seem to be 
166  * sufficiently different from their cm205/cm250 counterparts
167  * in order to write a complete new driver.
168  * 
169  * I call all routines connected to the Linux kernel something
170  * with `cm206' in it, as this stuff is too series-dependent. 
171  * 
172  * Currently, my limited knowledge is based on:
173  * - The Linux Kernel Hacker's guide, v. 0.5, by Michael K. Johnson
174  * - Linux Kernel Programmierung, by Michael Beck and others
175  * - Philips/LMS cm206 and cm226 product specification
176  * - Philips/LMS cm260 product specification
177  *
178  * David van Leeuwen, david@tm.tno.nl.  */
179 #define REVISION "$Revision: 1.5 $"
180
181 #include <linux/module.h>
182
183 #include <linux/errno.h>        /* These include what we really need */
184 #include <linux/delay.h>
185 #include <linux/string.h>
186 #include <linux/sched.h>
187 #include <linux/interrupt.h>
188 #include <linux/timer.h>
189 #include <linux/cdrom.h>
190 #include <linux/devfs_fs_kernel.h>
191 #include <linux/ioport.h>
192 #include <linux/mm.h>
193 #include <linux/slab.h>
194 #include <linux/init.h>
195
196 /* #include <linux/ucdrom.h> */
197
198 #include <asm/io.h>
199
200 #define MAJOR_NR CM206_CDROM_MAJOR
201
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 spinlock_t cm206_lock = SPIN_LOCK_UNLOCKED;
306
307 /* First, we define some polling functions. These are actually
308    only being used in the initialization. */
309
310 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 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 uch send_receive_polled(int command)
332 {
333         send_command_polled(command);
334         return receive_echo_polled();
335 }
336
337 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 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 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 void cm206_delay(int nr_jiffies)
469 {
470         DECLARE_WAIT_QUEUE_HEAD(wait);
471         sleep_or_timeout(&wait, nr_jiffies);
472 }
473
474 void send_command(int command)
475 {
476         debug(("Sending 0x%x\n", command));
477         if (!(inw(r_line_status) & ls_transmitter_buffer_empty)) {
478                 cd->command = command;
479                 cli();          /* don't interrupt before sleep */
480                 outw(dc_mask_sync_error | dc_no_stop_on_error |
481                      (inw(r_data_status) & 0x7f), r_data_control);
482                 /* interrupt routine sends command */
483                 if (sleep_or_timeout(&cd->uart, UART_TIMEOUT)) {
484                         debug(("Time out on write-buffer\n"));
485                         stats(write_timeout);
486                         outw(command, r_uart_transmit);
487                 }
488                 debug(("Write commmand delayed\n"));
489         } else
490                 outw(command, r_uart_transmit);
491 }
492
493 uch receive_byte(int timeout)
494 {
495         uch ret;
496         cli();
497         debug(("cli\n"));
498         ret = cd->ur[cd->ur_r];
499         if (cd->ur_r != cd->ur_w) {
500                 sti();
501                 debug(("returning #%d: 0x%x\n", cd->ur_r,
502                        cd->ur[cd->ur_r]));
503                 cd->ur_r++;
504                 cd->ur_r %= UR_SIZE;
505                 return ret;
506         } else if (sleep_or_timeout(&cd->uart, timeout)) {      /* does sti() */
507                 debug(("Time out on receive-buffer\n"));
508 #ifdef STATISTICS
509                 if (timeout == UART_TIMEOUT)
510                         stats(receive_timeout)  /* no `;'! */
511                             else
512                         stats(dsb_timeout);
513 #endif
514                 return 0xda;
515         }
516         ret = cd->ur[cd->ur_r];
517         debug(("slept; returning #%d: 0x%x\n", cd->ur_r,
518                cd->ur[cd->ur_r]));
519         cd->ur_r++;
520         cd->ur_r %= UR_SIZE;
521         return ret;
522 }
523
524 inline uch receive_echo(void)
525 {
526         return receive_byte(UART_TIMEOUT);
527 }
528
529 inline uch send_receive(int command)
530 {
531         send_command(command);
532         return receive_echo();
533 }
534
535 inline uch wait_dsb(void)
536 {
537         return receive_byte(DSB_TIMEOUT);
538 }
539
540 int type_0_command(int command, int expect_dsb)
541 {
542         int e;
543         clear_ur();
544         if (command != (e = send_receive(command))) {
545                 debug(("command 0x%x echoed as 0x%x\n", command, e));
546                 stats(echo);
547                 return -1;
548         }
549         if (expect_dsb) {
550                 cd->dsb = wait_dsb();   /* wait for command to finish */
551         }
552         return 0;
553 }
554
555 int type_1_command(int command, int bytes, uch * status)
556 {                               /* returns info */
557         int i;
558         if (type_0_command(command, 0))
559                 return -1;
560         for (i = 0; i < bytes; i++)
561                 status[i] = send_receive(c_gimme);
562         return 0;
563 }
564
565 /* This function resets the adapter card. We'd better not do this too
566  * often, because it tends to generate `lost interrupts.' */
567 void reset_cm260(void)
568 {
569         outw(dc_normal | dc_initialize | READ_AHEAD, r_data_control);
570         udelay(10);             /* 3.3 mu sec minimum */
571         outw(dc_normal | READ_AHEAD, r_data_control);
572 }
573
574 /* fsm: frame-sec-min from linear address; one of many */
575 void fsm(int lba, uch * fsm)
576 {
577         fsm[0] = lba % 75;
578         lba /= 75;
579         lba += 2;
580         fsm[1] = lba % 60;
581         fsm[2] = lba / 60;
582 }
583
584 inline int fsm2lba(uch * fsm)
585 {
586         return fsm[0] + 75 * (fsm[1] - 2 + 60 * fsm[2]);
587 }
588
589 inline int f_s_m2lba(uch f, uch s, uch m)
590 {
591         return f + 75 * (s - 2 + 60 * m);
592 }
593
594 int start_read(int start)
595 {
596         uch read_sector[4] = { c_read_data, };
597         int i, e;
598
599         fsm(start, &read_sector[1]);
600         clear_ur();
601         for (i = 0; i < 4; i++)
602                 if (read_sector[i] != (e = send_receive(read_sector[i]))) {
603                         debug(("read_sector: %x echoes %x\n",
604                                read_sector[i], e));
605                         stats(echo);
606                         if (e == 0xff) {        /* this seems to happen often */
607                                 e = receive_echo();
608                                 debug(("Second try %x\n", e));
609                                 if (e != read_sector[i])
610                                         return -1;
611                         }
612                 }
613         return 0;
614 }
615
616 int stop_read(void)
617 {
618         int e;
619         type_0_command(c_stop, 0);
620         if ((e = receive_echo()) != 0xff) {
621                 debug(("c_stop didn't send 0xff, but 0x%x\n", e));
622                 stats(stop_0xff);
623                 return -1;
624         }
625         return 0;
626 }
627
628 /* This function starts to read sectors in adapter memory, the
629    interrupt routine should stop the read. In fact, the bottom_half
630    routine takes care of this. Set a flag `background' in the cd
631    struct to indicate the process. */
632
633 int read_background(int start, int reading)
634 {
635         if (cd->background)
636                 return -1;      /* can't do twice */
637         outw(dc_normal | BACK_AHEAD, r_data_control);
638         if (!reading && start_read(start))
639                 return -2;
640         cd->adapter_first = cd->adapter_last = start;
641         cd->background = 1;     /* flag a read is going on */
642         return 0;
643 }
644
645 #ifdef USE_INSW
646 #define transport_data insw
647 #else
648 /* this routine implements insw(,,). There was a time i had the
649    impression that there would be any difference in error-behaviour. */
650 void transport_data(int port, ush * dest, int count)
651 {
652         int i;
653         ush *d;
654         for (i = 0, d = dest; i < count; i++, d++)
655                 *d = inw(port);
656 }
657 #endif
658
659
660 #define MAX_TRIES 100
661 int read_sector(int start)
662 {
663         int tries = 0;
664         if (cd->background) {
665                 cd->background = 0;
666                 cd->adapter_last = -1;  /* invalidate adapter memory */
667                 stop_read();
668         }
669         cd->fifo_overflowed = 0;
670         reset_cm260();          /* empty fifo etc. */
671         if (start_read(start))
672                 return -1;
673         do {
674                 if (sleep_or_timeout(&cd->data, DATA_TIMEOUT)) {
675                         debug(("Read timed out sector 0x%x\n", start));
676                         stats(read_timeout);
677                         stop_read();
678                         return -3;
679                 }
680                 tries++;
681         } while (cd->intr_ds & ds_fifo_empty && tries < MAX_TRIES);
682         if (tries > 1)
683                 debug(("Took me some tries\n"))
684                     else
685         if (tries == MAX_TRIES)
686                 debug(("MAX_TRIES tries for read sector\n"));
687         transport_data(r_fifo_output_buffer, cd->sector,
688                        READ_AHEAD * RAW_SECTOR_SIZE / 2);
689         if (read_background(start + READ_AHEAD, 1))
690                 stats(read_background);
691         cd->sector_first = start;
692         cd->sector_last = start + READ_AHEAD;
693         stats(read_restarted);
694         return 0;
695 }
696
697 /* The function of bottom-half is to send a stop command to the drive
698    This isn't easy because the routine is not `owned' by any process;
699    we can't go to sleep! The variable cd->background gives the status:
700    0 no read pending
701    1 a read is pending
702    2 c_stop waits for write_buffer_empty
703    3 c_stop waits for receive_buffer_full: echo
704    4 c_stop waits for receive_buffer_full: 0xff
705 */
706
707 static void cm206_tasklet_func(unsigned long ignore)
708 {
709         debug(("bh: %d\n", cd->background));
710         switch (cd->background) {
711         case 1:
712                 stats(bh);
713                 if (!(cd->intr_ls & ls_transmitter_buffer_empty)) {
714                         cd->command = c_stop;
715                         outw(dc_mask_sync_error | dc_no_stop_on_error |
716                              (inw(r_data_status) & 0x7f), r_data_control);
717                         cd->background = 2;
718                         break;  /* we'd better not time-out here! */
719                 } else
720                         outw(c_stop, r_uart_transmit);
721                 /* fall into case 2: */
722         case 2:
723                 /* the write has been satisfied by interrupt routine */
724                 cd->background = 3;
725                 break;
726         case 3:
727                 if (cd->ur_r != cd->ur_w) {
728                         if (cd->ur[cd->ur_r] != c_stop) {
729                                 debug(("cm206_bh: c_stop echoed 0x%x\n",
730                                        cd->ur[cd->ur_r]));
731                                 stats(echo);
732                         }
733                         cd->ur_r++;
734                         cd->ur_r %= UR_SIZE;
735                 }
736                 cd->background++;
737                 break;
738         case 4:
739                 if (cd->ur_r != cd->ur_w) {
740                         if (cd->ur[cd->ur_r] != 0xff) {
741                                 debug(("cm206_bh: c_stop reacted with 0x%x\n", cd->ur[cd->ur_r]));
742                                 stats(stop_0xff);
743                         }
744                         cd->ur_r++;
745                         cd->ur_r %= UR_SIZE;
746                 }
747                 cd->background = 0;
748         }
749 }
750
751 static DECLARE_TASKLET(cm206_tasklet, cm206_tasklet_func, 0);
752
753 /* This command clears the dsb_possible_media_change flag, so we must 
754  * retain it.
755  */
756 void get_drive_status(void)
757 {
758         uch status[2];
759         type_1_command(c_drive_status, 2, status);      /* this might be done faster */
760         cd->dsb = status[0];
761         cd->cc = status[1];
762         cd->media_changed |=
763             !!(cd->dsb & (dsb_possible_media_change |
764                           dsb_drive_not_ready | dsb_tray_not_closed));
765 }
766
767 void get_disc_status(void)
768 {
769         if (type_1_command(c_disc_status, 7, cd->disc_status)) {
770                 debug(("get_disc_status: error\n"));
771         }
772 }
773
774 /* The new open. The real opening strategy is defined in cdrom.c. */
775
776 static int cm206_open(struct cdrom_device_info *cdi, int purpose)
777 {
778         if (!cd->openfiles) {   /* reset only first time */
779                 cd->background = 0;
780                 reset_cm260();
781                 cd->adapter_last = -1;  /* invalidate adapter memory */
782                 cd->sector_last = -1;
783         }
784         ++cd->openfiles;
785         stats(open);
786         return 0;
787 }
788
789 static void cm206_release(struct cdrom_device_info *cdi)
790 {
791         if (cd->openfiles == 1) {
792                 if (cd->background) {
793                         cd->background = 0;
794                         stop_read();
795                 }
796                 cd->sector_last = -1;   /* Make our internal buffer invalid */
797                 FIRST_TRACK = 0;        /* No valid disc status */
798         }
799         --cd->openfiles;
800 }
801
802 /* Empty buffer empties $sectors$ sectors of the adapter card buffer,
803  * and then reads a sector in kernel memory.  */
804 void empty_buffer(int sectors)
805 {
806         while (sectors >= 0) {
807                 transport_data(r_fifo_output_buffer,
808                                cd->sector + cd->fifo_overflowed,
809                                RAW_SECTOR_SIZE / 2 - cd->fifo_overflowed);
810                 --sectors;
811                 ++cd->adapter_first;    /* update the current adapter sector */
812                 cd->fifo_overflowed = 0;        /* reset overflow bit */
813                 stats(sector_transferred);
814         }
815         cd->sector_first = cd->adapter_first - 1;
816         cd->sector_last = cd->adapter_first;    /* update the buffer sector */
817 }
818
819 /* try_adapter. This function determines if the requested sector is
820    in adapter memory, or will appear there soon. Returns 0 upon
821    success */
822 int try_adapter(int sector)
823 {
824         if (cd->adapter_first <= sector && sector < cd->adapter_last) {
825                 /* sector is in adapter memory */
826                 empty_buffer(sector - cd->adapter_first);
827                 return 0;
828         } else if (cd->background == 1 && cd->adapter_first <= sector
829                    && sector < cd->adapter_first + cd->max_sectors) {
830                 /* a read is going on, we can wait for it */
831                 cd->wait_back = 1;
832                 while (sector >= cd->adapter_last) {
833                         if (sleep_or_timeout(&cd->data, DATA_TIMEOUT)) {
834                                 debug(("Timed out during background wait: %d %d %d %d\n", sector, cd->adapter_last, cd->adapter_first, cd->background));
835                                 stats(back_read_timeout);
836                                 cd->wait_back = 0;
837                                 return -1;
838                         }
839                 }
840                 cd->wait_back = 0;
841                 empty_buffer(sector - cd->adapter_first);
842                 return 0;
843         } else
844                 return -2;
845 }
846
847 /* This is not a very smart implementation. We could optimize for 
848    consecutive block numbers. I'm not convinced this would really
849    bring down the processor load. */
850 static void do_cm206_request(request_queue_t * q)
851 {
852         long int i, cd_sec_no;
853         int quarter, error;
854         uch *source, *dest;
855         struct request *req;
856
857         while (1) {     /* repeat until all requests have been satisfied */
858                 req = elv_next_request(q);
859                 if (!req)
860                         return;
861
862                 if (req->cmd != READ) {
863                         debug(("Non-read command %d on cdrom\n", req->cmd));
864                         end_request(req, 0);
865                         continue;
866                 }
867                 spin_unlock_irq(q->queue_lock);
868                 error = 0;
869                 for (i = 0; i < req->nr_sectors; i++) {
870                         int e1, e2;
871                         cd_sec_no = (req->sector + i) / BLOCKS_ISO;     /* 4 times 512 bytes */
872                         quarter = (req->sector + i) % BLOCKS_ISO;
873                         dest = req->buffer + i * LINUX_BLOCK_SIZE;
874                         /* is already in buffer memory? */
875                         if (cd->sector_first <= cd_sec_no
876                             && cd_sec_no < cd->sector_last) {
877                                 source =
878                                     ((uch *) cd->sector) + 16 +
879                                     quarter * LINUX_BLOCK_SIZE +
880                                     (cd_sec_no -
881                                      cd->sector_first) * RAW_SECTOR_SIZE;
882                                 memcpy(dest, source, LINUX_BLOCK_SIZE);
883                         } else if (!(e1 = try_adapter(cd_sec_no)) ||
884                                    !(e2 = read_sector(cd_sec_no))) {
885                                 source =
886                                     ((uch *) cd->sector) + 16 +
887                                     quarter * LINUX_BLOCK_SIZE;
888                                 memcpy(dest, source, LINUX_BLOCK_SIZE);
889                         } else {
890                                 error = 1;
891                                 debug(("cm206_request: %d %d\n", e1, e2));
892                         }
893                 }
894                 spin_lock_irq(q->queue_lock);
895                 end_request(req, !error);
896         }
897 }
898
899 /* Audio support. I've tried very hard, but the cm206 drive doesn't 
900    seem to have a get_toc (table-of-contents) function, while i'm
901    pretty sure it must read the toc upon disc insertion. Therefore
902    this function has been implemented through a binary search 
903    strategy. All track starts that happen to be found are stored in
904    cd->toc[], for future use. 
905
906    I've spent a whole day on a bug that only shows under Workman---
907    I don't get it. Tried everything, nothing works. If workman asks
908    for track# 0xaa, it'll get the wrong time back. Any other program
909    receives the correct value. I'm stymied.
910 */
911
912 /* seek seeks to address lba. It does wait to arrive there. */
913 void seek(int lba)
914 {
915         int i;
916         uch seek_command[4] = { c_seek, };
917
918         fsm(lba, &seek_command[1]);
919         for (i = 0; i < 4; i++)
920                 type_0_command(seek_command[i], 0);
921         cd->dsb = wait_dsb();
922 }
923
924 uch bcdbin(unsigned char bcd)
925 {                               /* stolen from mcd.c! */
926         return (bcd >> 4) * 10 + (bcd & 0xf);
927 }
928
929 inline uch normalize_track(uch track)
930 {
931         if (track < 1)
932                 return 1;
933         if (track > LAST_TRACK)
934                 return LAST_TRACK + 1;
935         return track;
936 }
937
938 /* This function does a binary search for track start. It records all
939  * tracks seen in the process. Input $track$ must be between 1 and
940  * #-of-tracks+1.  Note that the start of the disc must be in toc[1].fsm. 
941  */
942 int get_toc_lba(uch track)
943 {
944         int max = 74 * 60 * 75 - 150, min = fsm2lba(cd->toc[1].fsm);
945         int i, lba, l, old_lba = 0;
946         uch *q = cd->q;
947         uch ct;                 /* current track */
948         int binary = 0;
949         const int skip = 3 * 60 * 75;   /* 3 minutes */
950
951         for (i = track; i > 0; i--)
952                 if (cd->toc[i].track) {
953                         min = fsm2lba(cd->toc[i].fsm);
954                         break;
955                 }
956         lba = min + skip;
957         do {
958                 seek(lba);
959                 type_1_command(c_read_current_q, 10, q);
960                 ct = normalize_track(q[1]);
961                 if (!cd->toc[ct].track) {
962                         l = q[9] - bcdbin(q[5]) + 75 * (q[8] -
963                                                         bcdbin(q[4]) - 2 +
964                                                         60 * (q[7] -
965                                                               bcdbin(q
966                                                                      [3])));
967                         cd->toc[ct].track = q[1];       /* lead out still 0xaa */
968                         fsm(l, cd->toc[ct].fsm);
969                         cd->toc[ct].q0 = q[0];  /* contains adr and ctrl info */
970                         if (ct == track)
971                                 return l;
972                 }
973                 old_lba = lba;
974                 if (binary) {
975                         if (ct < track)
976                                 min = lba;
977                         else
978                                 max = lba;
979                         lba = (min + max) / 2;
980                 } else {
981                         if (ct < track)
982                                 lba += skip;
983                         else {
984                                 binary = 1;
985                                 max = lba;
986                                 min = lba - skip;
987                                 lba = (min + max) / 2;
988                         }
989                 }
990         } while (lba != old_lba);
991         return lba;
992 }
993
994 void update_toc_entry(uch track)
995 {
996         track = normalize_track(track);
997         if (!cd->toc[track].track)
998                 get_toc_lba(track);
999 }
1000
1001 /* return 0 upon success */
1002 int read_toc_header(struct cdrom_tochdr *hp)
1003 {
1004         if (!FIRST_TRACK)
1005                 get_disc_status();
1006         if (hp) {
1007                 int i;
1008                 hp->cdth_trk0 = FIRST_TRACK;
1009                 hp->cdth_trk1 = LAST_TRACK;
1010                 /* fill in first track position */
1011                 for (i = 0; i < 3; i++)
1012                         cd->toc[1].fsm[i] = cd->disc_status[3 + i];
1013                 update_toc_entry(LAST_TRACK + 1);       /* find most entries */
1014                 return 0;
1015         }
1016         return -1;
1017 }
1018
1019 void play_from_to_msf(struct cdrom_msf *msfp)
1020 {
1021         uch play_command[] = { c_play,
1022                 msfp->cdmsf_frame0, msfp->cdmsf_sec0, msfp->cdmsf_min0,
1023                 msfp->cdmsf_frame1, msfp->cdmsf_sec1, msfp->cdmsf_min1, 2,
1024                     2
1025         };
1026         int i;
1027         for (i = 0; i < 9; i++)
1028                 type_0_command(play_command[i], 0);
1029         for (i = 0; i < 3; i++)
1030                 PLAY_TO.fsm[i] = play_command[i + 4];
1031         PLAY_TO.track = 0;      /* say no track end */
1032         cd->dsb = wait_dsb();
1033 }
1034
1035 void play_from_to_track(int from, int to)
1036 {
1037         uch play_command[8] = { c_play, };
1038         int i;
1039
1040         if (from == 0) {        /* continue paused play */
1041                 for (i = 0; i < 3; i++) {
1042                         play_command[i + 1] = cd->audio_status[i + 2];
1043                         play_command[i + 4] = PLAY_TO.fsm[i];
1044                 }
1045         } else {
1046                 update_toc_entry(from);
1047                 update_toc_entry(to + 1);
1048                 for (i = 0; i < 3; i++) {
1049                         play_command[i + 1] = cd->toc[from].fsm[i];
1050                         PLAY_TO.fsm[i] = play_command[i + 4] =
1051                             cd->toc[to + 1].fsm[i];
1052                 }
1053                 PLAY_TO.track = to;
1054         }
1055         for (i = 0; i < 7; i++)
1056                 type_0_command(play_command[i], 0);
1057         for (i = 0; i < 2; i++)
1058                 type_0_command(0x2, 0); /* volume */
1059         cd->dsb = wait_dsb();
1060 }
1061
1062 int get_current_q(struct cdrom_subchnl *qp)
1063 {
1064         int i;
1065         uch *q = cd->q;
1066         if (type_1_command(c_read_current_q, 10, q))
1067                 return 0;
1068 /*  q[0] = bcdbin(q[0]); Don't think so! */
1069         for (i = 2; i < 6; i++)
1070                 q[i] = bcdbin(q[i]);
1071         qp->cdsc_adr = q[0] & 0xf;
1072         qp->cdsc_ctrl = q[0] >> 4;      /* from mcd.c */
1073         qp->cdsc_trk = q[1];
1074         qp->cdsc_ind = q[2];
1075         if (qp->cdsc_format == CDROM_MSF) {
1076                 qp->cdsc_reladdr.msf.minute = q[3];
1077                 qp->cdsc_reladdr.msf.second = q[4];
1078                 qp->cdsc_reladdr.msf.frame = q[5];
1079                 qp->cdsc_absaddr.msf.minute = q[7];
1080                 qp->cdsc_absaddr.msf.second = q[8];
1081                 qp->cdsc_absaddr.msf.frame = q[9];
1082         } else {
1083                 qp->cdsc_reladdr.lba = f_s_m2lba(q[5], q[4], q[3]);
1084                 qp->cdsc_absaddr.lba = f_s_m2lba(q[9], q[8], q[7]);
1085         }
1086         get_drive_status();
1087         if (cd->dsb & dsb_play_in_progress)
1088                 qp->cdsc_audiostatus = CDROM_AUDIO_PLAY;
1089         else if (PAUSED)
1090                 qp->cdsc_audiostatus = CDROM_AUDIO_PAUSED;
1091         else
1092                 qp->cdsc_audiostatus = CDROM_AUDIO_NO_STATUS;
1093         return 0;
1094 }
1095
1096 void invalidate_toc(void)
1097 {
1098         memset(cd->toc, 0, sizeof(cd->toc));
1099         memset(cd->disc_status, 0, sizeof(cd->disc_status));
1100 }
1101
1102 /* cdrom.c guarantees that cdte_format == CDROM_MSF */
1103 void get_toc_entry(struct cdrom_tocentry *ep)
1104 {
1105         uch track = normalize_track(ep->cdte_track);
1106         update_toc_entry(track);
1107         ep->cdte_addr.msf.frame = cd->toc[track].fsm[0];
1108         ep->cdte_addr.msf.second = cd->toc[track].fsm[1];
1109         ep->cdte_addr.msf.minute = cd->toc[track].fsm[2];
1110         ep->cdte_adr = cd->toc[track].q0 & 0xf;
1111         ep->cdte_ctrl = cd->toc[track].q0 >> 4;
1112         ep->cdte_datamode = 0;
1113 }
1114
1115 /* Audio ioctl.  Ioctl commands connected to audio are in such an
1116  * idiosyncratic i/o format, that we leave these untouched. Return 0
1117  * upon success. Memory checking has been done by cdrom_ioctl(), the
1118  * calling function, as well as LBA/MSF sanitization.
1119 */
1120 int cm206_audio_ioctl(struct cdrom_device_info *cdi, unsigned int cmd,
1121                       void *arg)
1122 {
1123         switch (cmd) {
1124         case CDROMREADTOCHDR:
1125                 return read_toc_header((struct cdrom_tochdr *) arg);
1126         case CDROMREADTOCENTRY:
1127                 get_toc_entry((struct cdrom_tocentry *) arg);
1128                 return 0;
1129         case CDROMPLAYMSF:
1130                 play_from_to_msf((struct cdrom_msf *) arg);
1131                 return 0;
1132         case CDROMPLAYTRKIND:   /* admittedly, not particularly beautiful */
1133                 play_from_to_track(((struct cdrom_ti *) arg)->cdti_trk0,
1134                                    ((struct cdrom_ti *) arg)->cdti_trk1);
1135                 return 0;
1136         case CDROMSTOP:
1137                 PAUSED = 0;
1138                 if (cd->dsb & dsb_play_in_progress)
1139                         return type_0_command(c_stop, 1);
1140                 else
1141                         return 0;
1142         case CDROMPAUSE:
1143                 get_drive_status();
1144                 if (cd->dsb & dsb_play_in_progress) {
1145                         type_0_command(c_stop, 1);
1146                         type_1_command(c_audio_status, 5,
1147                                        cd->audio_status);
1148                         PAUSED = 1;     /* say we're paused */
1149                 }
1150                 return 0;
1151         case CDROMRESUME:
1152                 if (PAUSED)
1153                         play_from_to_track(0, 0);
1154                 PAUSED = 0;
1155                 return 0;
1156         case CDROMSTART:
1157         case CDROMVOLCTRL:
1158                 return 0;
1159         case CDROMSUBCHNL:
1160                 return get_current_q((struct cdrom_subchnl *) arg);
1161         default:
1162                 return -EINVAL;
1163         }
1164 }
1165
1166 /* Ioctl. These ioctls are specific to the cm206 driver. I have made
1167    some driver statistics accessible through ioctl calls.
1168  */
1169
1170 static int cm206_ioctl(struct cdrom_device_info *cdi, unsigned int cmd,
1171                        unsigned long arg)
1172 {
1173         switch (cmd) {
1174 #ifdef STATISTICS
1175         case CM206CTL_GET_STAT:
1176                 if (arg >= NR_STATS)
1177                         return -EINVAL;
1178                 else
1179                         return cd->stats[arg];
1180         case CM206CTL_GET_LAST_STAT:
1181                 if (arg >= NR_STATS)
1182                         return -EINVAL;
1183                 else
1184                         return cd->last_stat[arg];
1185 #endif
1186         default:
1187                 debug(("Unknown ioctl call 0x%x\n", cmd));
1188                 return -EINVAL;
1189         }
1190 }
1191
1192 int cm206_media_changed(struct cdrom_device_info *cdi, int disc_nr)
1193 {
1194         if (cd != NULL) {
1195                 int r;
1196                 get_drive_status();     /* ensure cd->media_changed OK */
1197                 r = cd->media_changed;
1198                 cd->media_changed = 0;  /* clear bit */
1199                 return r;
1200         } else
1201                 return -EIO;
1202 }
1203
1204 /* The new generic cdrom support. Routines should be concise, most of
1205    the logic should be in cdrom.c */
1206
1207 /* returns number of times device is in use */
1208 int cm206_open_files(struct cdrom_device_info *cdi)
1209 {
1210         if (cd)
1211                 return cd->openfiles;
1212         return -1;
1213 }
1214
1215 /* controls tray movement */
1216 int cm206_tray_move(struct cdrom_device_info *cdi, int position)
1217 {
1218         if (position) {         /* 1: eject */
1219                 type_0_command(c_open_tray, 1);
1220                 invalidate_toc();
1221         } else
1222                 type_0_command(c_close_tray, 1);        /* 0: close */
1223         return 0;
1224 }
1225
1226 /* gives current state of the drive */
1227 int cm206_drive_status(struct cdrom_device_info *cdi, int slot_nr)
1228 {
1229         get_drive_status();
1230         if (cd->dsb & dsb_tray_not_closed)
1231                 return CDS_TRAY_OPEN;
1232         if (!(cd->dsb & dsb_disc_present))
1233                 return CDS_NO_DISC;
1234         if (cd->dsb & dsb_drive_not_ready)
1235                 return CDS_DRIVE_NOT_READY;
1236         return CDS_DISC_OK;
1237 }
1238
1239 /* locks or unlocks door lock==1: lock; return 0 upon success */
1240 int cm206_lock_door(struct cdrom_device_info *cdi, int lock)
1241 {
1242         uch command = (lock) ? c_lock_tray : c_unlock_tray;
1243         type_0_command(command, 1);     /* wait and get dsb */
1244         /* the logic calculates the success, 0 means successful */
1245         return lock ^ ((cd->dsb & dsb_tray_locked) != 0);
1246 }
1247
1248 /* Although a session start should be in LBA format, we return it in 
1249    MSF format because it is slightly easier, and the new generic ioctl
1250    will take care of the necessary conversion. */
1251 int cm206_get_last_session(struct cdrom_device_info *cdi,
1252                            struct cdrom_multisession *mssp)
1253 {
1254         if (!FIRST_TRACK)
1255                 get_disc_status();
1256         if (mssp != NULL) {
1257                 if (DISC_STATUS & cds_multi_session) {  /* multi-session */
1258                         mssp->addr.msf.frame = cd->disc_status[3];
1259                         mssp->addr.msf.second = cd->disc_status[4];
1260                         mssp->addr.msf.minute = cd->disc_status[5];
1261                         mssp->addr_format = CDROM_MSF;
1262                         mssp->xa_flag = 1;
1263                 } else {
1264                         mssp->xa_flag = 0;
1265                 }
1266                 return 1;
1267         }
1268         return 0;
1269 }
1270
1271 int cm206_get_upc(struct cdrom_device_info *cdi, struct cdrom_mcn *mcn)
1272 {
1273         uch upc[10];
1274         char *ret = mcn->medium_catalog_number;
1275         int i;
1276
1277         if (type_1_command(c_read_upc, 10, upc))
1278                 return -EIO;
1279         for (i = 0; i < 13; i++) {
1280                 int w = i / 2 + 1, r = i % 2;
1281                 if (r)
1282                         ret[i] = 0x30 | (upc[w] & 0x0f);
1283                 else
1284                         ret[i] = 0x30 | ((upc[w] >> 4) & 0x0f);
1285         }
1286         ret[13] = '\0';
1287         return 0;
1288 }
1289
1290 int cm206_reset(struct cdrom_device_info *cdi)
1291 {
1292         stop_read();
1293         reset_cm260();
1294         outw(dc_normal | dc_break | READ_AHEAD, r_data_control);
1295         mdelay(1);              /* 750 musec minimum */
1296         outw(dc_normal | READ_AHEAD, r_data_control);
1297         cd->sector_last = -1;   /* flag no data buffered */
1298         cd->adapter_last = -1;
1299         invalidate_toc();
1300         return 0;
1301 }
1302
1303 int cm206_select_speed(struct cdrom_device_info *cdi, int speed)
1304 {
1305         int r;
1306         switch (speed) {
1307         case 0:
1308                 r = type_0_command(c_auto_mode, 1);
1309                 break;
1310         case 1:
1311                 r = type_0_command(c_force_1x, 1);
1312                 break;
1313         case 2:
1314                 r = type_0_command(c_force_2x, 1);
1315                 break;
1316         default:
1317                 return -1;
1318         }
1319         if (r < 0)
1320                 return r;
1321         else
1322                 return 1;
1323 }
1324
1325 static struct cdrom_device_ops cm206_dops = {
1326         .open                   = cm206_open,
1327         .release                = cm206_release,
1328         .drive_status           = cm206_drive_status,
1329         .media_changed          = cm206_media_changed,
1330         .tray_move              = cm206_tray_move,
1331         .lock_door              = cm206_lock_door,
1332         .select_speed           = cm206_select_speed,
1333         .get_last_session       = cm206_get_last_session,
1334         .get_mcn                = cm206_get_upc,
1335         .reset                  = cm206_reset,
1336         .audio_ioctl            = cm206_audio_ioctl,
1337         .dev_ioctl              = cm206_ioctl,
1338         .capability             = CDC_CLOSE_TRAY | CDC_OPEN_TRAY | CDC_LOCK |
1339                                   CDC_MULTI_SESSION | CDC_MEDIA_CHANGED |
1340                                   CDC_MCN | CDC_PLAY_AUDIO | CDC_SELECT_SPEED |
1341                                   CDC_IOCTLS | CDC_DRIVE_STATUS,
1342         .n_minors               = 1,
1343 };
1344
1345
1346 static struct cdrom_device_info cm206_info = {
1347         .ops            = &cm206_dops,
1348         .speed          = 2,
1349         .capacity       = 1,
1350         .name           = "cm206",
1351 };
1352
1353 static int cm206_block_open(struct inode *inode, struct file *file)
1354 {
1355         return cdrom_open(&cm206_info, inode, file);
1356 }
1357
1358 static int cm206_block_release(struct inode *inode, struct file *file)
1359 {
1360         return cdrom_release(&cm206_info, file);
1361 }
1362
1363 static int cm206_block_ioctl(struct inode *inode, struct file *file,
1364                                 unsigned cmd, unsigned long arg)
1365 {
1366         return cdrom_ioctl(&cm206_info, inode, cmd, arg);
1367 }
1368
1369 static int cm206_block_media_changed(struct gendisk *disk)
1370 {
1371         return cdrom_media_changed(&cm206_info);
1372 }
1373
1374 static struct block_device_operations cm206_bdops =
1375 {
1376         .owner          = THIS_MODULE,
1377         .open           = cm206_block_open,
1378         .release        = cm206_block_release,
1379         .ioctl          = cm206_block_ioctl,
1380         .media_changed  = cm206_block_media_changed,
1381 };
1382
1383 static struct gendisk *cm206_gendisk;
1384
1385 /* This function probes for the adapter card. It returns the base
1386    address if it has found the adapter card. One can specify a base 
1387    port to probe specifically, or 0 which means span all possible
1388    bases. 
1389
1390    Linus says it is too dangerous to use writes for probing, so we
1391    stick with pure reads for a while. Hope that 8 possible ranges,
1392    request_region, 15 bits of one port and 6 of another make things
1393    likely enough to accept the region on the first hit...
1394  */
1395 int __init probe_base_port(int base)
1396 {
1397         int b = 0x300, e = 0x370;       /* this is the range of start addresses */
1398         volatile int fool, i;
1399
1400         if (base)
1401                 b = e = base;
1402         for (base = b; base <= e; base += 0x10) {
1403                 if (!request_region(base, 0x10,"cm206"))
1404                         continue;
1405                 for (i = 0; i < 3; i++)
1406                         fool = inw(base + 2);   /* empty possibly uart_receive_buffer */
1407                 if ((inw(base + 6) & 0xffef) != 0x0001 ||       /* line_status */
1408                     (inw(base) & 0xad00) != 0)  { /* data status */
1409                         release_region(base,0x10);
1410                         continue;
1411                 }
1412                 return (base);
1413         }
1414         return 0;
1415 }
1416
1417 #if !defined(MODULE) || defined(AUTO_PROBE_MODULE)
1418 /* Probe for irq# nr. If nr==0, probe for all possible irq's. */
1419 int __init probe_irq(int nr)
1420 {
1421         int irqs, irq;
1422         outw(dc_normal | READ_AHEAD, r_data_control);   /* disable irq-generation */
1423         sti();
1424         irqs = probe_irq_on();
1425         reset_cm260();          /* causes interrupt */
1426         udelay(100);            /* wait for it */
1427         irq = probe_irq_off(irqs);
1428         outw(dc_normal | READ_AHEAD, r_data_control);   /* services interrupt */
1429         if (nr && irq != nr && irq > 0)
1430                 return 0;       /* wrong interrupt happened */
1431         else
1432                 return irq;
1433 }
1434 #endif
1435
1436 int __init cm206_init(void)
1437 {
1438         uch e = 0;
1439         long int size = sizeof(struct cm206_struct);
1440         struct gendisk *disk;
1441
1442         printk(KERN_INFO "cm206 cdrom driver " REVISION);
1443         cm206_base = probe_base_port(auto_probe ? 0 : cm206_base);
1444         if (!cm206_base) {
1445                 printk(" can't find adapter!\n");
1446                 return -EIO;
1447         }
1448         printk(" adapter at 0x%x", cm206_base);
1449         cd = (struct cm206_struct *) kmalloc(size, GFP_KERNEL);
1450         if (!cd)
1451                goto out_base;
1452         /* Now we have found the adaptor card, try to reset it. As we have
1453          * found out earlier, this process generates an interrupt as well,
1454          * so we might just exploit that fact for irq probing! */
1455 #if !defined(MODULE) || defined(AUTO_PROBE_MODULE)
1456         cm206_irq = probe_irq(auto_probe ? 0 : cm206_irq);
1457         if (cm206_irq <= 0) {
1458                 printk("can't find IRQ!\n");
1459                 goto out_probe;
1460         } else
1461                 printk(" IRQ %d found\n", cm206_irq);
1462 #else
1463         cli();
1464         reset_cm260();
1465         /* Now, the problem here is that reset_cm260 can generate an
1466            interrupt. It seems that this can cause a kernel oops some time
1467            later. So we wait a while and `service' this interrupt. */
1468         mdelay(1);
1469         outw(dc_normal | READ_AHEAD, r_data_control);
1470         sti();
1471         printk(" using IRQ %d\n", cm206_irq);
1472 #endif
1473         if (send_receive_polled(c_drive_configuration) !=
1474             c_drive_configuration) {
1475                 printk(KERN_INFO " drive not there\n");
1476                 goto out_probe;
1477         }
1478         e = send_receive_polled(c_gimme);
1479         printk(KERN_INFO "Firmware revision %d", e & dcf_revision_code);
1480         if (e & dcf_transfer_rate)
1481                 printk(" double");
1482         else
1483                 printk(" single");
1484         printk(" speed drive");
1485         if (e & dcf_motorized_tray)
1486                 printk(", motorized tray");
1487         if (request_irq(cm206_irq, cm206_interrupt, 0, "cm206", NULL)) {
1488                 printk("\nUnable to reserve IRQ---aborted\n");
1489                 goto out_probe;
1490         }
1491         printk(".\n");
1492
1493         if (register_blkdev(MAJOR_NR, "cm206"))
1494                 goto out_blkdev;
1495
1496         disk = alloc_disk(1);
1497         if (!disk)
1498                 goto out_disk;
1499         disk->major = MAJOR_NR;
1500         disk->first_minor = 0;
1501         sprintf(disk->disk_name, "cm206cd");
1502         disk->fops = &cm206_bdops;
1503         disk->flags = GENHD_FL_CD;
1504         cm206_gendisk = disk;
1505         if (register_cdrom(&cm206_info) != 0) {
1506                 printk(KERN_INFO "Cannot register for cdrom %d!\n", MAJOR_NR);
1507                 goto out_cdrom;
1508         }
1509         cm206_queue = blk_init_queue(do_cm206_request, &cm206_lock);
1510         if (!cm206_queue)
1511                 goto out_queue;
1512                 
1513         blk_queue_hardsect_size(cm206_queue, 2048);
1514         disk->queue = cm206_queue;
1515         add_disk(disk);
1516
1517         memset(cd, 0, sizeof(*cd));     /* give'm some reasonable value */
1518         cd->sector_last = -1;   /* flag no data buffered */
1519         cd->adapter_last = -1;
1520         init_timer(&cd->timer);
1521         cd->timer.function = cm206_timeout;
1522         cd->max_sectors = (inw(r_data_status) & ds_ram_size) ? 24 : 97;
1523         printk(KERN_INFO "%d kB adapter memory available, "
1524                " %ld bytes kernel memory used.\n", cd->max_sectors * 2,
1525                size);
1526         return 0;
1527
1528 out_queue:
1529         unregister_cdrom(&cm206_info);
1530 out_cdrom:
1531         put_disk(disk);
1532 out_disk:
1533         unregister_blkdev(MAJOR_NR, "cm206");
1534 out_blkdev:
1535         free_irq(cm206_irq, NULL);
1536 out_probe:
1537         kfree(cd);
1538 out_base:
1539         release_region(cm206_base, 16);
1540         return -EIO;
1541 }
1542
1543 #ifdef MODULE
1544
1545
1546 static void __init parse_options(void)
1547 {
1548         int i;
1549         for (i = 0; i < 2; i++) {
1550                 if (0x300 <= cm206[i] && i <= 0x370
1551                     && cm206[i] % 0x10 == 0) {
1552                         cm206_base = cm206[i];
1553                         auto_probe = 0;
1554                 } else if (3 <= cm206[i] && cm206[i] <= 15) {
1555                         cm206_irq = cm206[i];
1556                         auto_probe = 0;
1557                 }
1558         }
1559 }
1560
1561 int __cm206_init(void)
1562 {
1563         parse_options();
1564 #if !defined(AUTO_PROBE_MODULE)
1565         auto_probe = 0;
1566 #endif
1567         return cm206_init();
1568 }
1569
1570 void __exit cm206_exit(void)
1571 {
1572         del_gendisk(cm206_gendisk);
1573         put_disk(cm206_gendisk);
1574         if (unregister_cdrom(&cm206_info)) {
1575                 printk("Can't unregister cdrom cm206\n");
1576                 return;
1577         }
1578         if (unregister_blkdev(MAJOR_NR, "cm206")) {
1579                 printk("Can't unregister major cm206\n");
1580                 return;
1581         }
1582         blk_cleanup_queue(cm206_queue);
1583         free_irq(cm206_irq, NULL);
1584         kfree(cd);
1585         release_region(cm206_base, 16);
1586         printk(KERN_INFO "cm206 removed\n");
1587 }
1588
1589 module_init(__cm206_init);
1590 module_exit(cm206_exit);
1591
1592 #else                           /* !MODULE */
1593
1594 /* This setup function accepts either `auto' or numbers in the range
1595  * 3--11 (for irq) or 0x300--0x370 (for base port) or both. */
1596
1597 static int __init cm206_setup(char *s)
1598 {
1599         int i, p[4];
1600
1601         (void) get_options(s, ARRAY_SIZE(p), p);
1602
1603         if (!strcmp(s, "auto"))
1604                 auto_probe = 1;
1605         for (i = 1; i <= p[0]; i++) {
1606                 if (0x300 <= p[i] && i <= 0x370 && p[i] % 0x10 == 0) {
1607                         cm206_base = p[i];
1608                         auto_probe = 0;
1609                 } else if (3 <= p[i] && p[i] <= 15) {
1610                         cm206_irq = p[i];
1611                         auto_probe = 0;
1612                 }
1613         }
1614         return 1;
1615 }
1616
1617 __setup("cm206=", cm206_setup);
1618
1619 #endif                          /* !MODULE */
1620 MODULE_ALIAS_BLOCKDEV_MAJOR(CM206_CDROM_MAJOR);
1621
1622 /*
1623  * Local variables:
1624  * 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"
1625  * End:
1626  */