Adaptec 2842 VLB, aic7xxx and zip-drive

Doug Ledford dledford at dialnet.net
Mon Mar 23 21:12:08 PST 1998


Achim Kaiser wrote:
> 
> Hi,
> 
> I have a problem updating to version 5.0.8 of your scsi-driver.
> After detecting my first 2 harddisks the driver doesn't recognize my
> ZIP-drive and go into a "timeout-loop". It doesn't matter if there is 

OK..I haven't gotten back to anyone on this particular problem yet because
it established a pattern and I was busy tracking down the cause.

The general scenario is that the 5.0.7 driver was working great for many
people, and then it quit working at 5.0.8.  The problem, invariably, was
people that had a device like the Zip drive (in some cases a tape drive, or
a CD-ROM or CD-R device) that would refuse sync negotiation and make the
driver fall back to async transfers.

There was a pattern that the driver would hang anytime an SDTR request ended
with a REJECT message from the device.  It didn't actually hang with the
REJECT message, it hung right before then like it was never completing the
REQINIT phase of the SDTR request.  This turned out to be the case in my
testing.  So, I've attached a test patch to this email.  If it works for
people, this will become the new 5.0.9 driver.  The patch applies against an
already 5.0.8 kernel.  If this works, then I'll give a more complete
description of what the problem was since 5.0.8 technically should have been
more reliable in regards to the REQINIT handler than 5.0.7, but I think the
changes I made uncovered a second bug in the REQINIT system that Justin
might be interested in.

If you don't already have the 5.0.8 version of the driver, then you can get
it from ftp.dialnet.net:/pub/linux/aic7xxx.  I didn't want to send a full
patch against 2.0.33 since that is a huge thing, but this 5.0.8 to 5.0.9
test patch isn't that bad.

The second item of interest in this test patch is that with this patch, we
now use MMAPed I/O on all PCI controllers.  This means that other
architectures, such as the PPC, might work with this driver without any
modification.  However, I don't have a 64 bit machine to test on so I don't
guarantee this will work, but I tried to do the needed things like aligning
all of my internal data structures properly as well as compensating for the
size difference between pointers on 32 bit and 64 bit architectures. 
However, I'm new to this area of programming so be gentle on me if it
doesn't work :)

-- 

 Doug Ledford  <dledford at dialnet.net>
  Opinions expressed are my own, but
     they should be everybody's.
-------------- next part --------------
diff -U 3 -rN linux-5.0.8/drivers/scsi/aic7xxx.c linux/drivers/scsi/aic7xxx.c
--- linux-5.0.8/drivers/scsi/aic7xxx.c	Sun Mar 15 18:30:30 1998
+++ linux/drivers/scsi/aic7xxx.c	Mon Mar 23 22:35:06 1998
@@ -170,6 +170,7 @@
 #include <stdarg.h>
 #include <asm/io.h>
 #include <asm/irq.h>
+#include <linux/version.h>
 #include <linux/string.h>
 #include <linux/errno.h>
 #include <linux/kernel.h>
@@ -208,7 +209,7 @@
     0, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL
 };
 
-#define AIC7XXX_C_VERSION  "5.0.8"
+#define AIC7XXX_C_VERSION  "5.0.9"
 
 #define NUMBER(arr)     (sizeof(arr) / sizeof(arr[0]))
 #define MIN(a,b)        (((a) < (b)) ? (a) : (b))
@@ -990,6 +991,14 @@
                                               * to cards that have cable
                                               * detection logic and a SEEPROM
                                               */
+static int aic7xxx_panic_on_abort = 0;       /*
+                                              * Set this to non-0 in order
+                                              * to force the driver to panic
+                                              * the kernel and print out
+                                              * debugging info on an abort
+                                              * or reset call into the
+                                              * driver.
+                                              */
 
 /*
  * So that insmod can find the variable and make it point to something
@@ -1065,6 +1074,7 @@
  *
  ***************************************************************************/
 
+
 static inline unsigned char
 aic_inb(struct aic7xxx_host *p, long port)
 {
@@ -1140,6 +1150,7 @@
     { "reverse_scan",&aic7xxx_reverse_scan },
     { "7895_irq_hack", &aic7xxx_7895_irq_hack },
     { "override_term", &aic7xxx_override_term },
+    { "panic_on_abort", &aic7xxx_panic_on_abort },
     { "tag_info",    NULL }
   };
 
