patch-1.3.14 linux/drivers/block/cdu31a.c
Next file: linux/drivers/block/cm206.c
Previous file: linux/drivers/block/aztcd.c
Back to the patch index
Back to the overall index
- Lines: 768
- Date:
Mon Jul 31 10:34:08 1995
- Orig file:
v1.3.13/linux/drivers/block/cdu31a.c
- Orig date:
Tue Jul 25 18:21:21 1995
diff -u --recursive --new-file v1.3.13/linux/drivers/block/cdu31a.c linux/drivers/block/cdu31a.c
@@ -160,6 +160,17 @@
* 4, but I think that is a mistake.
*/
+#include <linux/major.h>
+#include <linux/config.h>
+
+#ifdef MODULE
+# include <linux/module.h>
+# include <linux/version.h>
+# ifndef CONFIG_MODVERSIONS
+ char kernel_version[]= UTS_RELEASE;
+# endif
+#endif
+
#include <linux/errno.h>
#include <linux/signal.h>
#include <linux/sched.h>
@@ -237,7 +248,7 @@
/* The base I/O address of the Sony Interface. This is a variable (not a
#define) so it can be easily changed via some future ioctl() */
-static unsigned short sony_cd_base_io = 0;
+static unsigned short cdu31a_port = 0;
/*
* The following are I/O addresses of the various registers for the drive. The
@@ -267,15 +278,15 @@
static int sony_pas_init = 0; /* Initialize the Pro-Audio
Spectrum card? */
-static struct s_sony_session_toc *sony_toc; /* Points to the
+static struct s_sony_session_toc sony_toc; /* Holds the
table of
contents. */
static int sony_toc_read = 0; /* Has the TOC been read for
the drive? */
-static struct s_sony_subcode * volatile last_sony_subcode; /* Points to the last
- subcode address read */
+static struct s_sony_subcode last_sony_subcode; /* Points to the last
+ subcode address read */
static volatile int sony_inuse = 0; /* Is the drive in use? Only one operation
at a time allowed */
@@ -305,7 +316,7 @@
static unsigned volatile char final_pos_msf[3] = { 0, 0, 0 };
/* What IRQ is the drive using? 0 if none. */
-static int irq_used = 0;
+static int cdu31a_irq = 0;
/* The interrupt handler will wake this queue up when it gets an
interrupts. */
@@ -321,7 +332,7 @@
/* Variable for using the readahead buffer. The readahead buffer
is used for raw sector reads and for blocksizes that are smaller
than 2048 bytes. */
-static char *readahead_buffer = NULL; /* Used for 1024 byte blocksize. */
+static char readahead_buffer[CD_FRAMESIZE_RAW];
static int readahead_dataleft = 0;
static int readahead_bad = 0;
@@ -330,6 +341,11 @@
the drive from flashing for very long. */
static struct timer_list cdu31a_abort_timer;
+/* Marks if the timeout has started an abort read. This is used
+ on entry to the drive to tell the code to read out the status
+ from the abort read. */
+static int abort_read_started = 0;
+
/*
* This routine returns 1 if the disk has been changed since the last
@@ -387,7 +403,7 @@
{
unsigned long flags;
- if (irq_used <= 0)
+ if (cdu31a_irq <= 0)
{
current->state = TASK_INTERRUPTIBLE;
current->timeout = jiffies;
@@ -799,13 +815,14 @@
{
recursive_call = 1;
}
- restore_flags(flags);
num_retries = 0;
retry_cd_operation:
while (handle_sony_cd_attention())
;
+
+ sti();
retry_count = jiffies + SONY_JIFFIES_TIMEOUT;
while ((retry_count > jiffies) && (is_busy()))
@@ -851,6 +868,8 @@
sony_inuse = 0;
wake_up_interruptible(&sony_wait);
}
+
+ restore_flags(flags);
}
@@ -868,9 +887,26 @@
{
unsigned char atten_code;
static int num_consecutive_attentions = 0;
+ volatile int val;
- if (is_attention())
+ if (abort_read_started)
+ {
+ while (is_result_reg_not_empty())
+ {
+ val = read_result_register();
+ }
+ clear_data_ready();
+ clear_result_ready();
+ /* Clear out the data */
+ while (is_data_requested())
+ {
+ val = read_data_register();
+ }
+ abort_read_started = 0;
+ return(1);
+ }
+ else if (is_attention())
{
if (num_consecutive_attentions > CDU31A_MAX_CONSECUTIVE_ATTENTIONS)
{
@@ -1018,9 +1054,9 @@
* If the full read-ahead would go beyond the end of the media, trim
* it back to read just till the end of the media.
*/
- else if ((sector + nsect) >= sony_toc->lead_out_start_lba)
+ else if ((sector + nsect) >= sony_toc.lead_out_start_lba)
{
- read_size = sony_toc->lead_out_start_lba - sector;
+ read_size = sony_toc.lead_out_start_lba - sector;
}
/* Read the full readahead amount. */
else
@@ -1106,7 +1142,22 @@
static void
handle_abort_timeout(unsigned long data)
{
- abort_read();
+ /* If it is in use, ignore it. */
+ if (!sony_inuse)
+ {
+ /* We can't use abort_read(), because it will sleep
+ or schedule in the timer interrupt. Just start
+ the operation, finish it on the next access to
+ the drive. */
+ clear_result_ready();
+ clear_param_reg();
+ write_cmd(SONY_ABORT_CMD);
+
+ sony_blocks_left = 0;
+ readahead_dataleft = 0;
+ readahead_bad = 0;
+ abort_read_started = 1;
+ }
}
/* Actually get data and status from the drive. */
@@ -1411,12 +1462,13 @@
}
sony_inuse = 1;
has_cd_task = current;
- sti();
/* Get drive status before doing anything. */
while (handle_sony_cd_attention())
;
+ sti();
+
/* If the timer is running, cancel it. */
if (cdu31a_abort_timer.next != NULL)
{
@@ -1478,7 +1530,7 @@
if (block < 80)
{
/* Offset the request into the session. */
- block += (sony_toc->start_track_lba * 4);
+ block += (sony_toc.start_track_lba * 4);
}
switch(CURRENT->cmd)
@@ -1489,20 +1541,20 @@
* the media, return an error.
*/
#if 0
- if ((block / 4) < sony_toc->start_track_lba)
+ if ((block / 4) < sony_toc.start_track_lba)
{
printk("CDU31A: Request before beginning of media\n");
end_request(0);
goto cdu31a_request_startover;
}
#endif
- if ((block / 4) >= sony_toc->lead_out_start_lba)
+ if ((block / 4) >= sony_toc.lead_out_start_lba)
{
printk("CDU31A: Request past end of media\n");
end_request(0);
goto cdu31a_request_startover;
}
- if (((block + nblock) / 4) >= sony_toc->lead_out_start_lba)
+ if (((block + nblock) / 4) >= sony_toc.lead_out_start_lba)
{
printk("CDU31A: Request past end of media\n");
end_request(0);
@@ -1599,7 +1651,7 @@
#else
/* Start a timer to time out after a while to disable
the read. */
- cdu31a_abort_timer.expires = 200; /* Wait 2 seconds */
+ cdu31a_abort_timer.expires = jiffies + 2*HZ; /* Wait 2 seconds */
add_timer(&cdu31a_abort_timer);
#endif
@@ -1694,9 +1746,9 @@
do_sony_cd_cmd(SONY_REQ_TOC_DATA_SPEC_CMD,
parms,
1,
- (unsigned char *) sony_toc,
+ (unsigned char *) &sony_toc,
&res_size);
- if ((res_size < 2) || ((sony_toc->exec_status[0] & 0xf0) == 0x20))
+ if ((res_size < 2) || ((sony_toc.exec_status[0] & 0xf0) == 0x20))
{
/* An error reading the TOC. Return without sony_toc_read
set. */
@@ -1707,57 +1759,57 @@
/* For points that do not exist, move the data over them
to the right location. */
- if (sony_toc->pointb0 != 0xb0)
+ if (sony_toc.pointb0 != 0xb0)
{
- mcovlp(((char *) sony_toc) + 27,
- ((char *) sony_toc) + 18,
+ mcovlp(((char *) &sony_toc) + 27,
+ ((char *) &sony_toc) + 18,
res_size - 18);
res_size += 9;
}
- if (sony_toc->pointb1 != 0xb1)
+ if (sony_toc.pointb1 != 0xb1)
{
- mcovlp(((char *) sony_toc) + 36,
- ((char *) sony_toc) + 27,
+ mcovlp(((char *) &sony_toc) + 36,
+ ((char *) &sony_toc) + 27,
res_size - 27);
res_size += 9;
}
- if (sony_toc->pointb2 != 0xb2)
+ if (sony_toc.pointb2 != 0xb2)
{
- mcovlp(((char *) sony_toc) + 45,
- ((char *) sony_toc) + 36,
+ mcovlp(((char *) &sony_toc) + 45,
+ ((char *) &sony_toc) + 36,
res_size - 36);
res_size += 9;
}
- if (sony_toc->pointb3 != 0xb3)
+ if (sony_toc.pointb3 != 0xb3)
{
- mcovlp(((char *) sony_toc) + 54,
- ((char *) sony_toc) + 45,
+ mcovlp(((char *) &sony_toc) + 54,
+ ((char *) &sony_toc) + 45,
res_size - 45);
res_size += 9;
}
- if (sony_toc->pointb4 != 0xb4)
+ if (sony_toc.pointb4 != 0xb4)
{
- mcovlp(((char *) sony_toc) + 63,
- ((char *) sony_toc) + 54,
+ mcovlp(((char *) &sony_toc) + 63,
+ ((char *) &sony_toc) + 54,
res_size - 54);
res_size += 9;
}
- if (sony_toc->pointc0 != 0xc0)
+ if (sony_toc.pointc0 != 0xc0)
{
- mcovlp(((char *) sony_toc) + 72,
- ((char *) sony_toc) + 63,
+ mcovlp(((char *) &sony_toc) + 72,
+ ((char *) &sony_toc) + 63,
res_size - 63);
res_size += 9;
}
- sony_toc->start_track_lba = msf_to_log(sony_toc->tracks[0].track_start_msf);
- sony_toc->lead_out_start_lba = msf_to_log(sony_toc->lead_out_start_msf);
+ sony_toc.start_track_lba = msf_to_log(sony_toc.tracks[0].track_start_msf);
+ sony_toc.lead_out_start_lba = msf_to_log(sony_toc.lead_out_start_msf);
#if DEBUG
printk("Disk session %d, start track: %d, stop track: %d\n",
session,
- sony_toc->start_track_lba,
- sony_toc->lead_out_start_lba);
+ sony_toc.start_track_lba,
+ sony_toc.lead_out_start_lba);
#endif
}
#if DEBUG
@@ -1776,10 +1828,10 @@
int num_tracks;
- num_tracks = sony_toc->last_track_num - sony_toc->first_track_num + 1;
+ num_tracks = sony_toc.last_track_num - sony_toc.first_track_num + 1;
for (i = 0; i < num_tracks; i++)
{
- if (sony_toc->tracks[i].track == track)
+ if (sony_toc.tracks[i].track == track)
{
return i;
}
@@ -1801,12 +1853,12 @@
do_sony_cd_cmd(SONY_REQ_SUBCODE_ADDRESS_CMD,
NULL,
0,
- (unsigned char *) last_sony_subcode,
+ (unsigned char *) &last_sony_subcode,
&res_size);
- if ((res_size < 2) || ((last_sony_subcode->exec_status[0] & 0xf0) == 0x20))
+ if ((res_size < 2) || ((last_sony_subcode.exec_status[0] & 0xf0) == 0x20))
{
printk("Sony CDROM error 0x%2.2x (read_subcode)\n",
- last_sony_subcode->exec_status[1]);
+ last_sony_subcode.exec_status[1]);
return -EIO;
}
@@ -1868,24 +1920,24 @@
}
schi.cdsc_audiostatus = sony_audio_status;
- schi.cdsc_adr = last_sony_subcode->address;
- schi.cdsc_ctrl = last_sony_subcode->control;
- schi.cdsc_trk = bcd_to_int(last_sony_subcode->track_num);
- schi.cdsc_ind = bcd_to_int(last_sony_subcode->index_num);
+ schi.cdsc_adr = last_sony_subcode.address;
+ schi.cdsc_ctrl = last_sony_subcode.control;
+ schi.cdsc_trk = bcd_to_int(last_sony_subcode.track_num);
+ schi.cdsc_ind = bcd_to_int(last_sony_subcode.index_num);
if (schi.cdsc_format == CDROM_MSF)
{
- schi.cdsc_absaddr.msf.minute = bcd_to_int(last_sony_subcode->abs_msf[0]);
- schi.cdsc_absaddr.msf.second = bcd_to_int(last_sony_subcode->abs_msf[1]);
- schi.cdsc_absaddr.msf.frame = bcd_to_int(last_sony_subcode->abs_msf[2]);
-
- schi.cdsc_reladdr.msf.minute = bcd_to_int(last_sony_subcode->rel_msf[0]);
- schi.cdsc_reladdr.msf.second = bcd_to_int(last_sony_subcode->rel_msf[1]);
- schi.cdsc_reladdr.msf.frame = bcd_to_int(last_sony_subcode->rel_msf[2]);
+ schi.cdsc_absaddr.msf.minute = bcd_to_int(last_sony_subcode.abs_msf[0]);
+ schi.cdsc_absaddr.msf.second = bcd_to_int(last_sony_subcode.abs_msf[1]);
+ schi.cdsc_absaddr.msf.frame = bcd_to_int(last_sony_subcode.abs_msf[2]);
+
+ schi.cdsc_reladdr.msf.minute = bcd_to_int(last_sony_subcode.rel_msf[0]);
+ schi.cdsc_reladdr.msf.second = bcd_to_int(last_sony_subcode.rel_msf[1]);
+ schi.cdsc_reladdr.msf.frame = bcd_to_int(last_sony_subcode.rel_msf[2]);
}
else if (schi.cdsc_format == CDROM_LBA)
{
- schi.cdsc_absaddr.lba = msf_to_log(last_sony_subcode->abs_msf);
- schi.cdsc_reladdr.lba = msf_to_log(last_sony_subcode->rel_msf);
+ schi.cdsc_absaddr.lba = msf_to_log(last_sony_subcode.abs_msf);
+ schi.cdsc_reladdr.lba = msf_to_log(last_sony_subcode.rel_msf);
}
memcpy_tofs((char *) arg, &schi, sizeof(schi));
@@ -2217,12 +2269,13 @@
return(retval);
}
-/*
- * The big ugly ioctl handler.
- */
-
-static int do_sony_cd_cmd_chk(char *name, unsigned char cmd, unsigned char *params, unsigned int num_params,
- unsigned char *result_buffer, unsigned int *result_size)
+static int
+do_sony_cd_cmd_chk(char *name,
+ unsigned char cmd,
+ unsigned char *params,
+ unsigned int num_params,
+ unsigned char *result_buffer,
+ unsigned int *result_size)
{
do_sony_cd_cmd(cmd, params, num_params, result_buffer, result_size);
if ((*result_size < 2) || ((result_buffer[0] & 0xf0) == 0x20))
@@ -2233,6 +2286,9 @@
return 0;
}
+/*
+ * The big ugly ioctl handler.
+ */
static int scd_ioctl(struct inode *inode,
struct file *file,
unsigned int cmd,
@@ -2274,9 +2330,9 @@
{
return -EIO;
}
- cur_pos_msf[0] = last_sony_subcode->abs_msf[0];
- cur_pos_msf[1] = last_sony_subcode->abs_msf[1];
- cur_pos_msf[2] = last_sony_subcode->abs_msf[2];
+ cur_pos_msf[0] = last_sony_subcode.abs_msf[0];
+ cur_pos_msf[1] = last_sony_subcode.abs_msf[1];
+ cur_pos_msf[2] = last_sony_subcode.abs_msf[2];
sony_audio_status = CDROM_AUDIO_PAUSED;
return 0;
break;
@@ -2340,8 +2396,8 @@
i=verify_area(VERIFY_WRITE, hdr, sizeof(*hdr));
if(i<0)
return i;
- loc_hdr.cdth_trk0 = bcd_to_int(sony_toc->first_track_num);
- loc_hdr.cdth_trk1 = bcd_to_int(sony_toc->last_track_num);
+ loc_hdr.cdth_trk0 = bcd_to_int(sony_toc.first_track_num);
+ loc_hdr.cdth_trk1 = bcd_to_int(sony_toc.last_track_num);
memcpy_tofs(hdr, &loc_hdr, sizeof(*hdr));
}
return 0;
@@ -2372,9 +2428,9 @@
/* Lead out is handled separately since it is special. */
if (loc_entry.cdte_track == CDROM_LEADOUT)
{
- loc_entry.cdte_adr = sony_toc->address2;
- loc_entry.cdte_ctrl = sony_toc->control2;
- msf_val = sony_toc->lead_out_start_msf;
+ loc_entry.cdte_adr = sony_toc.address2;
+ loc_entry.cdte_ctrl = sony_toc.control2;
+ msf_val = sony_toc.lead_out_start_msf;
}
else
{
@@ -2384,9 +2440,9 @@
return -EINVAL;
}
- loc_entry.cdte_adr = sony_toc->tracks[track_idx].address;
- loc_entry.cdte_ctrl = sony_toc->tracks[track_idx].control;
- msf_val = sony_toc->tracks[track_idx].track_start_msf;
+ loc_entry.cdte_adr = sony_toc.tracks[track_idx].address;
+ loc_entry.cdte_ctrl = sony_toc.tracks[track_idx].control;
+ msf_val = sony_toc.tracks[track_idx].track_start_msf;
}
/* Logical buffer address or MSF format requested? */
@@ -2421,8 +2477,8 @@
return i;
memcpy_fromfs(&ti, (char *) arg, sizeof(ti));
- if ( (ti.cdti_trk0 < sony_toc->first_track_num)
- || (ti.cdti_trk0 > sony_toc->last_track_num)
+ if ( (ti.cdti_trk0 < sony_toc.first_track_num)
+ || (ti.cdti_trk0 > sony_toc.last_track_num)
|| (ti.cdti_trk1 < ti.cdti_trk0))
{
return -EINVAL;
@@ -2433,17 +2489,17 @@
{
return -EINVAL;
}
- params[1] = sony_toc->tracks[track_idx].track_start_msf[0];
- params[2] = sony_toc->tracks[track_idx].track_start_msf[1];
- params[3] = sony_toc->tracks[track_idx].track_start_msf[2];
+ params[1] = sony_toc.tracks[track_idx].track_start_msf[0];
+ params[2] = sony_toc.tracks[track_idx].track_start_msf[1];
+ params[3] = sony_toc.tracks[track_idx].track_start_msf[2];
/*
* If we want to stop after the last track, use the lead-out
* MSF to do that.
*/
- if (ti.cdti_trk1 >= bcd_to_int(sony_toc->last_track_num))
+ if (ti.cdti_trk1 >= bcd_to_int(sony_toc.last_track_num))
{
- log_to_msf(msf_to_log(sony_toc->lead_out_start_msf)-1,
+ log_to_msf(msf_to_log(sony_toc.lead_out_start_msf)-1,
&(params[4]));
}
else
@@ -2453,7 +2509,7 @@
{
return -EINVAL;
}
- log_to_msf(msf_to_log(sony_toc->tracks[track_idx].track_start_msf)-1,
+ log_to_msf(msf_to_log(sony_toc.tracks[track_idx].track_start_msf)-1,
&(params[4]));
}
params[0] = 0x03;
@@ -2525,8 +2581,8 @@
if (ra.addr_format == CDROM_LBA)
{
- if ( (ra.addr.lba >= sony_toc->lead_out_start_lba)
- || (ra.addr.lba + ra.nframes >= sony_toc->lead_out_start_lba))
+ if ( (ra.addr.lba >= sony_toc.lead_out_start_lba)
+ || (ra.addr.lba + ra.nframes >= sony_toc.lead_out_start_lba))
{
return -EINVAL;
}
@@ -2543,8 +2599,8 @@
ra.addr.lba = ( (ra.addr.msf.minute * 4500)
+ (ra.addr.msf.second * 75)
+ ra.addr.msf.frame);
- if ( (ra.addr.lba >= sony_toc->lead_out_start_lba)
- || (ra.addr.lba + ra.nframes >= sony_toc->lead_out_start_lba))
+ if ( (ra.addr.lba >= sony_toc.lead_out_start_lba)
+ || (ra.addr.lba + ra.nframes >= sony_toc.lead_out_start_lba))
{
return -EINVAL;
}
@@ -2638,7 +2694,7 @@
/* For XA on the CDU31A only, we have to do special reads.
The CDU33A handles XA automagically. */
- if ( (sony_toc->disk_type == SONY_XA_DISK_TYPE)
+ if ( (sony_toc.disk_type == SONY_XA_DISK_TYPE)
&& (!is_double_speed))
{
params[0] = SONY_SD_DECODE_PARAM;
@@ -2743,17 +2799,17 @@
/* Set the base address */
- sony_cd_base_io = base_io;
+ cdu31a_port = base_io;
/* Set up all the register locations */
- sony_cd_cmd_reg = sony_cd_base_io + SONY_CMD_REG_OFFSET;
- sony_cd_param_reg = sony_cd_base_io + SONY_PARAM_REG_OFFSET;
- sony_cd_write_reg = sony_cd_base_io + SONY_WRITE_REG_OFFSET;
- sony_cd_control_reg = sony_cd_base_io + SONY_CONTROL_REG_OFFSET;
- sony_cd_status_reg = sony_cd_base_io + SONY_STATUS_REG_OFFSET;
- sony_cd_result_reg = sony_cd_base_io + SONY_RESULT_REG_OFFSET;
- sony_cd_read_reg = sony_cd_base_io + SONY_READ_REG_OFFSET;
- sony_cd_fifost_reg = sony_cd_base_io + SONY_FIFOST_REG_OFFSET;
+ sony_cd_cmd_reg = cdu31a_port + SONY_CMD_REG_OFFSET;
+ sony_cd_param_reg = cdu31a_port + SONY_PARAM_REG_OFFSET;
+ sony_cd_write_reg = cdu31a_port + SONY_WRITE_REG_OFFSET;
+ sony_cd_control_reg = cdu31a_port + SONY_CONTROL_REG_OFFSET;
+ sony_cd_status_reg = cdu31a_port + SONY_STATUS_REG_OFFSET;
+ sony_cd_result_reg = cdu31a_port + SONY_RESULT_REG_OFFSET;
+ sony_cd_read_reg = cdu31a_port + SONY_READ_REG_OFFSET;
+ sony_cd_fifost_reg = cdu31a_port + SONY_FIFOST_REG_OFFSET;
/*
* Check to see if anything exists at the status register location.
@@ -2806,11 +2862,11 @@
{
if (ints[0] > 0)
{
- sony_cd_base_io = ints[1];
+ cdu31a_port = ints[1];
}
if (ints[0] > 1)
{
- irq_used = ints[2];
+ cdu31a_irq = ints[2];
}
if ((strings != NULL) && (*strings != '\0'))
{
@@ -2830,8 +2886,13 @@
/*
* Initialize the driver.
*/
+#ifndef MODULE
unsigned long
cdu31a_init(unsigned long mem_start, unsigned long mem_end)
+#else
+int
+init_module(void)
+#endif
{
struct s_sony_drive_config drive_config;
unsigned int res_size;
@@ -2856,15 +2917,15 @@
drive_found = 0;
/* Setting the base I/O address to 0xffff will disable it. */
- if (sony_cd_base_io == 0xffff)
+ if (cdu31a_port == 0xffff)
{
}
- else if (sony_cd_base_io != 0)
+ else if (cdu31a_port != 0)
{
- tmp_irq = irq_used; /* Need IRQ 0 because we can't sleep here. */
- irq_used = 0;
+ tmp_irq = cdu31a_irq; /* Need IRQ 0 because we can't sleep here. */
+ cdu31a_irq = 0;
- get_drive_configuration(sony_cd_base_io,
+ get_drive_configuration(cdu31a_port,
drive_config.exec_status,
&res_size);
if ((res_size > 2) && ((drive_config.exec_status[0] & 0xf0) == 0x00))
@@ -2872,11 +2933,11 @@
drive_found = 1;
}
- irq_used = tmp_irq;
+ cdu31a_irq = tmp_irq;
}
else
{
- irq_used = 0;
+ cdu31a_irq = 0;
i = 0;
while ( (cdu31a_addresses[i].base != 0)
&& (!drive_found))
@@ -2891,7 +2952,7 @@
if ((res_size > 2) && ((drive_config.exec_status[0] & 0xf0) == 0x00))
{
drive_found = 1;
- irq_used = cdu31a_addresses[i].int_num;
+ cdu31a_irq = cdu31a_addresses[i].int_num;
}
else
{
@@ -2902,12 +2963,16 @@
if (drive_found)
{
- request_region(sony_cd_base_io, 4,"cdu31a");
+ request_region(cdu31a_port, 4,"cdu31a");
if (register_blkdev(MAJOR_NR,"cdu31a",&scd_fops))
{
printk("Unable to get major %d for CDU-31a\n", MAJOR_NR);
+#ifdef MODULE
+ return -EIO;
+#else
return mem_start;
+#endif
}
if (SONY_HWC_DOUBLE_SPEED(drive_config))
@@ -2915,35 +2980,19 @@
is_double_speed = 1;
}
- /* A negative irq_used will attempt an autoirq. */
- if (irq_used < 0)
- {
- autoirq_setup(0);
- enable_interrupts();
- reset_drive();
- tmp_irq = autoirq_report(10);
- disable_interrupts();
-
- irq_used = 0;
- set_drive_params();
- irq_used = tmp_irq;
- }
- else
- {
- tmp_irq = irq_used; /* Need IRQ 0 because we can't sleep here. */
- irq_used = 0;
+ tmp_irq = cdu31a_irq; /* Need IRQ 0 because we can't sleep here. */
+ cdu31a_irq = 0;
- set_drive_params();
+ set_drive_params();
- irq_used = tmp_irq;
- }
+ cdu31a_irq = tmp_irq;
- if (irq_used > 0)
+ if (cdu31a_irq > 0)
{
- if (request_irq(irq_used, cdu31a_interrupt, SA_INTERRUPT, "cdu31a"))
+ if (request_irq(cdu31a_irq, cdu31a_interrupt, SA_INTERRUPT, "cdu31a"))
{
- printk("Unable to grab IRQ%d for the CDU31A driver\n", irq_used);
- irq_used = 0;
+ printk("Unable to grab IRQ%d for the CDU31A driver\n", cdu31a_irq);
+ cdu31a_irq = 0;
}
}
@@ -2977,9 +3026,9 @@
{
printk(", double speed");
}
- if (irq_used > 0)
+ if (cdu31a_irq > 0)
{
- printk(", irq %d", irq_used);
+ printk(", irq %d", cdu31a_irq);
}
printk("\n");
@@ -2989,13 +3038,6 @@
/* use 'mount -o block=2048' */
blksize_size[MAJOR_NR] = &cdu31a_block_size;
- last_sony_subcode = (struct s_sony_subcode *) mem_start;
- mem_start += sizeof(*last_sony_subcode);
- readahead_buffer = (unsigned char *) mem_start;
- mem_start += CD_FRAMESIZE_RAW;
- sony_toc = (struct s_sony_session_toc *) mem_start;
- mem_start += sizeof(struct s_sony_session_toc);
-
cdu31a_abort_timer.next = NULL;
cdu31a_abort_timer.prev = NULL;
cdu31a_abort_timer.function = handle_abort_timeout;
@@ -3004,5 +3046,36 @@
disk_changed = 1;
+#ifdef MODULE
+ if (drive_found)
+ {
+ return(0);
+ }
+ else
+ {
+ return -EIO;
+ }
+#else
return mem_start;
+#endif
}
+
+#ifdef MODULE
+void
+cleanup_module(void)
+{
+ if (sony_usage != 0)
+ {
+ printk("cdu31a module in use - can't remove it.\n");
+ return;
+ }
+
+ if ((unregister_blkdev(MAJOR_NR, "cdu31a") == -EINVAL))
+ {
+ printk("Can't unregister cdu31a\n");
+ return;
+ }
+ release_region(cdu31a_port,4);
+ printk("cdu31a module released.\n");
+}
+#endif MODULE
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov
with Sam's (original) version of this