Re: Sony cdu31a locks up system

Michael Driscoll (fenris@lightspeed.net)
Thu, 6 Mar 1997 14:48:03 -0800


>What happens is that the machine goes through the booting system, mounts the
>cdrom and then soon after, it just locks up.

Here's the patch I've been using. It seems to work.
Mike

--- linux/drivers/cdrom/cdu31a.c Mon Feb 24 00:00:18 1997
+++ cdu31a.c Sun Feb 23 23:51:29 1997
@@ -933,6 +933,9 @@
volatile int val;


+#if DEBUG
+ printk("Entering handle_sony_cd_attention\n");
+#endif
if (is_attention())
{
if (num_consecutive_attentions > CDU31A_MAX_CONSECUTIVE_ATTENTIONS)
@@ -940,6 +943,9 @@
printk("cdu31a: Too many consecutive attentions: %d\n",
num_consecutive_attentions);
num_consecutive_attentions = 0;
+#if DEBUG
+ printk("Leaving handle_sony_cd_attention at %d\n", __LINE__);
+#endif
return(0);
}

@@ -982,6 +988,9 @@
}

num_consecutive_attentions++;
+#if DEBUG
+ printk("Leaving handle_sony_cd_attention at %d\n", __LINE__);
+#endif
return(1);
}
else if (abort_read_started)
@@ -998,10 +1007,16 @@
val = read_data_register();
}
abort_read_started = 0;
+#if DEBUG
+ printk("Leaving handle_sony_cd_attention at %d\n", __LINE__);
+#endif
return(1);
}

num_consecutive_attentions = 0;
+#if DEBUG
+ printk("Leaving handle_sony_cd_attention at %d\n", __LINE__);
+#endif
return(0);
}

@@ -1090,6 +1105,9 @@
unsigned int retry_count;


+#if DEBUG
+ printk("Entering start_request\n");
+#endif
log_to_msf(sector, params);
/* If requested, read exactly what was asked. */
if (read_nsect_only)
@@ -1130,6 +1148,9 @@
if (is_busy())
{
printk("CDU31A: Timeout while waiting to issue command\n");
+#if DEBUG
+ printk("Leaving start_request at %d\n", __LINE__);
+#endif
return(1);
}
else
@@ -1145,8 +1166,14 @@
sony_next_block = sector * 4;
readahead_dataleft = 0;
readahead_bad = 0;
+#if DEBUG
+ printk("Leaving start_request at %d\n", __LINE__);
+#endif
return(0);
}
+#if DEBUG
+ printk("Leaving start_request at %d\n", __LINE__);
+#endif
}

/* Abort a pending read operation. Clear all the drive status and
@@ -1188,6 +1215,13 @@
static void
handle_abort_timeout(unsigned long data)
{
+ unsigned long flags;
+
+#if DEBUG
+ printk("Entering handle_abort_timeout\n");
+#endif
+ save_flags(flags);
+ cli();
/* If it is in use, ignore it. */
if (!sony_inuse)
{
@@ -1204,6 +1238,10 @@
readahead_bad = 0;
abort_read_started = 1;
}
+ restore_flags(flags);
+#if DEBUG
+ printk("Leaving handle_abort_timeout\n");
+#endif
}

/* Actually get data and status from the drive. */
@@ -1218,6 +1256,9 @@
volatile unsigned char val;


+#if DEBUG
+ printk("Entering input_data\n");
+#endif
/* If an XA disk on a CDU31A, skip the first 12 bytes of data from
the disk. The real data is after that. */
if (sony_xa_mode)
@@ -1266,6 +1307,9 @@
val = read_data_register();
}
}
+#if DEBUG
+ printk("Leaving input_data at %d\n", __LINE__);
+#endif
}

/* read data from the drive. Note the nsect must be <= 4. */
@@ -1282,6 +1326,10 @@
unsigned int skip;


+#if DEBUG
+ printk("Entering read_data_block\n");
+#endif
+
res_reg[0] = 0;
res_reg[1] = 0;
*res_size = 0;
@@ -1347,6 +1395,9 @@
{
get_result(res_reg, res_size);
}
+#if DEBUG
+ printk("Leaving read_data_block at %d\n", __LINE__);
+#endif
return;
}
}
@@ -1466,6 +1517,9 @@
}
}
}
+#if DEBUG
+ printk("Leaving read_data_block at %d\n", __LINE__);
+#endif
}

/*
@@ -1486,6 +1540,10 @@
unsigned long flags;


+#if DEBUG
+ printk("Entering do_cdu31a_request\n");
+#endif
+
/*
* Make sure no one else is using the driver; wait for them
* to finish if it is so.
@@ -1503,6 +1561,9 @@
end_request(0);
}
restore_flags(flags);
+#if DEBUG
+ printk("Leaving do_cdu31a_request at %d\n", __LINE__);
+#endif
return;
}
}
@@ -1518,11 +1579,8 @@

sti();

- /* If the timer is running, cancel it. */
- if (cdu31a_abort_timer.next != NULL)
- {
- del_timer(&cdu31a_abort_timer);
- }
+ /* Make sure the timer is cancelled. */
+ del_timer(&cdu31a_abort_timer);

while (1)
{
@@ -1694,6 +1752,7 @@
}

end_do_cdu31a_request:
+ cli();
#if 0
/* After finished, cancel any pending operations. */
abort_read();
@@ -1708,6 +1767,9 @@
sony_inuse = 0;
wake_up_interruptible(&sony_wait);
restore_flags(flags);
+#if DEBUG
+ printk("Leaving do_cdu31a_request at %d\n", __LINE__);
+#endif
}

/* Copy overlapping buffers. */
@@ -3141,8 +3203,7 @@
/* use 'mount -o block=2048' */
blksize_size[MAJOR_NR] = &cdu31a_block_size;

- cdu31a_abort_timer.next = NULL;
- cdu31a_abort_timer.prev = NULL;
+ init_timer(&cdu31a_abort_timer);
cdu31a_abort_timer.function = handle_abort_timeout;
}