@@ -1587,9 +1598,11 @@
   unsigned char response_period;
   unsigned char tindex;
   unsigned short target_mask;
+  unsigned char lun;
 
   tindex = target | (channel << 3);
   target_mask = 0x01 << tindex;
+  lun = aic_inb(p, SCB_TCL) & 0x07;
 
   response_period = *period;
 
@@ -1642,7 +1655,7 @@
              (p->dev_flags[tindex] & DEVICE_PRINT_SDTR) )
         {
           printk(INFO_LEAD "Synchronous at %sMHz, "
-                 "offset %d.\n", p->host_no, channel, target, 0,
+                 "offset %d.\n", p->host_no, channel, target, lun,
                  aic7xxx_syncrates[i].english, *offset);
           p->dev_flags[tindex] &= ~ DEVICE_PRINT_SDTR;
         }
@@ -1664,7 +1677,7 @@
          (p->dev_flags[tindex] & DEVICE_PRINT_SDTR) )
     {
       printk(INFO_LEAD "Using asynchronous transfers.\n",
-             p->host_no, channel, target, 0);
+             p->host_no, channel, target, lun);
       p->dev_flags[tindex] &= ~DEVICE_PRINT_SDTR;
     }
   }
@@ -2027,9 +2040,15 @@
 
     /*
      * Optimize for 30 scbs at a time, but allow a final allocation of
-     * fewer than 30 scbs
+     * fewer than 30 scbs.  Except on 64 bit platforms, we optimize for
+     * 29 SCBs at a time because a pointer is 4 bytes larger and we don't
+     * want to overrun this suppossedly 32K allocation to 64K and waste
+     * tons of space.
      */
-    scb_count = MIN(30, p->scb_data->maxscbs - p->scb_data->numscbs);
+    if( sizeof(void *) == sizeof(int) )
+      scb_count = MIN(30, p->scb_data->maxscbs - p->scb_data->numscbs);
+    else
+      scb_count = MIN(29, p->scb_data->maxscbs - p->scb_data->numscbs);
     
     scb_ap = (struct aic7xxx_scb *)kmalloc(scb_size * scb_count, GFP_ATOMIC);
     if (scb_ap != NULL)
@@ -3068,7 +3087,8 @@
     if (aic7xxx_verbose & VERBOSE_RESET_PROCESS)
       printk(INFO_LEAD "Resetting currently active channel.\n", p->host_no,
         channel, -1, -1);
-    aic_outb(p, aic_inb(p, SIMODE1) & ~(ENBUSFREE|ENREQINIT), SIMODE1);
+    aic_outb(p, aic_inb(p, SIMODE1) & ~(ENBUSFREE|ENREQINIT|ENPHASEMIS),
+      SIMODE1);
     p->flags &= ~AHC_HANDLING_REQINITS;
     p->msg_type = MSG_TYPE_NONE;
     p->msg_len = 0;
@@ -3151,9 +3171,14 @@
   }
   if (sent)
   {
-    pause_sequencer(p);
-    aic_outb(p, p->qinfifonext, KERNEL_QINPOS);
-    unpause_sequencer(p, FALSE);
+    if(p->type & AHC_AIC78x0)
+      aic_outb(p, p->qinfifonext, KERNEL_QINPOS);
+    else
+    {
+      pause_sequencer(p);
+      aic_outb(p, p->qinfifonext, KERNEL_QINPOS);
+      unpause_sequencer(p, FALSE);
+    }
     if (p->activescbs > p->max_activescbs)
       p->max_activescbs = p->activescbs;
   }
@@ -3421,7 +3446,7 @@
         * REQINIT interrupts and let our interrupt handler
         * do the rest (REQINIT should already be true).
         */
-        aic_outb(p, aic_inb(p, SIMODE1) | ENREQINIT, SIMODE1);
+        aic_outb(p, aic_inb(p, SIMODE1) | ENREQINIT | ENPHASEMIS, SIMODE1);
         p->flags |= AHC_HANDLING_REQINITS;
 
        /*
@@ -3949,7 +3974,8 @@
         p->msg_index = 0;
         p->msg_type = MSG_TYPE_INITIATOR_MSGOUT;
         p->flags |= AHC_HANDLING_REQINITS;
-        aic_outb(p, aic_inb(p, SIMODE1) | ENREQINIT, SIMODE1);
+        aic_outb(p, MSGOUT_PHASEMIS, RETURN_1);
+        aic_outb(p, aic_inb(p, SIMODE1) | ENREQINIT | ENPHASEMIS, SIMODE1);
         aic_outb(p, CLRSEQINT, CLRINT);
         return;
       }
@@ -4318,20 +4344,23 @@
           /* Time to end the message */
           p->msg_len = 0;
           p->msg_type = MSG_TYPE_NONE;
-          aic_outb(p, aic_inb(p, SIMODE1) & ~ENREQINIT, SIMODE1);
+          aic_outb(p, aic_inb(p, SIMODE1) & ~(ENREQINIT | ENPHASEMIS), SIMODE1);
           aic_outb(p, CLRREQINIT, CLRSINT1);
           aic_outb(p, CLRSCSIINT, CLRINT);
           p->flags &= ~AHC_HANDLING_REQINITS;
 
+          /*
+           * RETURN_1 is preloaded with MSGOUT_PHASEMIS when we start the
+           * REQINIT handler.  We have to do this because the sequencer
+           * automatically unpauses on PHASEMIS.  This way, we only get here
+           * if we actually complete the message.
+           */
+
           if (phasemis == 0)
           {
             aic_outb(p, p->msg_buf[p->msg_index], SINDEX);
             aic_outb(p, 0, RETURN_1);
           }
-          else
-          {
-            aic_outb(p, MSGOUT_PHASEMIS, RETURN_1);
-          }
           unpause_sequencer(p, TRUE);
         }
         else
@@ -4368,7 +4397,7 @@
           p->msg_len = 0;
           p->msg_type = MSG_TYPE_NONE;
           p->flags &= ~AHC_HANDLING_REQINITS;
-          aic_outb(p, aic_inb(p, SIMODE1) & ~ENREQINIT, SIMODE1 );
+          aic_outb(p, aic_inb(p, SIMODE1) & ~(ENREQINIT | ENPHASEMIS), SIMODE1);
           aic_outb(p, CLRREQINIT, CLRSINT1);
           aic_outb(p, CLRSCSIINT, CLRINT);
           unpause_sequencer(p, TRUE);
@@ -4413,6 +4442,29 @@
     scb = NULL;
   }
 
+
+  if ( ((status & REQINIT) && (p->flags & AHC_HANDLING_REQINITS)) ||
+       ((p->flags & AHC_HANDLING_REQINITS) &&
+       (status & PHASEMIS)) )
+  {
+    if (scb)
+    {
+      aic7xxx_handle_reqinit(p, scb);
+      if ( (status & (SELTO | SCSIRSTI | BUSFREE | SCSIPERR)) == 0 )
+        return;
+    }
+    else
+    {
+      p->flags &= ~AHC_HANDLING_REQINITS;
+      aic_outb(p, aic_inb(p, SIMODE1) & ~(ENREQINIT | ENPHASEMIS), SIMODE1);
+      aic_outb(p, CLRREQINIT, CLRSINT1);
+      aic_outb(p, CLRSCSIINT, CLRINT);
+      p->msg_type = MSG_TYPE_NONE;
+      p->msg_index = 0;
+      p->msg_len = 0;
+    }
+  }
+
   if ((status & SCSIRSTI) != 0)
   {
     int channel;
@@ -4494,9 +4546,10 @@
              (aic_inb(p, SEQADDR1) << 8) | aic_inb(p, SEQADDR0));
       scb = NULL;
     }
-    aic_outb(p, aic_inb(p, SIMODE1) & ~(ENBUSFREE|ENREQINIT), SIMODE1);
+    aic_outb(p, aic_inb(p, SIMODE1) & ~(ENBUSFREE|ENREQINIT|ENPHASEMIS),
+      SIMODE1);
     p->flags &= ~AHC_HANDLING_REQINITS;
-    aic_outb(p, CLRBUSFREE, CLRSINT1);
+    aic_outb(p, CLRBUSFREE | CLRREQINIT, CLRSINT1);
     aic_outb(p, CLRSCSIINT, CLRINT);
     restart_sequencer(p);
     unpause_sequencer(p, TRUE);
@@ -4584,9 +4637,9 @@
      * Stop the selection.
      */
     aic_outb(p, 0, SCSISEQ);
