SCSI reset on 2.1.27 with MCA (microchannel- level triggered interrupts)

Donald R. Harter Jr. (ah230@traverse.lib.mi.us)
Sun, 9 Mar 1997 10:52:20 -0500 (EST)


When my system boots up I get the following messages:
scsi0 channel 0: resetting for second half of retries
scsi bus i being reset for host 0 channel 0
ibm MCA SCSI: resetting all devices
The kernel/system then locks up. I have traced this problem to a change
that was made in the file scsi.c. The problem could be with scsi.c or the
ibmmca.c driver. I had been using an MCA version of about 2.0.23. When I
tried to upgrade it, the change in scsi.c broke the kernel for the mca
system. I was able to get 2.1.27 to run by making a few changes in scsi.c
using code from the older version of scsi.c. Enclosed is my patch for
2.2.27 scsi.c. To apply it you would have to change the file names.
scsi.c.new is what I called the standard 2.1.27 scsi.c file.

Donald Harter Jr. *** scsi.c Sat Mar 8 19:54:14 1997 ---
scsi.c.new Sat Mar 8 19:03:09 1997 *************** *** 1170,1176 ****
inline void internal_cmnd (Scsi_Cmnd * SCpnt)
{
unsigned long flags, timeout; - int temp;
struct Scsi_Host * host;
#ifdef DEBUG_DELAY
unsigned long clock; --- 1170,1175 ---- *************** ***
1192,1200 ****
/* Assign a unique nonzero serial_number. */
if (++serial_number == 0) serial_number = 1;
SCpnt->serial_number = serial_number; ! sti(); ! temp =
host->last_reset + MIN_RESET_DELAY; ! while (jiffies < temp);
restore_flags(flags);

update_timeout(SCpnt, SCpnt->timeout_per_command); --- 1191,1217
----
/* Assign a unique nonzero serial_number. */
if (++serial_number == 0) serial_number = 1;
SCpnt->serial_number = serial_number; ! ! /* ! * We will wait
MIN_RESET_DELAY clock ticks after the last reset so ! * we can avoid the
drive not being ready. ! */ ! timeout = host->last_reset +
MIN_RESET_DELAY; ! if (jiffies < timeout) { ! int ticks_remaining =
timeout - jiffies; ! /* ! * NOTE: This may be executed from within an
interrupt ! * handler! This is bad, but for now, it'll do. The irq ! *
level of the interrupt handler has been masked out by the ! * platform
dependent interrupt handling code already, so the ! * sti() here will not
cause another call to the SCSI host's ! * interrupt handler (assuming
there is one irq-level per ! * host). ! */ ! sti(); ! while
(--ticks_remaining >= 0) udelay(1000000/HZ); ! host->last_reset = jiffies
- MIN_RESET_DELAY; ! }
restore_flags(flags);

update_timeout(SCpnt, SCpnt->timeout_per_command); ***************
*** 1759,1765 ****
if ((++SCpnt->retries) < SCpnt->allowed)
{
if ((SCpnt->retries >= (SCpnt->allowed >> 1)) ! && !(jiffies <
SCpnt->host->last_reset + MIN_RESET_PERIOD)
&& !(SCpnt->flags & WAS_RESET))
{
printk("scsi%d channel %d : resetting for second half of retries.\n",
--- 1776,1783 ----
if ((++SCpnt->retries) < SCpnt->allowed)
{
if ((SCpnt->retries >= (SCpnt->allowed >> 1)) ! &&
!(SCpnt->host->last_reset > 0 && ! jiffies < SCpnt->host->last_reset +
MIN_RESET_PERIOD)
&& !(SCpnt->flags & WAS_RESET))
{
printk("scsi%d channel %d : resetting for second half of retries.\n",