Linux Headquarters
[ Register ]
[ About us ] [ Home Page ]

Advertisement
[ Kernel ] [ Documentation ] [ Links ] [ Books ]

Advertisement

Kernel v2.2.19pre10 /aic7xxx-5.1.32.patch

Filename:/aic7xxx-5.1.32.patch
Lines Added:7633
Lines Deleted:0
Also changed in: (Previous)
(Following)

Location
[  2.2.19pre10
   o  aic7xxx-5.1.32.patch

Patch

diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/aic7xxx-5.1.32.patch linux.19p10/aic7xxx-5.1.32.patch
--- linux.vanilla/aic7xxx-5.1.32.patch   Thu Jan  1 01:00:00 1970
+++ linux.19p10/aic7xxx-5.1.32.patch   Mon Feb 12 14:57:06 2001
@@ -0,0 +1,7633 @@
+diff -U 3 -rN linux-2.2.17/drivers/scsi/Config.in linux/drivers/scsi/Config.in
+--- linux-2.2.17/drivers/scsi/Config.in   Wed May  3 20:16:44 2000
++++ linux/drivers/scsi/Config.in   Tue Feb  6 03:50:13 2001
+@@ -28,10 +28,9 @@
+ dep_tristate 'Adaptec AHA1740 support' CONFIG_SCSI_AHA1740 $CONFIG_SCSI
+ dep_tristate 'Adaptec AIC7xxx support' CONFIG_SCSI_AIC7XXX $CONFIG_SCSI
+ if [ "$CONFIG_SCSI_AIC7XXX" != "n" ]; then
+-    bool '   Enable Tagged Command Queueing (TCQ) by default' CONFIG_AIC7XXX_TCQ_ON_BY_DEFAULT
+-    int  '   Maximum number of TCQ commands per device' CONFIG_AIC7XXX_CMDS_PER_DEVICE 8
+-    bool '   Collect statistics to report in /proc' CONFIG_AIC7XXX_PROC_STATS N
+-    int  '   Delay in seconds after SCSI bus reset' CONFIG_AIC7XXX_RESET_DELAY 5
++    bool '   Enable Tagged Command Queueing (TCQ) by default' CONFIG_AIC7XXX_TCQ_ON_BY_DEFAULT y
++    int  '   Maximum number of TCQ commands per device' CONFIG_AIC7XXX_CMDS_PER_DEVICE 24
++    bool '   Collect statistics to report in /proc' CONFIG_AIC7XXX_PROC_STATS y
+ fi
+ dep_tristate 'IBM ServeRAID support' CONFIG_SCSI_IPS $CONFIG_SCSI
+ dep_tristate 'AdvanSys SCSI support' CONFIG_SCSI_ADVANSYS $CONFIG_SCSI
+diff -U 3 -rN linux-2.2.17/drivers/scsi/README.aic7xxx linux/drivers/scsi/README.aic7xxx
+--- linux-2.2.17/drivers/scsi/README.aic7xxx   Wed May  3 20:16:44 2000
++++ linux/drivers/scsi/README.aic7xxx   Tue Feb  6 03:49:36 2001
+@@ -14,50 +14,17 @@
+     Adaptec Cards
+     ----------------------------
+     AHA-274x
+-    AHA-274xT               
+-    AHA-2842
+-    AHA-2910B               
+-    AHA-2920C
+-    AHA-2930
+-    AHA-2930U
+-    AHA-2930CU
+-    AHA-2930U2
+-    AHA-2940               
+-    AHA-2940W              
+-    AHA-2940U              
+-    AHA-2940UW
+-    AHA-2940UW-PRO
+-    AHA-2940AU 
+-    AHA-2940U2W
+-    AHA-2940U2
+-    AHA-2940U2B
+-    AHA-2940U2BOEM
+-    AHA-2944D              
+-    AHA-2944WD
+-    AHA-2944UD
+-    AHA-2944UWD
+-    AHA-2950U2
+-    AHA-2950U2W
+-    AHA-2950U2B
+-    AHA-29160M
+-    AHA-3940
+-    AHA-3940U
+-    AHA-3940W
+-    AHA-3940UW
+-    AHA-3940AUW
+-    AHA-3940U2W
+-    AHA-3950U2B
+-    AHA-3950U2D
+-    AHA-3960D
+-    AHA-39160M
+-    AHA-3985
+-    AHA-3985U
+-    AHA-3985W
+-    AHA-3985UW
++    AHA-274xT
++    AHA-274xW
++    AHA-284x
++    AHA-284xW
++    All PCI based cards using any of the chipsets listed under motherboard
++    chipsets.  In general, this means *all* of the Adaptec SCSI controllers
++    except the ones specifically excluded later on in this document.
+ 
+     Motherboard Chipsets
+     ----------------------------
+-    AIC-777x   
++    AIC-777x
+     AIC-785x
+     AIC-786x
+     AIC-787x
+@@ -71,15 +38,14 @@
+         SCSI-1/SCSI-2 50pin devices, transfer rates up to 20MB/s.
+     U - Ultra SCSI, transfer rates up to 40MB/s.
+     U2- Ultra 2 SCSI, transfer rates up to 80MB/s.
++    U3- Ultra 3 SCSI, transfer rates up to 160MB/s.
+     D - Differential SCSI.
+     T - Twin Channel SCSI. Up to 14 SCSI devices.
+ 
+     AHA-274x - EISA SCSI controller
+     AHA-284x - VLB SCSI controller
+     AHA-29xx - PCI SCSI controller
+-    AHA-394x - PCI controllers with two separate SCSI controllers on-board.
+-    AHA-398x - PCI RAID controllers with three separate SCSI controllers
+-               on-board.
++    AHA-39xx - PCI controllers with multiple separate SCSI channels on-board.
+ 
+   Not Supported Devices
+   ------------------------------
+@@ -93,7 +59,7 @@
+ 
+     Motherboard Chipsets
+     ----------------------------
+-    AIC-7810
++    AIC-781x
+ 
+     Bus Types
+     ----------------------------
+diff -U 3 -rN linux-2.2.17/drivers/scsi/aic7xxx/aic7xxx.h linux/drivers/scsi/aic7xxx/aic7xxx.h
+--- linux-2.2.17/drivers/scsi/aic7xxx/aic7xxx.h   Wed Dec 31 19:00:00 1969
++++ linux/drivers/scsi/aic7xxx/aic7xxx.h   Tue Feb  6 03:49:36 2001
+@@ -0,0 +1,114 @@
++/*+M*************************************************************************
++ * Adaptec AIC7xxx device driver for Linux.
++ *
++ * Copyright (c) 1994 John Aycock
++ *   The University of Calgary Department of Computer Science.
++ *
++ * 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
++ * the Free Software Foundation; either version 2, or (at your option)
++ * any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; see the file COPYING.  If not, write to
++ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
++ * 
++ * $Id: aic7xxx.h,v 3.2 1996/07/23 03:37:26 deang Exp $
++ *-M*************************************************************************/
++#ifndef _aic7xxx_h
++#define _aic7xxx_h
++
++#define AIC7XXX_H_VERSION  "3.2.4"
++
++#ifndef LINUX_VERSION_CODE
++#include <linux/version.h>
++#endif
++
++#ifndef KERNEL_VERSION
++#define KERNEL_VERSION(x,y,z) (((x)<<16)+((y)<<8)+(z))
++#endif
++
++#if defined(__i386__)
++#  define AIC7XXX_BIOSPARAM aic7xxx_biosparam
++#else
++#  define AIC7XXX_BIOSPARAM NULL
++#endif
++
++/*
++ * Scsi_Host_Template (see hosts.h) for AIC-7xxx - some fields
++ * to do with card config are filled in after the card is detected.
++ */
++#if LINUX_VERSION_CODE > KERNEL_VERSION(2,1,65)
++#define AIC7XXX   {                  \
++   next: NULL,                  \
++   module: NULL,                  \
++   proc_dir: NULL,                  \
++   proc_info: aic7xxx_proc_info,            \
++   name: NULL,                  \
++   detect: aic7xxx_detect,               \
++   release: aic7xxx_release,            \
++   info: aic7xxx_info,               \
++   command: NULL,                  \
++   queuecommand: aic7xxx_queue,            \
++   eh_strategy_handler: NULL,            \
++   eh_abort_handler: NULL,               \
++   eh_device_reset_handler: NULL,            \
++   eh_bus_reset_handler: NULL,            \
++   eh_host_reset_handler: NULL,            \
++   abort: aic7xxx_abort,               \
++   reset: aic7xxx_reset,               \
++   slave_attach: NULL,               \
++   bios_param: AIC7XXX_BIOSPARAM,            \
++   can_queue: 255,      /* max simultaneous cmds      */\
++   this_id: -1,      /* scsi id of host adapter    */\
++   sg_tablesize: 0,   /* max scatter-gather cmds    */\
++   cmd_per_lun: 3,      /* cmds per lun (linked cmds) */\
++   present: 0,      /* number of 7xxx's present   */\
++   unchecked_isa_dma: 0,   /* no memory DMA restrictions */\
++   use_clustering: ENABLE_CLUSTERING,         \
++   use_new_eh_code: 0               \
++}
++#else
++#define AIC7XXX   {                  \
++   next: NULL,                  \
++   usage_count: NULL,               \
++   proc_dir: NULL,                \
++   proc_info: aic7xxx_proc_info,            \
++   name: NULL,                  \
++   detect: aic7xxx_detect,               \
++   release: aic7xxx_release,            \
++   info: aic7xxx_info,               \
++   command: NULL,                  \
++   queuecommand: aic7xxx_queue,            \
++   abort: aic7xxx_abort,               \
++   reset: aic7xxx_reset,               \
++   slave_attach: NULL,               \
++   bios_param: AIC7XXX_BIOSPARAM,            \
++   can_queue: 255,      /* max simultaneous cmds      */\
++   this_id: -1,      /* scsi id of host adapter    */\
++   sg_tablesize: 0,   /* max scatter-gather cmds    */\
++   cmd_per_lun: 3,      /* cmds per lun (linked cmds) */\
++   present: 0,      /* number of 7xxx's present   */\
++   unchecked_isa_dma: 0,   /* no memory DMA restrictions */\
++   use_clustering: ENABLE_CLUSTERING         \
++}
++#endif
++
++extern int aic7xxx_queue(Scsi_Cmnd *, void (*)(Scsi_Cmnd *));
++extern int aic7xxx_biosparam(Disk *, kdev_t, int[]);
++extern int aic7xxx_detect(Scsi_Host_Template *);
++extern int aic7xxx_command(Scsi_Cmnd *);
++extern int aic7xxx_reset(Scsi_Cmnd *, unsigned int);
++extern int aic7xxx_abort(Scsi_Cmnd *);
++extern int aic7xxx_release(struct Scsi_Host *);
++
++extern const char *aic7xxx_info(struct Scsi_Host *);
++
++extern int aic7xxx_proc_info(char *, char **, off_t, int, int, int);
++
++#endif /* _aic7xxx_h */
+diff -U 3 -rN linux-2.2.17/drivers/scsi/aic7xxx/aic7xxx.reg linux/drivers/scsi/aic7xxx/aic7xxx.reg
+--- linux-2.2.17/drivers/scsi/aic7xxx/aic7xxx.reg   Wed May  3 20:16:44 2000
++++ linux/drivers/scsi/aic7xxx/aic7xxx.reg   Tue Feb  6 03:49:36 2001
+@@ -703,7 +703,12 @@
+                    * it that it can fill the
+                    * message buffer.
+                    */
+-   mask   TRACEPOINT   0xb0|SEQINT
++   mask   SEQ_SG_FIXUP   0xb0|SEQINT   /* need help with fixing up
++                   * the sg array pointer after
++                   * a phasemis with no valid
++                   * sg elements in the shadow
++                   * pipeline.
++                   */
+    mask   TRACEPOINT2   0xc0|SEQINT
+    mask   MSGIN_PHASEMIS   0xd0|SEQINT   /*
+                    * Target changed phase on us
+diff -U 3 -rN linux-2.2.17/drivers/scsi/aic7xxx/aic7xxx.seq linux/drivers/scsi/aic7xxx/aic7xxx.seq
+--- linux-2.2.17/drivers/scsi/aic7xxx/aic7xxx.seq   Mon Sep  4 13:39:20 2000
++++ linux/drivers/scsi/aic7xxx/aic7xxx.seq   Tue Feb  6 03:49:36 2001
+@@ -291,7 +291,11 @@
+ 
+    mov   A, LASTPHASE;
+ 
+-   test   A, ~P_DATAIN   jz p_data;
++   if ((p->features & AHC_ULTRA2) != 0) {
++      test   A, ~P_DATAIN   jz u2_p_data;
++   } else {
++      test   A, ~P_DATAIN   jz p_data;
++   }
+    cmp   A,P_COMMAND   je p_command;
+    cmp   A,P_MESGOUT   je p_mesgout;
+    cmp   A,P_STATUS   je p_status;
+@@ -332,133 +336,73 @@
+    /* clear target specific flags */
+    clr   SEQ_FLAGS ret;
+ 
++    if ((p->features & AHC_ULTRA2) != 0) {
++
++
++
++u2_data_phase_reinit:
+ /*
+  * If we re-enter the data phase after going through another phase, the
+  * STCNT may have been cleared, so restore it from the residual field.
++ * On Ultra2, we have to put it into the HCNT field because we have to
++ * drop the data down into the shadow layer via the preload ability.
+  */
+-data_phase_reinit:
+-   if ((p->features & AHC_ULTRA2) != 0) {
+       bmov   HADDR, SHADDR, 4;
+       bmov    HCNT, SCB_RESID_DCNT, 3;
+-   }
+-   if ((p->chip & AHC_CHIPID_MASK) == AHC_AIC7895) {
+-      bmov    STCNT, SCB_RESID_DCNT, 3;
+-   }
+-   if ((p->features & AHC_CMD_CHAN) == 0) {
+-      mvi   DINDEX, STCNT;
+-      mvi   SCB_RESID_DCNT   call bcopy_3;
+-   }
+-   jmp   data_phase_loop;
+-
+-p_data:
+-   if ((p->features & AHC_ULTRA2) != 0) {
++      jmp   u2_data_phase_loop;
++u2_p_data:
+       mvi   DMAPARAMS, PRELOADEN|SCSIEN|HDMAEN;
+-   } else {
+-      mvi   DMAPARAMS, WIDEODD|SCSIEN|SDMAEN|HDMAEN|FIFORESET;
+-   }
+-   test   LASTPHASE, IOI jnz . + 2;
+-   or   DMAPARAMS, DIRECTION;
+-   call   assert;         /*
++      test   LASTPHASE, IOI jnz . + 2;
++      or   DMAPARAMS, DIRECTION;
++      call   assert;      /*
+                 * Ensure entering a data
+                 * phase is okay - seen identify, etc.
+                 */
+-   if ((p->features & AHC_CMD_CHAN) != 0) {
+       mvi   CCSGADDR, CCSGADDR_MAX;
+-   }
+-   test   SEQ_FLAGS, DPHASE   jnz data_phase_reinit;
+-
+-   /* We have seen a data phase */
+-   or   SEQ_FLAGS, DPHASE;
+-
+-   /*
+-    * Initialize the DMA address and counter from the SCB.
+-    * Also set SG_COUNT and SG_NEXT in memory since we cannot
+-    * modify the values in the SCB itself until we see a
+-    * save data pointers message.
+-    */
+-   if ((p->features & AHC_CMD_CHAN) != 0) {
++      test   SEQ_FLAGS, DPHASE   jnz u2_data_phase_reinit;
++      or   SEQ_FLAGS, DPHASE;   /* we've seen a data phase */
++      /*
++       * Initialize the DMA address and counter from the SCB.
++       * Also set SG_COUNT and SG_NEXT in memory since we cannot
++       * modify the values in the SCB itself until we see a
++       * save data pointers message.
++       */
+       bmov   HADDR, SCB_DATAPTR, 7;
+-      bmov    STCNT, HCNT, 3;
+       bmov    SG_COUNT, SCB_SGCOUNT, 5;
+-   } else {
+-      mvi   DINDEX, HADDR;
+-      mvi   SCB_DATAPTR   call bcopy_7;
+-      call   set_stcnt_from_hcnt;
+-      mvi   DINDEX, SG_COUNT;
+-      mvi   SCB_SGCOUNT   call bcopy_5;
+-   }
+-
+-data_phase_loop:
+-/* Guard against overruns */
+-   test   SG_COUNT, 0xff jnz data_phase_inbounds;
++u2_data_phase_loop:
++      /* Guard against overruns */
++      test   SG_COUNT, 0xff jnz u2_data_phase_inbounds;
+ /*
+  * Turn on 'Bit Bucket' mode, set the transfer count to
+  * 16meg and let the target run until it changes phase.
+  * When the transfer completes, notify the host that we
+  * had an overrun.
+  */
+-   or   SXFRCTL1,BITBUCKET;
+-   and   DMAPARAMS, ~(HDMAEN|SDMAEN);
+-   if ((p->features & AHC_CMD_CHAN) != 0) {
+-      if ((p->features & AHC_ULTRA2) != 0) {
+-         bmov   HCNT, ALLONES, 3;
+-      }
+-      bmov   STCNT, ALLONES, 3;
+-   } else {
+-      mvi   STCNT[0], 0xFF;
+-      mvi   STCNT[1], 0xFF;
+-      mvi   STCNT[2], 0xFF;
+-   }
+-data_phase_inbounds:
++      or   SXFRCTL1,BITBUCKET;
++      and   DMAPARAMS, DIRECTION;
++      bmov   HCNT, ALLONES, 3;
++u2_data_phase_inbounds:
+ /* If we are the last SG block, tell the hardware. */
+-   cmp   SG_COUNT,0x01 jne data_phase_wideodd;
+-   if ((p->features & AHC_ULTRA2) == 0) {
+-      and   DMAPARAMS, ~WIDEODD;
+-   } else {
+-      mvi   SG_CACHEPTR, LAST_SEG;
+-   }
+-data_phase_wideodd:
+-   if ((p->features & AHC_ULTRA2) != 0) {
+-      mov   SINDEX, ALLONES;
+-      mov   DFCNTRL, DMAPARAMS;
+-      test   SSTAT0, SDONE jnz .;
+-data_phase_dma_loop:
+-      test   SSTAT0, SDONE jnz data_phase_dma_done;
+-      test   SSTAT1,PHASEMIS   jz data_phase_dma_loop;   /* ie. underrun */
+-data_phase_dma_phasemis:
+-      test   SSTAT0,SDONE   jnz data_phase_dma_done;
+-      clr   SINDEX;         /* Remember the phasemiss */
+-   } else {
+-      mov   DMAPARAMS  call dma;
+-   }
+-
+-data_phase_dma_done:
+-/* Go tell the host about any overruns */
+-   test   SXFRCTL1,BITBUCKET jnz data_phase_overrun;
+-
+-/* Exit if we had an underrun.  dma clears SINDEX in this case. */
+-   test   SINDEX,0xff   jz data_phase_finish;
+-
++      shl   A, 2, SG_COUNT;
++      cmp   SG_COUNT,0x01 jne u2_data_phase_lastseg;
++      or   A, LAST_SEG;
++u2_data_phase_lastseg:
++      mov   SG_CACHEPTR, A;
++      mov   DFCNTRL, DMAPARAMS; /* start the operation */
++      test   SXFRCTL1, BITBUCKET jnz u2_data_phase_overrun;
++u2_preload_wait:
++      test   SSTAT1, PHASEMIS jnz u2_phasemis;
++      test   DFSTATUS, PRELOAD_AVAIL jz u2_preload_wait;
+ /*
+- * Advance the scatter-gather pointers if needed 
++ * Advance the scatter-gather pointers 
+  */
+-sg_advance:
+-   dec   SG_COUNT;   /* one less segment to go */
++u2_sg_advance:
++      cmp   SG_COUNT, 0x01   je u2_data_phase_finish;
+ 
+-   test   SG_COUNT, 0xff   jz data_phase_finish; /* Are we done? */
+-/*
+- * Load a struct scatter and set up the data address and length.
+- * If the working value of the SG count is nonzero, then
+- * we need to load a new set of values.
+- *
+- * This, like all DMA's, assumes little-endian host data storage.
+- */
+-sg_load:
+-   if ((p->features & AHC_CMD_CHAN) != 0) {
+       /*
+        * Do we have any prefetch left???
+        */
+-      cmp   CCSGADDR, CCSGADDR_MAX jne prefetched_segs_avail;
++      cmp   CCSGADDR, CCSGADDR_MAX jne u2_prefetch_avail;
+ 
+       /*
+        * Fetch MIN(CCSGADDR_MAX, (SG_COUNT * 8)) bytes.
+@@ -474,48 +418,263 @@
+       and   CCSGCTL, ~CCSGEN;
+       test   CCSGCTL, CCSGEN jnz .;
+       mvi   CCSGCTL, CCSGRESET;
+-prefetched_segs_avail:
+-      bmov    HADDR, CCSGRAM, 8;
+-      if ((p->features & AHC_ULTRA2) == 0) {
+-         bmov    STCNT, HCNT, 3;
++u2_prefetch_avail:
++      /* Test for a phasemis before we drop the stuff into the
++       * host regs.  We might have actually missed the phasemis
++       * while doing the dma of the sg segs.
++       */
++      test   SSTAT1, PHASEMIS jnz u2_phasemis;
++      dec   SG_COUNT;         /* one less segment to go */
++      bmov    HADDR, CCSGRAM, 8;    /* drop the address in place */
++      clr   A;            /* Advance the SG pointer by */
++      add   SG_NEXT[0],SG_SIZEOF; /* adding SG_SIZEOF to addr0 */
++      adc   SG_NEXT[1],A;         /* and adding any carry to */
++      jmp   u2_data_phase_loop;   /* addr1 */
++
++
++/*
++ * We've loaded all of our segments into the preload layer.  Now, we simply
++ * have to wait for it to finish or for us to get a phasemis.  And, since
++ * we'll get a phasemis if we do finish, all we really need to do is wait
++ * for a phasemis then check if we did actually complete all the segments.
++ */
++u2_data_phase_finish:
++      test   SSTAT1, PHASEMIS jnz u2_phasemis;
++      test   SG_CACHEPTR, LAST_SEG_DONE jz u2_data_phase_finish;
++      clr   SG_COUNT;
++      test   SSTAT1, REQINIT   jz .;
++      test   SSTAT1, PHASEMIS jz u2_data_phase_loop;
++u2_phasemis:
++      call   ultra2_dmafinish;
++      test   SG_CACHEPTR, LAST_SEG_DONE jnz u2_phasemis_end;
++      test   SSTAT2, SHVALID jnz u2_fixup_residual;
++      mvi   INTSTAT, SEQ_SG_FIXUP;
++      jmp   u2_phasemis_end;
++u2_fixup_residual:
++      shr   ARG_1, 2, SG_CACHEPTR;
++u2_phasemis_loop:
++      and   A, 0x3f, SG_COUNT;
++      cmp   ARG_1, A je u2_phasemis_end;
++/*
++ * Subtract SG_SIZEOF from the SG_NEXT pointer and add 1 to the SG_COUNT
++ */
++       clr   A;
++      add   SG_NEXT[0], -SG_SIZEOF;
++      adc   SG_NEXT[1], 0xff;
++      inc   SG_COUNT;
++      jmp   u2_phasemis_loop;
++u2_phasemis_end:
++      bmov   SCB_RESID_DCNT, STCNT, 3;
++      mov   SCB_RESID_SGCNT, SG_COUNT;
++      or   SXFRCTL0, CLRSTCNT|CLRCHN;
++      jmp   ITloop;
++
++
++
++/*
++ * Actually turn off the DMA hardware, save our current position into the
++ * proper residual variables, wait for the next REQ signal, then jump to
++ * the ITloop.  Jumping to the ITloop ensures that if we happen to get
++ * brought into the data phase again (or are still in it after our last
++ * segment) that we will properly signal an overrun to the kernel.
++ */
++ultra2_dmafinish:
++      test   DFCNTRL, DIRECTION jnz ultra2_dmahalt;
++      and   DFCNTRL, ~SCSIEN;
++      test   DFCNTRL, SCSIEN jnz .;
++      if ((p->bugs & AHC_BUG_AUTOFLUSH) != 0) {
++         or   DFCNTRL, FIFOFLUSH;
+       }
+-   } else {
+-      mvi   DINDEX, HADDR;
+-      mvi   SG_NEXT   call bcopy_4;
++ultra2_dmafifoflush:
++      if ((p->bugs & AHC_BUG_AUTOFLUSH) != 0) {
++         /*
++          * hardware bug alert!  This needless set of jumps
++          * works around a glitch in the silicon.  When the
++          * PCI DMA fifo goes empty, but there is still SCSI
++          * data to be flushed into the PCI DMA fifo (and from
++          * there on into main memory), the FIFOEMP bit will
++          * come on between the time when the PCI DMA buffer
++          * went empty and the next bit of data is copied from
++          * the SCSI fifo into the PCI fifo.  It should only
++          * come on when both FIFOs (meaning the entire FIFO
++          * chain) are emtpy.  Since it can take up to 4 cycles
++          * for new data to be copied from the SCSI fifo into
++          * the PCI fifo, testing for FIFOEMP status for 4
++          * extra times gives the needed time for any
++          * remaining SCSI fifo data to be put in the PCI fifo
++          * before we declare it *truly* empty.
++          */
++         test   DFSTATUS, FIFOEMP jz ultra2_dmafifoflush;
++         test   DFSTATUS, FIFOEMP jz ultra2_dmafifoflush;
++         test   DFSTATUS, FIFOEMP jz ultra2_dmafifoflush;
++         test   DFSTATUS, FIFOEMP jz ultra2_dmafifoflush;
++      }
++      test   DFSTATUS, FIFOEMP jz ultra2_dmafifoflush;
++      test   DFSTATUS, MREQPEND   jnz .;
++ultra2_dmahalt:
++      and     DFCNTRL, ~(HDMAEN|SCSIEN);
++      test   DFCNTRL, (HDMAEN|SCSIEN) jnz .;
++      ret;
+ 
+-      mvi   HCNT[0],SG_SIZEOF;
+-      clr   HCNT[1];
+-      clr   HCNT[2];
++u2_data_phase_overrun:
++/*
++ * Wait for the target to quit transferring data on the SCSI bus
++ */
++       test   SSTAT1, PHASEMIS jz .;
++      call   ultra2_dmafinish;
++/*
++ * Turn off BITBUCKET mode and notify the host
++ */
++      and   SXFRCTL1, ~BITBUCKET;
++      mvi   INTSTAT,DATA_OVERRUN;
++      jmp   ITloop;
++
++
++
++   } else {  /* NOT Ultra2 */
+ 
+-      or   DFCNTRL, HDMAEN|DIRECTION|FIFORESET;
+ 
+-      call   dma_finish;
+ 
++data_phase_reinit:
++/*
++ * If we re-enter the data phase after going through another phase, the
++ * STCNT may have been cleared, so restore it from the residual field.
++ */
++      if ((p->features & AHC_CMD_CHAN) != 0) {
++         bmov    STCNT, SCB_RESID_DCNT, 3;
++      } else {
++         mvi   DINDEX, STCNT;
++         mvi   SCB_RESID_DCNT   call bcopy_3;
++      }
++      jmp   data_phase_loop;
++p_data:
++      mvi   DMAPARAMS, WIDEODD|SCSIEN|SDMAEN|HDMAEN|FIFORESET;
++      test   LASTPHASE, IOI jnz . + 2;
++      or   DMAPARAMS, DIRECTION;
++      call   assert;      /*
++                * Ensure entering a data
++                * phase is okay - seen identify, etc.
++                */
++      if ((p->features & AHC_CMD_CHAN) != 0) {
++         mvi   CCSGADDR, CCSGADDR_MAX;
++      }
++      test   SEQ_FLAGS, DPHASE   jnz data_phase_reinit;
++      or   SEQ_FLAGS, DPHASE;   /* we've seen a data phase */
+       /*
+-       * Copy data from FIFO into SCB data pointer and data count.
+-       * This assumes that the SG segments are of the form:
+-       * struct ahc_dma_seg {
+-       *   u_int32_t   addr;   four bytes, little-endian order
+-       *   u_int32_t   len;   four bytes, little endian order
+-       * };
++       * Initialize the DMA address and counter from the SCB.
++       * Also set SG_COUNT and SG_NEXT in memory since we cannot
++       * modify the values in the SCB itself until we see a
++       * save data pointers message.
+        */
+-      mvi   HADDR   call dfdat_in_7;
+-      call   set_stcnt_from_hcnt;
+-   }
++      if ((p->features & AHC_CMD_CHAN) != 0) {
++         bmov   HADDR, SCB_DATAPTR, 7;
++         bmov    STCNT, HCNT, 3;
++         bmov    SG_COUNT, SCB_SGCOUNT, 5;
++      } else {
++         mvi   DINDEX, HADDR;
++         mvi   SCB_DATAPTR   call bcopy_7;
++         call   set_stcnt_from_hcnt;
++         mvi   DINDEX, SG_COUNT;
++         mvi   SCB_SGCOUNT   call bcopy_5;
++      }
++data_phase_loop:
++      /* Guard against overruns */
++      test   SG_COUNT, 0xff jnz data_phase_inbounds;
++/*
++ * Turn on 'Bit Bucket' mode, set the transfer count to
++ * 16meg and let the target run until it changes phase.
++ * When the transfer completes, notify the host that we
++ * had an overrun.
++ */
++      or   SXFRCTL1,BITBUCKET;
++      and   DMAPARAMS, ~(HDMAEN|SDMAEN);
++      if ((p->features & AHC_CMD_CHAN) != 0) {
++         bmov   STCNT, ALLONES, 3;
++      } else {
++         mvi   STCNT[0], 0xFF;
++         mvi   STCNT[1], 0xFF;
++         mvi   STCNT[2], 0xFF;
++      }
+ 
+-/* Advance the SG pointer */
+-   clr   A;         /* add sizeof(struct scatter) */
+-   add   SG_NEXT[0],SG_SIZEOF;
+-   adc   SG_NEXT[1],A;
++data_phase_inbounds:
++/* If we are the last SG block, tell the hardware. */
++      cmp   SG_COUNT,0x01 jne data_phase_wideodd;
++      and   DMAPARAMS, ~WIDEODD;
++data_phase_wideodd:
++      mov   DMAPARAMS  call dma;
++data_phase_dma_done:
++/* Go tell the host about any overruns */
++      test   SXFRCTL1,BITBUCKET jnz data_phase_overrun;
++
++/* Exit if we had an underrun.  dma clears SINDEX in this case. */
++      test   SINDEX,0xff   jz data_phase_finish;
++/*
++ * Advance the scatter-gather pointers if needed 
++ */
++sg_advance:
++      cmp   SG_COUNT, 0x01   je data_phase_finish; /* Are we done? */
++      dec   SG_COUNT;   /* one less segment to go */
++/*
++ * Load a struct scatter and set up the data address and length.
++ * If the working value of the SG count is nonzero, then
++ * we need to load a new set of values.
++ *
++ * This, like all DMA's, assumes little-endian host data storage.
++ */
++sg_load:
++      if ((p->features & AHC_CMD_CHAN) != 0) {
++         /*
++          * Do we have any prefetch left???
++          */
++         cmp   CCSGADDR, CCSGADDR_MAX jne prefetch_avail;
++
++         /*
++          * Fetch MIN(CCSGADDR_MAX, (SG_COUNT * 8)) bytes.
++          */
++         add   A, -(CCSGRAM_MAXSEGS + 1), SG_COUNT;
++         mvi   A, CCSGADDR_MAX;
++         jc   . + 2;
++         shl   A, 3, SG_COUNT;
++         mov   CCHCNT, A;
++         bmov   CCHADDR, SG_NEXT, 4;
++         mvi   CCSGCTL, CCSGEN|CCSGRESET;
++         test   CCSGCTL, CCSGDONE jz .;
++         and   CCSGCTL, ~CCSGEN;
++         test   CCSGCTL, CCSGEN jnz .;
++         mvi   CCSGCTL, CCSGRESET;
++prefetch_avail:
++         bmov    HADDR, CCSGRAM, 8;
++         bmov    STCNT, HCNT, 3;
++      } else {
++         mvi   DINDEX, HADDR;
++         mvi   SG_NEXT   call bcopy_4;
+ 
+-   test    SSTAT1, REQINIT jz .;
+-   test   SSTAT1,PHASEMIS   jz data_phase_loop;
++         mvi   HCNT[0],SG_SIZEOF;
++         clr   HCNT[1];
++         clr   HCNT[2];
+ 
+-/* This drops the last SG segment down to the shadow layer for us */
+-   if ((p->features & AHC_ULTRA2) != 0) {
+-      mov   DFCNTRL, DMAPARAMS;
+-      test   SSTAT0, SDONE   jnz .;
+-   }
++         or   DFCNTRL, HDMAEN|DIRECTION|FIFORESET;
++
++         call   dma_finish;
++
++/*
++ * Copy data from FIFO into SCB data pointer and data count.
++ * This assumes that the SG segments are of the form:
++ * struct ahc_dma_seg {
++ *   u_int32_t   addr;   four bytes, little-endian order
++ *   u_int32_t   len;   four bytes, little endian order
++ * };
++ */
++         mvi   HADDR   call dfdat_in_7;
++         call   set_stcnt_from_hcnt;
++      }
++/* Advance the SG pointer */
++      clr   A;      /* add sizeof(struct scatter) */
++      add   SG_NEXT[0],SG_SIZEOF;
++      adc   SG_NEXT[1],A;
++
++      test    SSTAT1, REQINIT jz .;
++      test   SSTAT1,PHASEMIS   jz data_phase_loop;
+ 
+ data_phase_finish:
+ /*
+@@ -523,10 +682,7 @@
+  * We use STCNT instead of HCNT, since it's a reflection of how many bytes 
+  * were transferred on the SCSI (as opposed to the host) bus.
+  */
+-   if ((p->features & AHC_ULTRA2) != 0) {
+-      call   ultra2_dmafinish;
+-   }
+-   if ((p->features & AHC_ULTRA2) == 0) {
++      clr   SG_COUNT;
+       if ((p->features & AHC_CMD_CHAN) != 0) {
+          bmov    SCB_RESID_DCNT, STCNT, 3;
+          mov   SCB_RESID_SGCNT, SG_COUNT;
+@@ -536,52 +692,19 @@
+          mov   SCB_RESID_DCNT[2],STCNT[2];
+          mov   SCB_RESID_SGCNT, SG_COUNT;
+       }
+-   }
+ 
+-   jmp   ITloop;
++      jmp   ITloop;
+ 
+ data_phase_overrun:
+-   if ((p->features & AHC_ULTRA2) != 0) {
+-      call   ultra2_dmafinish;
+-   }
+ /*
+  * Turn off BITBUCKET mode and notify the host
+  */
+-   and   SXFRCTL1, ~BITBUCKET;
+-   mvi   INTSTAT,DATA_OVERRUN;
+-   jmp   ITloop;
++      and   SXFRCTL1, ~BITBUCKET;
++      mvi   INTSTAT,DATA_OVERRUN;
++      jmp   ITloop;
++
++
+ 
+-ultra2_dmafinish:
+-   if ((p->features & AHC_ULTRA2) != 0) {
+-      test   DFCNTRL, DIRECTION jnz ultra2_dmahalt;
+-      and   DFCNTRL, ~SCSIEN;
+-      test   DFCNTRL, SCSIEN jnz .;
+-ultra2_dmafifoflush:
+-      or   DFCNTRL, FIFOFLUSH;
+-      test   DFSTATUS, FIFOEMP jz . - 1;
+-      /*
+-       * hardware bug alert!  This needless set of jumps is to
+-       * protect against a FIFOEMP status bit glitch in the
+-       * silicon.
+-       */
+-      test   DFSTATUS, FIFOEMP jz ultra2_dmafifoflush;
+-      test   DFSTATUS, FIFOEMP jz ultra2_dmafifoflush;
+-      test   DFSTATUS, FIFOEMP jz ultra2_dmafifoflush;
+-      test   DFSTATUS, FIFOEMP jz ultra2_dmafifoflush;
+-      test   DFSTATUS, FIFOEMP jz ultra2_dmafifoflush;
+-      test   DFSTATUS, MREQPEND   jnz .;
+-ultra2_dmahalt:
+-      test   SCSIOFFSET, 0x7f   jnz ultra2_shutdown;
+-ultra2_await_nreq:
+-      test   SCSISIGI, REQI   jz ultra2_shutdown;
+-      test   SSTAT1, (PHASEMIS|REQINIT)   jz ultra2_await_nreq;
+-ultra2_shutdown:
+-      and     DFCNTRL, ~(HDMAEN|SCSIEN);
+-      test   DFCNTRL, (HDMAEN|SCSIEN) jnz .;
+-      bmov   SCB_RESID_DCNT, STCNT, 3;
+-      mov   SCB_RESID_SGCNT, SG_COUNT;
+-      or   SXFRCTL0, CLRSTCNT|CLRCHN;
+-      ret;
+    }
+ 
+ /*
+@@ -1021,6 +1144,7 @@
+ inb_last:
+    mov   NONE,SCSIDATL ret;      /*dummy read from latch to ACK*/
+ 
++   
+ mesgin_phasemis:
+ /*
+  * We expected to receive another byte, but the target changed phase
+@@ -1080,7 +1204,9 @@
+     * to drain the data fifo until there is space for the input
+     * latch to drain and HDMAEN de-asserts.
+     */
+-   mov   NONE, DFDAT;
++   if ((p->bugs & AHC_BUG_PCI_2_1_RETRY) != 0) {
++      mov   NONE, DFDAT;
++   }
+    test   DFCNTRL, (SCSIEN|SDMAEN|HDMAEN) jnz dma_halt;
+ }
+ return:
+@@ -1306,11 +1432,17 @@
+       cmp   CCSCBCTL, CCSCBDONE|ARRDONE|CCARREN|CCSCBEN|CCSCBDIR jne .;
+       jmp   dma_scb_finish;
+ dma_scb_tohost:
+-      if ((p->chip & AHC_CHIPID_MASK) == AHC_AIC7895) {
++      if ((p->features & AHC_ULTRA2) == 0) {
+          mvi   CCSCBCTL, CCSCBRESET;
+          bmov   CCSCBRAM, SCB_CONTROL, 32;
+          or   CCSCBCTL, CCSCBEN|CCSCBRESET;
+          test   CCSCBCTL, CCSCBDONE jz .;
++      } else if ((p->bugs & AHC_BUG_SCBCHAN_UPLOAD) != 0) {
++                        mvi     CCSCBCTL, CCARREN|CCSCBRESET;
++         cmp     CCSCBCTL, ARRDONE|CCARREN jne .;
++                        mvi     CCHCNT, 32;
++         mvi     CCSCBCTL, CCSCBEN|CCSCBRESET;
++         cmp     CCSCBCTL, CCSCBDONE|CCSCBEN jne .;
+       } else {
+          mvi   CCSCBCTL, CCARREN|CCSCBEN|CCSCBRESET;
+          cmp   CCSCBCTL, CCSCBDONE|ARRDONE|CCARREN|CCSCBEN jne .;
+@@ -1342,17 +1474,81 @@
+       mov   DFDAT,SINDIR;
+       cmp   SINDEX, A jne copy_scb_tofifo_loop;
+       or   DFCNTRL, HDMAEN|FIFOFLUSH;
++      jmp   dma_finish;
+ dma_scb_fromhost:
+-      call   dma_finish;
+-      /* If we were putting the SCB, we are done */
+-      test   DMAPARAMS, DIRECTION   jz   return;
+-      mvi   SCB_CONTROL  call dfdat_in_7;
+-      call   dfdat_in_7_continued;
+-      call   dfdat_in_7_continued;
+-      jmp   dfdat_in_7_continued;
++      mvi   DINDEX, SCB_CONTROL;
++      if ((p->bugs & AHC_BUG_PCI_2_1_RETRY) != 0) {
++         /*
++          * Set the A to -24.  It it hits 0, then we let
++          * our code fall through to dfdat_in_8 to complete
++          * the last of the copy.
++          *
++          * Also, things happen 8 bytes at a time in this
++          * case, so we may need to drain the fifo at most
++          * 3 times to keep things flowing
++          */
++         mvi   A, -24;
++dma_scb_hang_fifo:
++         /* Wait for the first bit of data to hit the fifo */
++         test   DFSTATUS, FIFOEMP jnz .;
++dma_scb_hang_wait:
++         /* OK, now they've started to transfer into the fifo,
++          * so wait for them to stop trying to transfer any
++          * more data.
++          */
++         test   DFSTATUS, MREQPEND jnz .;
++         /*
++          * OK, they started, then they stopped, now see if they
++          * managed to complete the job before stopping.  Try
++          * it multiple times to give the chip a few cycles to
++          * set the flag if it did complete.
++          */
++         test   DFSTATUS, HDONE jnz dma_scb_hang_dma_done;
++         test   DFSTATUS, HDONE jnz dma_scb_hang_dma_done;
++         test   DFSTATUS, HDONE jnz dma_scb_hang_dma_done;
++         /*
++          * Too bad, the chip didn't complete the DMA, but there
++          * aren't any more memory requests pending, so that
++          * means it stopped part way through and hung.  That's
++          * our bug, so now we drain what data there is in the
++          * fifo in order to get things going again.
++          */
++dma_scb_hang_empty_fifo:
++         call   dfdat_in_8;
++         add   A, 8;
++         add   SINDEX, A, HCNT;
++         /*
++          * If there are another 8 bytes of data waiting in the
++          * fifo, then the carry bit will be set as a result
++          * of the above add command (unless A is non-negative,
++          * in which case the carry bit won't be set).
++          */
++         jc   dma_scb_hang_empty_fifo;
++         /*
++          * We've emptied the fifo now, but we wouldn't have got
++          * here if the memory transfer hadn't stopped part way
++          * through, so go back up to the beginning of the
++          * loop and start over.  When it succeeds in getting
++          * all the data down, HDONE will be set and we'll
++          * jump to the code just below here.
++          */
++         jmp   dma_scb_hang_fifo;
++dma_scb_hang_dma_done:
++         and   DFCNTRL, ~HDMAEN;
++         test   DFCNTRL, HDMAEN jnz .;
++         call   dfdat_in_8;
++         add   A, 8;
++         cmp   A, 8 jne . - 2;
++         ret;
++      } else {
++         call   dma_finish;
++         call   dfdat_in_8;
++         call   dfdat_in_8;
++         call   dfdat_in_8;
++      }
++dfdat_in_8:
++      mov   DINDIR,DFDAT;
+ dfdat_in_7:
+-      mov     DINDEX,SINDEX;
+-dfdat_in_7_continued:
+       mov   DINDIR,DFDAT;
+       mov   DINDIR,DFDAT;
+       mov   DINDIR,DFDAT;
+diff -U 3 -rN linux-2.2.17/drivers/scsi/aic7xxx/aic7xxx_proc.c linux/drivers/scsi/aic7xxx/aic7xxx_proc.c
+--- linux-2.2.17/drivers/scsi/aic7xxx/aic7xxx_proc.c   Wed Dec 31 19:00:00 1969
++++ linux/drivers/scsi/aic7xxx/aic7xxx_proc.c   Tue Feb  6 03:49:36 2001
+@@ -0,0 +1,414 @@
++/*+M*************************************************************************
++ * Adaptec AIC7xxx device driver proc support for Linux.
++ *
++ * Copyright (c) 1995, 1996 Dean W. Gehnert
++ *
++ * 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
++ * the Free Software Foundation; either version 2, or (at your option)
++ * any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; see the file COPYING.  If not, write to
++ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
++ *
++ * ----------------------------------------------------------------
++ *  o Modified from the EATA-DMA /proc support.
++ *  o Additional support for device block statistics provided by
++ *    Matthew Jacob.
++ *  o Correction of overflow by Heinz Mauelshagen
++ *  o Adittional corrections by Doug Ledford
++ *
++ *  Dean W. Gehnert, deang@teleport.com, 05/01/96
++ *
++ *  $Id: aic7xxx_proc.c,v 4.1 1997/06/97 08:23:42 deang Exp $
++ *-M*************************************************************************/
++
++#include <linux/config.h>
++
++#define   BLS   (&aic7xxx_buffer[size])
++#define HDRB \
++"             < 2K      2K+     4K+     8K+    16K+    32K+    64K+   128K+"
++
++#ifdef PROC_DEBUG
++extern int vsprintf(char *, const char *, va_list);
++
++static void
++proc_debug(const char *fmt, ...)
++{
++  va_list ap;
++  char buf[256];
++
++  va_start(ap, fmt);
++  vsprintf(buf, fmt, ap);
++  printk(buf);
++  va_end(ap);
++}
++#else /* PROC_DEBUG */
++#  define proc_debug(fmt, args...)
++#endif /* PROC_DEBUG */
++
++static int aic7xxx_buffer_size = 0;
++static char *aic7xxx_buffer = NULL;
++
++
++/*+F*************************************************************************
++ * Function:
++ *   aic7xxx_set_info
++ *
++ * Description:
++ *   Set parameters for the driver from the /proc filesystem.
++ *-F*************************************************************************/
++int
++aic7xxx_set_info(char *buffer, int length, struct Scsi_Host *HBAptr)
++{
++  proc_debug("aic7xxx_set_info(): %s\n", buffer);
++  return (-ENOSYS);  /* Currently this is a no-op */
++}
++
++
++/*+F*************************************************************************
++ * Function:
++ *   aic7xxx_proc_info
++ *
++ * Description:
++ *   Return information to handle /proc support for the driver.
++ *-F*************************************************************************/
++int
++aic7xxx_proc_info ( char *buffer, char **start, off_t offset, int length, 
++                    int hostno, int inout)
++{
++  struct Scsi_Host *HBAptr;
++  struct aic7xxx_host *p;
++  int    size = 0;
++  unsigned char i;
++  struct aic7xxx_xferstats *sp;
++  unsigned char target;
++
++  HBAptr = NULL;
++
++  for(p=first_aic7xxx; p->host->host_no != hostno; p=p->next)
++    ;
++
++  if (!p)
++  {
++    size += sprintf(buffer, "Can't find adapter for host number %d\n", hostno);
++    if (size > length)
++    {
++      return (size);
++    }
++    else
++    {
++      return (length);
++    }
++  }
++
++  HBAptr = p->host;
++
++  if (inout == TRUE) /* Has data been written to the file? */ 
++  {
++    return (aic7xxx_set_info(buffer, length, HBAptr));
++  }
++
++  p = (struct aic7xxx_host *) HBAptr->hostdata;
++
++  /*
++   * It takes roughly 1K of space to hold all relevant card info, not
++   * counting any proc stats, so we start out with a 1.5k buffer size and
++   * if proc_stats is defined, then we sweep the stats structure to see
++   * how many drives we will be printing out for and add 384 bytes per
++   * device with active stats.
++   *
++   * Hmmmm...that 1.5k seems to keep growing as items get added so they
++   * can be easily viewed for debugging purposes.  So, we bumped that
++   * 1.5k to 4k so we can quit having to bump it all the time.
++   */
++
++  size = 4096;
++  for (target = 0; target < MAX_TARGETS; target++)
++  {
++    if (p->dev_flags[target] & DEVICE_PRESENT)
++#ifdef AIC7XXX_PROC_STATS
++      size += 512;
++#else
++      size += 256;
++#endif
++  }
++  if (aic7xxx_buffer_size != size)
++  {
++    if (aic7xxx_buffer != NULL) 
++    {
++      kfree(aic7xxx_buffer);
++      aic7xxx_buffer_size = 0;
++    }
++    aic7xxx_buffer = kmalloc(size, GFP_KERNEL);
++  }
++  if (aic7xxx_buffer == NULL)
++  {
++    size = sprintf(buffer, "AIC7xxx - kmalloc error at line %d\n",
++        __LINE__);
++    return size;
++  }
++  aic7xxx_buffer_size = size;
++
++  size = 0;
++  size += sprintf(BLS, "Adaptec AIC7xxx driver version: ");
++  size += sprintf(BLS, "%s/", AIC7XXX_C_VERSION);
++  size += sprintf(BLS, "%s", AIC7XXX_H_VERSION);
++  size += sprintf(BLS, "\n");
++  size += sprintf(BLS, "Compile Options:\n");
++#ifdef CONFIG_AIC7XXX_TCQ_ON_BY_DEFAULT
++  size += sprintf(BLS, "  TCQ Enabled By Default : Enabled\n");
++#else
++  size += sprintf(BLS, "  TCQ Enabled By Default : Disabled\n");
++#endif
++#ifdef AIC7XXX_PROC_STATS
++  size += sprintf(BLS, "  AIC7XXX_PROC_STATS     : Enabled\n");
++#else
++  size += sprintf(BLS, "  AIC7XXX_PROC_STATS     : Disabled\n");
++#endif
++  size += sprintf(BLS, "  AIC7XXX_RESET_DELAY    : %d\n", AIC7XXX_RESET_DELAY);
++  size += sprintf(BLS, "\n");
++  size += sprintf(BLS, "Adapter Configuration:\n");
++  size += sprintf(BLS, "           SCSI Adapter: %s\n",
++      board_names[p->board_name_index]);
++  if (p->flags & AHC_TWIN)
++    size += sprintf(BLS, "                         Twin Channel Controller ");
++  else
++  {
++    char *channel = "";
++    char *ultra = "";
++    char *wide = "Narrow ";
++    if (p->flags & AHC_MULTI_CHANNEL)
++    {
++      channel = " Channel A";
++      if (p->flags & (AHC_CHNLB|AHC_CHNLC))
++        channel = (p->flags & AHC_CHNLB) ? " Channel B" : " Channel C";
++    }
++    if (p->features & AHC_WIDE)
++      wide = "Wide ";
++    if (p->features & AHC_ULTRA3)
++    {
++      switch(p->chip & AHC_CHIPID_MASK)
++      {
++        case AHC_AIC7892:
++        case AHC_AIC7899:
++          ultra = "Ultra-160/m LVD/SE ";
++          break;
++        default:
++          ultra = "Ultra-3 LVD/SE ";
++          break;
++      }
++    }
++    else if (p->features & AHC_ULTRA2)
++      ultra = "Ultra-2 LVD/SE ";
++    else if (p->features & AHC_ULTRA)
++      ultra = "Ultra ";
++    size += sprintf(BLS, "                           %s%sController%s ",
++      ultra, wide, channel);
++  }
++  switch(p->chip & ~AHC_CHIPID_MASK)
++  {
++    case AHC_VL:
++      size += sprintf(BLS, "at VLB slot %d\n", p->pci_device_fn);
++      break;
++    case AHC_EISA:
++      size += sprintf(BLS, "at EISA slot %d\n", p->pci_device_fn);
++      break;
++    default:
++      size += sprintf(BLS, "at PCI %d/%d/%d\n", p->pci_bus,
++        PCI_SLOT(p->pci_device_fn), PCI_FUNC(p->pci_device_fn));
++      break;
++  }
++  if( !(p->maddr) )
++  {
++    size += sprintf(BLS, "    Programmed I/O Base: %lx\n", p->base);
++  }
++  else
++  {
++    size += sprintf(BLS, "    PCI MMAPed I/O Base: 0x%lx\n", p->mbase);
++  }
++  if( (p->chip & (AHC_VL | AHC_EISA)) )
++  {
++    size += sprintf(BLS, "    BIOS Memory Address: 0x%08x\n", p->bios_address);
++  }
++  size += sprintf(BLS, " Adapter SEEPROM Config: %s\n",
++          (p->flags & AHC_SEEPROM_FOUND) ? "SEEPROM found and used." :
++         ((p->flags & AHC_USEDEFAULTS) ? "SEEPROM not found, using defaults." :
++           "SEEPROM not found, using leftover BIOS values.") );
++  size += sprintf(BLS, "      Adaptec SCSI BIOS: %s\n",
++          (p->flags & AHC_BIOS_ENABLED) ? "Enabled" : "Disabled");
++  size += sprintf(BLS, "                    IRQ: %d\n", HBAptr->irq);
++  size += sprintf(BLS, "                   SCBs: Active %d, Max Active %d,\n",
++            p->activescbs, p->max_activescbs);
++  size += sprintf(BLS, "                         Allocated %d, HW %d, "
++            "Page %d\n", p->scb_data->numscbs, p->scb_data->maxhscbs,
++            p->scb_data->maxscbs);
++  if (p->flags & AHC_EXTERNAL_SRAM)
++    size += sprintf(BLS, "                         Using External SCB SRAM\n");
++  size += sprintf(BLS, "             Interrupts: %ld", p->isr_count);
++  if (p->chip & AHC_EISA)
++  {
++    size += sprintf(BLS, " %s\n",
++        (p->pause & IRQMS) ? "(Level Sensitive)" : "(Edge Triggered)");
++  }
++  else
++  {
++    size += sprintf(BLS, "\n");
++  }
++  size += sprintf(BLS, "      BIOS Control Word: 0x%04x\n",
++            p->bios_control);
++  size += sprintf(BLS, "   Adapter Control Word: 0x%04x\n",
++            p->adapter_control);
++  size += sprintf(BLS, "   Extended Translation: %sabled\n",
++      (p->flags & AHC_EXTEND_TRANS_A) ? "En" : "Dis");
++  size += sprintf(BLS, "Disconnect Enable Flags: 0x%04x\n", p->discenable);
++  if (p->features & (AHC_ULTRA | AHC_ULTRA2))
++  {
++    size += sprintf(BLS, "     Ultra Enable Flags: 0x%04x\n", p->ultraenb);
++  }
++  size += sprintf(BLS, " Tag Queue Enable Flags: 0x%04x\n", p->tagenable);
++  size += sprintf(BLS, "Ordered Queue Tag Flags: 0x%04x\n", p->orderedtag);
++  size += sprintf(BLS, "Default Tag Queue Depth: %d\n", AIC7XXX_CMDS_PER_DEVICE);
++  size += sprintf(BLS, "    Tagged Queue By Device array for aic7xxx host "
++                       "instance %d:\n", p->instance);
++  size += sprintf(BLS, "      {");
++  for(i=0; i < (MAX_TARGETS - 1); i++)
++    size += sprintf(BLS, "%d,",aic7xxx_tag_info[p->instance].tag_commands[i]);
++  size += sprintf(BLS, "%d}\n",aic7xxx_tag_info[p->instance].tag_commands[i]);
++  size += sprintf(BLS, "    Actual queue depth per device for aic7xxx host "
++                       "instance %d:\n", p->instance);
++  size += sprintf(BLS, "      {");
++  for(i=0; i < (MAX_TARGETS - 1); i++)
++    size += sprintf(BLS, "%d,", p->dev_max_queue_depth[i]);
++  size += sprintf(BLS, "%d}\n", p->dev_max_queue_depth[i]);
++
++  size += sprintf(BLS, "\n");
++  size += sprintf(BLS, "Statistics:\n\n");
++  for (target = 0; target < MAX_TARGETS; target++)
++  {
++    sp = &p->stats[target];
++    if ((p->dev_flags[target] & DEVICE_PRESENT) == 0)
++    {
++      continue;
++    }
++    if (p->features & AHC_TWIN)
++    {
++      size += sprintf(BLS, "(scsi%d:%d:%d:%d)\n",
++          p->host_no, (target >> 3), (target & 0x7), 0);
++    }
++    else
++    {
++      size += sprintf(BLS, "(scsi%d:%d:%d:%d)\n",
++          p->host_no, 0, target, 0);
++    }
++    size += sprintf(BLS, "  Device using %s/%s",
++          (p->transinfo[target].cur_width == MSG_EXT_WDTR_BUS_16_BIT) ?
++          "Wide" : "Narrow",
++          (p->transinfo[target].cur_offset != 0) ?
++          "Sync transfers at " : "Async transfers.\n" );
++    if (p->transinfo[target].cur_offset != 0)
++    {
++      struct aic7xxx_syncrate *sync_rate;
++      unsigned char options = p->transinfo[target].cur_options;
++      int period = p->transinfo[target].cur_period;
++      int rate = (p->transinfo[target].cur_width ==
++                  MSG_EXT_WDTR_BUS_16_BIT) ? 1 : 0;
++
++      sync_rate = aic7xxx_find_syncrate(p, &period, 0, &options);
++      if (sync_rate != NULL)
++      {
++        size += sprintf(BLS, "%s MByte/sec, offset %d\n",
++                        sync_rate->rate[rate],
++                        p->transinfo[target].cur_offset );
++      }
++      else
++      {
++        size += sprintf(BLS, "3.3 MByte/sec, offset %d\n",
++                        p->transinfo[target].cur_offset );
++      }
++    }
++    size += sprintf(BLS, "  Transinfo settings: ");
++    size += sprintf(BLS, "current(%d/%d/%d/%d), ",
++                    p->transinfo[target].cur_period,
++                    p->transinfo[target].cur_offset,
++                    p->transinfo[target].cur_width,
++                    p->transinfo[target].cur_options);
++    size += sprintf(BLS, "goal(%d/%d/%d/%d), ",
++                    p->transinfo[target].goal_period,
++                    p->transinfo[target].goal_offset,
++                    p->transinfo[target].goal_width,
++                    p->transinfo[target].goal_options);
++    size += sprintf(BLS, "user(%d/%d/%d/%d)\n",
++                    p->transinfo[target].user_period,
++                    p->transinfo[target].user_offset,
++                    p->transinfo[target].user_width,
++                    p->transinfo[target].user_options);
++#ifdef AIC7XXX_PROC_STATS
++    size += sprintf(BLS, "  Total transfers %ld (%ld reads and %ld writes)\n",
++        sp->r_total + sp->w_total, sp->r_total, sp->w_total);
++    size += sprintf(BLS, "%s\n", HDRB);
++    size += sprintf(BLS, "   Reads:");
++    for (i = 0; i < NUMBER(sp->r_bins); i++)
++    {
++      size += sprintf(BLS, " %7ld", sp->r_bins[i]);
++    }
++    size += sprintf(BLS, "\n");
++    size += sprintf(BLS, "  Writes:");
++    for (i = 0; i < NUMBER(sp->w_bins); i++)
++    {
++      size += sprintf(BLS, " %7ld", sp->w_bins[i]);
++    }
++    size += sprintf(BLS, "\n");
++#else
++    size += sprintf(BLS, "  Total transfers %ld (%ld reads and %ld writes)\n",
++        sp->r_total + sp->w_total, sp->r_total, sp->w_total);
++#endif /* AIC7XXX_PROC_STATS */
++    size += sprintf(BLS, "\n\n");
++  }
++
++  if (size >= aic7xxx_buffer_size)
++  {
++    printk(KERN_WARNING "aic7xxx: Overflow in aic7xxx_proc.c\n");
++  }
++
++  if (offset > size - 1)
++  {
++    kfree(aic7xxx_buffer);
++    aic7xxx_buffer = NULL;
++    aic7xxx_buffer_size = length = 0;
++    *start = NULL;
++  }
++  else
++  {
++    *start = buffer;
++    length = MIN(length, size - offset);
++    memcpy(buffer, &aic7xxx_buffer[offset], length);
++  }
++
++  return (length);
++}
++
++/*
++ * Overrides for Emacs so that we follow Linus's tabbing style.
++ * Emacs will notice this stuff at the end of the file and automatically
++ * adjust the settings for this buffer only.  This must remain at the end
++ * of the file.
++ * ---------------------------------------------------------------------------
++ * Local variables:
++ * c-indent-level: 2
++ * c-brace-imaginary-offset: 0
++ * c-brace-offset: -2
++ * c-argdecl-indent: 2
++ * c-label-offset: -2
++ * c-continued-statement-offset: 2
++ * c-continued-brace-offset: 0
++ * indent-tabs-mode: nil
++ * tab-width: 8
++ * End:
++ */
+diff -U 3 -rN linux-2.2.17/drivers/scsi/aic7xxx/aic7xxx_reg.h linux/drivers/scsi/aic7xxx/aic7xxx_reg.h
+--- linux-2.2.17/drivers/scsi/aic7xxx/aic7xxx_reg.h   Wed Dec 31 19:00:00 1969
++++ linux/drivers/scsi/aic7xxx/aic7xxx_reg.h   Tue Feb  6 03:49:36 2001
+@@ -0,0 +1,629 @@
++/*
++  * DO NOT EDIT - This file is automatically generated.
++  */
++
++#define   SCSISEQ               0x00
++#define      TEMODE             0x80
++#define      ENSELO             0x40
++#define      ENSELI             0x20
++#define      ENRSELI            0x10
++#define      ENAUTOATNO         0x08
++#define      ENAUTOATNI         0x04
++#define      ENAUTOATNP         0x02
++#define      SCSIRSTO           0x01
++
++#define   SXFRCTL0              0x01
++#define      DFON               0x80
++#define      DFPEXP             0x40
++#define      FAST20             0x20
++#define      CLRSTCNT           0x10
++#define      SPIOEN             0x08
++#define      SCAMEN             0x04
++#define      CLRCHN             0x02
++
++#define   SXFRCTL1              0x02
++#define      BITBUCKET          0x80
++#define      SWRAPEN            0x40
++#define      ENSPCHK            0x20
++#define      STIMESEL           0x18
++#define      ENSTIMER           0x04
++#define      ACTNEGEN           0x02
++#define      STPWEN             0x01
++
++#define   SCSISIGO              0x03
++#define      CDO                0x80
++#define      IOO                0x40
++#define      MSGO               0x20
++#define      ATNO               0x10
++#define      SELO               0x08
++#define      BSYO               0x04
++#define      REQO               0x02
++#define      ACKO               0x01
++
++#define   SCSISIGI              0x03
++#define      ATNI               0x10
++#define      SELI               0x08
++#define      BSYI               0x04
++#define      REQI               0x02
++#define      ACKI               0x01
++
++#define   SCSIRATE              0x04
++#define      WIDEXFER           0x80
++#define      SXFR_ULTRA2        0x7f
++#define      SXFR               0x70
++#define      SOFS               0x0f
++
++#define   SCSIID                0x05
++#define   SCSIOFFSET            0x05
++#define      SOFS_ULTRA2        0x7f
++
++#define   SCSIDATL              0x06
++
++#define   SCSIDATH              0x07
++
++#define   STCNT                 0x08
++
++#define   OPTIONMODE            0x08
++#define      AUTORATEEN         0x80
++#define      AUTOACKEN          0x40
++#define      ATNMGMNTEN         0x20
++#define      BUSFREEREV         0x10
++#define      EXPPHASEDIS        0x08
++#define      SCSIDATL_IMGEN     0x04
++#define      AUTO_MSGOUT_DE     0x02
++#define      DIS_MSGIN_DUALEDGE   0x01
++
++#define   CLRSINT0              0x0b
++#define      CLRSELDO           0x40
++#define      CLRSELDI           0x20
++#define      CLRSELINGO         0x10
++#define      CLRSWRAP           0x08
++#define      CLRSPIORDY         0x02
++
++#define   SSTAT0                0x0b
++#define      TARGET             0x80
++#define      SELDO              0x40
++#define      SELDI              0x20
++#define      SELINGO            0x10
++#define      IOERR              0x08
++#define      SWRAP              0x08
++#define      SDONE              0x04
++#define      SPIORDY            0x02
++#define      DMADONE            0x01
++
++#define   CLRSINT1              0x0c
++#define      CLRSELTIMEO        0x80
++#define      CLRATNO            0x40
++#define      CLRSCSIRSTI        0x20
++#define      CLRBUSFREE         0x08
++#define      CLRSCSIPERR        0x04
++#define      CLRPHASECHG        0x02
++#define      CLRREQINIT         0x01
++
++#define   SSTAT1                0x0c
++#define      SELTO              0x80
++#define      ATNTARG            0x40
++#define      SCSIRSTI           0x20
++#define      PHASEMIS           0x10
++#define      BUSFREE            0x08
++#define      SCSIPERR           0x04
++#define      PHASECHG           0x02
++#define      REQINIT            0x01
++
++#define   SSTAT2                0x0d
++#define      OVERRUN            0x80
++#define      SHVALID            0x40
++#define      WIDE_RES           0x20
++#define      SFCNT              0x1f
++#define      EXP_ACTIVE         0x10
++#define      CRCVALERR          0x08
++#define      CRCENDERR          0x04
++#define      CRCREQERR          0x02
++#define      DUAL_EDGE_ERROR    0x01
++
++#define   SSTAT3                0x0e
++#define      SCSICNT            0xf0
++#define      OFFCNT             0x0f
++
++#define   SCSIID_ULTRA2         0x0f
++#define      OID                0x0f
++
++#define   SIMODE0               0x10
++#define      ENSELDO            0x40
++#define      ENSELDI            0x20
++#define      ENSELINGO          0x10
++#define      ENIOERR            0x08
++#define      ENSWRAP            0x08
++#define      ENSDONE            0x04
++#define      ENSPIORDY          0x02
++#define      ENDMADONE          0x01
++
++#define   SIMODE1               0x11
++#define      ENSELTIMO          0x80
++#define      ENATNTARG          0x40
++#define      ENSCSIRST          0x20
++#define      ENPHASEMIS         0x10
++#define      ENBUSFREE          0x08
++#define      ENSCSIPERR         0x04
++#define      ENPHASECHG         0x02
++#define      ENREQINIT          0x01
++
++#define   SCSIBUSL              0x12
++
++#define   SCSIBUSH              0x13
++
++#define   SHADDR                0x14
++
++#define   SELTIMER              0x18
++#define      STAGE6             0x20
++#define      STAGE5             0x10
++#define      STAGE4             0x08
++#define      STAGE3             0x04
++#define      STAGE2             0x02
++#define      STAGE1             0x01
++
++#define   SELID                 0x19
++#define      SELID_MASK         0xf0
++#define      ONEBIT             0x08
++
++#define   SPIOCAP               0x1b
++#define      SOFT1              0x80
++#define      SOFT0              0x40
++#define      SOFTCMDEN          0x20
++#define      HAS_BRDCTL         0x10
++#define      SEEPROM            0x08
++#define      EEPROM             0x04
++#define      ROM                0x02
++#define      SSPIOCPS           0x01
++
++#define   BRDCTL                0x1d
++#define      BRDDAT7            0x80
++#define      BRDDAT6            0x40
++#define      BRDDAT5            0x20
++#define      BRDDAT4            0x10
++#define      BRDSTB             0x10
++#define      BRDCS              0x08
++#define      BRDDAT3            0x08
++#define      BRDDAT2            0x04
++#define      BRDRW              0x04
++#define      BRDRW_ULTRA2       0x02
++#define      BRDCTL1            0x02
++#define      BRDSTB_ULTRA2      0x01
++#define      BRDCTL0            0x01
++
++#define   SEECTL                0x1e
++#define      EXTARBACK          0x80
++#define      EXTARBREQ          0x40
++#define      SEEMS              0x20
++#define      SEERDY             0x10
++#define      SEECS              0x08
++#define      SEECK              0x04
++#define      SEEDO              0x02
++#define      SEEDI              0x01
++
++#define   SBLKCTL               0x1f
++#define      DIAGLEDEN          0x80
++#define      DIAGLEDON          0x40
++#define      AUTOFLUSHDIS       0x20
++#define      ENAB40             0x08
++#define      ENAB20             0x04
++#define      SELWIDE            0x02
++#define      XCVR               0x01
++
++#define   SRAM_BASE             0x20
++
++#define   TARG_SCSIRATE         0x20
++
++#define   ULTRA_ENB             0x30
++
++#define   DISC_DSB              0x32
++
++#define   MSG_OUT               0x34
++
++#define   DMAPARAMS             0x35
++#define      PRELOADEN          0x80
++#define      WIDEODD            0x40
++#define      SCSIEN             0x20
++#define      SDMAENACK          0x10
++#define      SDMAEN             0x10
++#define      HDMAEN             0x08
++#define      HDMAENACK          0x08
++#define      DIRECTION          0x04
++#define      FIFOFLUSH          0x02
++#define      FIFORESET          0x01
++
++#define   SEQ_FLAGS             0x36
++#define      IDENTIFY_SEEN      0x80
++#define      SCBPTR_VALID       0x20
++#define      DPHASE             0x10
++#define      AMTARGET           0x08
++#define      WIDE_BUS           0x02
++#define      TWIN_BUS           0x01
++
++#define   SAVED_TCL             0x37
++
++#define   SG_COUNT              0x38
++
++#define   SG_NEXT               0x39
++
++#define   LASTPHASE             0x3d
++#define      P_MESGIN           0xe0
++#define      PHASE_MASK         0xe0
++#define      P_STATUS           0xc0
++#define      P_MESGOUT          0xa0
++#define      P_COMMAND          0x80
++#define      CDI                0x80
++#define      IOI                0x40
++#define      P_DATAIN           0x40
++#define      MSGI               0x20
++#define      P_BUSFREE          0x01
++#define      P_DATAOUT          0x00
++
++#define   WAITING_SCBH          0x3e
++
++#define   DISCONNECTED_SCBH      0x3f
++
++#define   FREE_SCBH             0x40
++
++#define   HSCB_ADDR             0x41
++
++#define   SCBID_ADDR            0x45
++
++#define   TMODE_CMDADDR         0x49
++
++#define   KERNEL_QINPOS         0x4d
++
++#define   QINPOS                0x4e
++
++#define   QOUTPOS               0x4f
++
++#define   TMODE_CMDADDR_NEXT      0x50
++
++#define   ARG_1                 0x51
++#define   RETURN_1              0x51
++#define      SEND_MSG           0x80
++#define      SEND_SENSE         0x40
++#define      SEND_REJ           0x20
++#define      MSGOUT_PHASEMIS    0x10
++
++#define   ARG_2                 0x52
++#define   RETURN_2              0x52
++
++#define   LAST_MSG              0x53
++
++#define   PREFETCH_CNT          0x54
++
++#define   SCSICONF              0x5a
++#define      TERM_ENB           0x80
++#define      RESET_SCSI         0x40
++#define      HWSCSIID           0x0f
++#define      HSCSIID            0x07
++
++#define   HOSTCONF              0x5d
++
++#define   HA_274_BIOSCTRL       0x5f
++#define      BIOSMODE           0x30
++#define      BIOSDISABLED       0x30
++#define      CHANNEL_B_PRIMARY   0x08
++
++#define   SEQCTL                0x60
++#define      PERRORDIS          0x80
++#define      PAUSEDIS           0x40
++#define      FAILDIS            0x20
++#define      FASTMODE           0x10
++#define      BRKADRINTEN        0x08
++#define      STEP               0x04
++#define      SEQRESET           0x02
++#define      LOADRAM            0x01
++
++#define   SEQRAM                0x61
++
++#define   SEQADDR0              0x62
++
++#define   SEQADDR1              0x63
++#define      SEQADDR1_MASK      0x01
++
++#define   ACCUM                 0x64
++
++#define   SINDEX                0x65
++
++#define   DINDEX                0x66
++
++#define   ALLONES               0x69
++
++#define   ALLZEROS              0x6a
++
++#define   NONE                  0x6a
++
++#define   FLAGS                 0x6b
++#define      ZERO               0x02
++#define      CARRY              0x01
++
++#define   SINDIR                0x6c
++
++#define   DINDIR                0x6d
++
++#define   FUNCTION1             0x6e
++
++#define   STACK                 0x6f
++
++#define   TARG_OFFSET           0x70
++
++#define   BCTL                  0x84
++#define      ACE                0x08
++#define      ENABLE             0x01
++
++#define   DSCOMMAND0            0x84
++#define      INTSCBRAMSEL       0x08
++#define      RAMPS              0x04
++#define      USCBSIZE32         0x02
++#define      CIOPARCKEN         0x01
++
++#define   DSCOMMAND             0x84
++#define      CACHETHEN          0x80
++#define      DPARCKEN           0x40
++#define      MPARCKEN           0x20
++#define      EXTREQLCK          0x10
++
++#define   BUSTIME               0x85
++#define      BOFF               0xf0
++#define      BON                0x0f
++
++#define   BUSSPD                0x86
++#define      DFTHRSH            0xc0
++#define      STBOFF             0x38
++#define      STBON              0x07
++
++#define   DSPCISTATUS           0x86
++#define      DFTHRSH_100        0xc0
++
++#define   HCNTRL                0x87
++#define      POWRDN             0x40
++#define      SWINT              0x10
++#define      IRQMS              0x08
++#define      PAUSE              0x04
++#define      INTEN              0x02
++#define      CHIPRST            0x01
++#define      CHIPRSTACK         0x01
++
++#define   HADDR                 0x88
++
++#define   HCNT                  0x8c
++
++#define   SCBPTR                0x90
++
++#define   INTSTAT               0x91
++#define      SEQINT_MASK        0xf1
++#define      DATA_OVERRUN       0xe1
++#define      MSGIN_PHASEMIS     0xd1
++#define      TRACEPOINT2        0xc1
++#define      SEQ_SG_FIXUP       0xb1
++#define      AWAITING_MSG       0xa1
++#define      RESIDUAL           0x81
++#define      BAD_STATUS         0x71
++#define      REJECT_MSG         0x61
++#define      WIDE_RESIDUE       0x51
++#define      EXTENDED_MSG       0x41
++#define      NO_MATCH           0x31
++#define      NO_IDENT           0x21
++#define      SEND_REJECT        0x11
++#define      INT_PEND           0x0f
++#define      BRKADRINT          0x08
++#define      SCSIINT            0x04
++#define      CMDCMPLT           0x02
++#define      BAD_PHASE          0x01
++#define      SEQINT             0x01
++
++#define   CLRINT                0x92
++#define      CLRPARERR          0x10
++#define      CLRBRKADRINT       0x08
++#define      CLRSCSIINT         0x04
++#define      CLRCMDINT          0x02
++#define      CLRSEQINT          0x01
++
++#define   ERROR                 0x92
++#define      CIOPARERR          0x80
++#define      PCIERRSTAT         0x40
++#define      MPARERR            0x20
++#define      DPARERR            0x10
++#define      SQPARERR           0x08
++#define      ILLOPCODE          0x04
++#define      DSCTMOUT           0x02
++#define      ILLSADDR           0x02
++#define      ILLHADDR           0x01
++
++#define   DFCNTRL               0x93
++
++#define   DFSTATUS              0x94
++#define      PRELOAD_AVAIL      0x80
++#define      DWORDEMP           0x20
++#define      MREQPEND           0x10
++#define      HDONE              0x08
++#define      DFTHRESH           0x04
++#define      FIFOFULL           0x02
++#define      FIFOEMP            0x01
++
++#define   DFDAT                 0x99
++
++#define   SCBCNT                0x9a
++#define      SCBAUTO            0x80
++#define      SCBCNT_MASK        0x1f
++
++#define   QINFIFO               0x9b
++
++#define   QINCNT                0x9c
++
++#define   SCSIDATL_IMG          0x9c
++
++#define   QOUTFIFO              0x9d
++
++#define   CRCCONTROL1           0x9d
++#define      CRCONSEEN          0x80
++#define      CRCVALCHKEN        0x40
++#define      CRCENDCHKEN        0x20
++#define      CRCREQCHKEN        0x10
++#define      TARGCRCENDEN       0x08
++#define      TARGCRCCNTEN       0x04
++
++#define   SCSIPHASE             0x9e
++#define      SP_STATUS          0x20
++#define      SP_COMMAND         0x10
++#define      SP_MSG_IN          0x08
++#define      SP_MSG_OUT         0x04
++#define      SP_DATA_IN         0x02
++#define      SP_DATA_OUT        0x01
++
++#define   QOUTCNT               0x9e
++
++#define   SFUNCT                0x9f
++#define      ALT_MODE           0x80
++
++#define   SCB_CONTROL           0xa0
++#define      MK_MESSAGE         0x80
++#define      DISCENB            0x40
++#define      TAG_ENB            0x20
++#define      DISCONNECTED       0x04
++#define      SCB_TAG_TYPE       0x03
++
++#define   SCB_BASE              0xa0
++
++#define   SCB_TCL               0xa1
++#define      TID                0xf0
++#define      SELBUSB            0x08
++#define      LID                0x07
++
++#define   SCB_TARGET_STATUS      0xa2
++
++#define   SCB_SGCOUNT           0xa3
++
++#define   SCB_SGPTR             0xa4
++
++#define   SCB_RESID_SGCNT       0xa8
++
++#define   SCB_RESID_DCNT        0xa9
++
++#define   SCB_DATAPTR           0xac
++
++#define   SCB_DATACNT           0xb0
++
++#define   SCB_CMDPTR            0xb4
++
++#define   SCB_CMDLEN            0xb8
++
++#define   SCB_TAG               0xb9
++
++#define   SCB_NEXT              0xba
++
++#define   SCB_PREV              0xbb
++
++#define   SCB_BUSYTARGETS       0xbc
++
++#define   SEECTL_2840           0xc0
++#define      CS_2840            0x04
++#define      CK_2840            0x02
++#define      DO_2840            0x01
++
++#define   STATUS_2840           0xc1
++#define      EEPROM_TF          0x80
++#define      BIOS_SEL           0x60
++#define      ADSEL              0x1e
++#define      DI_2840            0x01
++
++#define   CCHADDR               0xe0
++
++#define   CCHCNT                0xe8
++
++#define   CCSGRAM               0xe9
++
++#define   CCSGADDR              0xea
++
++#define   CCSGCTL               0xeb
++#define      CCSGDONE           0x80
++#define      CCSGEN             0x08
++#define      FLAG               0x02
++#define      CCSGRESET          0x01
++
++#define   CCSCBRAM              0xec
++
++#define   CCSCBADDR             0xed
++
++#define   CCSCBCTL              0xee
++#define      CCSCBDONE          0x80
++#define      ARRDONE            0x40
++#define      CCARREN            0x10
++#define      CCSCBEN            0x08
++#define      CCSCBDIR           0x04
++#define      CCSCBRESET         0x01
++
++#define   CCSCBCNT              0xef
++
++#define   CCSCBPTR              0xf1
++
++#define   HNSCB_QOFF            0xf4
++
++#define   HESCB_QOFF            0xf5
++
++#define   SNSCB_QOFF            0xf6
++
++#define   SESCB_QOFF            0xf7
++
++#define   SDSCB_QOFF            0xf8
++
++#define   QOFF_CTLSTA           0xfa
++#define      ESTABLISH_SCB_AVAIL   0x80
++#define      SCB_AVAIL          0x40
++#define      SNSCB_ROLLOVER     0x20
++#define      SDSCB_ROLLOVER     0x10
++#define      SESCB_ROLLOVER     0x08
++#define      SCB_QSIZE          0x07
++#define      SCB_QSIZE_256      0x06
++
++#define   DFF_THRSH             0xfb
++#define      WR_DFTHRSH         0x70
++#define      WR_DFTHRSH_MAX     0x70
++#define      WR_DFTHRSH_90      0x60
++#define      WR_DFTHRSH_85      0x50
++#define      WR_DFTHRSH_75      0x40
++#define      WR_DFTHRSH_63      0x30
++#define      WR_DFTHRSH_50      0x20
++#define      WR_DFTHRSH_25      0x10
++#define      RD_DFTHRSH_MAX     0x07
++#define      RD_DFTHRSH         0x07
++#define      RD_DFTHRSH_90      0x06
++#define      RD_DFTHRSH_85      0x05
++#define      RD_DFTHRSH_75      0x04
++#define      RD_DFTHRSH_63      0x03
++#define      RD_DFTHRSH_50      0x02
++#define      RD_DFTHRSH_25      0x01
++#define      WR_DFTHRSH_MIN     0x00
++#define      RD_DFTHRSH_MIN     0x00
++
++#define   SG_CACHEPTR           0xfc
++#define      SG_USER_DATA       0xfc
++#define      LAST_SEG           0x02
++#define      LAST_SEG_DONE      0x01
++
++
++#define   CMD_GROUP2_BYTE_DELTA   0xfa
++#define   MAX_OFFSET_8BIT   0x0f
++#define   BUS_16_BIT   0x01
++#define   QINFIFO_OFFSET   0x02
++#define   CMD_GROUP5_BYTE_DELTA   0x0b
++#define   CMD_GROUP_CODE_SHIFT   0x05
++#define   MAX_OFFSET_ULTRA2   0x7f
++#define   MAX_OFFSET_16BIT   0x08
++#define   BUS_8_BIT   0x00
++#define   QOUTFIFO_OFFSET   0x01
++#define   UNTAGGEDSCB_OFFSET   0x00
++#define   CCSGRAM_MAXSEGS   0x10
++#define   SCB_LIST_NULL   0xff
++#define   SG_SIZEOF   0x08
++#define   CMD_GROUP4_BYTE_DELTA   0x04
++#define   CMD_GROUP0_BYTE_DELTA   0xfc
++#define   HOST_MSG   0xff
++#define   BUS_32_BIT   0x02
++#define   CCSGADDR_MAX   0x80
++
++
++/* Downloaded Constant Definitions */
++#define   TMODE_NUMCMDS   0x00
+diff -U 3 -rN linux-2.2.17/drivers/scsi/aic7xxx/aic7xxx_seq.c linux/drivers/scsi/aic7xxx/aic7xxx_seq.c
+--- linux-2.2.17/drivers/scsi/aic7xxx/aic7xxx_seq.c   Wed Dec 31 19:00:00 1969
++++ linux/drivers/scsi/aic7xxx/aic7xxx_seq.c   Tue Feb  6 03:49:36 2001
+@@ -0,0 +1,830 @@
++/*
++  * DO NOT EDIT - This file is automatically generated.
++  */
++static unsigned char seqprog[] = {
++   0xff, 0x6a, 0x06, 0x08,
++   0x7f, 0x02, 0x04, 0x08,
++   0x12, 0x6a, 0x00, 0x00,
++   0xff, 0x6a, 0xd6, 0x09,
++   0xff, 0x6a, 0xdc, 0x09,
++   0x00, 0x65, 0xcc, 0x58,
++   0xf7, 0x01, 0x02, 0x08,
++   0xff, 0x4e, 0xc8, 0x08,
++   0xbf, 0x60, 0xc0, 0x08,
++   0x60, 0x0b, 0x86, 0x68,
++   0x40, 0x00, 0x0c, 0x68,
++   0x08, 0x1f, 0x3e, 0x10,
++   0x60, 0x0b, 0x86, 0x68,
++   0x40, 0x00, 0x0c, 0x68,
++   0x08, 0x1f, 0x3e, 0x10,
++   0xff, 0x3e, 0x48, 0x60,
++   0x40, 0xfa, 0x10, 0x78,
++   0xff, 0xf6, 0xd4, 0x08,
++   0x01, 0x4e, 0x9c, 0x18,
++   0x40, 0x60, 0xc0, 0x00,
++   0x00, 0x4d, 0x10, 0x70,
++   0x01, 0x4e, 0x9c, 0x18,
++   0xbf, 0x60, 0xc0, 0x08,
++   0x00, 0x6a, 0xce, 0x5c,
++   0xff, 0x4e, 0xc8, 0x18,
++   0x02, 0x6a, 0xb8, 0x5b,
++   0xff, 0x52, 0x20, 0x09,
++   0x0d, 0x6a, 0x6a, 0x00,
++   0x00, 0x52, 0x2e, 0x5c,
++   0x03, 0xb0, 0x52, 0x31,
++   0xff, 0xb0, 0x52, 0x09,
++   0xff, 0xb1, 0x54, 0x09,
++   0xff, 0xb2, 0x56, 0x09,
++   0xff, 0xa3, 0x50, 0x09,
++   0xff, 0x3e, 0x74, 0x09,
++   0xff, 0x90, 0x7c, 0x08,
++   0xff, 0x3e, 0x20, 0x09,
++   0x00, 0x65, 0x4e, 0x58,
++   0x00, 0x65, 0x0c, 0x40,
++   0xf7, 0x1f, 0xca, 0x08,
++   0x08, 0xa1, 0xc8, 0x08,
++   0x00, 0x65, 0xca, 0x00,
++   0xff, 0x65, 0x3e, 0x08,
++   0xf0, 0xa1, 0xc8, 0x08,
++   0x0f, 0x0f, 0x1e, 0x08,
++   0x00, 0x0f, 0x1e, 0x00,
++   0xf0, 0xa1, 0xc8, 0x08,
++   0x0f, 0x05, 0x0a, 0x08,
++   0x00, 0x05, 0x0a, 0x00,
++   0xff, 0x6a, 0x0c, 0x08,
++   0x5a, 0x6a, 0x00, 0x04,
++   0x12, 0x65, 0x02, 0x00,
++   0x31, 0x6a, 0xca, 0x00,
++   0x80, 0x37, 0x6e, 0x68,
++   0xff, 0x65, 0xca, 0x18,
++   0xff, 0x37, 0xdc, 0x08,
++   0xff, 0x6e, 0xc8, 0x08,
++   0x00, 0x6c, 0x76, 0x78,
++   0x20, 0x01, 0x02, 0x00,
++   0x4c, 0x37, 0xc8, 0x28,
++   0x08, 0x1f, 0x7e, 0x78,
++   0x08, 0x37, 0x6e, 0x00,
++   0x08, 0x64, 0xc8, 0x00,
++   0x70, 0x64, 0xca, 0x18,
++   0xff, 0x6c, 0x0a, 0x08,
++   0x20, 0x64, 0xca, 0x18,
++   0xff, 0x6c, 0x08, 0x0c,
++   0x40, 0x0b, 0x96, 0x68,
++   0x20, 0x6a, 0x16, 0x00,
++   0xf0, 0x19, 0x6e, 0x08,
++   0x08, 0x6a, 0x18, 0x00,
++   0x08, 0x11, 0x22, 0x00,
++   0x08, 0x6a, 0x66, 0x58,
++   0x08, 0x6a, 0x68, 0x00,
++   0x00, 0x65, 0xaa, 0x40,
++   0x12, 0x6a, 0x00, 0x00,
++   0x40, 0x6a, 0x16, 0x00,
++   0xff, 0x3e, 0x20, 0x09,
++   0xff, 0xba, 0x7c, 0x08,
++   0xff, 0xa1, 0x6e, 0x08,
++   0x08, 0x6a, 0x18, 0x00,
++   0x08, 0x11, 0x22, 0x00,
++   0x08, 0x6a, 0x66, 0x58,
++   0x80, 0x6a, 0x68, 0x00,
++   0x80, 0x36, 0x6c, 0x00,
++   0x00, 0x65, 0x02, 0x5c,
++   0xff, 0x3d, 0xc8, 0x08,
++   0xbf, 0x64, 0xde, 0x78,
++   0xbf, 0x64, 0x88, 0x79,
++   0x80, 0x64, 0x10, 0x72,
++   0xa0, 0x64, 0x40, 0x72,
++   0xc0, 0x64, 0x38, 0x72,
++   0xe0, 0x64, 0x80, 0x72,
++   0x01, 0x6a, 0x22, 0x01,
++   0x00, 0x65, 0xaa, 0x40,
++   0xf7, 0x11, 0x22, 0x08,
++   0x00, 0x65, 0xcc, 0x58,
++   0xff, 0x06, 0xd4, 0x08,
++   0xf7, 0x01, 0x02, 0x08,
++   0x09, 0x0c, 0xc6, 0x78,
++   0x08, 0x0c, 0x0c, 0x68,
++   0x01, 0x6a, 0x22, 0x01,
++   0xff, 0x6a, 0x26, 0x09,
++   0x02, 0x6a, 0x08, 0x30,
++   0xff, 0x6a, 0x08, 0x08,
++   0xdf, 0x01, 0x02, 0x08,
++   0x01, 0x6a, 0x7a, 0x00,
++   0xff, 0x6a, 0x6c, 0x0c,
++   0x04, 0x14, 0x10, 0x31,
++   0x03, 0xa9, 0x18, 0x31,
++   0x00, 0x65, 0xf0, 0x40,
++   0xa8, 0x6a, 0x6a, 0x00,
++   0x40, 0x3d, 0xe4, 0x68,
++   0x04, 0x35, 0x6a, 0x00,
++   0x00, 0x65, 0x72, 0x5b,
++   0x80, 0x6a, 0xd4, 0x01,
++   0x10, 0x36, 0xd8, 0x68,
++   0x10, 0x36, 0x6c, 0x00,
++   0x07, 0xac, 0x10, 0x31,
++   0x05, 0xa3, 0x70, 0x30,
++   0xff, 0x38, 0xf8, 0x68,
++   0x80, 0x02, 0x04, 0x00,
++   0x04, 0x35, 0x6a, 0x08,
++   0x03, 0x69, 0x18, 0x31,
++   0x22, 0x38, 0xc8, 0x28,
++   0x01, 0x38, 0xfe, 0x60,
++   0x02, 0x64, 0xc8, 0x00,
++   0xff, 0x64, 0xf8, 0x09,
++   0xff, 0x35, 0x26, 0x09,
++   0x80, 0x02, 0x76, 0x69,
++   0x10, 0x0c, 0x3a, 0x69,
++   0x80, 0x94, 0x04, 0x79,
++   0x01, 0x38, 0x30, 0x71,
++   0x80, 0xea, 0x22, 0x61,
++   0xef, 0x38, 0xc8, 0x18,
++   0x80, 0x6a, 0xc8, 0x00,
++   0x00, 0x65, 0x14, 0x49,
++   0x33, 0x38, 0xc8, 0x28,
++   0xff, 0x64, 0xd0, 0x09,
++   0x04, 0x39, 0xc0, 0x31,
++   0x09, 0x6a, 0xd6, 0x01,
++   0x80, 0xeb, 0x1a, 0x79,
++   0xf7, 0xeb, 0xd6, 0x09,
++   0x08, 0xeb, 0x1e, 0x69,
++   0x01, 0x6a, 0xd6, 0x01,
++   0x10, 0x0c, 0x3a, 0x69,
++   0xff, 0x38, 0x70, 0x18,
++   0x08, 0xe9, 0x10, 0x31,
++   0xff, 0x6a, 0xc8, 0x08,
++   0x08, 0x39, 0x72, 0x18,
++   0x00, 0x3a, 0x74, 0x20,
++   0x00, 0x65, 0xf0, 0x40,
++   0x10, 0x0c, 0x3a, 0x69,
++   0x01, 0xfc, 0x30, 0x79,
++   0xff, 0x6a, 0x70, 0x08,
++   0x01, 0x0c, 0x36, 0x79,
++   0x10, 0x0c, 0xf0, 0x78,
++   0x00, 0x65, 0x5c, 0x59,
++   0x01, 0xfc, 0x54, 0x69,
++   0x40, 0x0d, 0x44, 0x69,
++   0xb1, 0x6a, 0x22, 0x01,
++   0x00, 0x65, 0x54, 0x41,
++   0x2e, 0xfc, 0xa2, 0x28,
++   0x3f, 0x38, 0xc8, 0x08,
++   0x00, 0x51, 0x54, 0x71,
++   0xff, 0x6a, 0xc8, 0x08,
++   0xf8, 0x39, 0x72, 0x18,
++   0xff, 0x3a, 0x74, 0x20,
++   0x01, 0x38, 0x70, 0x18,
++   0x00, 0x65, 0x46, 0x41,
++   0x03, 0x08, 0x52, 0x31,
++   0xff, 0x38, 0x50, 0x09,
++   0x12, 0x01, 0x02, 0x00,
++   0x00, 0x65, 0xaa, 0x40,
++   0x04, 0x93, 0x70, 0x69,
++   0xdf, 0x93, 0x26, 0x09,
++   0x20, 0x93, 0x60, 0x69,
++   0x02, 0x93, 0x26, 0x01,
++   0x01, 0x94, 0x64, 0x79,
++   0x01, 0x94, 0x64, 0x79,
++   0x01, 0x94, 0x64, 0x79,
++   0x01, 0x94, 0x64, 0x79,
++   0x01, 0x94, 0x64, 0x79,
++   0x10, 0x94, 0x6e, 0x69,
++   0xd7, 0x93, 0x26, 0x09,
++   0x28, 0x93, 0x72, 0x69,
++   0xff, 0x6a, 0xd4, 0x0c,
++   0x10, 0x0c, 0x76, 0x79,
++   0x00, 0x65, 0x5c, 0x59,
++   0x7f, 0x02, 0x04, 0x08,
++   0xe1, 0x6a, 0x22, 0x01,
++   0x00, 0x65, 0xaa, 0x40,
++   0x03, 0xa9, 0x10, 0x30,
++   0x08, 0x6a, 0xcc, 0x00,
++   0xa9, 0x6a, 0x18, 0x5c,
++   0x00, 0x65, 0xa6, 0x41,
++   0x79, 0x6a, 0x6a, 0x00,
++   0x40, 0x3d, 0x8e, 0x69,
++   0x04, 0x35, 0x6a, 0x00,
++   0x00, 0x65, 0x72, 0x5b,
++   0x80, 0x6a, 0xd4, 0x01,
++   0x10, 0x36, 0x80, 0x69,
++   0x10, 0x36, 0x6c, 0x00,
++   0x07, 0xac, 0x10, 0x31,
++   0x03, 0x8c, 0x10, 0x30,
++   0x05, 0xa3, 0x70, 0x30,
++   0x88, 0x6a, 0xcc, 0x00,
++   0xac, 0x6a, 0x10, 0x5c,
++   0x00, 0x65, 0x0a, 0x5c,
++   0x38, 0x6a, 0xcc, 0x00,
++   0xa3, 0x6a, 0x14, 0x5c,
++   0xff, 0x38, 0xb4, 0x69,
++   0x80, 0x02, 0x04, 0x00,
++   0xe7, 0x35, 0x6a, 0x08,
++   0x03, 0x69, 0x10, 0x30,
++   0xff, 0x6a, 0x10, 0x00,
++   0xff, 0x6a, 0x12, 0x00,
++   0xff, 0x6a, 0x14, 0x00,
++   0x01, 0x38, 0xb8, 0x61,
++   0xbf, 0x35, 0x6a, 0x08,
++   0x00, 0x35, 0x52, 0x5b,
++   0x80, 0x02, 0x0a, 0x6a,
++   0xff, 0x65, 0xfa, 0x79,
++   0x01, 0x38, 0xfa, 0x71,
++   0xff, 0x38, 0x70, 0x18,
++   0x80, 0xea, 0xda, 0x61,
++   0xef, 0x38, 0xc8, 0x18,
++   0x80, 0x6a, 0xc8, 0x00,
++   0x00, 0x65, 0xcc, 0x49,
++   0x33, 0x38, 0xc8, 0x28,
++   0xff, 0x64, 0xd0, 0x09,
++   0x04, 0x39, 0xc0, 0x31,
++   0x09, 0x6a, 0xd6, 0x01,
++   0x80, 0xeb, 0xd2, 0x79,
++   0xf7, 0xeb, 0xd6, 0x09,
++   0x08, 0xeb, 0xd6, 0x69,
++   0x01, 0x6a, 0xd6, 0x01,
++   0x08, 0xe9, 0x10, 0x31,
++   0x03, 0x8c, 0x10, 0x30,
++   0x88, 0x6a, 0xcc, 0x00,
++   0x39, 0x6a, 0x16, 0x5c,
++   0x08, 0x6a, 0x18, 0x01,
++   0xff, 0x6a, 0x1a, 0x09,
++   0xff, 0x6a, 0x1c, 0x09,
++   0x0d, 0x93, 0x26, 0x01,
++   0x00, 0x65, 0xc0, 0x5c,
++   0x88, 0x6a, 0xb2, 0x5c,
++   0x00, 0x65, 0x0a, 0x5c,
++   0xff, 0x6a, 0xc8, 0x08,
++   0x08, 0x39, 0x72, 0x18,
++   0x00, 0x3a, 0x74, 0x20,
++   0x01, 0x0c, 0xf6, 0x79,
++   0x10, 0x0c, 0xa6, 0x79,
++   0xff, 0x6a, 0x70, 0x08,
++   0x03, 0x08, 0x52, 0x31,
++   0xff, 0x38, 0x50, 0x09,
++   0xff, 0x08, 0x52, 0x09,
++   0xff, 0x09, 0x54, 0x09,
++   0xff, 0x0a, 0x56, 0x09,
++   0xff, 0x38, 0x50, 0x09,
++   0x00, 0x65, 0xaa, 0x40,
++   0x7f, 0x02, 0x04, 0x08,
++   0xe1, 0x6a, 0x22, 0x01,
++   0x00, 0x65, 0xaa, 0x40,
++   0x00, 0x65, 0x72, 0x5b,
++   0x05, 0xb4, 0x10, 0x31,
++   0x02, 0x6a, 0x1a, 0x31,
++   0x03, 0x8c, 0x10, 0x30,
++   0x88, 0x6a, 0xcc, 0x00,
++   0xb4, 0x6a, 0x14, 0x5c,
++   0xff, 0x6a, 0x1a, 0x09,
++   0xff, 0x6a, 0x1c, 0x09,
++   0x00, 0x65, 0x0a, 0x5c,
++   0x3d, 0x6a, 0x52, 0x5b,
++   0xac, 0x6a, 0x26, 0x01,
++   0x04, 0x0b, 0x26, 0x6a,
++   0x04, 0x0b, 0x2c, 0x6a,
++   0x10, 0x0c, 0x28, 0x7a,
++   0x02, 0x03, 0x30, 0x7a,
++   0x11, 0x0c, 0x2c, 0x7a,
++   0xd7, 0x93, 0x26, 0x09,
++   0x28, 0x93, 0x32, 0x6a,
++   0x12, 0x01, 0x02, 0x00,
++   0x00, 0x65, 0xaa, 0x40,
++   0x00, 0x65, 0x72, 0x5b,
++   0xff, 0x06, 0x44, 0x09,
++   0x00, 0x65, 0xaa, 0x40,
++   0x10, 0x3d, 0x06, 0x00,
++   0xff, 0x34, 0xca, 0x08,
++   0x80, 0x65, 0x64, 0x62,
++   0x0f, 0xa1, 0xca, 0x08,
++   0x07, 0xa1, 0xca, 0x08,
++   0x40, 0xa0, 0xc8, 0x08,
++   0x00, 0x65, 0xca, 0x00,
++   0x80, 0x65, 0xca, 0x00,
++   0x80, 0xa0, 0x54, 0x7a,
++   0xff, 0x65, 0x0c, 0x08,
++   0x00, 0x65, 0x66, 0x42,
++   0x20, 0xa0, 0x6c, 0x7a,
++   0xff, 0x65, 0x0c, 0x08,
++   0x00, 0x65, 0x02, 0x5c,
++   0xa0, 0x3d, 0x74, 0x62,
++   0x23, 0xa0, 0x0c, 0x08,
++   0x00, 0x65, 0x02, 0x5c,
++   0xa0, 0x3d, 0x74, 0x62,
++   0x00, 0xb9, 0x6c, 0x42,
++   0xff, 0x65, 0x6c, 0x62,
++   0xa1, 0x6a, 0x22, 0x01,
++   0xff, 0x6a, 0xd4, 0x08,
++   0x10, 0x51, 0x74, 0x72,
++   0x40, 0x6a, 0x18, 0x00,
++   0xff, 0x65, 0x0c, 0x08,
++   0x00, 0x65, 0x02, 0x5c,
++   0xa0, 0x3d, 0x3e, 0x72,
++   0x40, 0x6a, 0x18, 0x00,
++   0xff, 0x34, 0xa6, 0x08,
++   0x80, 0x34, 0x7c, 0x62,
++   0x7f, 0xa0, 0x40, 0x09,
++   0x08, 0x6a, 0x68, 0x00,
++   0x00, 0x65, 0xaa, 0x40,
++   0x64, 0x6a, 0x48, 0x5b,
++   0x80, 0x64, 0xf2, 0x6a,
++   0x04, 0x64, 0xd4, 0x72,
++   0x02, 0x64, 0xda, 0x72,
++   0x00, 0x6a, 0x9c, 0x72,
++   0x03, 0x64, 0xee, 0x72,
++   0x01, 0x64, 0xd0, 0x72,
++   0x07, 0x64, 0x30, 0x73,
++   0x08, 0x64, 0x98, 0x72,
++   0x23, 0x64, 0x34, 0x73,
++   0x11, 0x6a, 0x22, 0x01,
++   0x07, 0x6a, 0x3a, 0x5b,
++   0xff, 0x06, 0xd4, 0x08,
++   0x00, 0x65, 0xaa, 0x40,
++   0xff, 0xa8, 0xa0, 0x6a,
++   0xff, 0xa2, 0xb8, 0x7a,
++   0x01, 0x6a, 0x6a, 0x00,
++   0x00, 0xb9, 0x2e, 0x5c,
++   0xff, 0xa2, 0xb8, 0x7a,
++   0x71, 0x6a, 0x22, 0x01,
++   0xff, 0x6a, 0xd4, 0x08,
++   0x40, 0x51, 0xb8, 0x62,
++   0x0d, 0x6a, 0x6a, 0x00,
++   0x00, 0xb9, 0x2e, 0x5c,
++   0xff, 0x3e, 0x74, 0x09,
++   0xff, 0x90, 0x7c, 0x08,
++   0x00, 0x65, 0x4e, 0x58,
++   0x00, 0x65, 0xbe, 0x40,
++   0x20, 0xa0, 0xc0, 0x6a,
++   0xff, 0x37, 0xc8, 0x08,
++   0x00, 0x6a, 0xd8, 0x5b,
++   0xff, 0x6a, 0xee, 0x5b,
++   0xff, 0xf8, 0xc8, 0x08,
++   0xff, 0x4f, 0xc8, 0x08,
++   0x01, 0x6a, 0xd8, 0x5b,
++   0x00, 0xb9, 0xee, 0x5b,
++   0x01, 0x4f, 0x9e, 0x18,
++   0x02, 0x6a, 0x22, 0x01,
++   0x00, 0x65, 0xc8, 0x5c,
++   0x00, 0x65, 0xbe, 0x40,
++   0x41, 0x6a, 0x22, 0x01,
++   0x00, 0x65, 0xaa, 0x40,
++   0x04, 0xa0, 0x40, 0x01,
++   0x00, 0x65, 0xe0, 0x5c,
++   0x00, 0x65, 0xbe, 0x40,
++   0x10, 0x36, 0x98, 0x7a,
++   0x05, 0x38, 0x46, 0x31,
++   0x04, 0x14, 0x58, 0x31,
++   0x03, 0xa9, 0x60, 0x31,
++   0xa3, 0x6a, 0xcc, 0x00,
++   0x38, 0x6a, 0x14, 0x5c,
++   0xac, 0x6a, 0xcc, 0x00,
++   0x14, 0x6a, 0x16, 0x5c,
++   0xa9, 0x6a, 0x18, 0x5c,
++   0x00, 0x65, 0x98, 0x42,
++   0xef, 0x36, 0x6c, 0x08,
++   0x00, 0x65, 0x98, 0x42,
++   0x0f, 0x64, 0xc8, 0x08,
++   0x07, 0x64, 0xc8, 0x08,
++   0x00, 0x37, 0x6e, 0x00,
++   0xff, 0x6a, 0xa4, 0x00,
++   0x00, 0x65, 0xa8, 0x5b,
++   0xff, 0x51, 0x04, 0x73,
++   0x20, 0x36, 0x0e, 0x7b,
++   0x00, 0x90, 0x96, 0x5b,
++   0x00, 0x65, 0x10, 0x43,
++   0xff, 0x06, 0xd4, 0x08,
++   0x00, 0x65, 0x02, 0x5c,
++   0xe0, 0x3d, 0x2a, 0x63,
++   0x20, 0x12, 0x2a, 0x63,
++   0x51, 0x6a, 0x3e, 0x5b,
++   0x00, 0x65, 0x90, 0x5b,
++   0xff, 0x37, 0xc8, 0x08,
++   0x00, 0xa1, 0x22, 0x63,
++   0x04, 0xa0, 0x22, 0x7b,
++   0xfb, 0xa0, 0x40, 0x09,
++   0x80, 0x36, 0x6c, 0x00,
++   0x80, 0xa0, 0x98, 0x7a,
++   0x7f, 0xa0, 0x40, 0x09,
++   0xff, 0x6a, 0x3a, 0x5b,
++   0x00, 0x65, 0x98, 0x42,
++   0x04, 0xa0, 0x28, 0x7b,
++   0x00, 0x65, 0xe0, 0x5c,
++   0x00, 0x65, 0x2a, 0x43,
++   0x00, 0x65, 0xc8, 0x5c,
++   0x31, 0x6a, 0x22, 0x01,
++   0x0c, 0x6a, 0x3a, 0x5b,
++   0x00, 0x65, 0x98, 0x42,
++   0x61, 0x6a, 0x22, 0x01,
++   0x00, 0x65, 0x98, 0x42,
++   0x51, 0x6a, 0x3e, 0x5b,
++   0x51, 0x6a, 0x22, 0x01,
++   0x00, 0x65, 0x98, 0x42,
++   0x10, 0x3d, 0x06, 0x00,
++   0xff, 0x65, 0x68, 0x0c,
++   0xff, 0x06, 0xd4, 0x08,
++   0x01, 0x0c, 0x40, 0x7b,
++   0x04, 0x0c, 0x42, 0x6b,
++   0xe0, 0x03, 0x7a, 0x08,
++   0xe0, 0x3d, 0x4e, 0x63,
++   0xff, 0x65, 0xcc, 0x08,
++   0xff, 0x12, 0xda, 0x0c,
++   0xff, 0x06, 0xd4, 0x0c,
++   0xd1, 0x6a, 0x22, 0x01,
++   0x00, 0x65, 0xaa, 0x40,
++   0xff, 0x65, 0x26, 0x09,
++   0x01, 0x0b, 0x62, 0x6b,
++   0x10, 0x0c, 0x54, 0x7b,
++   0x04, 0x0b, 0x5c, 0x6b,
++   0xff, 0x6a, 0xca, 0x08,
++   0x04, 0x93, 0x60, 0x6b,
++   0x01, 0x94, 0x5e, 0x7b,
++   0x10, 0x94, 0x60, 0x6b,
++   0x80, 0x3d, 0x66, 0x73,
++   0x0f, 0x04, 0x6a, 0x6b,
++   0x02, 0x03, 0x6a, 0x7b,
++   0x11, 0x0c, 0x66, 0x7b,
++   0xc7, 0x93, 0x26, 0x09,
++   0xff, 0x99, 0xd4, 0x08,
++   0x38, 0x93, 0x6c, 0x6b,
++   0xff, 0x6a, 0xd4, 0x0c,
++   0x80, 0x36, 0x70, 0x6b,
++   0x21, 0x6a, 0x22, 0x05,
++   0xff, 0x65, 0x20, 0x09,
++   0xff, 0x51, 0x7e, 0x63,
++   0xff, 0x37, 0xc8, 0x08,
++   0xa1, 0x6a, 0x8a, 0x43,
++   0xff, 0x51, 0xc8, 0x08,
++   0xb9, 0x6a, 0x8a, 0x43,
++   0xff, 0x90, 0xa4, 0x08,
++   0xff, 0xba, 0x8e, 0x73,
++   0xff, 0xba, 0x20, 0x09,
++   0xff, 0x65, 0xca, 0x18,
++   0x00, 0x6c, 0x82, 0x63,
++   0xff, 0x90, 0xca, 0x0c,
++   0xff, 0x6a, 0xca, 0x04,
++   0x20, 0x36, 0xa2, 0x7b,
++   0x00, 0x90, 0x76, 0x5b,
++   0xff, 0x65, 0xa2, 0x73,
++   0xff, 0x52, 0xa0, 0x73,
++   0xff, 0xba, 0xcc, 0x08,
++   0xff, 0x52, 0x20, 0x09,
++   0xff, 0x66, 0x74, 0x09,
++   0xff, 0x65, 0x20, 0x0d,
++   0xff, 0xba, 0x7e, 0x0c,
++   0x00, 0x6a, 0xce, 0x5c,
++   0x0d, 0x6a, 0x6a, 0x00,
++   0x00, 0x51, 0x2e, 0x44,
++   0xff, 0x3f, 0xfc, 0x73,
++   0xff, 0x6a, 0xa2, 0x00,
++   0x00, 0x3f, 0x76, 0x5b,
++   0xff, 0x65, 0xfc, 0x73,
++   0x20, 0x36, 0x6c, 0x00,
++   0x20, 0xa0, 0xb6, 0x6b,
++   0xff, 0xb9, 0xa2, 0x0c,
++   0xff, 0x6a, 0xa2, 0x04,
++   0xff, 0x65, 0xa4, 0x08,
++   0xe0, 0x6a, 0xcc, 0x00,
++   0x45, 0x6a, 0x22, 0x5c,
++   0x01, 0x6a, 0xd0, 0x01,
++   0x09, 0x6a, 0xd6, 0x01,
++   0x80, 0xeb, 0xc2, 0x7b,
++   0x01, 0x6a, 0xd6, 0x01,
++   0x01, 0xe9, 0xa4, 0x34,
++   0x88, 0x6a, 0xcc, 0x00,
++   0x45, 0x6a, 0x22, 0x5c,
++   0x01, 0x6a, 0x18, 0x01,
++   0xff, 0x6a, 0x1a, 0x09,
++   0xff, 0x6a, 0x1c, 0x09,
++   0x0d, 0x6a, 0x26, 0x01,
++   0x00, 0x65, 0xc0, 0x5c,
++   0xff, 0x99, 0xa4, 0x0c,
++   0xff, 0x65, 0xa4, 0x08,
++   0xe0, 0x6a, 0xcc, 0x00,
++   0x45, 0x6a, 0x22, 0x5c,
++   0x01, 0x6a, 0xd0, 0x01,
++   0x01, 0x6a, 0xdc, 0x05,
++   0x88, 0x6a, 0xcc, 0x00,
++   0x45, 0x6a, 0x22, 0x5c,
++   0x01, 0x6a, 0x18, 0x01,
++   0xff, 0x6a, 0x1a, 0x09,
++   0xff, 0x6a, 0x1c, 0x09,
++   0x01, 0x6a, 0x26, 0x05,
++   0x01, 0x65, 0xd8, 0x31,
++   0x09, 0xee, 0xdc, 0x01,
++   0x80, 0xee, 0xf2, 0x7b,
++   0xff, 0x6a, 0xdc, 0x0d,
++   0xff, 0x65, 0x32, 0x09,
++   0x0a, 0x93, 0x26, 0x01,
++   0x00, 0x65, 0xc0, 0x44,
++   0xff, 0x37, 0xc8, 0x08,
++   0x00, 0x6a, 0xb8, 0x5b,
++   0xff, 0x52, 0xa2, 0x0c,
++   0x01, 0x0c, 0x02, 0x7c,
++   0x04, 0x0c, 0x02, 0x6c,
++   0xe0, 0x03, 0x06, 0x08,
++   0xe0, 0x03, 0x7a, 0x0c,
++   0xff, 0x8c, 0x10, 0x08,
++   0xff, 0x8d, 0x12, 0x08,
++   0xff, 0x8e, 0x14, 0x0c,
++   0xff, 0x6c, 0xda, 0x08,
++   0xff, 0x6c, 0xda, 0x08,
++   0xff, 0x6c, 0xda, 0x08,
++   0xff, 0x6c, 0xda, 0x08,
++   0xff, 0x6c, 0xda, 0x08,
++   0xff, 0x6c, 0xda, 0x08,
++   0xff, 0x6c, 0xda, 0x0c,
++   0x3d, 0x64, 0xa4, 0x28,
++   0x55, 0x64, 0xc8, 0x28,
++   0x00, 0x6c, 0xda, 0x18,
++   0xff, 0x52, 0xc8, 0x08,
++   0x00, 0x6c, 0xda, 0x20,
++   0xff, 0x6a, 0xc8, 0x08,
++   0x00, 0x6c, 0xda, 0x20,
++   0x00, 0x6c, 0xda, 0x24,
++   0xff, 0x65, 0xc8, 0x08,
++   0xe0, 0x6a, 0xcc, 0x00,
++   0x41, 0x6a, 0x1e, 0x5c,
++   0xff, 0x90, 0xe2, 0x09,
++   0x20, 0x6a, 0xd0, 0x01,
++   0x04, 0x35, 0x40, 0x7c,
++   0x1d, 0x6a, 0xdc, 0x01,
++   0xdc, 0xee, 0x3c, 0x64,
++   0x00, 0x65, 0x56, 0x44,
++   0x01, 0x6a, 0xdc, 0x01,
++   0x20, 0xa0, 0xd8, 0x31,
++   0x09, 0xee, 0xdc, 0x01,
++   0x80, 0xee, 0x46, 0x7c,
++   0x11, 0x6a, 0xdc, 0x01,
++   0x50, 0xee, 0x4a, 0x64,
++   0x20, 0x6a, 0xd0, 0x01,
++   0x09, 0x6a, 0xdc, 0x01,
++   0x88, 0xee, 0x50, 0x64,
++   0x19, 0x6a, 0xdc, 0x01,
++   0xd8, 0xee, 0x54, 0x64,
++   0xff, 0x6a, 0xdc, 0x09,
++   0x18, 0xee, 0x58, 0x6c,
++   0xff, 0x6a, 0xd4, 0x0c,
++   0x88, 0x6a, 0xcc, 0x00,
++   0x41, 0x6a, 0x1e, 0x5c,
++   0x20, 0x6a, 0x18, 0x01,
++   0xff, 0x6a, 0x1a, 0x09,
++   0xff, 0x6a, 0x1c, 0x09,
++   0xff, 0x35, 0x26, 0x09,
++   0x04, 0x35, 0x84, 0x6c,
++   0xa0, 0x6a, 0xca, 0x00,
++   0x20, 0x65, 0xc8, 0x18,
++   0xff, 0x6c, 0x32, 0x09,
++   0xff, 0x6c, 0x32, 0x09,
++   0xff, 0x6c, 0x32, 0x09,
++   0xff, 0x6c, 0x32, 0x09,
++   0xff, 0x6c, 0x32, 0x09,
++   0xff, 0x6c, 0x32, 0x09,
++   0xff, 0x6c, 0x32, 0x09,
++   0xff, 0x6c, 0x32, 0x09,
++   0x00, 0x65, 0x6e, 0x64,
++   0x0a, 0x93, 0x26, 0x01,
++   0x00, 0x65, 0xc0, 0x44,
++   0xa0, 0x6a, 0xcc, 0x00,
++   0xe8, 0x6a, 0xc8, 0x00,
++   0x01, 0x94, 0x88, 0x6c,
++   0x10, 0x94, 0x8a, 0x6c,
++   0x08, 0x94, 0x9c, 0x6c,
++   0x08, 0x94, 0x9c, 0x6c,
++   0x08, 0x94, 0x9c, 0x6c,
++   0x00, 0x65, 0xb0, 0x5c,
++   0x08, 0x64, 0xc8, 0x18,
++   0x00, 0x8c, 0xca, 0x18,
++   0x00, 0x65, 0x92, 0x4c,
++   0x00, 0x65, 0x88, 0x44,
++   0xf7, 0x93, 0x26, 0x09,
++   0x08, 0x93, 0x9e, 0x6c,
++   0x00, 0x65, 0xb0, 0x5c,
++   0x08, 0x64, 0xc8, 0x18,
++   0x08, 0x64, 0xa0, 0x64,
++   0xff, 0x6a, 0xd4, 0x0c,
++   0x00, 0x65, 0xc0, 0x5c,
++   0x00, 0x65, 0xb0, 0x5c,
++   0x00, 0x65, 0xb0, 0x5c,
++   0x00, 0x65, 0xb0, 0x5c,
++   0xff, 0x99, 0xda, 0x08,
++   0xff, 0x99, 0xda, 0x08,
++   0xff, 0x99, 0xda, 0x08,
++   0xff, 0x99, 0xda, 0x08,
++   0xff, 0x99, 0xda, 0x08,
++   0xff, 0x99, 0xda, 0x08,
++   0xff, 0x99, 0xda, 0x08,
++   0xff, 0x99, 0xda, 0x0c,
++   0x08, 0x94, 0xc0, 0x7c,
++   0xf7, 0x93, 0x26, 0x09,
++   0x08, 0x93, 0xc4, 0x6c,
++   0xff, 0x6a, 0xd4, 0x0c,
++   0xff, 0x40, 0x74, 0x09,
++   0xff, 0x90, 0x80, 0x08,
++   0xff, 0x6a, 0x72, 0x05,
++   0xff, 0x40, 0xdc, 0x64,
++   0xff, 0x3f, 0xd4, 0x64,
++   0xff, 0x6a, 0xca, 0x04,
++   0xff, 0x3f, 0x20, 0x09,
++   0x01, 0x6a, 0x6a, 0x00,
++   0x00, 0xb9, 0x2e, 0x5c,
++   0xff, 0xba, 0x7e, 0x0c,
++   0xff, 0x40, 0x20, 0x09,
++   0xff, 0xba, 0x80, 0x0c,
++   0xff, 0x3f, 0x74, 0x09,
++   0xff, 0x90, 0x7e, 0x0c,
++};
++
++static int aic7xxx_patch14_func(struct aic7xxx_host *p);
++
++static int
++aic7xxx_patch14_func(struct aic7xxx_host *p)
++{
++   return ((p->bugs & AHC_BUG_SCBCHAN_UPLOAD) != 0);
++}
++
++static int aic7xxx_patch13_func(struct aic7xxx_host *p);
++
++static int
++aic7xxx_patch13_func(struct aic7xxx_host *p)
++{
++   return ((p->features & AHC_CMD_CHAN) == 0);
++}
++
++static int aic7xxx_patch12_func(struct aic7xxx_host *p);
++
++static int
++aic7xxx_patch12_func(struct aic7xxx_host *p)
++{
++   return ((p->bugs & AHC_BUG_PCI_2_1_RETRY) != 0);
++}
++
++static int aic7xxx_patch11_func(struct aic7xxx_host *p);
++
++static int
++aic7xxx_patch11_func(struct aic7xxx_host *p)
++{
++   return ((p->features & AHC_WIDE) != 0);
++}
++
++static int aic7xxx_patch10_func(struct aic7xxx_host *p);
++
++static int
++aic7xxx_patch10_func(struct aic7xxx_host *p)
++{
++   return ((p->features & AHC_ULTRA2) == 0);
++}
++
++static int aic7xxx_patch9_func(struct aic7xxx_host *p);
++
++static int
++aic7xxx_patch9_func(struct aic7xxx_host *p)
++{
++   return ((p->bugs & AHC_BUG_AUTOFLUSH) != 0);
++}
++
++static int aic7xxx_patch8_func(struct aic7xxx_host *p);
++
++static int
++aic7xxx_patch8_func(struct aic7xxx_host *p)
++{
++   return ((p->features & AHC_ULTRA) != 0);
++}
++
++static int aic7xxx_patch7_func(struct aic7xxx_host *p);
++
++static int
++aic7xxx_patch7_func(struct aic7xxx_host *p)
++{
++   return ((p->features & AHC_ULTRA2) != 0);
++}
++
++static int aic7xxx_patch6_func(struct aic7xxx_host *p);
++
++static int
++aic7xxx_patch6_func(struct aic7xxx_host *p)
++{
++   return ((p->flags & AHC_PAGESCBS) == 0);
++}
++
++static int aic7xxx_patch5_func(struct aic7xxx_host *p);
++
++static int
++aic7xxx_patch5_func(struct aic7xxx_host *p)
++{
++   return ((p->flags & AHC_PAGESCBS) != 0);
++}
++
++static int aic7xxx_patch4_func(struct aic7xxx_host *p);
++
++static int
++aic7xxx_patch4_func(struct aic7xxx_host *p)
++{
++   return ((p->features & AHC_QUEUE_REGS) != 0);
++}
++
++static int aic7xxx_patch3_func(struct aic7xxx_host *p);
++
++static int
++aic7xxx_patch3_func(struct aic7xxx_host *p)
++{
++   return ((p->features & AHC_TWIN) != 0);
++}
++
++static int aic7xxx_patch2_func(struct aic7xxx_host *p);
++
++static int
++aic7xxx_patch2_func(struct aic7xxx_host *p)
++{
++   return ((p->features & AHC_QUEUE_REGS) == 0);
++}
++
++static int aic7xxx_patch1_func(struct aic7xxx_host *p);
++
++static int
++aic7xxx_patch1_func(struct aic7xxx_host *p)
++{
++   return ((p->features & AHC_CMD_CHAN) != 0);
++}
++
++static int aic7xxx_patch0_func(struct aic7xxx_host *p);
++
++static int
++aic7xxx_patch0_func(struct aic7xxx_host *p)
++{
++   return (0);
++}
++
++struct sequencer_patch {
++   int      (*patch_func)(struct aic7xxx_host *);
++   unsigned int   begin      :10,
++         skip_instr :10,
++         skip_patch :12;
++} sequencer_patches[] = {
++   { aic7xxx_patch1_func, 3, 2, 1 },
++   { aic7xxx_patch2_func, 7, 1, 1 },
++   { aic7xxx_patch2_func, 8, 1, 1 },
++   { aic7xxx_patch3_func, 11, 4, 1 },
++   { aic7xxx_patch4_func, 16, 3, 2 },
++   { aic7xxx_patch0_func, 19, 4, 1 },
++   { aic7xxx_patch5_func, 23, 1, 1 },
++   { aic7xxx_patch6_func, 26, 1, 1 },
++   { aic7xxx_patch1_func, 29, 1, 2 },
++   { aic7xxx_patch0_func, 30, 3, 1 },
++   { aic7xxx_patch3_func, 39, 4, 1 },
++   { aic7xxx_patch7_func, 43, 3, 2 },
++   { aic7xxx_patch0_func, 46, 3, 1 },
++   { aic7xxx_patch8_func, 52, 7, 1 },
++   { aic7xxx_patch3_func, 60, 3, 1 },
++   { aic7xxx_patch7_func, 63, 2, 1 },
++   { aic7xxx_patch7_func, 87, 1, 2 },
++   { aic7xxx_patch0_func, 88, 1, 1 },
++   { aic7xxx_patch7_func, 103, 1, 2 },
++   { aic7xxx_patch0_func, 104, 2, 1 },
++   { aic7xxx_patch7_func, 108, 84, 15 },
++   { aic7xxx_patch9_func, 177, 1, 1 },
++   { aic7xxx_patch9_func, 178, 4, 1 },
++   { aic7xxx_patch0_func, 192, 72, 12 },
++   { aic7xxx_patch1_func, 192, 1, 2 },
++   { aic7xxx_patch0_func, 193, 2, 1 },
++   { aic7xxx_patch1_func, 200, 1, 1 },
++   { aic7xxx_patch1_func, 203, 3, 2 },
++   { aic7xxx_patch0_func, 206, 5, 1 },
++   { aic7xxx_patch1_func, 214, 1, 2 },
++   { aic7xxx_patch0_func, 215, 3, 1 },
++   { aic7xxx_patch1_func, 225, 14, 2 },
++   { aic7xxx_patch0_func, 239, 9, 1 },
++   { aic7xxx_patch1_func, 254, 2, 2 },
++   { aic7xxx_patch0_func, 256, 4, 1 },
++   { aic7xxx_patch1_func, 265, 3, 3 },
++   { aic7xxx_patch10_func, 267, 1, 1 },
++   { aic7xxx_patch0_func, 268, 5, 1 },
++   { aic7xxx_patch10_func, 273, 1, 2 },
++   { aic7xxx_patch0_func, 274, 9, 1 },
++   { aic7xxx_patch11_func, 290, 1, 2 },
++   { aic7xxx_patch0_func, 291, 1, 1 },
++   { aic7xxx_patch4_func, 352, 1, 2 },
++   { aic7xxx_patch0_func, 353, 1, 1 },
++   { aic7xxx_patch2_func, 356, 1, 1 },
++   { aic7xxx_patch1_func, 366, 3, 2 },
++   { aic7xxx_patch0_func, 369, 5, 1 },
++   { aic7xxx_patch11_func, 377, 1, 2 },
++   { aic7xxx_patch0_func, 378, 1, 1 },
++   { aic7xxx_patch5_func, 383, 1, 1 },
++   { aic7xxx_patch10_func, 425, 15, 2 },
++   { aic7xxx_patch12_func, 438, 1, 1 },
++   { aic7xxx_patch1_func, 477, 7, 2 },
++   { aic7xxx_patch0_func, 484, 8, 1 },
++   { aic7xxx_patch1_func, 493, 4, 2 },
++   { aic7xxx_patch0_func, 497, 6, 1 },
++   { aic7xxx_patch1_func, 503, 4, 2 },
++   { aic7xxx_patch0_func, 507, 3, 1 },
++   { aic7xxx_patch13_func, 517, 10, 1 },
++   { aic7xxx_patch1_func, 536, 22, 8 },
++   { aic7xxx_patch10_func, 544, 4, 4 },
++   { aic7xxx_patch0_func, 548, 7, 3 },
++   { aic7xxx_patch14_func, 548, 5, 2 },
++   { aic7xxx_patch0_func, 553, 2, 1 },
++   { aic7xxx_patch0_func, 558, 50, 3 },
++   { aic7xxx_patch12_func, 579, 17, 2 },
++   { aic7xxx_patch0_func, 596, 4, 1 },
++   { aic7xxx_patch13_func, 608, 4, 1 },
++   { aic7xxx_patch5_func, 612, 2, 1 },
++   { aic7xxx_patch5_func, 615, 9, 1 },
++
++};
+diff -U 3 -rN linux-2.2.17/drivers/scsi/aic7xxx.c linux/drivers/scsi/aic7xxx.c
+--- linux-2.2.17/drivers/scsi/aic7xxx.c   Mon Sep  4 13:39:21 2000
++++ linux/drivers/scsi/aic7xxx.c   Tue Feb  6 03:49:37 2001
+@@ -246,11 +246,11 @@
+ #include "sd.h"
+ #include "scsi.h"
+ #include "hosts.h"
+-#include "aic7xxx.h"
++#include "aic7xxx/aic7xxx.h"
+ 
+ #include "aic7xxx/sequencer.h"
+ #include "aic7xxx/scsi_message.h"
+-#include "aic7xxx_reg.h"
++#include "aic7xxx/aic7xxx_reg.h"
+ #include <scsi/scsicam.h>
+ 
+ #include <linux/stat.h>
+@@ -270,7 +270,7 @@
+     0, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL
+ };
+ 
+-#define AIC7XXX_C_VERSION  "5.1.31"
++#define AIC7XXX_C_VERSION  "5.1.32"
+ 
+ #define NUMBER(arr)     (sizeof(arr) / sizeof(arr[0]))
+ #define MIN(a,b)        (((a) < (b)) ? (a) : (b))
+@@ -790,6 +790,7 @@
+ 
+ typedef enum {
+         SCB_FREE                = 0x0000,
++        SCB_DTR_SCB             = 0x0001,
+         SCB_WAITINGQ            = 0x0002,
+         SCB_ACTIVE              = 0x0004,
+         SCB_SENSE               = 0x0008,
+@@ -896,6 +897,17 @@
+   AHC_AIC7899_FE       = AHC_AIC7890_FE|AHC_ULTRA3,
+ } ahc_feature;
+ 
++typedef enum {
++  AHC_BUG_NONE            = 0x0000,
++  AHC_BUG_TMODE_WIDEODD   = 0x0001,
++  AHC_BUG_AUTOFLUSH       = 0x0002,
++  AHC_BUG_CACHETHEN       = 0x0004,
++  AHC_BUG_CACHETHEN_DIS   = 0x0008,
++  AHC_BUG_PCI_2_1_RETRY   = 0x0010,
++  AHC_BUG_PCI_MWI         = 0x0020,
++  AHC_BUG_SCBCHAN_UPLOAD  = 0x0040,
++} ahc_bugs;
++
+ struct aic7xxx_scb {
+         struct aic7xxx_hwscb  *hscb;          /* corresponding hardware scb */
+         Scsi_Cmnd             *cmd;              /* Scsi_Cmnd for this scb */
+@@ -1004,7 +1016,6 @@
+   unsigned long            isr_count;        /* Interrupt count */
+   unsigned long            spurious_int;
+   scb_data_type           *scb_data;
+-  volatile unsigned short  needdv;
+   volatile unsigned short  needppr;
+   volatile unsigned short  needsdtr;
+   volatile unsigned short  needwdtr;
+@@ -1032,10 +1043,9 @@
+ #define  BUS_DEVICE_RESET_PENDING       0x02
+ #define  DEVICE_RESET_DELAY             0x04
+ #define  DEVICE_PRINT_DTR               0x08
+-#define  DEVICE_PARITY_ERROR            0x10
+-#define  DEVICE_WAS_BUSY                0x20
+-#define  DEVICE_SCSI_3                  0x40
+-#define  DEVICE_SCANNED                 0x80
++#define  DEVICE_WAS_BUSY                0x10
++#define  DEVICE_SCSI_3                  0x20
++#define  DEVICE_DTR_SCANNED             0x40
+   volatile unsigned char   dev_flags[MAX_TARGETS];
+   volatile unsigned char   dev_active_cmds[MAX_TARGETS];
+   volatile unsigned char   dev_temp_queue_depth[MAX_TARGETS];
+@@ -1051,10 +1061,6 @@
+ #endif
+ 
+ 
+-  Scsi_Cmnd               *dev_dtr_cmnd[MAX_TARGETS];
+-
+-  unsigned int             dev_checksum[MAX_TARGETS];
+-  
+   unsigned char            dev_last_queue_full[MAX_TARGETS];
+   unsigned char            dev_last_queue_full_count[MAX_TARGETS];
+   unsigned char            dev_max_queue_depth[MAX_TARGETS];
+@@ -1111,6 +1117,7 @@
+   int                      host_no;          /* SCSI host number */
+   unsigned long            mbase;            /* I/O memory address */
+   ahc_chip                 chip;             /* chip type */
++  ahc_bugs                 bugs;             /* hardware bugs this chip has */
+ 
+   /*
+    * Statistics Kept:
+@@ -1712,7 +1719,7 @@
+  * prototype, our code has to be ordered that way, it's a left-over from
+  * the original driver days.....I should fix it some time DL).
+  */
+-#include "aic7xxx_seq.c"
++#include "aic7xxx/aic7xxx_seq.c"
+ 
+ /*+F*************************************************************************
+  * Function:
+@@ -2876,138 +2883,98 @@
+   {
+     p->flags &= ~AHC_ABORT_PENDING;
+   }
+-  if (scb->flags & SCB_RESET)
++  if (scb->flags & (SCB_RESET|SCB_ABORT))
+   {
+-      cmd->result = (DID_RESET << 16) | (cmd->result & 0xffff);
++    cmd->result |= (DID_RESET << 16);
+   }
+-  else if (scb->flags & SCB_ABORT)
+-  {
+-      cmd->result = (DID_RESET << 16) | (cmd->result & 0xffff);
+-  }
+-  else if (!(p->dev_flags[tindex] & DEVICE_SCANNED))
++
++  if (!(p->dev_flags[tindex] & DEVICE_PRESENT))
+   {
+     if ( (cmd->cmnd[0] == INQUIRY) && (cmd->result == DID_OK) )
+     {
+-      char *buffer;
+-      
++    
+       p->dev_flags[tindex] |= DEVICE_PRESENT;
+-      if(cmd->use_sg)
+-      {
+-        struct scatterlist *sg;
+-
+-        sg = (struct scatterlist *)cmd->request_buffer;
+-        buffer = (char *)sg[0].address;
+-      }
+-      else
+-      {
+-        buffer = (char *)cmd->request_buffer;
+-      }
+ #define WIDE_INQUIRY_BITS 0x60
+ #define SYNC_INQUIRY_BITS 0x10
+ #define SCSI_VERSION_BITS 0x07
+ #define SCSI_DT_BIT       0x04
+-      if ( (buffer[7] & WIDE_INQUIRY_BITS) &&
+-           (p->features & AHC_WIDE) )
+-      {
+-        p->needwdtr |= (1<<tindex);
+-        p->needwdtr_copy |= (1<<tindex);
+-        p->transinfo[tindex].goal_width = p->transinfo[tindex].user_width;
+-      }
+-      else
+-      {
+-        p->needwdtr &= ~(1<<tindex);
+-        p->needwdtr_copy &= ~(1<<tindex);
+-        pause_sequencer(p);
+-        aic7xxx_set_width(p, cmd->target, cmd->channel, cmd->lun,
+-                          MSG_EXT_WDTR_BUS_8_BIT, (AHC_TRANS_ACTIVE |
+-                                                   AHC_TRANS_GOAL |
+-                                                   AHC_TRANS_CUR) );
+-        unpause_sequencer(p, FALSE);
+-      }
+-      if ( (buffer[7] & SYNC_INQUIRY_BITS) &&
+-            p->transinfo[tindex].user_offset )
+-      {
+-        p->transinfo[tindex].goal_period = p->transinfo[tindex].user_period;
+-        p->transinfo[tindex].goal_options = p->transinfo[tindex].user_options;
+-        if (p->features & AHC_ULTRA2)
+-          p->transinfo[tindex].goal_offset = MAX_OFFSET_ULTRA2;
+-        else if (p->transinfo[tindex].goal_width == MSG_EXT_WDTR_BUS_16_BIT)
+-          p->transinfo[tindex].goal_offset = MAX_OFFSET_16BIT;
++      if(!(p->dev_flags[tindex] & DEVICE_DTR_SCANNED)) {
++        char *buffer;
++
++        if(cmd->use_sg)
++        {
++          struct scatterlist *sg;
++
++          sg = (struct scatterlist *)cmd->request_buffer;
++          buffer = (char *)sg[0].address;
++        }
++        else
++        {
++          buffer = (char *)cmd->request_buffer;
++        }
++
++
++        if ( (buffer[7] & WIDE_INQUIRY_BITS) &&
++             (p->features & AHC_WIDE) )
++        {
++          p->needwdtr |= (1<<tindex);
++          p->needwdtr_copy |= (1<<tindex);
++          p->transinfo[tindex].goal_width = p->transinfo[tindex].user_width;
++        }
+         else
+-          p->transinfo[tindex].goal_offset = MAX_OFFSET_8BIT;
+-        if ( (((buffer[2] & SCSI_VERSION_BITS) == 3) ||
+-               (buffer[56] & SCSI_DT_BIT) ||
+-          (p->dev_flags[tindex] & DEVICE_SCSI_3) ) &&
+-               (p->transinfo[tindex].user_period <= 9) &&
+-               (p->transinfo[tindex].user_options) )
+         {
+-          p->needppr |= (1<<tindex);
+-          p->needppr_copy |= (1<<tindex);
+-          p->needsdtr &= ~(1<<tindex);
+-          p->needsdtr_copy &= ~(1<<tindex);
+           p->needwdtr &= ~(1<<tindex);
+           p->needwdtr_copy &= ~(1<<tindex);
+-          p->dev_flags[tindex] |= DEVICE_SCSI_3;
++          pause_sequencer(p);
++          aic7xxx_set_width(p, cmd->target, cmd->channel, cmd->lun,
++                            MSG_EXT_WDTR_BUS_8_BIT, (AHC_TRANS_ACTIVE |
++                                                     AHC_TRANS_GOAL |
++                                                     AHC_TRANS_CUR) );
++          unpause_sequencer(p, FALSE);
+         }
+-        else
++        if ( (buffer[7] & SYNC_INQUIRY_BITS) &&
++              p->transinfo[tindex].user_offset )
+         {
+-          p->needsdtr |= (1<<tindex);
+-          p->needsdtr_copy |= (1<<tindex);
+-          p->transinfo[tindex].goal_period = 
+-            MAX(10, p->transinfo[tindex].goal_period);
+-          p->transinfo[tindex].goal_options = 0;
++          p->transinfo[tindex].goal_period = p->transinfo[tindex].user_period;
++          p->transinfo[tindex].goal_options = p->transinfo[tindex].user_options;
++          if (p->features & AHC_ULTRA2)
++            p->transinfo[tindex].goal_offset = MAX_OFFSET_ULTRA2;
++          else if (p->transinfo[tindex].goal_width == MSG_EXT_WDTR_BUS_16_BIT)
++            p->transinfo[tindex].goal_offset = MAX_OFFSET_16BIT;
++          else
++            p->transinfo[tindex].goal_offset = MAX_OFFSET_8BIT;
++          if ( (((buffer[2] & SCSI_VERSION_BITS) >= 3) ||
++                 (buffer[56] & SCSI_DT_BIT) ||
++                 (p->dev_flags[tindex] & DEVICE_SCSI_3) ) &&
++                 (p->transinfo[tindex].user_period <= 9) &&
++                 (p->transinfo[tindex].user_options) )
++          {
++            p->needppr |= (1<<tindex);
++            p->needppr_copy |= (1<<tindex);
++            p->needsdtr &= ~(1<<tindex);
++            p->needsdtr_copy &= ~(1<<tindex);
++            p->needwdtr &= ~(1<<tindex);
++            p->needwdtr_copy &= ~(1<<tindex);
++            p->dev_flags[tindex] |= DEVICE_SCSI_3;
++          }
++          else
++          {
++            p->needsdtr |= (1<<tindex);
++            p->needsdtr_copy |= (1<<tindex);
++            p->transinfo[tindex].goal_period = 
++              MAX(10, p->transinfo[tindex].goal_period);
++            p->transinfo[tindex].goal_options = 0;
++          }
+         }
+-      }
+-      else
+-      {
+-        p->needsdtr &= ~(1<<tindex);
+-        p->needsdtr_copy &= ~(1<<tindex);
+-        p->transinfo[tindex].goal_period = 255;
+-        p->transinfo[tindex].goal_offset = 0;
+-        p->transinfo[tindex].goal_options = 0;
+-      }
+-      /*
+-       * This is needed to work around a sequencer bug for now.  Regardless
+-       * of the controller in use, if we have a Quantum drive, we need to
+-       * limit the speed to 80MByte/sec.  As soon as I get a fixed version
+-       * of the sequencer, this code will get yanked.
+-       */
+-      if(!strncmp(buffer + 8, "QUANTUM", 7) &&
+-         p->transinfo[tindex].goal_options )
+-      {
+-        p->transinfo[tindex].goal_period = 
+-          MAX(p->transinfo[tindex].goal_period, 10);
+-        p->transinfo[tindex].goal_options = 0;
+-        p->needppr &= ~(1<<tindex);
+-        p->needppr_copy &= ~(1<<tindex);
+-        p->needsdtr |= (1<<tindex);
+-        p->needsdtr_copy |= (1<<tindex);
+-        p->needwdtr |= (1<<tindex);
+-        p->needwdtr_copy |= (1<<tindex);
+-      }
+-      /*
+-       * Get the INQUIRY checksum.  We use this on Ultra 160/m
+-       * and older devices both.  It allows us to drop speed on any bus type
+-       * while at the same time giving us the needed domain validation for
+-       * Ultra 160/m
+-       *
+-       * Note: We only get the checksum and set the SCANNED bit if this is
+-       * one of our dtr commands.  If we don't do this, then we end up
+-       * getting bad checksum results on the mid-level SCSI code's INQUIRY
+-       * commands.
+-       */
+-      if(p->dev_dtr_cmnd[tindex] == cmd) {
+-        unsigned int checksum = 0;
+-        int *ibuffer;
+-        int i=0;
+-
+-        ibuffer = (int *)buffer;
+-        for( i = 0; i < (cmd->request_bufflen >> 2); i++)
++        else
+         {
+-          checksum += ibuffer[i];
++          p->needsdtr &= ~(1<<tindex);
++          p->needsdtr_copy &= ~(1<<tindex);
++          p->transinfo[tindex].goal_period = 255;
++          p->transinfo[tindex].goal_offset = 0;
++          p->transinfo[tindex].goal_options = 0;
+         }
+-        p->dev_checksum[tindex] = checksum;
+-        p->dev_flags[tindex] |= DEVICE_SCANNED;
++        p->dev_flags[tindex] |= DEVICE_DTR_SCANNED;
+         p->dev_flags[tindex] |= DEVICE_PRINT_DTR;
+       }
+ #undef WIDE_INQUIRY_BITS
+@@ -3016,7 +2983,8 @@
+ #undef SCSI_DT_BIT
+     }
+   }
+-  else if ((scb->flags & SCB_MSGOUT_BITS) != 0)
++
++  if ((scb->flags & SCB_MSGOUT_BITS) != 0)
+   {
+     unsigned short mask;
+     int message_error = FALSE;
+@@ -3036,7 +3004,6 @@
+ 
+     if (scb->flags & SCB_MSGOUT_WDTR)
+     {
+-      p->dtr_pending &= ~mask;
+       if (message_error)
+       {
+         if ( (aic7xxx_verbose & VERBOSE_NEGOTIATION2) &&
+@@ -3055,7 +3022,6 @@
+     }
+     if (scb->flags & SCB_MSGOUT_SDTR)
+     {
+-      p->dtr_pending &= ~mask;
+       if (message_error)
+       {
+         if ( (aic7xxx_verbose & VERBOSE_NEGOTIATION2) &&
+@@ -3075,7 +3041,6 @@
+     }
+     if (scb->flags & SCB_MSGOUT_PPR)
+     {
+-      p->dtr_pending &= ~mask;
+       if(message_error)
+       {
+         if ( (aic7xxx_verbose & VERBOSE_NEGOTIATION2) &&
+@@ -3100,6 +3065,7 @@
+       }
+     }
+   }
++
+   queue_depth = p->dev_temp_queue_depth[tindex];
+   if (queue_depth >= p->dev_active_cmds[tindex])
+   {
+@@ -3133,9 +3099,18 @@
+       }
+     }
+   }
+-  if ( !(scb->tag_action) && (p->tagenable & (1<<tindex)) )
++  if (!(scb->tag_action))
++  {
++    aic7xxx_index_busy_target(p, scb->hscb->target_channel_lun,
++                              /* unbusy */ TRUE);
++    if (p->tagenable & (1<<tindex))
++    {
++      p->dev_temp_queue_depth[tindex] = p->dev_max_queue_depth[tindex];
++    }
++  }
++  if(scb->flags & SCB_DTR_SCB)
+   {
+-    p->dev_temp_queue_depth[tindex] = p->dev_max_queue_depth[tindex];
++    p->dtr_pending &= ~(1 << tindex);
+   }
+   p->dev_active_cmds[tindex]--;
+   p->activescbs--;
+@@ -3244,6 +3219,14 @@
+         printk(INFO_LEAD "Aborting scb %d\n",
+              p->host_no, CTL_OF_SCB(scb), scb->hscb->tag);
+       found++;
++      /*
++       * Clear any residual information since the normal aic7xxx_done() path
++       * doesn't touch the residuals.
++       */
++      scb->hscb->residual_SG_segment_count = 0;
++      scb->hscb->residual_data_count[0] = 0;
++      scb->hscb->residual_data_count[1] = 0;
++      scb->hscb->residual_data_count[2] = 0;
+       aic7xxx_done(p, scb);
+     }
+   }
+@@ -3456,8 +3439,22 @@
+   active_scb = aic_inb(p, SCBPTR);
+ 
+   if (aic7xxx_verbose & (VERBOSE_RESET_PROCESS | VERBOSE_ABORT_PROCESS))
++  {
+     printk(INFO_LEAD "Reset device, active_scb %d\n",
+          p->host_no, channel, target, lun, active_scb);
++    printk(INFO_LEAD "Current scb_tag %d, SEQADDR 0x%x, LASTPHASE "
++           "0x%x\n",
++         p->host_no, channel, target, lun, aic_inb(p, SCB_TAG),
++         aic_inb(p, SEQADDR0) | (aic_inb(p, SEQADDR1) << 8),
++         aic_inb(p, LASTPHASE));
++    printk(INFO_LEAD "SG_CACHEPTR 0x%x, SG_COUNT %d, SCSISIGI 0x%x\n",
++         p->host_no, channel, target, lun,
++         (p->features & AHC_ULTRA2) ?  aic_inb(p, SG_CACHEPTR) : 0,
++         aic_inb(p, SG_COUNT), aic_inb(p, SCSISIGI));
++    printk(INFO_LEAD "SSTAT0 0x%x, SSTAT1 0x%x, SSTAT2 0x%x\n",
++         p->host_no, channel, target, lun, aic_inb(p, SSTAT0),
++         aic_inb(p, SSTAT1), aic_inb(p, SSTAT2));
++  }
+   /*
+    * Deal with the busy target and linked next issues.
+    */
+@@ -3501,11 +3498,11 @@
+       if (aic7xxx_verbose & (VERBOSE_ABORT_PROCESS | VERBOSE_RESET_PROCESS))
+         printk(INFO_LEAD "Cleaning up status information "
+           "and delayed_scbs.\n", p->host_no, channel, i, lun);
+-      p->dev_flags[i] &= ~(BUS_DEVICE_RESET_PENDING | DEVICE_PARITY_ERROR);
++      p->dev_flags[i] &= ~BUS_DEVICE_RESET_PENDING;
+       if ( tag == SCB_LIST_NULL )
+       {
+         p->dev_flags[i] |= DEVICE_PRINT_DTR | DEVICE_RESET_DELAY;
+-        p->dev_expires[i] = jiffies + (4 * HZ);
++        p->dev_expires[i] = jiffies + (1 * HZ);
+         p->dev_timer_active |= (0x01 << i);
+         p->dev_last_queue_full_count[i] = 0;
+         p->dev_last_queue_full[i] = 0;
+@@ -3550,7 +3547,7 @@
+           prev_scbp->flags |= SCB_RESET | SCB_QUEUED_FOR_DONE;
+         }
+       }
+-      if ( j > (p->scb_data->maxscbs + 1) )
++      if ( j > (p->scb_data->numscbs + 1) )
+       {
+         if (aic7xxx_verbose & (VERBOSE_ABORT | VERBOSE_RESET))
+           printk(WARN_LEAD "Yikes!! There's a loop in the "
+@@ -3611,7 +3608,7 @@
+         prev_scbp->flags |= SCB_RESET | SCB_QUEUED_FOR_DONE;
+       }
+     }
+-    if ( j > (p->scb_data->maxscbs + 1) )
++    if ( j > (p->scb_data->numscbs + 1) )
+     {
+       if (aic7xxx_verbose & (VERBOSE_ABORT | VERBOSE_RESET))
+         printk(WARN_LEAD "Yikes!! There's a loop in the "
+@@ -4375,11 +4372,25 @@
+     if (actual < cmd->underflow)
+     {
+       if (aic7xxx_verbose & VERBOSE_MINOR_ERROR)
++      {
+         printk(INFO_LEAD "Underflow - Wanted %u, %s %u, residual SG "
+           "count %d.\n", p->host_no, CTL_OF_SCB(scb), cmd->underflow,
+           (cmd->request.cmd == WRITE) ? "wrote" : "read", actual,
+           hscb->residual_SG_segment_count);
++        printk(INFO_LEAD "status 0x%x.\n", p->host_no, CTL_OF_SCB(scb),
++          hscb->target_status);
++      }
++      /*
++       * In 2.4, only send back the residual information, don't flag this
++       * as an error.  Before 2.4 we had to flag this as an error because
++       * the mid layer didn't check residual data counts to see if the
++       * command needs retried.
++       */
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
++      cmd->resid = scb->sg_length - actual;
++#else
+       aic7xxx_error(cmd) = DID_RETRY_COMMAND;
++#endif
+       aic7xxx_status(cmd) = hscb->target_status;
+     }
+   }
+@@ -4698,7 +4709,6 @@
+            */
+           p->needwdtr &= ~target_mask;
+           p->needwdtr_copy &= ~target_mask;
+-          p->dtr_pending &= ~target_mask;
+           scb->flags &= ~SCB_MSGOUT_BITS;
+           aic7xxx_set_width(p, target, channel, lun, MSG_EXT_WDTR_BUS_8_BIT,
+             (AHC_TRANS_ACTIVE|AHC_TRANS_GOAL|AHC_TRANS_CUR));
+@@ -4718,8 +4728,7 @@
+           */
+           p->needsdtr &= ~target_mask;
+           p->needsdtr_copy &= ~target_mask;
+-          p->dtr_pending &= ~target_mask;
+-          scb->flags &= ~SCB_MSGOUT_SDTR;
++          scb->flags &= ~SCB_MSGOUT_BITS;
+           aic7xxx_set_syncrate(p, NULL, target, channel, 0, 0, 0,
+             (AHC_TRANS_CUR|AHC_TRANS_ACTIVE|AHC_TRANS_GOAL));
+           if(aic7xxx_verbose & VERBOSE_NEGOTIATION2)
+@@ -4852,6 +4861,8 @@
+                 aic7xxx_error(cmd) = DID_OK;
+                 break;
+               }  /* first time sense, no errors */
++              printk(INFO_LEAD "CHECK_CONDITION on REQUEST_SENSE, returning "
++                     "an error.\n", p->host_no, CTL_OF_SCB(scb));
+               aic7xxx_error(cmd) = DID_ERROR;
+               scb->flags &= ~SCB_SENSE;
+               break;
+@@ -5214,12 +5225,21 @@
+           printk(KERN_WARNING "  %s seen Data Phase. Length=%d, NumSGs=%d.\n",
+             (aic_inb(p, SEQ_FLAGS) & DPHASE) ? "Have" : "Haven't",
+             scb->sg_length, scb->sg_count);
+-          for (i = 0; i < scb->sg_count; i++)
++          printk(KERN_WARNING "  Raw SCSI Command: 0x");
++          for (i = 0; i < scb->hscb->SCSI_cmd_length; i++)
++          {
++            printk("%02x ", scb->cmd->cmnd[i]);
++          }
++          printk("\n");
++          if(aic7xxx_verbose > 0xffff)
+           {
+-            printk(KERN_WARNING "     sg[%d] - Addr 0x%x : Length %d\n",
++            for (i = 0; i < scb->sg_count; i++)
++            {
++              printk(KERN_WARNING "     sg[%d] - Addr 0x%x : Length %d\n",
+                  i, 
+                  le32_to_cpu(scb->sg_list[i].address),
+                  le32_to_cpu(scb->sg_list[i].length) );
++            }
+           }
+           aic7xxx_error(scb->cmd) = DID_ERROR;
+         }
+@@ -5234,7 +5254,7 @@
+         unsigned char resid_sgcnt, index;
+         unsigned char scb_index = aic_inb(p, SCB_TAG);
+         unsigned int cur_addr, resid_dcnt;
+-        unsigned int native_addr, native_length;
++        unsigned int native_addr, native_length, sg_addr;
+         int i;
+ 
+         if(scb_index > p->scb_data->numscbs)
+@@ -5254,6 +5274,9 @@
+                  scb->flags, (unsigned int)scb->cmd);
+           break;
+         }
++        if(aic7xxx_verbose & VERBOSE_MINOR_ERROR)
++          printk(INFO_LEAD "Got WIDE_RESIDUE message, patching up data "
++                 "pointer.\n", p->host_no, CTL_OF_SCB(scb));
+ 
+         /*
+          * We have a valid scb to use on this WIDE_RESIDUE message, so
+@@ -5266,132 +5289,87 @@
+          */
+         cur_addr = aic_inb(p, SHADDR) | (aic_inb(p, SHADDR + 1) << 8) |
+           (aic_inb(p, SHADDR + 2) << 16) | (aic_inb(p, SHADDR + 3) << 24);
++        sg_addr = aic_inb(p, SG_COUNT + 1) | (aic_inb(p, SG_COUNT + 2) << 8) |
++          (aic_inb(p, SG_COUNT + 3) << 16) | (aic_inb(p, SG_COUNT + 4) << 24);
+         resid_sgcnt = aic_inb(p, SCB_RESID_SGCNT);
+         resid_dcnt = aic_inb(p, SCB_RESID_DCNT) |
+           (aic_inb(p, SCB_RESID_DCNT + 1) << 8) |
+           (aic_inb(p, SCB_RESID_DCNT + 2) << 16);
+-        index = scb->sg_count - (resid_sgcnt + 1);
++        index = scb->sg_count - ((resid_sgcnt) ? resid_sgcnt : 1);
+         native_addr = le32_to_cpu(scb->sg_list[index].address);
+         native_length = le32_to_cpu(scb->sg_list[index].length);
+         /*
+-         * Make sure this is a valid sg_seg for the given pointer
++         * If resid_dcnt == native_length, then we just loaded this SG
++         * segment and we need to back it up one...
+          */
+-        if(cur_addr < native_addr ||
+-           cur_addr > (native_addr + native_length + 1))
+-        {
+-          printk(WARN_LEAD "invalid cur_addr:0x%x during WIDE_RESIDUE\n",
+-                 p->host_no, CTL_OF_SCB(scb), cur_addr);
+-          if(index > 0)
+-            printk(WARN_LEAD "  sg_address[-1]:0x%x sg_length[-1]:%d\n",
+-                   p->host_no, CTL_OF_SCB(scb),
+-                   le32_to_cpu(scb->sg_list[index - 1].address),
+-                   le32_to_cpu(scb->sg_list[index - 1].length));
+-          printk(WARN_LEAD "  sg_address:0x%x sg_length:%d\n",
+-                 p->host_no, CTL_OF_SCB(scb),
+-                 native_addr, native_length);
+-          if(resid_sgcnt > 1)
+-            printk(WARN_LEAD "  sg_address[1]:0x%x sg_length[1]:%d\n",
+-                   p->host_no, CTL_OF_SCB(scb),
+-                   le32_to_cpu(scb->sg_list[index + 1].address),
+-                   le32_to_cpu(scb->sg_list[index + 1].length));
+-          printk(WARN_LEAD "  cur_address:0x%x resid_dcnt:0x%06x\n",
+-                 p->host_no, CTL_OF_SCB(scb),
+-                 cur_addr, resid_dcnt);
+-          break;
+-        }
+-
+-        if( (resid_sgcnt == 0) &&
+-            ((resid_dcnt == 0) || (resid_dcnt == 0xffffff)))
++        if(resid_dcnt == native_length)
+         {
+-          /*
+-           * We are at the end of the transfer and this is about a byte
+-           * we ignored already (because the sequencer knew this was
+-           * the last segment and set the adapter to ignore any wide
+-           * residue bytes that might come through, which is only done
+-           * on the last scatter gather segment of transfers).
+-           */
+-          break;
+-        }
+-        else if(cur_addr == native_addr)
+-        {
+-          /*
+-           * If our current address matches the sg_seg->address then we
+-           * have to back up the sg array to the previous segment and set
+-           * it up to have only one byte of transfer left to go.
+-           */
+           if(index == 0)
+           {
+-            printk(WARN_LEAD "bogus WIDE_RESIDUE message, no data has been "
+-                   "transferred.\n", p->host_no, CTL_OF_SCB(scb));
++            /*
++             * Oops, this isn't right, we can't back up to before the
++             * beginning.  This must be a bogus message, ignore it.
++             */
+             break;
+           }
+-          resid_sgcnt++;
+-          index--;
+-          cur_addr = le32_to_cpu(scb->sg_list[index].address) + 
+-            le32_to_cpu(scb->sg_list[index].length) - 1;
+-          native_addr = aic_inb(p, SG_NEXT) | (aic_inb(p, SG_NEXT + 1) << 8)
+-            | (aic_inb(p, SG_NEXT + 2) << 16) | (aic_inb(p, SG_NEXT + 3) << 24);
+-          native_addr -= SG_SIZEOF;
+-          aic_outb(p, resid_sgcnt, SG_COUNT);
+-          aic_outb(p, resid_sgcnt, SCB_RESID_SGCNT);
+-          aic_outb(p, native_addr & 0xff, SG_NEXT);
+-          aic_outb(p, (native_addr >> 8) & 0xff, SG_NEXT + 1);
+-          aic_outb(p, (native_addr >> 16) & 0xff, SG_NEXT + 2);
+-          aic_outb(p, (native_addr >> 24) & 0xff, SG_NEXT + 3);
+-          aic_outb(p, 1, SCB_RESID_DCNT); 
+-          aic_outb(p, 0, SCB_RESID_DCNT + 1); 
+-          aic_outb(p, 0, SCB_RESID_DCNT + 2); 
+-          aic_outb(p, 1, HCNT); 
+-          aic_outb(p, 0, HCNT + 1); 
+-          aic_outb(p, 0, HCNT + 2); 
+-          aic_outb(p, cur_addr & 0xff, HADDR);
+-          aic_outb(p, (cur_addr >> 8) & 0xff, HADDR + 1);
+-          aic_outb(p, (cur_addr >> 16) & 0xff, HADDR + 2);
+-          aic_outb(p, (cur_addr >> 24) & 0xff, HADDR + 3);
++          resid_dcnt = 1;
++          resid_sgcnt += 1;
++          native_addr = le32_to_cpu(scb->sg_list[index - 1].address);
++          native_length = le32_to_cpu(scb->sg_list[index - 1].length);
++          cur_addr = native_addr + (native_length - 1);
++          sg_addr -= sizeof(struct hw_scatterlist);
+         }
+         else
+         {
+           /*
+-           * Back the data pointer up by one and add one to the remaining
+-           * byte count.  Then store that in the HCNT and HADDR registers.
++           * resid_dcnt != native_length, so we are in the middle of a SG
++           * element.  Back it up one byte and leave the rest alone.
+            */
+-          cur_addr--;
+-          resid_dcnt++;
+-          aic_outb(p, resid_dcnt & 0xff, SCB_RESID_DCNT); 
+-          aic_outb(p, (resid_dcnt >> 8) & 0xff, SCB_RESID_DCNT + 1); 
+-          aic_outb(p, (resid_dcnt >> 16) & 0xff, SCB_RESID_DCNT + 2); 
+-          aic_outb(p, resid_dcnt & 0xff, HCNT); 
+-          aic_outb(p, (resid_dcnt >> 8) & 0xff, HCNT + 1); 
+-          aic_outb(p, (resid_dcnt >> 16) & 0xff, HCNT + 2); 
+-          aic_outb(p, cur_addr & 0xff, HADDR);
+-          aic_outb(p, (cur_addr >> 8) & 0xff, HADDR + 1);
+-          aic_outb(p, (cur_addr >> 16) & 0xff, HADDR + 2);
+-          aic_outb(p, (cur_addr >> 24) & 0xff, HADDR + 3);
++          resid_dcnt += 1;
++          cur_addr -= 1;
+         }
++        
++        /*
++         * Output the new addres