-    aic_outb(p, aic_inb(p, SIMODE1) & ~ENREQINIT, SIMODE1);
+    aic_outb(p, aic_inb(p, SIMODE1) & ~(ENREQINIT | ENPHASEMIS), SIMODE1);
     p->flags &= ~AHC_HANDLING_REQINITS;
-    aic_outb(p, CLRSELTIMEO | CLRBUSFREE, CLRSINT1);
+    aic_outb(p, CLRSELTIMEO | CLRBUSFREE | CLRREQINIT, CLRSINT1);
     aic_outb(p, CLRSCSIINT, CLRINT);
     restart_sequencer(p);
     unpause_sequencer(p, TRUE);
@@ -4608,11 +4661,6 @@
     unpause_sequencer(p, /* unpause always */ TRUE);
     scb = NULL;
   }
-  else if ((status & REQINIT) != 0)
-  {
-    aic7xxx_handle_reqinit(p, scb);
-    scb = NULL;
-  }
   else if (status & SCSIPERR)
   {
     /*
@@ -4856,6 +4904,7 @@
    * Indicate that we're in the interrupt handler.
    */
   p->flags |= AHC_IN_ISR;
+  restore_flags(flags);
   while ( (intstat = aic_inb(p, INTSTAT)) &
           (CMDCMPLT | SCSIINT | SEQINT | BRKADRINT) )
   {
@@ -4925,6 +4974,8 @@
               p->dev_flags[TARGET_INDEX(cmd)] |= 
                  DEVICE_SUCCESS | DEVICE_PRESENT;
             aic7xxx_done(p, scb);
+            aic7xxx_done_cmds_complete(p);
+            aic7xxx_run_waiting_queues(p);
             break;
         }      
       }
@@ -4954,20 +5005,23 @@
       aic_outb(p, CLRBRKADRINT, CLRINT);
     }
 
-    if (intstat & SEQINT)
+    if ( (intstat & SEQINT) && !(p->flags & AHC_HANDLING_REQINITS) )
     {
+      cli();
       aic7xxx_handle_seqint(p, intstat);
+      restore_flags(flags);
     }
 
     if (intstat & SCSIINT)
     {
+      cli();
       aic7xxx_handle_scsiint(p, intstat);
+      restore_flags(flags);
     }
 
   }
   if ( !(p->flags & AHC_HANDLING_REQINITS) )
     unpause_sequencer(p, TRUE);
-  restore_flags(flags);
   aic7xxx_done_cmds_complete(p);
   aic7xxx_run_waiting_queues(p);
   p->flags &= ~AHC_IN_ISR;
@@ -6027,11 +6081,11 @@
    */
   detect_maxscb(p);
   printk("%d/%d SCBs\n", p->scb_data->maxhscbs, p->scb_data->maxscbs);
-  printk(KERN_INFO "(scsi%d) BIOS %sabled, IO Port 0x%x, IO Mem 0x%x, "
-    "IO Addr 0x%x, IRQ %d\n", p->host_no,
-    (p->flags & AHC_BIOS_ENABLED) ? "en" : "dis",
-    p->base, p->mbase, (unsigned int)p->maddr, p->irq);
-
+  printk(KERN_INFO "(scsi%d) BIOS %sabled, IO Port 0x%x, IRQ %d\n",
+    p->host_no, (p->flags & AHC_BIOS_ENABLED) ? "en" : "dis",
+    p->base, p->irq);
+  printk(KERN_INFO "(scsi%d) IO Memory at 0x%08x, MMAP Memory at 0x%08x\n",
+    p->host_no, p->mbase, (unsigned int)p->maddr);
 
 
   if (aic7xxx_boards[p->irq] == NULL)
@@ -7159,11 +7213,12 @@
        AHC_PAGESCBS | AHC_NEWEEPROM_FMT | AHC_BIOS_ENABLED, 19 }
     };
 
-    int error;
     int done = 0;
     unsigned short index = 0;
-    unsigned char pci_bus, pci_device_fn;
-    unsigned int  devconfig;
+    unsigned char pci_bus, pci_device_fn, command;
+    unsigned int  devconfig, exromctl;
+    unsigned long page_offset;
+    unsigned long base;
     struct aic7xxx_host *first_7895 = NULL;
 
     for (i = 0; i < NUMBER(aic7xxx_pci_devices); i++)
@@ -7206,15 +7261,22 @@
           /*
            * Read sundry information from PCI BIOS.
            */
-          error = pcibios_read_config_dword(pci_bus, pci_device_fn,
-                               PCI_BASE_ADDRESS_0, &temp_p->base);
-          error += pcibios_read_config_byte(pci_bus, pci_device_fn,
-                               PCI_INTERRUPT_LINE, &temp_p->irq);
-          error += pcibios_read_config_dword(pci_bus, pci_device_fn,
-                               PCI_BASE_ADDRESS_1, &temp_p->mbase);
-          error += pcibios_read_config_dword(pci_bus, pci_device_fn,
-                               DEVCONFIG, &devconfig);
-
+          pcibios_read_config_dword(pci_bus, pci_device_fn,
+            PCI_BASE_ADDRESS_0, &temp_p->base);
+          pcibios_read_config_byte(pci_bus, pci_device_fn,
+            PCI_INTERRUPT_LINE, &temp_p->irq);
+          pcibios_read_config_dword(pci_bus, pci_device_fn,
+            PCI_BASE_ADDRESS_1, &temp_p->mbase);
+          pcibios_read_config_dword(pci_bus, pci_device_fn,
+            DEVCONFIG, &devconfig);
+          pcibios_read_config_dword(pci_bus, pci_device_fn,
+            PCI_ROM_ADDRESS, &exromctl);
+          pcibios_write_config_dword(pci_bus, pci_device_fn,
+            PCI_ROM_ADDRESS, exromctl & ~(PCI_ROM_ADDRESS_ENABLE));
+          pcibios_read_config_byte(pci_bus, pci_device_fn,
+            PCI_COMMAND + 1, &command);
+          pcibios_write_config_byte(pci_bus, pci_device_fn,
+            PCI_COMMAND + 1, command | 0x03);
           /*
            * The first bit (LSB) of PCI_BASE_ADDRESS_0 is always set, so
            * we mask it off.
@@ -7224,10 +7286,15 @@
           temp_p->unpause = (aic_inb(temp_p, HCNTRL) & IRQMS) | INTEN;
           temp_p->pause = temp_p->unpause | PAUSE;
 
-          temp_p->maddr = 0;   /* for now, until we get the remap code
-                                * up and running, this makes sure we use
-                                * regular programmed I/O. 
-                                */
+          base = temp_p->mbase & PAGE_MASK;
+          page_offset = temp_p->mbase - base;
+          /*
+           * replace the next line with this one if you are using 2.1.x:
+           * temp_p->maddr = ioremap(base, page_offset + 256);
+           */
+          temp_p->maddr = vremap(base, page_offset + 256);
+          if(temp_p->maddr)
+            temp_p->maddr += page_offset;
 
           aic_outb(temp_p, temp_p->pause, HCNTRL);
           while( (aic_inb(temp_p, HCNTRL) & PAUSE) == 0 ) ;
@@ -7932,8 +7999,7 @@
     {
         scbq_insert_tail(&p->waiting_scbs, scb);
     }
-    if (  (p->flags & 
-          (AHC_IN_ISR | AHC_IN_ABORT | AHC_IN_RESET)) == 0)
+    if ( (p->flags & (AHC_IN_ISR | AHC_IN_ABORT | AHC_IN_RESET)) == 0)
     {
       aic7xxx_run_waiting_queues(p);
     }
@@ -8135,6 +8201,40 @@
 
 /*+F*************************************************************************
  * Function:
+ *   aic7xxx_panic_abort
+ *
+ * Description:
+ *   Abort the current SCSI command(s).
+ *-F*************************************************************************/
+void
+aic7xxx_panic_abort(struct aic7xxx_host *p)
+{
+  int i;
+
+  printk("aic7xxx driver version %s\n", AIC7XXX_C_VERSION);
+  printk("Controller type:\n    %s\n", board_names[p->board_name_index]);
+  for(i=0; i<MAX_TARGETS; i++)
+  {
+    if(p->dev_flags[i] & DEVICE_PRESENT)
+    {
+      printk(INFO_LEAD "dev_flags=0x%x, WDTR:%s, SDTR:%s, q_depth=%d:%d\n",
+        p->host_no, 0, i, 0, p->dev_flags[i],
+        (p->needwdtr_copy & (1 << i)) ? "Yes" : "No",
+        (p->needsdtr_copy & (1 << i)) ? "Yes" : "No",
+        p->dev_max_queue_depth[i], p->dev_mid_level_queue_depth[i]);
+    }
+  }
+  printk("SIMODE0=0x%x, SIMODE1=0x%x, SSTAT0=0x%x, SSTAT1=0x%x, INTSTAT=0x%x\n",
+    aic_inb(p, SIMODE0), aic_inb(p, SIMODE1), aic_inb(p, SSTAT0),
+    aic_inb(p, SSTAT1), aic_inb(p, INTSTAT) );
+  printk("p->flags=0x%x, p->type=0x%x, sequencer %s paused\n",
+     p->flags, p->type,
+    (aic_inb(p, HCNTRL) & PAUSE) ? "is" : "isn't" );
+  panic("Stopping to debug\n");
+}
+
+/*+F*************************************************************************
+ * Function:
  *   aic7xxx_abort
  *
  * Description:
@@ -8153,8 +8253,18 @@
   p = (struct aic7xxx_host *) cmd->host->hostdata;
   scb = (p->scb_data->scb_array[aic7xxx_position(cmd)]);
 
+  /*
+   * I added a new config option to the driver: "panic_on_abort" that will
+   * cause the driver to panic and the machine to stop on the first abort
+   * or reset call into the driver.  At that point, it prints out a lot of
+   * usefull information for me which I can then use to try and debug the
+   * problem.  Simply enable the boot time prompt in order to activate this
+   * code.
+   */
+  if (aic7xxx_panic_on_abort)
+    aic7xxx_panic_abort(p);
+
   save_flags(processor_flags);
-  pause_sequencer(p);
   cli();
 
 /*
@@ -8165,7 +8275,17 @@
  *  code.
  */
 
-  while ( (aic_inb(p, INTSTAT) & INT_PEND) && !(p->flags & AHC_IN_ISR) )
+  while( (p->flags & AHC_IN_ISR) )
+  {
+    /*
+     * Oops, we're in the interrupt routine, return an error
+     */
+    restore_flags(processor_flags);
+    return(SCSI_ABORT_BUSY);
+  } 
+
+  pause_sequencer(p);
+  while ( (aic_inb(p, INTSTAT) & INT_PEND) )
   {
     aic7xxx_isr(p->irq, (void *)NULL, (void *)NULL);
     pause_sequencer(p);
@@ -8477,10 +8597,31 @@
   scb = (p->scb_data->scb_array[aic7xxx_position(cmd)]);
   tindex = TARGET_INDEX(cmd);
 
+  /*
+   * I added a new config option to the driver: "panic_on_abort" that will
+   * cause the driver to panic and the machine to stop on the first abort
+   * or reset call into the driver.  At that point, it prints out a lot of
+   * usefull information for me which I can then use to try and debug the
+   * problem.  Simply enable the boot time prompt in order to activate this
+   * code.
+   */
+  if (aic7xxx_panic_on_abort)
+    aic7xxx_panic_abort(p);
+
   save_flags(processor_flags);
-  pause_sequencer(p);
   cli();
-  while ( (aic_inb(p, INTSTAT) & INT_PEND) && !(p->flags & AHC_IN_ISR) )
+
+  if( (p->flags & AHC_IN_ISR) )
+  {
+    /*
+     * Oops, we're in the interrupt routine, return an error
+     */
+    restore_flags(processor_flags);
+    return(SCSI_RESET_ERROR);
+  } 
+
+  pause_sequencer(p);
+  while ( (aic_inb(p, INTSTAT) & INT_PEND) )
   {
     aic7xxx_isr(p->irq, (void *)NULL, (void *)NULL );
     pause_sequencer(p);
@@ -8666,9 +8807,9 @@
       else
       {
         result = SCSI_RESET_SUCCESS | SCSI_RESET_HOST_RESET;
-        aic7xxx_clear_intstat(p);
-        aic_outb(p,  aic_inb(p, SIMODE1) & ~(ENREQINIT|ENBUSFREE),
+        aic_outb(p,  aic_inb(p, SIMODE1) & ~(ENREQINIT|ENBUSFREE|ENPHASEMIS),
           SIMODE1);
+        aic7xxx_clear_intstat(p);
         p->flags &= ~AHC_HANDLING_REQINITS;
         p->msg_type = MSG_TYPE_NONE;
         p->msg_index = 0;


More information about the aic7xxx mailing list