patch-2.1.77 linux/drivers/cdrom/cm206.c
Next file: linux/drivers/char/Config.in
Previous file: linux/drivers/cdrom/cdrom.c
Back to the patch index
Back to the overall index
- Lines: 685
- Date:
Wed Dec 31 11:34:16 1997
- Orig file:
v2.1.76/linux/drivers/cdrom/cm206.c
- Orig date:
Tue Dec 2 16:45:18 1997
diff -u --recursive --new-file v2.1.76/linux/drivers/cdrom/cm206.c linux/drivers/cdrom/cm206.c
@@ -1,5 +1,6 @@
/* cm206.c. A linux-driver for the cm206 cdrom player with cm260 adapter card.
- Copyright (c) 1995, 1996 David van Leeuwen.
+ Copyright (c) 1995--1997 David A. van Leeuwen.
+ $Id: cm206.c,v 1.5 1997/12/26 11:02:51 david Exp $
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -70,40 +71,84 @@
open only for ioctl operation, e.g., for operation of
tray etc.
4 apr 1996: 0.97 First implementation of layer between VFS and cdrom
- driver, a Uniform interface. Much of the functionality
+ driver, a generic interface. Much of the functionality
of cm206_open() and cm206_ioctl() is transferred to a
- new file cdrom.c and its header cdrom.h.
+ new file cdrom.c and its header ucdrom.h.
Upgrade to Linux kernel 1.3.78.
11 apr 1996 0.98 Upgrade to Linux kernel 1.3.85
More code moved to cdrom.c
+
+ 0.99 Some more small changes to decrease number
+ of oopses at module load;
+
+ 27 jul 1996 0.100 Many hours of debugging, kernel change from 1.2.13
+ to 2.0.7 seems to have introduced some weird behavior
+ in (interruptible_)sleep_on(&cd->data): the process
+ seems to be woken without any explicit wake_up in my own
+ code. Patch to try 100x in case such untriggered wake_up's
+ occur.
- 0.99 Some more small changes to decrease number
- of oopses at module load;
-
- Branch from here:
+ 28 jul 1996 0.101 Rewriting of the code that receives the command echo,
+ using a fifo to store echoed bytes.
- 0.99.1.0 Update to kernel release 2.0.10 dev_t -> kdev_t
- (emoenke) various typos found by others. extra
- module-load oops protection.
-
- 0.99.1.1 Initialization constant cdrom_dops.speed
- changed from float (2.0) to int (2); Cli()-sti() pair
- around cm260_reset() in module initialization code.
-
- 0.99.1.2 Changes literally as proposed by Scott Snyder
- <snyder@d0sgif.fnal.gov>, which have to do mainly with
- the poor minor support i had. The major new concept is
- to change a cdrom driver's operations struct from the
- capabilities struct. This reflects the fact that there
- is one major for a driver, whilst there can be many
- minors whith completely different capabilities.
+ Branch from 0.99:
+
+ 0.99.1.0 Update to kernel release 2.0.10 dev_t -> kdev_t
+ (emoenke) various typos found by others. extra
+ module-load oops protection.
+
+ 0.99.1.1 Initialization constant cdrom_dops.speed
+ changed from float (2.0) to int (2); Cli()-sti() pair
+ around cm260_reset() in module initialization code.
+
+ 0.99.1.2 Changes literally as proposed by Scott Snyder
+ <snyder@d0sgif.fnal.gov> for the 2.1 kernel line, which
+ have to do mainly with the poor minor support i had. The
+ major new concept is to change a cdrom driver's
+ operations struct from the capabilities struct. This
+ reflects the fact that there is one major for a driver,
+ whilst there can be many minors whith completely
+ different capabilities.
0.99.1.3 More changes for operations/info separation.
0.99.1.4 Added speed selection (someone had to do this
first).
+
+ 23 jan 1997 0.99.1.5 MODULE_PARMS call added.
+
+ 23 jan 1997 0.100.1.2--0.100.1.5 following similar lines as
+ 0.99.1.1--0.99.1.5. I get too many complaints about the
+ drive making read errors. What't wrong with the 2.0+
+ kernel line? Why get i (and othe cm206 owners) weird
+ results? Why were things good in the good old 1.1--1.2
+ era? Why don't i throw away the drive?
+
+ 2 feb 1997 0.102 Added `volatile' to values in cm206_struct. Seems to
+ reduce many of the problems. Rewrote polling routines
+ to use fixed delays between polls.
+ 0.103 Changed printk behavior.
+ 0.104 Added a 0.100 -> 0.100.1.1 change
+
+11 feb 1997 0.105 Allow auto_probe during module load, disable
+ with module option "auto_probe=0". Moved some debugging
+ statements to lower priority. Implemented select_speed()
+ function.
+
+13 feb 1997 1.0 Final version for 2.0 kernel line.
+
+ All following changes will be for the 2.1 kernel line.
+
+15 feb 1997 1.1 Keep up with kernel 2.1.26, merge in changes from
+ cdrom.c 0.100.1.1--1.0. Add some more MODULE_PARMS.
+
+14 sep 1997 1.2 Upgrade to Linux 2.1.55. Added blksize_size[], patch
+ sent by James Bottomley <James.Bottomley@columbiasc.ncr.com>.
+
+21 dec 1997 1.4 Upgrade to Linux 2.1.72.
+
*
* Parts of the code are based upon lmscd.c written by Kai Petzke,
* sbpcd.c written by Eberhard Moenkeberg, and mcd.c by Martin
@@ -123,8 +168,8 @@
* - Philips/LMS cm206 and cm226 product specification
* - Philips/LMS cm260 product specification
*
- * David van Leeuwen, david@tm.tno.nl. */
-#define VERSION "$Id: cm206.c,v 0.99.1.4 1996/12/23 21:46:13 david Exp $"
+ * David van Leeuwen, david@tm.tno.nl. */
+#define REVISION "$Revision: 1.5 $"
#include <linux/module.h>
@@ -140,6 +185,8 @@
#include <linux/malloc.h>
#include <linux/init.h>
+/* #include <linux/ucdrom.h> */
+
#include <asm/io.h>
#define MAJOR_NR CM206_CDROM_MAJOR
@@ -147,7 +194,7 @@
#undef DEBUG
#define STATISTICS /* record times and frequencies of events */
-#undef AUTO_PROBE_MODULE
+#define AUTO_PROBE_MODULE
#define USE_INSW
#include "cm206.h"
@@ -160,15 +207,18 @@
static int cm206_base = CM206_BASE;
static int cm206_irq = CM206_IRQ;
-MODULE_PARM(cm206_base, "i");
-MODULE_PARM(cm206_irq, "i");
+MODULE_PARM(cm206_base, "i"); /* base */
+MODULE_PARM(cm206_irq, "i"); /* irq */
+MODULE_PARM(cm206, "1-2i"); /* base,irq or irq,base */
+MODULE_PARM(auto_probe, "i"); /* auto probe base and irq */
-#define POLLOOP 10000
+#define POLLOOP 100 /* milliseconds */
#define READ_AHEAD 1 /* defines private buffer, waste! */
#define BACK_AHEAD 1 /* defines adapter-read ahead */
#define DATA_TIMEOUT (3*HZ) /* measured in jiffies (10 ms) */
#define UART_TIMEOUT (5*HZ/100)
#define DSB_TIMEOUT (7*HZ) /* time for the slowest command to finish */
+#define UR_SIZE 4 /* uart receive buffer fifo size */
#define LINUX_BLOCK_SIZE 512 /* WHERE is this defined? */
#define RAW_SECTOR_SIZE 2352 /* ok, is also defined in cdrom.h */
@@ -181,13 +231,14 @@
cd->last_stat[st_ ## i] = cd->stat_counter++; \
}
#else
-#define stats(i) (void) 0
+#define stats(i) (void) 0;
#endif
-#ifdef DEBUG /* from lmscd.c */
-#define debug(a) printk a
+#define Debug(a) {printk (KERN_DEBUG); printk a;}
+#ifdef DEBUG
+#define debug(a) Debug(a)
#else
-#define debug(a) (void) 0
+#define debug(a) (void) 0;
#endif
typedef unsigned char uch; /* 8-bits */
@@ -197,21 +248,23 @@
uch track, fsm[3], q0;
};
+static int cm206_blocksizes[1] = { 2048 };
+
struct cm206_struct {
- ush intr_ds; /* data status read on last interrupt */
- ush intr_ls; /* uart line status read on last interrupt*/
- uch intr_ur; /* uart receive buffer */
- uch dsb, cc; /* drive status byte and condition (error) code */
- uch fool;
+ volatile ush intr_ds; /* data status read on last interrupt */
+ volatile ush intr_ls; /* uart line status read on last interrupt*/
+ volatile uch ur[UR_SIZE]; /* uart receive buffer fifo */
+ volatile uch ur_w, ur_r; /* write/read buffer index */
+ volatile uch dsb, cc; /* drive status byte and condition (error) code */
int command; /* command to be written to the uart */
int openfiles;
ush sector[READ_AHEAD*RAW_SECTOR_SIZE/2]; /* buffered cd-sector */
- int sector_first, sector_last; /* range of these sector */
- struct wait_queue * uart; /* wait for interrupt */
+ int sector_first, sector_last; /* range of these sectors */
+ struct wait_queue * uart; /* wait queues for interrupt */
struct wait_queue * data;
struct timer_list timer; /* time-out */
char timed_out;
- signed char max_sectors;
+ signed char max_sectors; /* number of sectors that fit in adapter mem */
char wait_back; /* we're waiting for a background-read */
char background; /* is a read going on in the background? */
int adapter_first; /* if so, that's the starting sector */
@@ -243,15 +296,20 @@
void send_command_polled(int command)
{
int loop=POLLOOP;
- while (!(inw(r_line_status) & ls_transmitter_buffer_empty) && loop>0)
+ while (!(inw(r_line_status) & ls_transmitter_buffer_empty) && loop>0) {
+ udelay(1000); /* one millisec delay */
--loop;
+ }
outw(command, r_uart_transmit);
}
uch receive_echo_polled(void)
{
int loop=POLLOOP;
- while (!(inw(r_line_status) & ls_receive_buffer_full) && loop>0) --loop;
+ while (!(inw(r_line_status) & ls_receive_buffer_full) && loop>0) {
+ udelay(1000);
+ --loop;
+ }
return ((uch) inw(r_uart_receive));
}
@@ -261,6 +319,15 @@
return receive_echo_polled();
}
+inline void clear_ur(void) {
+ if (cd->ur_r != cd->ur_w) {
+ debug(("Deleting bytes from fifo:"));
+ for(;cd->ur_r != cd->ur_w; cd->ur_r++, cd->ur_r %= UR_SIZE)
+ debug((" 0x%x", cd->ur[cd->ur_r]));
+ debug(("\n"));
+ }
+}
+
/* The interrupt handler. When the cm260 generates an interrupt, very
much care has to be taken in reading out the registers in the right
order; in case of a receive_buffer_full interrupt, first the
@@ -282,18 +349,27 @@
crc_error, sync_error, toc_ready
interrupts */
cd->intr_ls = inw(r_line_status); /* resets overrun bit */
+ debug(("Intr, 0x%x 0x%x, %d\n", cd->intr_ds, cd->intr_ls, cd->background));
if (cd->intr_ls & ls_attention) stats(attention);
/* receive buffer full? */
if (cd->intr_ls & ls_receive_buffer_full) {
- cd->intr_ur = inb(r_uart_receive); /* get order right! */
+ cd->ur[cd->ur_w] = inb(r_uart_receive); /* get order right! */
cd->intr_ls = inw(r_line_status); /* resets rbf interrupt */
- if (!cd->background && cd->uart) wake_up_interruptible(&cd->uart);
+ debug(("receiving #%d: 0x%x\n", cd->ur_w, cd->ur[cd->ur_w]));
+ cd->ur_w++; cd->ur_w %= UR_SIZE;
+ if (cd->ur_w == cd->ur_r) debug(("cd->ur overflow!\n"));
+ if (cd->uart && cd->background < 2) {
+ del_timer(&cd->timer);
+ wake_up_interruptible(&cd->uart);
+ }
}
/* data ready in fifo? */
else if (cd->intr_ds & ds_data_ready) {
if (cd->background) ++cd->adapter_last;
- if ((cd->wait_back || !cd->background) && cd->data)
+ if (cd->data && (cd->wait_back || !cd->background)) {
+ del_timer(&cd->timer);
wake_up_interruptible(&cd->data);
+ }
stats(data_ready);
}
/* ready to issue a write command? */
@@ -340,6 +416,7 @@
void cm206_timeout(unsigned long who)
{
cd->timed_out = 1;
+ debug(("Timing out\n"));
wake_up_interruptible((struct wait_queue **) who);
}
@@ -347,9 +424,11 @@
happened */
int sleep_or_timeout(struct wait_queue ** wait, int timeout)
{
+ cd->timed_out=0;
cd->timer.data=(unsigned long) wait;
cd->timer.expires = jiffies + timeout;
add_timer(&cd->timer);
+ debug(("going to sleep\n"));
interruptible_sleep_on(wait);
del_timer(&cd->timer);
if (cd->timed_out) {
@@ -359,14 +438,15 @@
else return 0;
}
-void cm206_delay(int jiffies)
+void cm206_delay(int nr_jiffies)
{
struct wait_queue * wait = NULL;
- sleep_or_timeout(&wait, jiffies);
+ sleep_or_timeout(&wait, nr_jiffies);
}
void send_command(int command)
{
+ debug(("Sending 0x%x\n", command));
if (!(inw(r_line_status) & ls_transmitter_buffer_empty)) {
cd->command = command;
cli(); /* don't interrupt before sleep */
@@ -378,19 +458,40 @@
stats(write_timeout);
outw(command, r_uart_transmit);
}
+ debug(("Write commmand delayed\n"));
}
else outw(command, r_uart_transmit);
}
-uch receive_echo(void)
+uch receive_byte(int timeout)
{
- if (!(inw(r_line_status) & ls_receive_buffer_full) &&
- sleep_or_timeout(&cd->uart, UART_TIMEOUT)) {
+ uch ret;
+ cli();
+ debug(("cli\n"));
+ ret = cd->ur[cd->ur_r];
+ if (cd->ur_r != cd->ur_w) {
+ sti();
+ debug(("returning #%d: 0x%x\n", cd->ur_r, cd->ur[cd->ur_r]));
+ cd->ur_r++; cd->ur_r %= UR_SIZE;
+ return ret;
+ }
+ else if (sleep_or_timeout(&cd->uart, timeout)) { /* does sti() */
debug(("Time out on receive-buffer\n"));
- stats(receive_timeout);
- return ((uch) inw(r_uart_receive));
+#ifdef STATISTICS
+ if (timeout==UART_TIMEOUT) stats(receive_timeout) /* no `;'! */
+ else stats(dsb_timeout);
+#endif
+ return 0xda;
}
- return cd->intr_ur;
+ ret = cd->ur[cd->ur_r];
+ debug(("slept; returning #%d: 0x%x\n", cd->ur_r, cd->ur[cd->ur_r]));
+ cd->ur_r++; cd->ur_r %= UR_SIZE;
+ return ret;
+}
+
+inline uch receive_echo(void)
+{
+ return receive_byte(UART_TIMEOUT);
}
inline uch send_receive(int command)
@@ -399,20 +500,15 @@
return receive_echo();
}
-uch wait_dsb(void)
+inline uch wait_dsb(void)
{
- if (!(inw(r_line_status) & ls_receive_buffer_full) &&
- sleep_or_timeout(&cd->uart, DSB_TIMEOUT)) {
- debug(("Time out on Drive Status Byte\n"));
- stats(dsb_timeout);
- return ((uch) inw(r_uart_receive));
- }
- return cd->intr_ur;
+ return receive_byte(DSB_TIMEOUT);
}
int type_0_command(int command, int expect_dsb)
{
int e;
+ clear_ur();
if (command != (e=send_receive(command))) {
debug(("command 0x%x echoed as 0x%x\n", command, e));
stats(echo);
@@ -433,8 +529,8 @@
return 0;
}
-/* This function resets the adapter card. We'd better not do this too */
-/* often, because it tends to generate `lost interrupts.' */
+/* This function resets the adapter card. We'd better not do this too
+ * often, because it tends to generate `lost interrupts.' */
void reset_cm260(void)
{
outw(dc_normal | dc_initialize | READ_AHEAD, r_data_control);
@@ -442,7 +538,7 @@
outw(dc_normal | READ_AHEAD, r_data_control);
}
-/* fsm: frame-sec-min from linear address */
+/* fsm: frame-sec-min from linear address; one of many */
void fsm(int lba, uch * fsm)
{
fsm[0] = lba % 75;
@@ -466,20 +562,26 @@
int i, e;
fsm(start, &read_sector[1]);
+ clear_ur();
for (i=0; i<4; i++)
if (read_sector[i] != (e=send_receive(read_sector[i]))) {
debug(("read_sector: %x echoes %x\n", read_sector[i], e));
stats(echo);
- return -1;
+ if (e==0xff) { /* this seems to happen often */
+ e = receive_echo();
+ debug(("Second try %x\n", e));
+ if (e!=read_sector[i]) return -1;
+ }
}
return 0;
}
int stop_read(void)
{
+ int e;
type_0_command(c_stop,0);
- if(receive_echo() != 0xff) {
- debug(("c_stop didn't send 0xff\n"));
+ if((e=receive_echo()) != 0xff) {
+ debug(("c_stop didn't send 0xff, but 0x%x\n", e));
stats(stop_0xff);
return -1;
}
@@ -515,8 +617,11 @@
}
#endif
+
+#define MAX_TRIES 100
int read_sector(int start)
{
+ int tries=0;
if (cd->background) {
cd->background=0;
cd->adapter_last = -1; /* invalidate adapter memory */
@@ -525,12 +630,18 @@
cd->fifo_overflowed=0;
reset_cm260(); /* empty fifo etc. */
if (start_read(start)) return -1;
- if (sleep_or_timeout(&cd->data, DATA_TIMEOUT)) {
- debug(("Read timed out sector 0x%x\n", start));
- stats(read_timeout);
- stop_read();
- return -3;
- }
+ do {
+ if (sleep_or_timeout(&cd->data, DATA_TIMEOUT)) {
+ debug(("Read timed out sector 0x%x\n", start));
+ stats(read_timeout);
+ stop_read();
+ return -3;
+ }
+ tries++;
+ } while (cd->intr_ds & ds_fifo_empty && tries < MAX_TRIES);
+ if (tries>1) debug(("Took me some tries\n"))
+ else if (tries == MAX_TRIES)
+ debug(("MAX_TRIES tries for read sector\n"));
transport_data(r_fifo_output_buffer, cd->sector,
READ_AHEAD*RAW_SECTOR_SIZE/2);
if (read_background(start+READ_AHEAD,1)) stats(read_background);
@@ -569,16 +680,22 @@
cd->background=3;
break;
case 3:
- if (cd->intr_ur != c_stop) {
- debug(("cm206_bh: c_stop echoed 0x%x\n", cd->intr_ur));
- stats(echo);
+ if (cd->ur_r != cd->ur_w) {
+ if (cd->ur[cd->ur_r] != c_stop) {
+ debug(("cm206_bh: c_stop echoed 0x%x\n", cd->ur[cd->ur_r]));
+ stats(echo);
+ }
+ cd->ur_r++; cd->ur_r %= UR_SIZE;
}
cd->background++;
break;
case 4:
- if (cd->intr_ur != 0xff) {
- debug(("cm206_bh: c_stop reacted with 0x%x\n", cd->intr_ur));
- stats(stop_0xff);
+ if (cd->ur_r != cd->ur_w) {
+ if (cd->ur[cd->ur_r] != 0xff) {
+ debug(("cm206_bh: c_stop reacted with 0x%x\n", cd->ur[cd->ur_r]));
+ stats(stop_0xff);
+ }
+ cd->ur_r++; cd->ur_r %= UR_SIZE;
}
cd->background=0;
}
@@ -699,6 +816,7 @@
}
error=0;
for (i=0; i<CURRENT->nr_sectors; i++) {
+ int e1, e2;
cd_sec_no = (CURRENT->sector+i)/BLOCKS_ISO; /* 4 times 512 bytes */
quarter = (CURRENT->sector+i) % BLOCKS_ISO;
dest = CURRENT->buffer + i*LINUX_BLOCK_SIZE;
@@ -708,12 +826,14 @@
+ (cd_sec_no-cd->sector_first)*RAW_SECTOR_SIZE;
memcpy(dest, source, LINUX_BLOCK_SIZE);
}
- else if (!try_adapter(cd_sec_no) || !read_sector(cd_sec_no)) {
+ else if (!(e1=try_adapter(cd_sec_no)) ||
+ !(e2=read_sector(cd_sec_no))) {
source = ((uch *) cd->sector)+16+quarter*LINUX_BLOCK_SIZE;
memcpy(dest, source, LINUX_BLOCK_SIZE);
}
else {
error=1;
+ debug(("cm206_request: %d %d\n", e1, e2));
}
}
end_request(!error);
@@ -758,21 +878,22 @@
/* This function does a binary search for track start. It records all
* tracks seen in the process. Input $track$ must be between 1 and
- * #-of-tracks+1 */
+ * #-of-tracks+1. Note that the start of the disc must be in toc[1].fsm.
+ */
int get_toc_lba(uch track)
{
- int max=74*60*75-150, min=0;
+ int max=74*60*75-150, min=fsm2lba(cd->toc[1].fsm);
int i, lba, l, old_lba=0;
uch * q = cd->q;
uch ct; /* current track */
int binary=0;
- const skip = 3*60*75;
+ const skip = 3*60*75; /* 3 minutes */
for (i=track; i>0; i--) if (cd->toc[i].track) {
min = fsm2lba(cd->toc[i].fsm);
break;
}
- lba = min + skip; /* 3 minutes */
+ lba = min + skip;
do {
seek(lba);
type_1_command(c_read_current_q, 10, q);
@@ -811,11 +932,11 @@
int read_toc_header(struct cdrom_tochdr * hp)
{
if (!FIRST_TRACK) get_disc_status();
- if (hp && DISC_STATUS & cds_all_audio) { /* all audio */
+ if (hp) {
int i;
hp->cdth_trk0 = FIRST_TRACK;
- hp->cdth_trk1 = LAST_TRACK;
- cd->toc[1].track=1; /* fill in first track position */
+ hp->cdth_trk1 = LAST_TRACK;
+ /* fill in first track position */
for (i=0; i<3; i++) cd->toc[1].fsm[i] = cd->disc_status[3+i];
update_toc_entry(LAST_TRACK+1); /* find most entries */
return 0;
@@ -988,7 +1109,7 @@
else return -EIO;
}
-/* The new Uniform cdrom support. Routines should be concise, most of
+/* The new generic cdrom support. Routines should be concise, most of
the logic should be in cdrom.c */
/* returns number of times device is in use */
@@ -1019,6 +1140,24 @@
return CDS_DISC_OK;
}
+/* gives current state of disc in drive */
+int cm206_disc_status(struct cdrom_device_info * cdi)
+{
+ uch xa;
+ get_drive_status();
+ if ((cd->dsb & dsb_not_useful) | !(cd->dsb & dsb_disc_present))
+ return CDS_NO_DISC;
+ get_disc_status();
+ if (DISC_STATUS & cds_all_audio) return CDS_AUDIO;
+ xa = DISC_STATUS >> 4;
+ switch (xa) {
+ case 0: return CDS_DATA_1; /* can we detect CDS_DATA_2? */
+ case 1: return CDS_XA_2_1; /* untested */
+ case 2: return CDS_XA_2_2;
+ }
+ return 0;
+}
+
/* locks or unlocks door lock==1: lock; return 0 upon success */
int cm206_lock_door(struct cdrom_device_info * cdi, int lock)
{
@@ -1029,7 +1168,7 @@
}
/* Although a session start should be in LBA format, we return it in
- MSF format because it is slightly easier, and the new Uniform ioctl
+ MSF format because it is slightly easier, and the new generic ioctl
will take care of the necessary conversion. */
int cm206_get_last_session(struct cdrom_device_info * cdi,
struct cdrom_multisession * mssp)
@@ -1114,7 +1253,9 @@
cm206_audio_ioctl, /* audio ioctl */
cm206_ioctl, /* device-specific ioctl */
CDC_CLOSE_TRAY | CDC_OPEN_TRAY | CDC_LOCK | CDC_MULTI_SESSION |
- CDC_MEDIA_CHANGED | CDC_MCN | CDC_PLAY_AUDIO, /* capability */
+ CDC_MEDIA_CHANGED | CDC_MCN | CDC_PLAY_AUDIO | CDC_SELECT_SPEED |
+ CDC_IOCTLS | CDC_DRIVE_STATUS,
+ /* capability */
1, /* number of minor devices */
};
@@ -1206,7 +1347,7 @@
uch e=0;
long int size=sizeof(struct cm206_struct);
- printk(KERN_INFO VERSION);
+ printk(KERN_INFO "cm206 cdrom driver " REVISION);
cm206_base = probe_base_port(auto_probe ? 0 : cm206_base);
if (!cm206_base) {
printk(" can't find adapter!\n");
@@ -1233,14 +1374,14 @@
/* Now, the problem here is that reset_cm260 can generate an
interrupt. It seems that this can cause a kernel oops some time
later. So we wait a while and `service' this interrupt. */
- udelay(10);
+ udelay(1000);
outw(dc_normal | READ_AHEAD, r_data_control);
sti();
printk(" using IRQ %d\n", cm206_irq);
#endif
if (send_receive_polled(c_drive_configuration) != c_drive_configuration)
{
- printk(" drive not there\n");
+ printk(KERN_INFO " drive not there\n");
cleanup(1);
return -EIO;
}
@@ -1257,16 +1398,17 @@
}
printk(".\n");
if (register_blkdev(MAJOR_NR, "cm206", &cdrom_fops) != 0) {
- printk("Cannot register for major %d!\n", MAJOR_NR);
+ printk(KERN_INFO "Cannot register for major %d!\n", MAJOR_NR);
cleanup(3);
return -EIO;
}
if (register_cdrom(&cm206_info) != 0) {
- printk("Cannot register for cdrom %d!\n", MAJOR_NR);
+ printk(KERN_INFO "Cannot register for cdrom %d!\n", MAJOR_NR);
cleanup(3);
return -EIO;
}
blk_dev[MAJOR_NR].request_fn = DEVICE_REQUEST;
+ blksize_size[MAJOR_NR] = cm206_blocksizes;
read_ahead[MAJOR_NR] = 16; /* reads ahead what? */
init_bh(CM206_BH, cm206_bh);
@@ -1336,6 +1478,6 @@
#endif /* MODULE */
/*
* Local variables:
- * compile-command: "gcc -DMODULE -D__KERNEL__ -I. -I/usr/src/linux/include/linux -Wall -Wstrict-prototypes -O2 -m486 -c cm206.c -o cm206.o"
+ * compile-command: "gcc -D__KERNEL__ -I/usr/src/linux/include -Wall -Wstrict-prototypes -O2 -fomit-frame-pointer -D__SMP__ -pipe -fno-strength-reduce -m486 -DCPU=486 -D__SMP__ -DMODULE -DMODVERSIONS -include /usr/src/linux/include/linux/modversions.h -c -o cm206.o cm206.c"
* End:
*/
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov