--- /dev/null
+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 addresses and counts to the right places on the
++ * card.
++ */
++ aic_outb(p, resid_sgcnt, SG_COUNT);
++ aic_outb(p, resid_sgcnt, SCB_RESID_SGCNT);
++ aic_outb(p, sg_addr & 0xff, SG_COUNT + 1);
++ aic_outb(p, (sg_addr >> 8) & 0xff, SG_COUNT + 2);
++ aic_outb(p, (sg_addr >> 16) & 0xff, SG_COUNT + 3);
++ aic_outb(p, (sg_addr >> 24) & 0xff, SG_COUNT + 4);
++ 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);
++
+ /*
+- * The sequencer actually wants to find the new address and byte
+- * count in the SHCNT and SHADDR register sets. These registers
+- * are a shadow of the regular HCNT and HADDR registers. On the
+- * Ultra2 controllers, these registers are read only and the way
+- * we have to set their values is to put the values we want into
+- * the HCNT and HADDR registers and then output PRELOADEN into
+- * the DFCNTRL register which causes the card to latch the current
+- * values in the HADDR and HCNT registers and drop it through to
+- * the shadow registers. On older cards we copy them directly
+- * across by hand.
++ * The sequencer actually wants to find the new address
++ * in the SHADDR register set. On the Ultra2 and later controllers
++ * this register set is readonly. In order to get the right number
++ * into the register, you actually have to enter it in HADDR and then
++ * use the PRELOADEN bit of DFCNTRL to drop it through from the
++ * HADDR register to the SHADDR register. On non-Ultra2 controllers,
++ * we simply write it direct.
+ */
+ if(p->features & AHC_ULTRA2)
+ {
+- aic_outb(p, aic_inb(p, DMAPARAMS), DFCNTRL);
+- i=0;
++ /*
++ * We might as well be accurate and drop both the resid_dcnt and
++ * cur_addr into HCNT and HADDR and have both of them drop
++ * through to the shadow layer together.
++ */
++ 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);
++ aic_outb(p, aic_inb(p, DMAPARAMS) | PRELOADEN, DFCNTRL);
+ udelay(1);
+- while(((aic_inb(p, SSTAT0) & SDONE) != 0) && (i++ < 1000))
+- {
+- udelay(1);
+- }
+ aic_outb(p, aic_inb(p, DMAPARAMS) & ~(SCSIEN|HDMAEN), DFCNTRL);
+ i=0;
+- udelay(1);
+ while(((aic_inb(p, DFCNTRL) & (SCSIEN|HDMAEN)) != 0) && (i++ < 1000))
+ {
+ udelay(1);
+@@ -5399,9 +5377,6 @@
+ }
+ else
+ {
+- aic_outb(p, resid_dcnt & 0xff, STCNT);
+- aic_outb(p, (resid_dcnt >> 8) & 0xff, STCNT + 1);
+- aic_outb(p, (resid_dcnt >> 16) & 0xff, STCNT + 2);
+ aic_outb(p, cur_addr & 0xff, SHADDR);
+ aic_outb(p, (cur_addr >> 8) & 0xff, SHADDR + 1);
+ aic_outb(p, (cur_addr >> 16) & 0xff, SHADDR + 2);
+@@ -5410,15 +5385,82 @@
+ }
+ break;
+
+-
+-#if AIC7XXX_NOT_YET
+- case TRACEPOINT:
++ case SEQ_SG_FIXUP:
++ {
++ unsigned char scb_index, tmp;
++ int sg_addr, sg_length;
++
++ scb_index = aic_inb(p, SCB_TAG);
++
++ if(scb_index > p->scb_data->numscbs)
+ {
+- printk(INFO_LEAD "Tracepoint #1 reached.\n", p->host_no,
+- channel, target, lun);
++ printk(WARN_LEAD "invalid scb_index during SEQ_SG_FIXUP.\n",
++ p->host_no, -1, -1, -1);
++ printk(INFO_LEAD "SCSISIGI 0x%x, SEQADDR 0x%x, SSTAT0 0x%x, SSTAT1 "
++ "0x%x\n", p->host_no, -1, -1, -1,
++ aic_inb(p, SCSISIGI),
++ aic_inb(p, SEQADDR0) | (aic_inb(p, SEQADDR1) << 8),
++ aic_inb(p, SSTAT0), aic_inb(p, SSTAT1));
++ printk(INFO_LEAD "SG_CACHEPTR 0x%x, SSTAT2 0x%x, STCNT 0x%x\n",
++ p->host_no, -1, -1, -1, aic_inb(p, SG_CACHEPTR),
++ aic_inb(p, SSTAT2), aic_inb(p, STCNT + 2) << 16 |
++ aic_inb(p, STCNT + 1) << 8 | aic_inb(p, STCNT));
++ /*
++ * XXX: Add error handling here
++ */
++ break;
+ }
+- break;
++ scb = p->scb_data->scb_array[scb_index];
++ if(!(scb->flags & SCB_ACTIVE) || (scb->cmd == NULL))
++ {
++ printk(WARN_LEAD "invalid scb during SEQ_SG_FIXUP flags:0x%x "
++ "scb->cmd:0x%x\n", p->host_no, CTL_OF_SCB(scb),
++ scb->flags, (unsigned int)scb->cmd);
++ printk(INFO_LEAD "SCSISIGI 0x%x, SEQADDR 0x%x, SSTAT0 0x%x, SSTAT1 "
++ "0x%x\n", p->host_no, CTL_OF_SCB(scb),
++ aic_inb(p, SCSISIGI),
++ aic_inb(p, SEQADDR0) | (aic_inb(p, SEQADDR1) << 8),
++ aic_inb(p, SSTAT0), aic_inb(p, SSTAT1));
++ printk(INFO_LEAD "SG_CACHEPTR 0x%x, SSTAT2 0x%x, STCNT 0x%x\n",
++ p->host_no, CTL_OF_SCB(scb), aic_inb(p, SG_CACHEPTR),
++ aic_inb(p, SSTAT2), aic_inb(p, STCNT + 2) << 16 |
++ aic_inb(p, STCNT + 1) << 8 | aic_inb(p, STCNT));
++ break;
++ }
++ if(aic7xxx_verbose & VERBOSE_MINOR_ERROR)
++ printk(INFO_LEAD "Fixing up SG address for sequencer.\n", p->host_no,
++ CTL_OF_SCB(scb));
++ /*
++ * Advance the SG pointer to the next element in the list
++ */
++ tmp = aic_inb(p, SG_NEXT);
++ tmp += SG_SIZEOF;
++ aic_outb(p, tmp, SG_NEXT);
++ if( tmp < SG_SIZEOF )
++ aic_outb(p, aic_inb(p, SG_NEXT + 1) + 1, SG_NEXT + 1);
++ tmp = aic_inb(p, SG_COUNT) - 1;
++ aic_outb(p, tmp, SG_COUNT);
++ sg_addr = le32_to_cpu(scb->sg_list[scb->sg_count - tmp].address);
++ sg_length = le32_to_cpu(scb->sg_list[scb->sg_count - tmp].length);
++ /*
++ * Now stuff the element we just advanced past down onto the
++ * card so it can be stored in the residual area.
++ */
++ aic_outb(p, sg_addr & 0xff, HADDR);
++ aic_outb(p, (sg_addr >> 8) & 0xff, HADDR + 1);
++ aic_outb(p, (sg_addr >> 16) & 0xff, HADDR + 2);
++ aic_outb(p, (sg_addr >> 24) & 0xff, HADDR + 3);
++ aic_outb(p, sg_length & 0xff, HCNT);
++ aic_outb(p, (sg_length >> 8) & 0xff, HCNT + 1);
++ aic_outb(p, (sg_length >> 16) & 0xff, HCNT + 2);
++ aic_outb(p, (tmp << 2) | ((tmp == 1) ? LAST_SEG : 0), SG_CACHEPTR);
++ aic_outb(p, aic_inb(p, DMAPARAMS), DFCNTRL);
++ while(aic_inb(p, SSTAT0) & SDONE) udelay(1);
++ while(aic_inb(p, DFCNTRL) & (HDMAEN|SCSIEN)) aic_outb(p, 0, DFCNTRL);
++ }
++ break;
+
++#if AIC7XXX_NOT_YET
+ case TRACEPOINT2:
+ {
+ printk(INFO_LEAD "Tracepoint #2 reached.\n", p->host_no,
+@@ -5463,6 +5505,10 @@
+ unsigned char target_scsirate, tindex;
+ unsigned short target_mask;
+ unsigned char target, channel, lun;
++ unsigned char bus_width, new_bus_width;
++ unsigned char trans_options, new_trans_options;
++ unsigned int period, new_period, offset, new_offset, maxsync;
++ struct aic7xxx_syncrate *syncrate;
+
+ target = scb->cmd->target;
+ channel = scb->cmd->channel;
+@@ -5486,6 +5532,35 @@
+ }
+
+ /*
++ * Even if we are an Ultra3 card, don't allow Ultra3 sync rates when
++ * using the SDTR messages. We need the PPR messages to enable the
++ * higher speeds that include things like Dual Edge clocking.
++ */
++ if (p->features & AHC_ULTRA2)
++ {
++ if ( (aic_inb(p, SBLKCTL) & ENAB40) &&
++ !(aic_inb(p, SSTAT2) & EXP_ACTIVE) )
++ {
++ if (p->features & AHC_ULTRA3)
++ maxsync = AHC_SYNCRATE_ULTRA3;
++ else
++ maxsync = AHC_SYNCRATE_ULTRA2;
++ }
++ else
++ {
++ maxsync = AHC_SYNCRATE_ULTRA;
++ }
++ }
++ else if (p->features & AHC_ULTRA)
++ {
++ maxsync = AHC_SYNCRATE_ULTRA;
++ }
++ else
++ {
++ maxsync = AHC_SYNCRATE_FAST;
++ }
++
++ /*
+ * Just accept the length byte outright and perform
+ * more checking once we know the message type.
+ */
+@@ -5496,9 +5571,6 @@
+ {
+ case MSG_EXT_SDTR:
+ {
+- unsigned int period, offset;
+- unsigned char maxsync, saved_offset, options;
+- struct aic7xxx_syncrate *syncrate;
+
+ if (p->msg_buf[1] != MSG_EXT_SDTR_LEN)
+ {
+@@ -5511,35 +5583,18 @@
+ break;
+ }
+
+- period = p->msg_buf[3];
+- saved_offset = offset = p->msg_buf[4];
+- options = 0;
++ period = new_period = p->msg_buf[3];
++ offset = new_offset = p->msg_buf[4];
++ trans_options = new_trans_options = 0;
++ bus_width = new_bus_width = target_scsirate & WIDEXFER;
+
+ /*
+- * Even if we are an Ultra3 card, don't allow Ultra3 sync rates when
+- * using the SDTR messages. We need the PPR messages to enable the
+- * higher speeds that include things like Dual Edge clocking.
++ * If our current max syncrate is in the Ultra3 range, bump it back
++ * down to Ultra2 since we can't negotiate DT transfers using SDTR
+ */
+- if (p->features & AHC_ULTRA2)
+- {
+- if ( (aic_inb(p, SBLKCTL) & ENAB40) &&
+- !(aic_inb(p, SSTAT2) & EXP_ACTIVE) )
+- {
+- maxsync = AHC_SYNCRATE_ULTRA2;
+- }
+- else
+- {
+- maxsync = AHC_SYNCRATE_ULTRA;
+- }
+- }
+- else if (p->features & AHC_ULTRA)
+- {
+- maxsync = AHC_SYNCRATE_ULTRA;
+- }
+- else
+- {
+- maxsync = AHC_SYNCRATE_FAST;
+- }
++ if(maxsync == AHC_SYNCRATE_ULTRA3)
++ maxsync = AHC_SYNCRATE_ULTRA2;
++
+ /*
+ * We might have a device that is starting negotiation with us
+ * before we can start up negotiation with it....be prepared to
+@@ -5549,88 +5604,116 @@
+ if ( (scb->flags & (SCB_MSGOUT_SENT|SCB_MSGOUT_SDTR)) !=
+ (SCB_MSGOUT_SENT|SCB_MSGOUT_SDTR) )
+ {
+- if (!(p->dev_flags[tindex] & DEVICE_SCANNED) &&
+- !(p->needsdtr_copy & target_mask) &&
+- (p->transinfo[tindex].user_offset) )
++ if (!(p->dev_flags[tindex] & DEVICE_DTR_SCANNED))
+ {
+ /*
+- * Not only is the device starting this up, but it also hasn't
+- * been scanned yet, so this would likely be our TUR or our
+- * INQUIRY command at scan time, so we need to use the
+- * settings from the SEEPROM if they existed. Of course, even
+- * if we didn't find a SEEPROM, we stuffed default values into
+- * the user settings anyway, so use those in all cases.
++ * We shouldn't get here unless this is a narrow drive, wide
++ * devices should trigger this same section of code in the WDTR
++ * handler first instead.
+ */
+- p->transinfo[tindex].goal_period =
+- p->transinfo[tindex].user_period;
+- if(p->features & AHC_ULTRA2)
+- {
+- p->transinfo[tindex].goal_offset = MAX_OFFSET_ULTRA2;
+- }
+- else if (p->transinfo[tindex].cur_width)
++ p->transinfo[tindex].goal_width = MSG_EXT_WDTR_BUS_8_BIT;
++ p->transinfo[tindex].goal_options = 0;
++ if(p->transinfo[tindex].user_offset)
+ {
+- p->transinfo[tindex].goal_offset = MAX_OFFSET_16BIT;
++ p->needsdtr_copy |= target_mask;
++ p->transinfo[tindex].goal_period =
++ MAX(10,p->transinfo[tindex].user_period);
++ if(p->features & AHC_ULTRA2)
++ {
++ p->transinfo[tindex].goal_offset = MAX_OFFSET_ULTRA2;
++ }
++ else
++ {
++ p->transinfo[tindex].goal_offset = MAX_OFFSET_8BIT;
++ }
+ }
+ else
+ {
+- p->transinfo[tindex].goal_offset = MAX_OFFSET_8BIT;
++ p->needsdtr_copy &= ~target_mask;
++ p->transinfo[tindex].goal_period = 255;
++ p->transinfo[tindex].goal_offset = 0;
+ }
+- p->needsdtr_copy |= target_mask;
++ p->dev_flags[tindex] |= DEVICE_DTR_SCANNED | DEVICE_PRINT_DTR;
++ }
++ else if ((p->needsdtr_copy & target_mask) == 0)
++ {
++ /*
++ * This is a preemptive message from the target, we've already
++ * scanned this target and set our options for it, and we
++ * don't need a WDTR with this target (for whatever reason),
++ * so reject this incoming WDTR
++ */
++ reject = TRUE;
++ break;
+ }
++
++ /* The device is sending this message first and we have to reply */
++ reply = TRUE;
++
+ if (aic7xxx_verbose & VERBOSE_NEGOTIATION2)
+ {
+ printk(INFO_LEAD "Received pre-emptive SDTR message from "
+ "target.\n", p->host_no, CTL_OF_SCB(scb));
+ }
+- if ( !p->transinfo[tindex].goal_offset )
+- period = 255;
+- if ( p->transinfo[tindex].goal_period > period )
+- period = p->transinfo[tindex].goal_period;
++ /*
++ * Validate the values the device passed to us against our SEEPROM
++ * settings. We don't have to do this if we aren't replying since
++ * the device isn't allowed to send values greater than the ones
++ * we first sent to it.
++ */
++ new_period = MAX(period, p->transinfo[tindex].goal_period);
++ new_offset = MIN(offset, p->transinfo[tindex].goal_offset);
+ }
+-
+- syncrate = aic7xxx_find_syncrate(p, &period, maxsync, &options);
+- aic7xxx_validate_offset(p, syncrate, &offset,
+- target_scsirate & WIDEXFER);
+- aic7xxx_set_syncrate(p, syncrate, target, channel, period,
+- offset, options, AHC_TRANS_ACTIVE|AHC_TRANS_CUR);
++
++ /*
++ * Use our new_period, new_offset, bus_width, and card options
++ * to determine the actual syncrate settings
++ */
++ syncrate = aic7xxx_find_syncrate(p, &new_period, maxsync,
++ &trans_options);
++ aic7xxx_validate_offset(p, syncrate, &new_offset, bus_width);
+
+ /*
+- * Did we drop to async? Or are we sending a reply? If we are,
+- * then we have to make sure that the reply value reflects the proper
+- * settings so we need to set the goal values according to what
+- * we need to send.
++ * Did we drop to async? If so, send a reply regardless of whether
++ * or not we initiated this negotiation.
+ */
+- if ( (offset != saved_offset) ||
+- ((scb->flags & (SCB_MSGOUT_SENT|SCB_MSGOUT_SDTR)) !=
+- (SCB_MSGOUT_SENT|SCB_MSGOUT_SDTR) ) )
++ if ((new_offset == 0) && (new_offset != offset))
+ {
+- aic7xxx_set_syncrate(p, syncrate, target, channel, period, offset,
+- options, AHC_TRANS_GOAL|AHC_TRANS_QUITE);
++ p->needsdtr_copy &= ~target_mask;
++ reply = TRUE;
+ }
+
+ /*
+- * Did we start this, if not, or if we went to low and had to
++ * Did we start this, if not, or if we went too low and had to
+ * go async, then send an SDTR back to the target
+ */
+- p->needsdtr &= ~target_mask;
+- p->dtr_pending &= ~target_mask;
+- if ( ((scb->flags & (SCB_MSGOUT_SENT|SCB_MSGOUT_SDTR)) !=
+- (SCB_MSGOUT_SENT|SCB_MSGOUT_SDTR)) ||
+- (offset != saved_offset) )
++ if(reply)
+ {
+- reply = TRUE;
+- p->dtr_pending |= target_mask;
++ /* when sending a reply, make sure that the goal settings are
++ * updated along with current and active since the code that
++ * will actually build the message for the sequencer uses the
++ * goal settings as its guidelines.
++ */
++ aic7xxx_set_syncrate(p, syncrate, target, channel, new_period,
++ new_offset, trans_options,
++ AHC_TRANS_GOAL|AHC_TRANS_ACTIVE|AHC_TRANS_CUR);
+ scb->flags &= ~SCB_MSGOUT_BITS;
+ scb->flags |= SCB_MSGOUT_SDTR;
+ aic_outb(p, HOST_MSG, MSG_OUT);
+ aic_outb(p, aic_inb(p, SCSISIGO) | ATNO, SCSISIGO);
+ }
++ else
++ {
++ aic7xxx_set_syncrate(p, syncrate, target, channel, new_period,
++ new_offset, trans_options,
++ AHC_TRANS_ACTIVE|AHC_TRANS_CUR);
++ p->needsdtr &= ~target_mask;
++ }
+ done = TRUE;
+ break;
+ }
+ case MSG_EXT_WDTR:
+ {
+- unsigned char bus_width;
+
+ if (p->msg_buf[1] != MSG_EXT_WDTR_LEN)
+ {
+@@ -5643,7 +5726,8 @@
+ break;
+ }
+
+- bus_width = p->msg_buf[3];
++ bus_width = new_bus_width = p->msg_buf[3];
++
+ if ( (scb->flags & (SCB_MSGOUT_SENT|SCB_MSGOUT_WDTR)) ==
+ (SCB_MSGOUT_SENT|SCB_MSGOUT_WDTR) )
+ {
+@@ -5662,7 +5746,7 @@
+ } /* We fall through on purpose */
+ case MSG_EXT_WDTR_BUS_8_BIT:
+ {
+- bus_width = MSG_EXT_WDTR_BUS_8_BIT;
++ p->transinfo[tindex].goal_width = MSG_EXT_WDTR_BUS_8_BIT;
+ p->needwdtr_copy &= ~target_mask;
+ break;
+ }
+@@ -5671,29 +5755,40 @@
+ break;
+ }
+ }
+- p->dtr_pending &= ~target_mask;
+ p->needwdtr &= ~target_mask;
++ aic7xxx_set_width(p, target, channel, lun, new_bus_width,
++ AHC_TRANS_ACTIVE|AHC_TRANS_CUR);
+ }
+ else
+ {
+- if ( !(p->dev_flags[tindex] & DEVICE_SCANNED) )
++ if ( !(p->dev_flags[tindex] & DEVICE_DTR_SCANNED) )
+ {
+ /*
+ * Well, we now know the WDTR and SYNC caps of this device since
+ * it contacted us first, mark it as such and copy the user stuff
+ * over to the goal stuff.
+ */
+- p->transinfo[tindex].goal_period =
+- p->transinfo[tindex].user_period;
++ if( (p->features & AHC_WIDE) && p->transinfo[tindex].user_width )
++ {
++ p->transinfo[tindex].goal_width = MSG_EXT_WDTR_BUS_16_BIT;
++ p->needwdtr_copy |= target_mask;
++ }
++
++ /*
++ * Devices that support DT transfers don't start WDTR requests
++ */
++ p->transinfo[tindex].goal_options = 0;
++
+ if(p->transinfo[tindex].user_offset)
+ {
++ p->needsdtr_copy |= target_mask;
++ p->transinfo[tindex].goal_period =
++ MAX(10,p->transinfo[tindex].user_period);
+ if(p->features & AHC_ULTRA2)
+ {
+ p->transinfo[tindex].goal_offset = MAX_OFFSET_ULTRA2;
+ }
+- else if( p->transinfo[tindex].user_width &&
+- (bus_width == MSG_EXT_WDTR_BUS_16_BIT) &&
+- p->features & AHC_WIDE )
++ else if( p->transinfo[tindex].goal_width )
+ {
+ p->transinfo[tindex].goal_offset = MAX_OFFSET_16BIT;
+ }
+@@ -5701,48 +5796,76 @@
+ {
+ p->transinfo[tindex].goal_offset = MAX_OFFSET_8BIT;
+ }
++ } else {
++ p->needsdtr_copy &= ~target_mask;
++ p->transinfo[tindex].goal_period = 255;
++ p->transinfo[tindex].goal_offset = 0;
+ }
+- p->transinfo[tindex].goal_width =
+- p->transinfo[tindex].user_width;
+- p->needwdtr_copy |= target_mask;
+- p->needsdtr_copy |= target_mask;
++
++ p->dev_flags[tindex] |= DEVICE_DTR_SCANNED | DEVICE_PRINT_DTR;
+ }
+- if (aic7xxx_verbose & VERBOSE_NEGOTIATION2)
++ else if ((p->needwdtr_copy & target_mask) == 0)
+ {
+- printk(INFO_LEAD "Received pre-emptive WDTR message from "
+- "target.\n", p->host_no, CTL_OF_SCB(scb));
+- }
++ /*
++ * This is a preemptive message from the target, we've already
++ * scanned this target and set our options for it, and we
++ * don't need a WDTR with this target (for whatever reason),
++ * so reject this incoming WDTR
++ */
++ reject = TRUE;
++ break;
++ }
++
++ /* The device is sending this message first and we have to reply */
++ reply = TRUE;
++
++ if (aic7xxx_verbose & VERBOSE_NEGOTIATION2)
++ {
++ printk(INFO_LEAD "Received pre-emptive WDTR message from "
++ "target.\n", p->host_no, CTL_OF_SCB(scb));
++ }
+ switch(bus_width)
+ {
+- default:
++ case MSG_EXT_WDTR_BUS_16_BIT:
+ {
+ if ( (p->features & AHC_WIDE) &&
+ (p->transinfo[tindex].goal_width ==
+ MSG_EXT_WDTR_BUS_16_BIT) )
+ {
+- bus_width = MSG_EXT_WDTR_BUS_16_BIT;
++ new_bus_width = MSG_EXT_WDTR_BUS_16_BIT;
+ break;
+ }
+ } /* Fall through if we aren't a wide card */
++ default:
+ case MSG_EXT_WDTR_BUS_8_BIT:
+ {
+ p->needwdtr_copy &= ~target_mask;
+- bus_width = MSG_EXT_WDTR_BUS_8_BIT;
+- aic7xxx_set_width(p, target, channel, lun, bus_width,
+- AHC_TRANS_GOAL|AHC_TRANS_QUITE);
++ new_bus_width = MSG_EXT_WDTR_BUS_8_BIT;
+ break;
+ }
+ }
+- reply = TRUE;
+ scb->flags &= ~SCB_MSGOUT_BITS;
+ scb->flags |= SCB_MSGOUT_WDTR;
+ p->needwdtr &= ~target_mask;
+- p->dtr_pending |= target_mask;
++ if((p->dtr_pending & target_mask) == 0)
++ {
++ /* there is no other command with SCB_DTR_SCB already set that will
++ * trigger the release of the dtr_pending bit. Both set the bit
++ * and set scb->flags |= SCB_DTR_SCB
++ */
++ p->dtr_pending |= target_mask;
++ scb->flags |= SCB_DTR_SCB;
++ }
+ aic_outb(p, HOST_MSG, MSG_OUT);
+ aic_outb(p, aic_inb(p, SCSISIGO) | ATNO, SCSISIGO);
++ /* when sending a reply, make sure that the goal settings are
++ * updated along with current and active since the code that
++ * will actually build the message for the sequencer uses the
++ * goal settings as its guidelines.
++ */
++ aic7xxx_set_width(p, target, channel, lun, new_bus_width,
++ AHC_TRANS_GOAL|AHC_TRANS_ACTIVE|AHC_TRANS_CUR);
+ }
+- aic7xxx_set_width(p, target, channel, lun, bus_width,
+- AHC_TRANS_ACTIVE|AHC_TRANS_CUR);
+
+ /*
+ * By virtue of the SCSI spec, a WDTR message negates any existing
+@@ -5759,10 +5882,6 @@
+ }
+ case MSG_EXT_PPR:
+ {
+- unsigned char bus_width, trans_options, new_trans_options;
+- unsigned int period, offset;
+- unsigned char maxsync, saved_offset;
+- struct aic7xxx_syncrate *syncrate;
+
+ if (p->msg_buf[1] != MSG_EXT_PPR_LEN)
+ {
+@@ -5775,9 +5894,9 @@
+ break;
+ }
+
+- period = p->msg_buf[3];
+- offset = saved_offset = p->msg_buf[5];
+- bus_width = p->msg_buf[6];
++ period = new_period = p->msg_buf[3];
++ offset = new_offset = p->msg_buf[5];
++ bus_width = new_bus_width = p->msg_buf[6];
+ trans_options = new_trans_options = p->msg_buf[7] & 0xf;
+
+ if(aic7xxx_verbose & VERBOSE_NEGOTIATION2)
+@@ -5787,22 +5906,6 @@
+ trans_options);
+ }
+
+- if ( (aic_inb(p, SBLKCTL) & ENAB40) &&
+- !(aic_inb(p, SSTAT2) & EXP_ACTIVE) )
+- {
+- if(p->features & AHC_ULTRA3)
+- {
+- maxsync = AHC_SYNCRATE_ULTRA3;
+- }
+- else
+- {
+- maxsync = AHC_SYNCRATE_ULTRA2;
+- }
+- }
+- else
+- {
+- maxsync = AHC_SYNCRATE_ULTRA;
+- }
+ /*
+ * We might have a device that is starting negotiation with us
+ * before we can start up negotiation with it....be prepared to
+@@ -5811,13 +5914,22 @@
+ */
+ if ( (scb->flags & (SCB_MSGOUT_SENT|SCB_MSGOUT_PPR)) !=
+ (SCB_MSGOUT_SENT|SCB_MSGOUT_PPR) )
+- {
+- reply = TRUE;
+- scb->flags &= ~SCB_MSGOUT_BITS;
+- scb->flags |= SCB_MSGOUT_PPR;
+- p->dev_flags[tindex] |= DEVICE_SCSI_3;
+- if (!(p->dev_flags[tindex] & DEVICE_SCANNED))
+- {
++ {
++ /* Have we scanned the device yet? */
++ if (!(p->dev_flags[tindex] & DEVICE_DTR_SCANNED))
++ {
++ /* The device is electing to use PPR messages, so we will too until
++ * we know better */
++ p->needppr |= target_mask;
++ p->needppr_copy |= target_mask;
++ p->needsdtr &= ~target_mask;
++ p->needsdtr_copy &= ~target_mask;
++ p->needwdtr &= ~target_mask;
++ p->needwdtr_copy &= ~target_mask;
++
++ /* We know the device is SCSI-3 compliant due to PPR */
++ p->dev_flags[tindex] |= DEVICE_SCSI_3;
++
+ /*
+ * Not only is the device starting this up, but it also hasn't
+ * been scanned yet, so this would likely be our TUR or our
+@@ -5826,15 +5938,19 @@
+ * if we didn't find a SEEPROM, we stuffed default values into
+ * the user settings anyway, so use those in all cases.
+ */
+- p->transinfo[tindex].goal_period =
+- p->transinfo[tindex].user_period;
++ p->transinfo[tindex].goal_width =
++ p->transinfo[tindex].user_width;
+ if(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].user_width &&
++ else if( p->transinfo[tindex].goal_width &&
+ (bus_width == MSG_EXT_WDTR_BUS_16_BIT) &&
+ p->features & AHC_WIDE )
+ {
+@@ -5845,117 +5961,142 @@
+ p->transinfo[tindex].goal_offset = MAX_OFFSET_8BIT;
+ }
+ }
+- p->transinfo[tindex].goal_width =
+- p->transinfo[tindex].user_width;
+- p->transinfo[tindex].goal_options =
+- p->transinfo[tindex].user_options;
++ else
++ {
++ p->transinfo[tindex].goal_period = 255;
++ p->transinfo[tindex].goal_offset = 0;
++ p->transinfo[tindex].goal_options = 0;
++ }
++ p->dev_flags[tindex] |= DEVICE_DTR_SCANNED | DEVICE_PRINT_DTR;
++ }
++ else if ((p->needppr_copy & target_mask) == 0)
++ {
++ /*
++ * This is a preemptive message from the target, we've already
++ * scanned this target and set our options for it, and we
++ * don't need a PPR with this target (for whatever reason),
++ * so reject this incoming PPR
++ */
++ reject = TRUE;
++ break;
+ }
++
++ /* The device is sending this message first and we have to reply */
++ reply = TRUE;
++
+ if (aic7xxx_verbose & VERBOSE_NEGOTIATION2)
+ {
+ printk(INFO_LEAD "Received pre-emptive PPR message from "
+ "target.\n", p->host_no, CTL_OF_SCB(scb));
+ }
+- if ( !p->transinfo[tindex].goal_offset )
+- period = 255;
+- if ( p->transinfo[tindex].goal_period > period )
+- period = p->transinfo[tindex].goal_period;
+- if ( p->transinfo[tindex].goal_options == 0 )
+- new_trans_options = 0;
+- switch(bus_width)
++
++ }
++
++ switch(bus_width)
++ {
++ case MSG_EXT_WDTR_BUS_16_BIT:
+ {
+- default:
+- {
+- if ( (p->features & AHC_WIDE) &&
+- (p->transinfo[tindex].goal_width ==
+- MSG_EXT_WDTR_BUS_16_BIT) )
+- {
+- bus_width = MSG_EXT_WDTR_BUS_16_BIT;
+- break;
+- }
+- } /* Fall through if we aren't a wide card */
+- case MSG_EXT_WDTR_BUS_8_BIT:
++ if ( (p->transinfo[tindex].goal_width ==
++ MSG_EXT_WDTR_BUS_16_BIT) && p->features & AHC_WIDE)
+ {
+- p->needwdtr_copy &= ~target_mask;
+- bus_width = MSG_EXT_WDTR_BUS_8_BIT;
+- aic7xxx_set_width(p, target, channel, lun, bus_width,
+- AHC_TRANS_GOAL|AHC_TRANS_QUITE);
+ break;
+ }
+ }
+- if ( (p->transinfo[tindex].goal_period > 9) ||
+- (p->transinfo[tindex].goal_options == 0) )
++ default:
+ {
+- scb->flags &= ~SCB_MSGOUT_BITS;
+- reject = TRUE;
+- reply = FALSE;
+- p->needppr &= ~(1 << tindex);
+- p->needppr_copy &= ~(1 << tindex);
+- if ( p->transinfo[tindex].goal_offset )
+- {
+- p->needsdtr |= (1 << tindex);
+- p->needsdtr_copy |= (1 << tindex);
+- }
+- if ( p->transinfo[tindex].goal_width )
+- {
+- p->needwdtr |= (1 << tindex);
+- p->needwdtr_copy |= (1 << tindex);
++ if ( (aic7xxx_verbose & VERBOSE_NEGOTIATION2) &&
++ ((p->dev_flags[tindex] & DEVICE_PRINT_DTR) ||
++ (aic7xxx_verbose > 0xffff)) )
++ {
++ reply = TRUE;
++ printk(INFO_LEAD "Requesting %d bit transfers, rejecting.\n",
++ p->host_no, CTL_OF_SCB(scb), 8 * (0x01 << bus_width));
+ }
++ } /* We fall through on purpose */
++ case MSG_EXT_WDTR_BUS_8_BIT:
++ {
++ /*
++ * According to the spec, if we aren't wide, we also can't be
++ * Dual Edge so clear the options byte
++ */
++ new_trans_options = 0;
++ new_bus_width = MSG_EXT_WDTR_BUS_8_BIT;
++ break;
+ }
+ }
++
++ if(reply)
++ {
++ /* when sending a reply, make sure that the goal settings are
++ * updated along with current and active since the code that
++ * will actually build the message for the sequencer uses the
++ * goal settings as its guidelines.
++ */
++ aic7xxx_set_width(p, target, channel, lun, new_bus_width,
++ AHC_TRANS_GOAL|AHC_TRANS_ACTIVE|AHC_TRANS_CUR);
++ syncrate = aic7xxx_find_syncrate(p, &new_period, maxsync,
++ &new_trans_options);
++ aic7xxx_validate_offset(p, syncrate, &new_offset, new_bus_width);
++ aic7xxx_set_syncrate(p, syncrate, target, channel, new_period,
++ new_offset, new_trans_options,
++ AHC_TRANS_GOAL|AHC_TRANS_ACTIVE|AHC_TRANS_CUR);
++ }
+ else
+ {
+- switch(bus_width)
++ aic7xxx_set_width(p, target, channel, lun, new_bus_width,
++ AHC_TRANS_ACTIVE|AHC_TRANS_CUR);
++ syncrate = aic7xxx_find_syncrate(p, &new_period, maxsync,
++ &new_trans_options);
++ aic7xxx_validate_offset(p, syncrate, &new_offset, new_bus_width);
++ aic7xxx_set_syncrate(p, syncrate, target, channel, new_period,
++ new_offset, new_trans_options,
++ AHC_TRANS_ACTIVE|AHC_TRANS_CUR);
++ }
++
++ /*
++ * As it turns out, if we don't *have* to have PPR messages, then
++ * configure ourselves not to use them since that makes some
++ * external drive chassis work (those chassis can't parse PPR
++ * messages and they mangle the SCSI bus until you send a WDTR
++ * and SDTR that they can understand).
++ */
++ if(new_trans_options == 0)
++ {
++ p->needppr &= ~target_mask;
++ p->needppr_copy &= ~target_mask;
++ if(new_offset)
+ {
+- default:
+- {
+- reject = TRUE;
+- if ( (aic7xxx_verbose & VERBOSE_NEGOTIATION2) &&
+- ((p->dev_flags[tindex] & DEVICE_PRINT_DTR) ||
+- (aic7xxx_verbose > 0xffff)) )
+- {
+- printk(INFO_LEAD "Requesting %d bit transfers, rejecting.\n",
+- p->host_no, CTL_OF_SCB(scb), 8 * (0x01 << bus_width));
+- }
+- } /* We fall through on purpose */
+- case MSG_EXT_WDTR_BUS_8_BIT:
+- {
+- /*
+- * According to the spec, if we aren't wide, we also can't be
+- * Dual Edge so clear the options byte
+- */
+- new_trans_options = 0;
+- bus_width = MSG_EXT_WDTR_BUS_8_BIT;
+- break;
+- }
+- case MSG_EXT_WDTR_BUS_16_BIT:
+- {
+- break;
+- }
++ p->needsdtr |= target_mask;
++ p->needsdtr_copy |= target_mask;
++ }
++ if (new_bus_width)
++ {
++ p->needwdtr |= target_mask;
++ p->needwdtr_copy |= target_mask;
+ }
+ }
+
+- if ( !reject )
++ if((new_offset == 0) && (offset != 0))
+ {
+- aic7xxx_set_width(p, target, channel, lun, bus_width,
+- AHC_TRANS_ACTIVE|AHC_TRANS_CUR);
+- syncrate = aic7xxx_find_syncrate(p, &period, maxsync,
+- &new_trans_options);
+- aic7xxx_validate_offset(p, syncrate, &offset, bus_width);
+- aic7xxx_set_syncrate(p, syncrate, target, channel, period,
+- offset, new_trans_options,
+- AHC_TRANS_ACTIVE|AHC_TRANS_CUR);
++ /*
++ * Oops, the syncrate went to low for this card and we fell off
++ * to async (should never happen with a device that uses PPR
++ * messages, but have to be complete)
++ */
++ reply = TRUE;
+ }
+
+- p->dtr_pending &= ~target_mask;
+- p->needppr &= ~target_mask;
+ if(reply)
+ {
+- p->dtr_pending |= target_mask;
+ scb->flags &= ~SCB_MSGOUT_BITS;
+ scb->flags |= SCB_MSGOUT_PPR;
+ aic_outb(p, HOST_MSG, MSG_OUT);
+ aic_outb(p, aic_inb(p, SCSISIGO) | ATNO, SCSISIGO);
+ }
++ else
++ {
++ p->needppr &= ~target_mask;
++ }
+ done = TRUE;
+ break;
+ }
+@@ -6193,16 +6334,14 @@
+ printerror = 0;
+ }
+ }
+- if ( (scb != NULL) &&
+- (scb->cmd == p->dev_dtr_cmnd[TARGET_INDEX(scb->cmd)]) )
++ if ( (scb != NULL) && (scb->flags & SCB_DTR_SCB) )
+ {
+ /*
+- * This might be a SCSI-3 device that is dropping the bus due to
+- * errors and signalling that we should reduce the transfer speed.
+- * All we have to do is complete this command (since it's a negotiation
+- * command already) and the checksum routine should flag an error and
+- * reduce the speed setting and renegotiate. We call the reset routing
+- * just to clean out the hardware from this scb.
++ * Hmmm...error during a negotiation command. Either we have a
++ * borken bus, or the device doesn't like our negotiation message.
++ * Since we check the INQUIRY data of a device before sending it
++ * negotiation messages, assume the bus is borken for whatever
++ * reason. Complete the command.
+ */
+ printerror = 0;
+ aic7xxx_reset_device(p, target, channel, ALL_LUNS, scb->hscb->tag);
+@@ -6334,19 +6473,6 @@
+ cmd->result = 0;
+ scb = NULL;
+ }
+- else if (scb->cmd == p->dev_dtr_cmnd[TARGET_INDEX(scb->cmd)])
+- {
+- /*
+- * Turn off the needsdtr, needwdtr, and needppr bits since this device
+- * doesn't seem to exist.
+- */
+- p->needppr &= ~(0x01 << TARGET_INDEX(scb->cmd));
+- p->needppr_copy &= ~(0x01 << TARGET_INDEX(scb->cmd));
+- p->needsdtr &= ~(0x01 << TARGET_INDEX(scb->cmd));
+- p->needsdtr_copy &= ~(0x01 << TARGET_INDEX(scb->cmd));
+- p->needwdtr &= ~(0x01 << TARGET_INDEX(scb->cmd));
+- p->needwdtr_copy &= ~(0x01 << TARGET_INDEX(scb->cmd));
+- }
+ }
+ /*
+ * Keep the sequencer from trying to restart any selections
+@@ -6469,7 +6595,6 @@
+ }
+ }
+ else if( (lastphase == P_MESGOUT) &&
+- (cmd == p->dev_dtr_cmnd[tindex]) &&
+ (scb->flags & SCB_MSGOUT_PPR) )
+ {
+ /*
+@@ -6488,7 +6613,6 @@
+ aic7xxx_set_syncrate(p, NULL, scb->cmd->target, scb->cmd->channel, 0, 0,
+ 0, AHC_TRANS_ACTIVE|AHC_TRANS_CUR|AHC_TRANS_QUITE);
+ p->transinfo[tindex].goal_options = 0;
+- p->dtr_pending &= ~(1 << tindex);
+ scb->flags &= ~SCB_MSGOUT_BITS;
+ if(aic7xxx_verbose & VERBOSE_NEGOTIATION2)
+ {
+@@ -6511,87 +6635,6 @@
+ }
+ scb = NULL;
+ }
+- else if(p->dev_flags[tindex] & DEVICE_PARITY_ERROR)
+- {
+- struct aic7xxx_syncrate *syncrate;
+- unsigned int period = p->transinfo[tindex].cur_period;
+- unsigned char options = p->transinfo[tindex].cur_options;
+- /*
+- * oops, we had a failure, lower the transfer rate and try again. It's
+- * worth noting here that it might be wise to also check for typical
+- * wide setting on narrow cable type problems and try disabling wide
+- * instead of slowing down if those exist. That's hard to do with simple
+- * checksums though.
+- */
+- printk(WARN_LEAD "Parity error during %s phase.\n",
+- p->host_no, CTL_OF_SCB(scb), phase);
+- if((syncrate = aic7xxx_find_syncrate(p, &period, 0, &options)) != NULL)
+- {
+- syncrate++;
+- if( (syncrate->rate[0] != NULL) &&
+- (!(p->features & AHC_ULTRA2) || (syncrate->sxfr_ultra2 == 0)) )
+- {
+- p->transinfo[tindex].goal_period = syncrate->period;
+- if( p->transinfo[tindex].goal_period > 9 )
+- {
+- p->transinfo[tindex].goal_options = 0;
+- p->needppr &= ~(1<<tindex);
+- p->needsdtr |= (1<<tindex);
+- p->needppr_copy &= ~(1<<tindex);
+- p->needsdtr_copy |= (1<<tindex);
+- if (p->transinfo[tindex].goal_width)
+- {
+- p->needwdtr |= (1<<tindex);
+- p->needwdtr_copy |= (1<<tindex);
+- }
+- }
+- }
+- else if (p->transinfo[tindex].goal_width)
+- {
+- p->transinfo[tindex].goal_width = 0;
+- p->needwdtr &= ~(1<<tindex);
+- p->needwdtr_copy &= ~(1<<tindex);
+- p->transinfo[tindex].goal_offset =
+- 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->transinfo[tindex].goal_period <= 9 )
+- {
+- p->needppr |= (1<<tindex);
+- p->needsdtr &= ~(1<<tindex);
+- p->needppr_copy |= (1<<tindex);
+- p->needsdtr_copy &= ~(1<<tindex);
+- }
+- else
+- {
+- p->needppr &= ~(1<<tindex);
+- p->needsdtr |= (1<<tindex);
+- p->needppr_copy &= ~(1<<tindex);
+- p->needsdtr_copy |= (1<<tindex);
+- }
+- }
+- else
+- {
+- p->transinfo[tindex].goal_offset = 0;
+- p->transinfo[tindex].goal_period = 255;
+- p->transinfo[tindex].goal_options = 0;
+- p->transinfo[tindex].goal_width = 0;
+- p->needppr &= ~(1<<tindex);
+- p->needsdtr &= ~(1<<tindex);
+- p->needwdtr &= ~(1<<tindex);
+- p->needppr_copy &= ~(1<<tindex);
+- p->needsdtr_copy &= ~(1<<tindex);
+- p->needwdtr_copy &= ~(1<<tindex);
+- }
+- }
+- p->dev_flags[tindex] &= ~DEVICE_PARITY_ERROR;
+- }
+- else
+- {
+- p->dev_flags[tindex] |= DEVICE_PARITY_ERROR;
+- }
+
+ /*
+ * We've set the hardware to assert ATN if we get a parity
+@@ -6860,34 +6903,11 @@
+ else if (scb->flags & SCB_SENSE)
+ {
+ char *buffer = &scb->cmd->sense_buffer[0];
+- if (scb->cmd == p->dev_dtr_cmnd[tindex])
+- {
+- struct aic7xxx_scb *old_scb;
+- /*
+- * We have valid sense data, send it back immediately.
+- */
+- old_scb = p->scb_data->scb_array[scb->cmd->next->tag];
+- *old_scb->cmd->sense_buffer = *scb->cmd->sense_buffer;
+- old_scb->hscb->target_status = scb->hscb->target_status;
+- old_scb->cmd->result = scb->hscb->target_status;
+- old_scb->cmd->result |= (DID_ERROR << 16);
+- aic7xxx_status(old_scb->cmd) = scb->hscb->target_status;
+- scbq_remove(&p->waiting_scbs, old_scb);
+- scbq_remove(&p->delayed_scbs[tindex], old_scb);
+- scb->cmd->next = NULL;
+- aic7xxx_done(p, scb);
+- aic7xxx_done(p, old_scb);
+- continue;
+- }
+- else if (buffer[12] == 0x47 || buffer[12] == 0x54)
++
++ if (buffer[12] == 0x47 || buffer[12] == 0x54)
+ {
+ /*
+- * SCSI errors, run domain validation and re-run negotiation
+- */
+- p->needdv |= (1<<tindex);
+- /*
+- * Signal that we need to re-negotiate things, this also gets us our
+- * INQUIRY command to re-checksum off of.
++ * Signal that we need to re-negotiate things.
+ */
+ p->needppr |= (p->needppr_copy & (1<<tindex));
+ p->needsdtr |= (p->needsdtr_copy & (1<<tindex));
+@@ -6900,7 +6920,18 @@
+ case BUSY:
+ scb->hscb->target_status = 0;
+ scb->cmd->result = 0;
++ 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_error(scb->cmd) = DID_OK;
++ aic7xxx_status(scb->cmd) = 0;
++ /*
++ * The QUEUE_FULL/BUSY handler in aic7xxx_seqint takes care of putting
++ * this command on a timer and allowing us to retry it. Here, we
++ * just 0 out a few values so that they don't carry through to when
++ * the command finally does complete.
++ */
+ break;
+ default:
+ cmd = scb->cmd;
+@@ -7065,33 +7096,27 @@
+ if(!p)
+ return;
+ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,95)
+- if(test_and_set_bit(AHC_IN_ISR_BIT, &p->flags))
+- {
+- return;
+- }
+ spin_lock_irqsave(&io_request_lock, cpu_flags);
++ p->flags |= AHC_IN_ISR;
+ do
+ {
+ aic7xxx_isr(irq, dev_id, regs);
+ } while ( (aic_inb(p, INTSTAT) & INT_PEND) );
+ aic7xxx_done_cmds_complete(p);
+ aic7xxx_run_waiting_queues(p);
+- clear_bit(AHC_IN_ISR_BIT, &p->flags);
++ p->flags &= ~AHC_IN_ISR;
+ spin_unlock_irqrestore(&io_request_lock, cpu_flags);
+ #else
+- if(set_bit(AHC_IN_ISR_BIT, (int *)&p->flags))
+- {
+- return;
+- }
+ DRIVER_LOCK
++ p->flags |= AHC_IN_ISR;
+ do
+ {
+ aic7xxx_isr(irq, dev_id, regs);
+ } while ( (aic_inb(p, INTSTAT) & INT_PEND) );
++ p->flags &= ~AHC_IN_ISR;
+ DRIVER_UNLOCK
+ aic7xxx_done_cmds_complete(p);
+ aic7xxx_run_waiting_queues(p);
+- clear_bit(AHC_IN_ISR_BIT, (int *)&p->flags);
+ #endif
+ }
+
+@@ -9012,22 +9037,6 @@
+ kfree(p->scb_data);
+ }
+
+- /*
+- * Free any alloced Scsi_Cmnd structures that might be around for
+- * negotiation purposes....
+- */
+- for (i = 0; i < MAX_TARGETS; i++)
+- {
+- if(p->dev_dtr_cmnd[i])
+- {
+- if(p->dev_dtr_cmnd[i]->request_buffer)
+- {
+- kfree(p->dev_dtr_cmnd[i]->request_buffer);
+- }
+- kfree(p->dev_dtr_cmnd[i]);
+- }
+- }
+-
+ }
+
+ /*+F*************************************************************************
+@@ -9413,7 +9422,7 @@
+ }
+ aic_outb(p, ~(p->discenable & 0xFF), DISC_DSB);
+ aic_outb(p, ~((p->discenable >> 8) & 0xFF), DISC_DSB + 1);
+- p->needppr = p->needppr_copy = p->needdv = 0;
++ p->needppr = p->needppr_copy = 0;
+ p->needwdtr = p->needwdtr_copy;
+ p->needsdtr = p->needsdtr_copy;
+ p->dtr_pending = 0;
+@@ -9471,53 +9480,165 @@
+
+ /*+F*************************************************************************
+ * Function:
+- * aic7xxx_detect
++ * aic7xxx_configure_bugs
+ *
+ * Description:
+- * Try to detect and register an Adaptec 7770 or 7870 SCSI controller.
+- *
+- * XXX - This should really be called aic7xxx_probe(). A sequence of
+- * probe(), attach()/detach(), and init() makes more sense than
+- * one do-it-all function. This may be useful when (and if) the
+- * mid-level SCSI code is overhauled.
++ * Take the card passed in and set the appropriate bug flags based upon
++ * the card model. Also make any changes needed to device registers or
++ * PCI registers while we are here.
+ *-F*************************************************************************/
+-int
+-aic7xxx_detect(Scsi_Host_Template *template)
++static void
++aic7xxx_configure_bugs(struct aic7xxx_host *p)
+ {
+- struct aic7xxx_host *temp_p = NULL;
+- struct aic7xxx_host *current_p = NULL;
+- struct aic7xxx_host *list_p = NULL;
+- int found = 0;
+-#if defined(__i386__) || defined(__alpha__)
+- ahc_flag_type flags = 0;
+- int type;
+-#endif
+- unsigned char sxfrctl1;
+-#if defined(__i386__) || defined(__alpha__)
+- unsigned char hcntrl, hostconf;
+- unsigned int slot, base;
+-#endif
+-
+-#ifdef MODULE
+- /*
+- * If we are called as a module, the aic7xxx pointer may not be null
+- * and it would point to our bootup string, just like on the lilo
+- * command line. IF not NULL, then process this config string with
+- * aic7xxx_setup
+- */
+- if(aic7xxx)
+- aic7xxx_setup(aic7xxx, NULL);
+- if(dummy_buffer[0] != 'P')
+- printk(KERN_WARNING "aic7xxx: Please read the file /usr/src/linux/drivers"
+- "/scsi/README.aic7xxx\n"
+- "aic7xxx: to see the proper way to specify options to the aic7xxx "
+- "module\n"
+- "aic7xxx: Specifically, don't use any commas when passing arguments to\n"
+- "aic7xxx: insmod or else it might trash certain memory areas.\n");
++ unsigned char pci_rev;
++ unsigned short tmp_word;
++
++ if((p->chip & ~AHC_CHIPID_MASK) == AHC_PCI)
++ {
++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,1,92)
++ pcibios_read_config_byte(p->pci_bus, p->pci_device_fn,
++ PCI_REVISION_ID, &pci_rev);
++#else
++ pci_read_config_byte(p->pdev, PCI_REVISION_ID, &pci_rev);
+ #endif
++ }
+
+- template->proc_dir = &proc_scsi_aic7xxx;
+- template->sg_tablesize = AIC7XXX_MAX_SG;
++ switch(p->chip & AHC_CHIPID_MASK)
++ {
++ case AHC_AIC7860:
++ if(pci_rev >= 1)
++ {
++ p->bugs |= AHC_BUG_PCI_2_1_RETRY;
++ }
++ /* fall through */
++ case AHC_AIC7850:
++ case AHC_AIC7870:
++ p->bugs |= AHC_BUG_TMODE_WIDEODD | AHC_BUG_CACHETHEN | AHC_BUG_PCI_MWI;
++ break;
++ case AHC_AIC7880:
++ p->bugs |= AHC_BUG_TMODE_WIDEODD;
++ if(pci_rev >= 1)
++ {
++ p->bugs |= AHC_BUG_PCI_2_1_RETRY;
++ }
++ else
++ {
++ p->bugs |= AHC_BUG_CACHETHEN | AHC_BUG_PCI_MWI;
++ }
++ break;
++ case AHC_AIC7890:
++ if(pci_rev == 0)
++ {
++ p->bugs |= AHC_BUG_AUTOFLUSH | AHC_BUG_CACHETHEN;
++ }
++ break;
++ case AHC_AIC7892:
++ p->bugs |= AHC_BUG_SCBCHAN_UPLOAD;
++ break;
++ case AHC_AIC7895:
++ p->bugs |= AHC_BUG_TMODE_WIDEODD | AHC_BUG_PCI_2_1_RETRY |
++ AHC_BUG_CACHETHEN;
++ if(pci_rev <= 3)
++ {
++ p->bugs |= AHC_BUG_PCI_MWI;
++ }
++ break;
++ case AHC_AIC7896:
++ p->bugs |= AHC_BUG_CACHETHEN_DIS;
++ break;
++ case AHC_AIC7899:
++ p->bugs |= AHC_BUG_SCBCHAN_UPLOAD;
++ break;
++ default:
++ /* Nothing to do */
++ break;
++ }
++
++ /*
++ * Now handle the bugs that require PCI register or card register tweaks
++ */
++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,1,92)
++ pcibios_read_config_word(p->pci_bus, p->pci_device_fn,
++ PCI_COMMAND, &tmp_word);
++#else
++ pci_read_config_word(p->pdev, PCI_COMMAND, &tmp_word);
++#endif
++ if(p->bugs & AHC_BUG_PCI_MWI)
++ {
++ tmp_word &= ~PCI_COMMAND_INVALIDATE;
++ }
++ else
++ {
++ tmp_word |= PCI_COMMAND_INVALIDATE;
++ }
++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,1,92)
++ pcibios_write_config_word(p->pci_bus, p->pci_device_fn,
++ PCI_COMMAND, tmp_word);
++#else
++ pci_write_config_word(p->pdev, PCI_COMMAND, tmp_word);
++#endif
++
++ if(p->bugs & AHC_BUG_CACHETHEN)
++ {
++ aic_outb(p, aic_inb(p, DSCOMMAND0) & ~CACHETHEN, DSCOMMAND0);
++ }
++ else if (p->bugs & AHC_BUG_CACHETHEN_DIS)
++ {
++ aic_outb(p, aic_inb(p, DSCOMMAND0) | CACHETHEN, DSCOMMAND0);
++ }
++
++ return;
++}
++
++/*+F*************************************************************************
++ * Function:
++ * aic7xxx_detect
++ *
++ * Description:
++ * Try to detect and register an Adaptec 7770 or 7870 SCSI controller.
++ *
++ * XXX - This should really be called aic7xxx_probe(). A sequence of
++ * probe(), attach()/detach(), and init() makes more sense than
++ * one do-it-all function. This may be useful when (and if) the
++ * mid-level SCSI code is overhauled.
++ *-F*************************************************************************/
++int
++aic7xxx_detect(Scsi_Host_Template *template)
++{
++ struct aic7xxx_host *temp_p = NULL;
++ struct aic7xxx_host *current_p = NULL;
++ struct aic7xxx_host *list_p = NULL;
++ int found = 0;
++#if defined(__i386__) || defined(__alpha__)
++ ahc_flag_type flags = 0;
++ int type;
++#endif
++ unsigned char sxfrctl1;
++#if defined(__i386__) || defined(__alpha__)
++ unsigned char hcntrl, hostconf;
++ unsigned int slot, base;
++#endif
++
++#ifdef MODULE
++ /*
++ * If we are called as a module, the aic7xxx pointer may not be null
++ * and it would point to our bootup string, just like on the lilo
++ * command line. IF not NULL, then process this config string with
++ * aic7xxx_setup
++ */
++ if(aic7xxx)
++ aic7xxx_setup(aic7xxx, NULL);
++ if(dummy_buffer[0] != 'P')
++ printk(KERN_WARNING "aic7xxx: Please read the file /usr/src/linux/drivers"
++ "/scsi/README.aic7xxx\n"
++ "aic7xxx: to see the proper way to specify options to the aic7xxx "
++ "module\n"
++ "aic7xxx: Specifically, don't use any commas when passing arguments to\n"
++ "aic7xxx: insmod or else it might trash certain memory areas.\n");
++#endif
++
++ template->proc_dir = &proc_scsi_aic7xxx;
++ template->sg_tablesize = AIC7XXX_MAX_SG;
+
+
+ #ifdef CONFIG_PCI
+@@ -10290,6 +10411,14 @@
+ aic_outb(temp_p, DFTHRSH_100, DSPCISTATUS);
+ }
+
++ /*
++ * Call our function to fixup any bugs that exist on this chipset.
++ * This may muck with PCI settings and other device settings, so
++ * make sure it's after all the other PCI and device register
++ * tweaks so it can back out bad settings on specific broken cards.
++ */
++ aic7xxx_configure_bugs(temp_p);
++
+ if ( list_p == NULL )
+ {
+ list_p = current_p = temp_p;
+@@ -10533,6 +10662,11 @@
+ }
+
+ /*
++ * All the 7770 based chipsets have this bug
++ */
++ temp_p->bugs |= AHC_BUG_TMODE_WIDEODD;
++
++ /*
+ * Set the FIFO threshold and the bus off time.
+ */
+ hostconf = aic_inb(temp_p, HOSTCONF);
+@@ -10751,297 +10885,6 @@
+ return (found);
+ }
+
+-static void aic7xxx_build_negotiation_cmnd(struct aic7xxx_host *p,
+- Scsi_Cmnd *old_cmd, int tindex);
+-
+-/*+F*************************************************************************
+- * Function:
+- * aic7xxx_allocate_negotiation_command
+- *
+- * Description:
+- * allocate the actual command struct and fill in the gaps...
+- *-F*************************************************************************/
+-static Scsi_Cmnd *
+-aic7xxx_allocate_negotiation_command(struct aic7xxx_host *p,
+- Scsi_Cmnd *old_cmd, int tindex)
+-{
+- Scsi_Cmnd *cmd;
+- char *buffer;
+-
+- if (!(p->dev_dtr_cmnd[tindex] = kmalloc(sizeof(Scsi_Cmnd), GFP_ATOMIC)) )
+- {
+- return(NULL);
+- }
+- if (!(buffer = kmalloc(256, GFP_ATOMIC)))
+- {
+- kfree(p->dev_dtr_cmnd[tindex]);
+- p->dev_dtr_cmnd[tindex] = NULL;
+- return(NULL);
+- }
+- cmd = p->dev_dtr_cmnd[tindex];
+- memset(cmd, 0, sizeof(Scsi_Cmnd));
+- memcpy(cmd, old_cmd, sizeof(Scsi_Cmnd));
+- memset(&cmd->cmnd[0], 0, sizeof(cmd->cmnd));
+- memset(&cmd->data_cmnd[0], 0, sizeof(cmd->data_cmnd));
+- cmd->lun = 0;
+- cmd->request_bufflen = 255;
+- cmd->request_buffer = buffer;
+- cmd->use_sg = cmd->old_use_sg = cmd->sglist_len = 0;
+- cmd->bufflen = 0;
+- cmd->buffer = NULL;
+- cmd->underflow = 0;
+- cmd->cmd_len = 6;
+- cmd->cmnd[0] = cmd->data_cmnd[0] = INQUIRY;
+- cmd->cmnd[1] = cmd->data_cmnd[1] = 0;
+- cmd->cmnd[2] = cmd->data_cmnd[2] = 0;
+- cmd->cmnd[3] = cmd->data_cmnd[3] = 0;
+- cmd->cmnd[4] = cmd->data_cmnd[4] = 255; /* match what scsi.c does here */
+- cmd->cmnd[5] = cmd->data_cmnd[5] = 0;
+- return(cmd);
+-}
+-
+-/*+F*************************************************************************
+- * Function:
+- * aic7xxx_negotiation_complete
+- *
+- * Description:
+- * Handle completion events for our Negotiation commands. Clear out the
+- * struct and get it ready for its next use.
+- *-F*************************************************************************/
+-static void
+-aic7xxx_negotiation_complete(Scsi_Cmnd *cmd)
+-{
+- unsigned int checksum;
+- int i;
+- int *ibuffer;
+- struct aic7xxx_host *p = (struct aic7xxx_host *)cmd->host->hostdata;
+- int tindex = TARGET_INDEX(cmd);
+- struct aic7xxx_syncrate *syncrate;
+-
+- /*
+- * perform our minimalistic domain validation
+- */
+- if(p->dev_flags[tindex] & DEVICE_SCANNED)
+- {
+- ibuffer = (int *)cmd->request_buffer;
+- checksum = 0;
+- for(i = 0; i < (cmd->request_bufflen >> 2); i++)
+- {
+- checksum += ibuffer[i];
+- }
+- if( (checksum != p->dev_checksum[tindex]) &&
+- (p->transinfo[tindex].cur_offset != 0) )
+- {
+- unsigned int period = p->transinfo[tindex].cur_period;
+- unsigned char options = p->transinfo[tindex].cur_options;
+-
+- if (p->needdv & (1<<tindex))
+- {
+- /*
+- * oops, we had a failure, lower the transfer rate and try again. It's
+- * worth noting here that it might be wise to also check for typical
+- * wide setting on narrow cable type problems and try disabling wide
+- * instead of slowing down if those exist. That's hard to do with simple
+- * checksums though.
+- */
+- if(aic7xxx_verbose & VERBOSE_NEGOTIATION2)
+- {
+- printk(INFO_LEAD "reducing SCSI transfer speed due to Domain "
+- "validation failure.\n", p->host_no, CTL_OF_CMD(cmd));
+- }
+- if((syncrate = aic7xxx_find_syncrate(p, &period, 0, &options)) != NULL)
+- {
+- syncrate++;
+- if( (syncrate->rate[0] != NULL) &&
+- (!(p->features & AHC_ULTRA2) || (syncrate->sxfr_ultra2 == 0)) )
+- {
+- p->transinfo[tindex].goal_period = syncrate->period;
+- if( p->transinfo[tindex].goal_period > 9 )
+- {
+- p->transinfo[tindex].goal_options = 0;
+- p->needppr &= ~(1<<tindex);
+- p->needsdtr |= (1<<tindex);
+- p->needppr_copy &= ~(1<<tindex);
+- p->needsdtr_copy |= (1<<tindex);
+- if (p->transinfo[tindex].goal_width)
+- {
+- p->needwdtr |= (1<<tindex);
+- p->needwdtr_copy |= (1<<tindex);
+- }
+- }
+- }
+- else if (p->transinfo[tindex].goal_width)
+- {
+- p->transinfo[tindex].goal_width = 0;
+- p->needwdtr &= ~(1<<tindex);
+- p->needwdtr_copy &= ~(1<<tindex);
+- p->transinfo[tindex].goal_offset =
+- 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->transinfo[tindex].goal_period <= 9 )
+- {
+- p->needppr |= (1<<tindex);
+- p->needsdtr &= ~(1<<tindex);
+- p->needppr_copy |= (1<<tindex);
+- p->needsdtr_copy &= ~(1<<tindex);
+- }
+- else
+- {
+- p->needppr &= ~(1<<tindex);
+- p->needsdtr |= (1<<tindex);
+- p->needppr_copy &= ~(1<<tindex);
+- p->needsdtr_copy |= (1<<tindex);
+- }
+- }
+- else
+- {
+- p->transinfo[tindex].goal_offset = 0;
+- p->transinfo[tindex].goal_period = 255;
+- p->transinfo[tindex].goal_options = 0;
+- p->transinfo[tindex].goal_width = 0;
+- p->needppr &= ~(1<<tindex);
+- p->needsdtr &= ~(1<<tindex);
+- p->needwdtr &= ~(1<<tindex);
+- p->needppr_copy &= ~(1<<tindex);
+- p->needsdtr_copy &= ~(1<<tindex);
+- p->needwdtr_copy &= ~(1<<tindex);
+- }
+- }
+- p->needdv &= ~(1<<tindex);
+- }
+- else
+- {
+- if(aic7xxx_verbose & VERBOSE_NEGOTIATION2)
+- {
+- printk(INFO_LEAD "Performing Domain validation.\n",
+- p->host_no, CTL_OF_CMD(cmd));
+- }
+- /*
+- * Update the checksum in case the INQUIRY data has changed, maybe
+- * in relation to a change in the mode pages, or whatever.
+- */
+- p->dev_checksum[tindex] = checksum;
+- /*
+- * Signal that we are trying out the domain validation
+- */
+- p->needdv |= (1<<tindex);
+- /*
+- * Signal that we need to re-negotiate things, this also gets us our
+- * INQUIRY command to re-checksum off of.
+- */
+- p->needppr |= (p->needppr_copy & (1<<tindex));
+- p->needsdtr |= (p->needsdtr_copy & (1<<tindex));
+- p->needwdtr |= (p->needwdtr_copy & (1<<tindex));
+- }
+- }
+- else
+- {
+- if( (aic7xxx_verbose & VERBOSE_NEGOTIATION2) &&
+- (p->needdv & (1<<tindex)) )
+- {
+- printk(INFO_LEAD "Successfully completed Domain validation.\n",
+- p->host_no, CTL_OF_CMD(cmd));
+- }
+- /*
+- * We successfully did our checksum, so don't leave the needdv flag set
+- * in case we might have set it last time through.
+- */
+- p->needdv &= ~(1<<tindex);
+- }
+- }
+-
+- p->dtr_pending &= ~(0x01 << tindex);
+- /*
+- * This looks recursive in the extreme, but if this was a WDTR negotiation
+- * and we didn't follow up with SDTR yet, then this will get it started.
+- * For all other cases, this should work out to be a no-op, unless we are
+- * doing domain validation and happen to need a new negotiation command.
+- *
+- * In case we don't want this to go any further, the cmdcmplt interrupt
+- * handler will NULL out the cmd->next entry so that the real SCSI command
+- * can be sent back to the mid layer code with SENSE data intact. We'll
+- * finish things up when the cmd gets sent back down to us, so no worries.
+- */
+- if(cmd->next)
+- {
+- aic7xxx_build_negotiation_cmnd(p, cmd->next, tindex);
+- }
+- return;
+-}
+-
+-/*+F*************************************************************************
+- * Function:
+- * aic7xxx_build_negotiation_command
+- *
+- * Description:
+- * Build a Scsi_Cmnd structure to perform negotiation with or else send
+- * a pre-built command specifically for this purpose.
+- *-F*************************************************************************/
+-static void
+-aic7xxx_build_negotiation_cmnd(struct aic7xxx_host *p, Scsi_Cmnd *old_cmd,
+- int tindex)
+-{
+-
+- if ( !(p->dtr_pending & (1<<tindex)) &&
+- ( (p->needppr & (1<<tindex)) ||
+- (p->needwdtr & (1<<tindex)) ||
+- (p->needsdtr & (1<<tindex)) ) )
+- {
+- if ( (p->dev_dtr_cmnd[tindex] == NULL) &&
+- (aic7xxx_allocate_negotiation_command(p, old_cmd, tindex) == NULL) )
+- {
+- return;
+- }
+- /*
+- * Before sending this thing out, we also make the cmd->next pointer
+- * point to the real command so we can stuff any possible SENSE data
+- * into the real command instead of this fake command. This has to be
+- * done each time the command is built, not just the first time, hence
+- * it's outside of the above if()...
+- */
+- p->dev_dtr_cmnd[tindex]->next = old_cmd;
+- /*
+- * Clear the buffer so checksums come out right....
+- */
+- memset(p->dev_dtr_cmnd[tindex]->request_buffer, 0,
+- p->dev_dtr_cmnd[tindex]->request_bufflen);
+- /*
+- * Remove any commands for this particular device that might be on the
+- * waiting_scbs queue or qinfifo so that this command goes out first.
+- * This is vital for our implementation of domain validation.
+- */
+- pause_sequencer(p);
+- aic7xxx_search_qinfifo(p, old_cmd->target, old_cmd->channel, ALL_LUNS,
+- SCB_LIST_NULL, 0, TRUE, &p->delayed_scbs[tindex]);
+- unpause_sequencer(p, FALSE);
+- {
+- struct aic7xxx_scb *scb, *next;
+-
+- scb = p->waiting_scbs.head;
+- while(scb != NULL)
+- {
+- if( aic7xxx_match_scb(p, scb, old_cmd->target, old_cmd->channel,
+- ALL_LUNS, SCB_LIST_NULL) )
+- {
+- next = scb->q_next;
+- scbq_remove(&p->waiting_scbs, scb);
+- scbq_insert_tail(&p->delayed_scbs[tindex], scb);
+- scb = next;
+- }
+- else
+- {
+- scb = scb->q_next;
+- }
+- }
+- }
+- aic7xxx_queue(p->dev_dtr_cmnd[tindex],
+- aic7xxx_negotiation_complete);
+- }
+-}
+-
+ #ifdef AIC7XXX_VERBOSE_DEBUGGING
+ /*+F*************************************************************************
+ * Function:
+@@ -11090,7 +10933,7 @@
+ */
+ hscb->control = 0;
+ scb->tag_action = 0;
+- cmd->tag = hscb->tag;
++
+ if (p->discenable & mask)
+ {
+ hscb->control |= DISCENB;
+@@ -11119,34 +10962,29 @@
+ }
+ }
+ }
+- if ( cmd == p->dev_dtr_cmnd[tindex] )
++ if ( !(p->dtr_pending & mask) &&
++ ( (p->needppr & mask) ||
++ (p->needwdtr & mask) ||
++ (p->needsdtr & mask) ) &&
++ (p->dev_flags[tindex] & DEVICE_DTR_SCANNED) )
+ {
+ p->dtr_pending |= mask;
+ scb->tag_action = 0;
+- if (p->dev_flags[tindex] & DEVICE_SCANNED)
++ hscb->control &= DISCENB;
++ hscb->control |= MK_MESSAGE;
++ if(p->needppr & mask)
+ {
+- hscb->control &= DISCENB;
+- hscb->control |= MK_MESSAGE;
+- if(p->needppr & mask)
+- {
+- scb->flags |= SCB_MSGOUT_PPR;
+- }
+- else if(p->needwdtr & mask)
+- {
+- scb->flags |= SCB_MSGOUT_WDTR;
+- }
+- else if(p->needsdtr & mask)
+- {
+- scb->flags |= SCB_MSGOUT_SDTR;
+- }
++ scb->flags |= SCB_MSGOUT_PPR;
+ }
+- }
+- if ( !(p->dtr_pending & mask) &&
+- ( (p->needppr & mask) ||
+- (p->needwdtr & mask) ||
+- (p->needsdtr & mask) ) )
+- {
+- aic7xxx_build_negotiation_cmnd(p, cmd, tindex);
++ else if(p->needwdtr & mask)
++ {
++ scb->flags |= SCB_MSGOUT_WDTR;
++ }
++ else if(p->needsdtr & mask)
++ {
++ scb->flags |= SCB_MSGOUT_SDTR;
++ }
++ scb->flags |= SCB_DTR_SCB;
+ }
+ hscb->target_channel_lun = ((cmd->target << 4) & 0xF0) |
+ ((cmd->channel & 0x01) << 3) | (cmd->lun & 0x07);
+@@ -11285,50 +11123,58 @@
+ aic7xxx_allocate_scb(p);
+ DRIVER_UNLOCK
+ scb = scbq_remove_head(&p->scb_data->free_scbs);
+- }
+- if (scb == NULL)
+- {
+- printk(WARN_LEAD "Couldn't get a free SCB.\n", p->host_no,
+- CTL_OF_CMD(cmd));
+- cmd->result = (DID_BUS_BUSY << 16);
++ if(scb == NULL)
++ printk(WARN_LEAD "Couldn't get a free SCB.\n", p->host_no,
++ CTL_OF_CMD(cmd));
++ }
++ while (scb == NULL)
++ {
++ /*
++ * Well, all SCBs are currently active on the bus. So, we spin here
++ * running the interrupt handler until one completes and becomes free.
++ * We can do this safely because we either A) hold the driver lock (in
++ * 2.0 kernels) or we have the io_request_lock held (in 2.2 and later
++ * kernels) and so either way, we won't take any other interrupts and
++ * the queue path will block until we release it. Also, we would worry
++ * about running the completion queues, but obviously there are plenty
++ * of commands outstanding to trigger a later interrupt that will do
++ * that for us, so skip it here.
++ */
+ DRIVER_LOCK
+- aic7xxx_queue_cmd_complete(p, cmd);
++ aic7xxx_isr(p->irq, p, NULL);
+ DRIVER_UNLOCK
+- return 0;
++ scb = scbq_remove_head(&p->scb_data->free_scbs);
+ }
+- else
+- {
+- scb->cmd = cmd;
+- aic7xxx_position(cmd) = scb->hscb->tag;
++ scb->cmd = cmd;
++ aic7xxx_position(cmd) = scb->hscb->tag;
+
+- /*
+- * Construct the SCB beforehand, so the sequencer is
+- * paused a minimal amount of time.
+- */
+- aic7xxx_buildscb(p, cmd, scb);
++ /*
++ * Make sure the Scsi_Cmnd pointer is saved, the struct it points to
++ * is set up properly, and the parity error flag is reset, then send
++ * the SCB to the sequencer and watch the fun begin.
++ */
++ cmd->scsi_done = fn;
++ cmd->result = DID_OK;
++ memset(cmd->sense_buffer, 0, sizeof(cmd->sense_buffer));
++ aic7xxx_error(cmd) = DID_OK;
++ aic7xxx_status(cmd) = 0;
++ cmd->host_scribble = NULL;
+
+- /*
+- * Make sure the Scsi_Cmnd pointer is saved, the struct it points to
+- * is set up properly, and the parity error flag is reset, then send
+- * the SCB to the sequencer and watch the fun begin.
+- */
+- cmd->scsi_done = fn;
+- cmd->result = DID_OK;
+- memset(cmd->sense_buffer, 0, sizeof(cmd->sense_buffer));
+- aic7xxx_error(cmd) = DID_OK;
+- aic7xxx_status(cmd) = 0;
+- cmd->host_scribble = NULL;
++ /*
++ * Construct the SCB beforehand, so the sequencer is
++ * paused a minimal amount of time.
++ */
++ aic7xxx_buildscb(p, cmd, scb);
+
+- scb->flags |= SCB_ACTIVE | SCB_WAITINGQ;
++ scb->flags |= SCB_ACTIVE | SCB_WAITINGQ;
+
+- DRIVER_LOCK
+- scbq_insert_tail(&p->waiting_scbs, scb);
+- if ( (p->flags & (AHC_IN_ISR | AHC_IN_ABORT | AHC_IN_RESET)) == 0)
+- {
+- aic7xxx_run_waiting_queues(p);
+- }
+- DRIVER_UNLOCK
++ DRIVER_LOCK
++ scbq_insert_tail(&p->waiting_scbs, scb);
++ if ( (p->flags & (AHC_IN_ISR | AHC_IN_ABORT | AHC_IN_RESET)) == 0)
++ {
++ aic7xxx_run_waiting_queues(p);
+ }
++ DRIVER_UNLOCK
+ return (0);
+ }
+
+@@ -11394,6 +11240,12 @@
+ aic_inb(p, SCSISIGI),
+ aic_inb(p, SEQADDR0) | (aic_inb(p, SEQADDR1) << 8),
+ aic_inb(p, SSTAT0), aic_inb(p, SSTAT1));
++ printk(INFO_LEAD "SG_CACHEPTR 0x%x, SSTAT2 0x%x, STCNT 0x%x\n", p->host_no,
++ CTL_OF_SCB(scb),
++ (p->features & AHC_ULTRA2) ? aic_inb(p, SG_CACHEPTR) : 0,
++ aic_inb(p, SSTAT2),
++ aic_inb(p, STCNT + 2) << 16 | aic_inb(p, STCNT + 1) << 8 |
++ aic_inb(p, STCNT));
+ }
+
+ channel = cmd->channel;
+@@ -11687,7 +11539,6 @@
+ #if LINUX_VERSION_CODE < KERNEL_VERSION(2,1,95)
+ unsigned long cpu_flags = 0;
+ #endif
+- Scsi_Cmnd *cmd_next, *cmd_prev;
+
+ p = (struct aic7xxx_host *) cmd->host->hostdata;
+ scb = (p->scb_data->scb_array[aic7xxx_position(cmd)]);
+@@ -11718,13 +11569,11 @@
+ {
+ aic7xxx_isr(p->irq, p, (void *)NULL);
+ pause_sequencer(p);
+- aic7xxx_done_cmds_complete(p);
+ }
++ aic7xxx_done_cmds_complete(p);
+
+- if ((scb == NULL) || (cmd->serial_number != cmd->serial_number_at_timeout))
+- /* Totally bogus cmd since it points beyond our */
+- { /* valid SCB range or doesn't even match it's own*/
+- /* timeout serial number. */
++ if (scb == NULL)
++ {
+ if (aic7xxx_verbose & VERBOSE_ABORT_MID)
+ printk(INFO_LEAD "Abort called with bogus Scsi_Cmnd "
+ "pointer.\n", p->host_no, CTL_OF_CMD(cmd));
+@@ -11743,28 +11592,6 @@
+ /* finish successfully, or to indicate that we */
+ /* don't have this cmd any more and the mid level */
+ /* code needs to find it. */
+- cmd_next = p->completeq.head;
+- cmd_prev = NULL;
+- while (cmd_next != NULL)
+- {
+- if (cmd_next == cmd)
+- {
+- if (aic7xxx_verbose & VERBOSE_ABORT_PROCESS)
+- printk(INFO_LEAD "Abort called for command "
+- "on completeq, completing.\n", p->host_no, CTL_OF_CMD(cmd));
+- if ( cmd_prev == NULL )
+- p->completeq.head = (Scsi_Cmnd *)cmd_next->host_scribble;
+- else
+- cmd_prev->host_scribble = cmd_next->host_scribble;
+- cmd_next->scsi_done(cmd_next);
+- unpause_sequencer(p, FALSE);
+- DRIVER_UNLOCK
+- return(SCSI_ABORT_NOT_RUNNING); /* It's already back as a successful
+- * completion */
+- }
+- cmd_prev = cmd_next;
+- cmd_next = (Scsi_Cmnd *)cmd_next->host_scribble;
+- }
+ if (aic7xxx_verbose & VERBOSE_ABORT_MID)
+ printk(INFO_LEAD "Abort called for already completed"
+ " command.\n", p->host_no, CTL_OF_CMD(cmd));
+@@ -11822,8 +11649,20 @@
+ found = 0;
+ p->flags |= AHC_IN_ABORT;
+ if (aic7xxx_verbose & VERBOSE_ABORT)
+- printk(INFO_LEAD "Aborting scb %d, flags 0x%x\n",
+- p->host_no, CTL_OF_SCB(scb), scb->hscb->tag, scb->flags);
++ {
++ printk(INFO_LEAD "Aborting scb %d, flags 0x%x, SEQADDR 0x%x, LASTPHASE "
++ "0x%x\n",
++ p->host_no, CTL_OF_SCB(scb), scb->hscb->tag, scb->flags,
++ 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, CTL_OF_SCB(scb), (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, CTL_OF_SCB(scb), aic_inb(p, SSTAT0),
++ aic_inb(p, SSTAT1), aic_inb(p, SSTAT2));
++ }
+
+ /*
+ * First, let's check to see if the currently running command is our target
+@@ -11851,6 +11690,16 @@
+ if (aic7xxx_verbose & VERBOSE_ABORT_PROCESS)
+ printk(INFO_LEAD "SCB is currently active. "
+ "Waiting on completion.\n", p->host_no, CTL_OF_SCB(scb));
++ printk(INFO_LEAD "SCSISIGI 0x%x, SEQADDR 0x%x, SSTAT0 0x%x, SSTAT1 "
++ "0x%x\n", p->host_no, CTL_OF_SCB(scb),
++ aic_inb(p, SCSISIGI),
++ aic_inb(p, SEQADDR0) | (aic_inb(p, SEQADDR1) << 8),
++ aic_inb(p, SSTAT0), aic_inb(p, SSTAT1));
++ printk(INFO_LEAD "SG_CACHEPTR 0x%x, SSTAT2 0x%x, STCNT 0x%x\n",
++ p->host_no, CTL_OF_SCB(scb),
++ (p->features & AHC_ULTRA2) ? aic_inb(p, SG_CACHEPTR) : 0,
++ aic_inb(p, SSTAT2), aic_inb(p, STCNT + 2) << 16 |
++ aic_inb(p, STCNT + 1) << 8 | aic_inb(p, STCNT));
+ unpause_sequencer(p, FALSE);
+ p->flags &= ~AHC_IN_ABORT;
+ scb->flags |= SCB_RECOVERY_SCB; /* Note the fact that we've been */
+@@ -11866,35 +11715,7 @@
+ if ((found == 0) && (scb->flags & SCB_WAITINGQ))
+ {
+ int tindex = TARGET_INDEX(cmd);
+- unsigned short mask;
+-
+- mask = (1 << tindex);
+
+- if (p->dtr_pending & mask)
+- {
+- if (p->dev_dtr_cmnd[tindex]->next != cmd)
+- found = 1;
+- else
+- found = 0;
+- }
+- else
+- {
+- found = 1;
+- }
+- if (found == 0)
+- {
+- /*
+- * OK..this means the command we are currently getting an abort
+- * for has an outstanding negotiation command in front of it.
+- * We don't really have a way to tie back into the negotiation
+- * commands, so we just send this back as pending, then it
+- * will get reset in 2 seconds.
+- */
+- unpause_sequencer(p, TRUE);
+- scb->flags |= SCB_ABORT;
+- DRIVER_UNLOCK
+- return(SCSI_ABORT_PENDING);
+- }
+ if (aic7xxx_verbose & VERBOSE_ABORT_PROCESS)
+ printk(INFO_LEAD "SCB found on waiting list and "
+ "aborted.\n", p->host_no, CTL_OF_SCB(scb));
+@@ -12051,10 +11872,8 @@
+ #define DEVICE_RESET 0x01
+ #define BUS_RESET 0x02
+ #define HOST_RESET 0x04
+-#define FAIL 0x08
+-#define RESET_DELAY 0x10
++#define RESET_DELAY 0x08
+ int action;
+- Scsi_Cmnd *cmd_prev, *cmd_next;
+
+
+ if ( cmd == NULL )
+@@ -12082,86 +11901,32 @@
+ DRIVER_LOCK
+
+ pause_sequencer(p);
+- while ( (aic_inb(p, INTSTAT) & INT_PEND) && !(p->flags & AHC_IN_ISR))
+- {
+- aic7xxx_isr(p->irq, p, (void *)NULL );
+- pause_sequencer(p);
+- aic7xxx_done_cmds_complete(p);
+- }
+
+- if (scb == NULL)
++ if(flags & SCSI_RESET_SYNCHRONOUS)
+ {
+ if (aic7xxx_verbose & VERBOSE_RESET_MID)
+- printk(INFO_LEAD "Reset called with bogus Scsi_Cmnd"
+- "->SCB mapping, improvising.\n", p->host_no, CTL_OF_CMD(cmd));
+- if ( flags & SCSI_RESET_SUGGEST_HOST_RESET )
+- {
+- action = HOST_RESET;
+- }
+- else
+- {
+- action = BUS_RESET;
+- }
++ printk(INFO_LEAD "Reset called for a SYNCHRONOUS reset, flags 0x%x, "
++ "cmd->result 0x%x.\n", p->host_no, CTL_OF_CMD(cmd), flags,
++ cmd->result);
++ scb = NULL;
++ action = HOST_RESET;
+ }
+- else if (scb->cmd != cmd)
++ else if ((scb == NULL) || (scb->cmd != cmd))
+ {
+ if (aic7xxx_verbose & VERBOSE_RESET_MID)
+- printk(INFO_LEAD "Reset called with recycled SCB "
+- "for cmd.\n", p->host_no, CTL_OF_CMD(cmd));
+- cmd_prev = NULL;
+- cmd_next = p->completeq.head;
+- while ( cmd_next != NULL )
+- {
+- if (cmd_next == cmd)
+- {
+- if (aic7xxx_verbose & VERBOSE_RESET_RETURN)
+- printk(INFO_LEAD "Reset, found cmd on completeq"
+- ", completing.\n", p->host_no, CTL_OF_CMD(cmd));
+- unpause_sequencer(p, FALSE);
+- DRIVER_UNLOCK
+- return(SCSI_RESET_NOT_RUNNING);
+- }
+- cmd_prev = cmd_next;
+- cmd_next = (Scsi_Cmnd *)cmd_next->host_scribble;
+- }
+- if ( !(flags & SCSI_RESET_SYNCHRONOUS) )
+- {
+- if (aic7xxx_verbose & VERBOSE_RESET_RETURN)
+- printk(INFO_LEAD "Reset, cmd not found,"
+- " failing.\n", p->host_no, CTL_OF_CMD(cmd));
+- unpause_sequencer(p, FALSE);
+- DRIVER_UNLOCK
+- return(SCSI_RESET_NOT_RUNNING);
+- }
+- else
+- {
+- if (aic7xxx_verbose & VERBOSE_RESET_MID)
+- printk(INFO_LEAD "Reset called, no scb, "
+- "flags 0x%x\n", p->host_no, CTL_OF_CMD(cmd), flags);
+- scb = NULL;
+- action = HOST_RESET;
+- }
++ printk(INFO_LEAD "Reset called with bogus Scsi_Cmnd"
++ "->SCB mapping, failing.\n", p->host_no, CTL_OF_CMD(cmd));
++ aic7xxx_done_cmds_complete(p);
++ aic7xxx_run_waiting_queues(p);
++ unpause_sequencer(p, FALSE);
++ DRIVER_UNLOCK
++ return(SCSI_RESET_NOT_RUNNING);
+ }
+ else
+ {
+ if (aic7xxx_verbose & VERBOSE_RESET_MID)
+ printk(INFO_LEAD "Reset called, scb %d, flags "
+ "0x%x\n", p->host_no, CTL_OF_SCB(scb), scb->hscb->tag, scb->flags);
+- if ( aic7xxx_scb_on_qoutfifo(p, scb) )
+- {
+- if(aic7xxx_verbose & VERBOSE_RESET_RETURN)
+- printk(INFO_LEAD "SCB on qoutfifo, completing.\n", p->host_no,
+- CTL_OF_SCB(scb));
+- if ((aic_inb(p,INTSTAT) & CMDCMPLT) == 0)
+- printk(INFO_LEAD "missed CMDCMPLT interrupt!\n", p->host_no,
+- CTL_OF_SCB(scb));
+- aic7xxx_handle_command_completion_intr(p);
+- aic7xxx_done_cmds_complete(p);
+- aic7xxx_run_waiting_queues(p);
+- unpause_sequencer(p, FALSE);
+- DRIVER_UNLOCK
+- return(SCSI_RESET_SUCCESS);
+- }
+ if ( flags & SCSI_RESET_SUGGEST_HOST_RESET )
+ {
+ action = HOST_RESET;
+@@ -12175,6 +11940,26 @@
+ action = DEVICE_RESET;
+ }
+ }
++
++ while((aic_inb(p, INTSTAT) & INT_PEND) && !(p->flags & AHC_IN_ISR))
++ {
++ aic7xxx_isr(p->irq, p, (void *)NULL );
++ pause_sequencer(p);
++ }
++ aic7xxx_done_cmds_complete(p);
++
++ if(scb && (scb->cmd == NULL))
++ {
++ /*
++ * We just completed the command when we ran the isr stuff, so we no
++ * longer have it.
++ */
++ aic7xxx_run_waiting_queues(p);
++ unpause_sequencer(p, FALSE);
++ DRIVER_UNLOCK
++ return(SCSI_RESET_SUCCESS);
++ }
++
+ if ( (action & DEVICE_RESET) &&
+ (p->dev_flags[tindex] & BUS_DEVICE_RESET_PENDING) )
+ {
+@@ -12234,14 +12019,13 @@
+ switch (action)
+ {
+ case RESET_DELAY:
++ aic7xxx_run_waiting_queues(p);
+ unpause_sequencer(p, FALSE);
+ DRIVER_UNLOCK
+- return(SCSI_RESET_PENDING);
+- break;
+- case FAIL:
+- unpause_sequencer(p, FALSE);
+- DRIVER_UNLOCK
+- return(SCSI_RESET_ERROR);
++ if(scb == NULL)
++ return(SCSI_RESET_PUNT);
++ else
++ return(SCSI_RESET_PENDING);
+ break;
+ case DEVICE_RESET:
+ p->flags |= AHC_IN_RESET;
+@@ -12259,7 +12043,7 @@
+ case HOST_RESET:
+ default:
+ p->flags |= AHC_IN_RESET | AHC_RESET_DELAY;
+- p->dev_expires[p->scsi_id] = jiffies + (3 * HZ);
++ p->dev_expires[p->scsi_id] = jiffies + (1 * HZ);
+ p->dev_timer_active |= (0x01 << p->scsi_id);
+ if ( !(p->dev_timer_active & (0x01 << MAX_TARGETS)) ||
+ time_after_eq(p->dev_timer.expires, p->dev_expires[p->scsi_id]) )
+@@ -12288,21 +12072,14 @@
+ p->msg_index = 0;
+ p->msg_len = 0;
+ }
+- aic7xxx_run_done_queue(p, TRUE);
+- /*
+- * If this a SCSI_RESET_SYNCHRONOUS then the command we were given is
+- * in need of being re-started, so send it on through to aic7xxx_queue
+- * and let it set until the delay is over. This keeps it from dying
+- * entirely and avoids getting a bogus dead command back through the
+- * mid-level code due to too many retries.
+- */
+-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,1,132)
+- if ( flags & SCSI_RESET_SYNCHRONOUS )
++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,1,95)
++ if(flags & SCSI_RESET_SYNCHRONOUS)
+ {
+- cmd->result = DID_BUS_BUSY << 16;
++ cmd->result = DID_RESET << 16;
+ cmd->done(cmd);
+ }
+ #endif
++ aic7xxx_run_done_queue(p, TRUE);
+ p->flags &= ~AHC_IN_RESET;
+ /*
+ * We can't rely on run_waiting_queues to unpause the sequencer for
+@@ -12313,7 +12090,10 @@
+ aic7xxx_run_waiting_queues(p);
+ unpause_sequencer(p, FALSE);
+ DRIVER_UNLOCK
+- return(result);
++ if(scb == NULL)
++ return(SCSI_RESET_SUCCESS|SCSI_RESET_HOST_RESET);
++ else
++ return(result);
+ break;
+ }
+ }
+@@ -12623,7 +12403,7 @@
+ }
+
+
+-#include "aic7xxx_proc.c"
++#include "aic7xxx/aic7xxx_proc.c"
+
+ #ifdef MODULE
+ /* Eventually this will go into an include file, but this will be later */
+diff -U 3 -rN linux-2.2.17/drivers/scsi/aic7xxx.h linux/drivers/scsi/aic7xxx.h
+--- linux-2.2.17/drivers/scsi/aic7xxx.h Tue May 11 13:36:28 1999
++++ linux/drivers/scsi/aic7xxx.h Wed Dec 31 19:00:00 1969
+@@ -1,114 +0,0 @@
+-/*+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_proc.c linux/drivers/scsi/aic7xxx_proc.c
+--- linux-2.2.17/drivers/scsi/aic7xxx_proc.c Wed May 3 20:16:44 2000
++++ linux/drivers/scsi/aic7xxx_proc.c Wed Dec 31 19:00:00 1969
+@@ -1,414 +0,0 @@
+-/*+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_reg.h linux/drivers/scsi/aic7xxx_reg.h
+--- linux-2.2.17/drivers/scsi/aic7xxx_reg.h Wed May 3 20:16:44 2000
++++ linux/drivers/scsi/aic7xxx_reg.h Wed Dec 31 19:00:00 1969
+@@ -1,629 +0,0 @@
+-/*
+- * 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 BRDCTL0 0x01
+-#define BRDSTB_ULTRA2 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 TRACEPOINT 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 QOUTCNT 0x9e
+-
+-#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 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 RD_DFTHRSH_MIN 0x00
+-#define WR_DFTHRSH_MIN 0x00
+-
+-#define SG_CACHEPTR 0xfc
+-#define SG_USER_DATA 0xfc
+-#define LAST_SEG 0x02
+-#define LAST_SEG_DONE 0x01
+-
+-
+-#define CMD_GROUP_CODE_SHIFT 0x05
+-#define BUS_8_BIT 0x00
+-#define QOUTFIFO_OFFSET 0x01
+-#define CCSGRAM_MAXSEGS 0x10
+-#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 MAX_OFFSET_ULTRA2 0x7f
+-#define MAX_OFFSET_16BIT 0x08
+-#define UNTAGGEDSCB_OFFSET 0x00
+-#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_seq.c linux/drivers/scsi/aic7xxx_seq.c
+--- linux-2.2.17/drivers/scsi/aic7xxx_seq.c Mon Sep 4 13:39:21 2000
++++ linux/drivers/scsi/aic7xxx_seq.c Wed Dec 31 19:00:00 1969
+@@ -1,745 +0,0 @@
+-/*
+- * 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, 0xca, 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, 0x3e, 0x5c,
+- 0xff, 0x4e, 0xc8, 0x18,
+- 0x02, 0x6a, 0x54, 0x5b,
+- 0xff, 0x52, 0x20, 0x09,
+- 0x0d, 0x6a, 0x6a, 0x00,
+- 0x00, 0x52, 0xca, 0x5b,
+- 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, 0x9e, 0x5b,
+- 0xff, 0x3d, 0xc8, 0x08,
+- 0xbf, 0x64, 0xe2, 0x78,
+- 0x80, 0x64, 0xac, 0x71,
+- 0xa0, 0x64, 0xdc, 0x71,
+- 0xc0, 0x64, 0xd4, 0x71,
+- 0xe0, 0x64, 0x1c, 0x72,
+- 0x01, 0x6a, 0x22, 0x01,
+- 0x00, 0x65, 0xaa, 0x40,
+- 0xf7, 0x11, 0x22, 0x08,
+- 0x00, 0x65, 0xca, 0x58,
+- 0xff, 0x06, 0xd4, 0x08,
+- 0xf7, 0x01, 0x02, 0x08,
+- 0x09, 0x0c, 0xc4, 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,
+- 0x03, 0xa9, 0x10, 0x30,
+- 0x08, 0x6a, 0xcc, 0x00,
+- 0xa9, 0x6a, 0xb4, 0x5b,
+- 0x00, 0x65, 0x02, 0x41,
+- 0xa8, 0x6a, 0x6a, 0x00,
+- 0x79, 0x6a, 0x6a, 0x00,
+- 0x40, 0x3d, 0xea, 0x68,
+- 0x04, 0x35, 0x6a, 0x00,
+- 0x00, 0x65, 0x0e, 0x5b,
+- 0x80, 0x6a, 0xd4, 0x01,
+- 0x10, 0x36, 0xd6, 0x68,
+- 0x10, 0x36, 0x6c, 0x00,
+- 0x07, 0xac, 0x10, 0x31,
+- 0x03, 0x8c, 0x10, 0x30,
+- 0x05, 0xa3, 0x70, 0x30,
+- 0x88, 0x6a, 0xcc, 0x00,
+- 0xac, 0x6a, 0xac, 0x5b,
+- 0x00, 0x65, 0xa6, 0x5b,
+- 0x38, 0x6a, 0xcc, 0x00,
+- 0xa3, 0x6a, 0xb0, 0x5b,
+- 0xff, 0x38, 0x12, 0x69,
+- 0x80, 0x02, 0x04, 0x00,
+- 0xe7, 0x35, 0x6a, 0x08,
+- 0x03, 0x69, 0x18, 0x31,
+- 0x03, 0x69, 0x10, 0x30,
+- 0xff, 0x6a, 0x10, 0x00,
+- 0xff, 0x6a, 0x12, 0x00,
+- 0xff, 0x6a, 0x14, 0x00,
+- 0x01, 0x38, 0x18, 0x61,
+- 0xbf, 0x35, 0x6a, 0x08,
+- 0x02, 0x6a, 0xf8, 0x01,
+- 0xff, 0x69, 0xca, 0x08,
+- 0xff, 0x35, 0x26, 0x09,
+- 0x04, 0x0b, 0x1c, 0x69,
+- 0x04, 0x0b, 0x28, 0x69,
+- 0x10, 0x0c, 0x1e, 0x79,
+- 0x04, 0x0b, 0x28, 0x69,
+- 0xff, 0x6a, 0xca, 0x08,
+- 0x00, 0x35, 0xee, 0x5a,
+- 0x80, 0x02, 0x7c, 0x69,
+- 0xff, 0x65, 0x6c, 0x79,
+- 0xff, 0x38, 0x70, 0x18,
+- 0xff, 0x38, 0x6c, 0x79,
+- 0x80, 0xea, 0x48, 0x61,
+- 0xef, 0x38, 0xc8, 0x18,
+- 0x80, 0x6a, 0xc8, 0x00,
+- 0x00, 0x65, 0x3a, 0x49,
+- 0x33, 0x38, 0xc8, 0x28,
+- 0xff, 0x64, 0xd0, 0x09,
+- 0x04, 0x39, 0xc0, 0x31,
+- 0x09, 0x6a, 0xd6, 0x01,
+- 0x80, 0xeb, 0x40, 0x79,
+- 0xf7, 0xeb, 0xd6, 0x09,
+- 0x08, 0xeb, 0x44, 0x69,
+- 0x01, 0x6a, 0xd6, 0x01,
+- 0x08, 0xe9, 0x10, 0x31,
+- 0x03, 0x8c, 0x10, 0x30,
+- 0x88, 0x6a, 0xcc, 0x00,
+- 0x39, 0x6a, 0xb2, 0x5b,
+- 0x08, 0x6a, 0x18, 0x01,
+- 0xff, 0x6a, 0x1a, 0x09,
+- 0xff, 0x6a, 0x1c, 0x09,
+- 0x0d, 0x93, 0x26, 0x01,
+- 0x00, 0x65, 0x30, 0x5c,
+- 0x88, 0x6a, 0x20, 0x5c,
+- 0x00, 0x65, 0xa6, 0x5b,
+- 0xff, 0x6a, 0xc8, 0x08,
+- 0x08, 0x39, 0x72, 0x18,
+- 0x00, 0x3a, 0x74, 0x20,
+- 0x01, 0x0c, 0x64, 0x79,
+- 0x10, 0x0c, 0x02, 0x79,
+- 0xff, 0x35, 0x26, 0x09,
+- 0x04, 0x0b, 0x6a, 0x69,
+- 0x00, 0x65, 0x84, 0x59,
+- 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,
+- 0x00, 0x65, 0x84, 0x59,
+- 0x7f, 0x02, 0x04, 0x08,
+- 0xe1, 0x6a, 0x22, 0x01,
+- 0x00, 0x65, 0xaa, 0x40,
+- 0x04, 0x93, 0x9a, 0x69,
+- 0xdf, 0x93, 0x26, 0x09,
+- 0x20, 0x93, 0x88, 0x69,
+- 0x02, 0x93, 0x26, 0x01,
+- 0x01, 0x94, 0x8a, 0x79,
+- 0x01, 0x94, 0x8a, 0x79,
+- 0x01, 0x94, 0x8a, 0x79,
+- 0x01, 0x94, 0x8a, 0x79,
+- 0x01, 0x94, 0x8a, 0x79,
+- 0x01, 0x94, 0x8a, 0x79,
+- 0x10, 0x94, 0x98, 0x69,
+- 0x7f, 0x05, 0xa0, 0x69,
+- 0x02, 0x03, 0xa0, 0x79,
+- 0x11, 0x0c, 0x9c, 0x79,
+- 0xd7, 0x93, 0x26, 0x09,
+- 0x28, 0x93, 0xa2, 0x69,
+- 0x03, 0x08, 0x52, 0x31,
+- 0xff, 0x38, 0x50, 0x09,
+- 0x12, 0x01, 0x02, 0x00,
+- 0xff, 0x6a, 0xd4, 0x0c,
+- 0x00, 0x65, 0x0e, 0x5b,
+- 0x05, 0xb4, 0x10, 0x31,
+- 0x02, 0x6a, 0x1a, 0x31,
+- 0x03, 0x8c, 0x10, 0x30,
+- 0x88, 0x6a, 0xcc, 0x00,
+- 0xb4, 0x6a, 0xb0, 0x5b,
+- 0xff, 0x6a, 0x1a, 0x09,
+- 0xff, 0x6a, 0x1c, 0x09,
+- 0x00, 0x65, 0xa6, 0x5b,
+- 0x3d, 0x6a, 0xee, 0x5a,
+- 0xac, 0x6a, 0x26, 0x01,
+- 0x04, 0x0b, 0xc2, 0x69,
+- 0x04, 0x0b, 0xc8, 0x69,
+- 0x10, 0x0c, 0xc4, 0x79,
+- 0x02, 0x03, 0xcc, 0x79,
+- 0x11, 0x0c, 0xc8, 0x79,
+- 0xd7, 0x93, 0x26, 0x09,
+- 0x28, 0x93, 0xce, 0x69,
+- 0x12, 0x01, 0x02, 0x00,
+- 0x00, 0x65, 0xaa, 0x40,
+- 0x00, 0x65, 0x0e, 0x5b,
+- 0xff, 0x06, 0x44, 0x09,
+- 0x00, 0x65, 0xaa, 0x40,
+- 0x10, 0x3d, 0x06, 0x00,
+- 0xff, 0x34, 0xca, 0x08,
+- 0x80, 0x65, 0x00, 0x62,
+- 0x0f, 0xa1, 0xca, 0x08,
+- 0x07, 0xa1, 0xca, 0x08,
+- 0x40, 0xa0, 0xc8, 0x08,
+- 0x00, 0x65, 0xca, 0x00,
+- 0x80, 0x65, 0xca, 0x00,
+- 0x80, 0xa0, 0xf0, 0x79,
+- 0xff, 0x65, 0x0c, 0x08,
+- 0x00, 0x65, 0x02, 0x42,
+- 0x20, 0xa0, 0x08, 0x7a,
+- 0xff, 0x65, 0x0c, 0x08,
+- 0x00, 0x65, 0x9e, 0x5b,
+- 0xa0, 0x3d, 0x10, 0x62,
+- 0x23, 0xa0, 0x0c, 0x08,
+- 0x00, 0x65, 0x9e, 0x5b,
+- 0xa0, 0x3d, 0x10, 0x62,
+- 0x00, 0xb9, 0x08, 0x42,
+- 0xff, 0x65, 0x08, 0x62,
+- 0xa1, 0x6a, 0x22, 0x01,
+- 0xff, 0x6a, 0xd4, 0x08,
+- 0x10, 0x51, 0x10, 0x72,
+- 0x40, 0x6a, 0x18, 0x00,
+- 0xff, 0x65, 0x0c, 0x08,
+- 0x00, 0x65, 0x9e, 0x5b,
+- 0xa0, 0x3d, 0xda, 0x71,
+- 0x40, 0x6a, 0x18, 0x00,
+- 0xff, 0x34, 0xa6, 0x08,
+- 0x80, 0x34, 0x18, 0x62,
+- 0x7f, 0xa0, 0x40, 0x09,
+- 0x08, 0x6a, 0x68, 0x00,
+- 0x00, 0x65, 0xaa, 0x40,
+- 0x64, 0x6a, 0xe4, 0x5a,
+- 0x80, 0x64, 0x8e, 0x6a,
+- 0x04, 0x64, 0x70, 0x72,
+- 0x02, 0x64, 0x76, 0x72,
+- 0x00, 0x6a, 0x38, 0x72,
+- 0x03, 0x64, 0x8a, 0x72,
+- 0x01, 0x64, 0x6c, 0x72,
+- 0x07, 0x64, 0xcc, 0x72,
+- 0x08, 0x64, 0x34, 0x72,
+- 0x23, 0x64, 0xd0, 0x72,
+- 0x11, 0x6a, 0x22, 0x01,
+- 0x07, 0x6a, 0xd6, 0x5a,
+- 0xff, 0x06, 0xd4, 0x08,
+- 0x00, 0x65, 0xaa, 0x40,
+- 0xff, 0xa8, 0x3c, 0x6a,
+- 0xff, 0xa2, 0x54, 0x7a,
+- 0x01, 0x6a, 0x6a, 0x00,
+- 0x00, 0xb9, 0xca, 0x5b,
+- 0xff, 0xa2, 0x54, 0x7a,
+- 0x71, 0x6a, 0x22, 0x01,
+- 0xff, 0x6a, 0xd4, 0x08,
+- 0x40, 0x51, 0x54, 0x62,
+- 0x0d, 0x6a, 0x6a, 0x00,
+- 0x00, 0xb9, 0xca, 0x5b,
+- 0xff, 0x3e, 0x74, 0x09,
+- 0xff, 0x90, 0x7c, 0x08,
+- 0x00, 0x65, 0x4e, 0x58,
+- 0x00, 0x65, 0xbc, 0x40,
+- 0x20, 0xa0, 0x5c, 0x6a,
+- 0xff, 0x37, 0xc8, 0x08,
+- 0x00, 0x6a, 0x74, 0x5b,
+- 0xff, 0x6a, 0x8a, 0x5b,
+- 0xff, 0xf8, 0xc8, 0x08,
+- 0xff, 0x4f, 0xc8, 0x08,
+- 0x01, 0x6a, 0x74, 0x5b,
+- 0x00, 0xb9, 0x8a, 0x5b,
+- 0x01, 0x4f, 0x9e, 0x18,
+- 0x02, 0x6a, 0x22, 0x01,
+- 0x00, 0x65, 0x38, 0x5c,
+- 0x00, 0x65, 0xbc, 0x40,
+- 0x41, 0x6a, 0x22, 0x01,
+- 0x00, 0x65, 0xaa, 0x40,
+- 0x04, 0xa0, 0x40, 0x01,
+- 0x00, 0x65, 0x50, 0x5c,
+- 0x00, 0x65, 0xbc, 0x40,
+- 0x10, 0x36, 0x34, 0x7a,
+- 0x05, 0x38, 0x46, 0x31,
+- 0x04, 0x14, 0x58, 0x31,
+- 0x03, 0xa9, 0x60, 0x31,
+- 0xa3, 0x6a, 0xcc, 0x00,
+- 0x38, 0x6a, 0xb0, 0x5b,
+- 0xac, 0x6a, 0xcc, 0x00,
+- 0x14, 0x6a, 0xb2, 0x5b,
+- 0xa9, 0x6a, 0xb4, 0x5b,
+- 0x00, 0x65, 0x34, 0x42,
+- 0xef, 0x36, 0x6c, 0x08,
+- 0x00, 0x65, 0x34, 0x42,
+- 0x0f, 0x64, 0xc8, 0x08,
+- 0x07, 0x64, 0xc8, 0x08,
+- 0x00, 0x37, 0x6e, 0x00,
+- 0xff, 0x6a, 0xa4, 0x00,
+- 0x00, 0x65, 0x44, 0x5b,
+- 0xff, 0x51, 0xa0, 0x72,
+- 0x20, 0x36, 0xaa, 0x7a,
+- 0x00, 0x90, 0x32, 0x5b,
+- 0x00, 0x65, 0xac, 0x42,
+- 0xff, 0x06, 0xd4, 0x08,
+- 0x00, 0x65, 0x9e, 0x5b,
+- 0xe0, 0x3d, 0xc6, 0x62,
+- 0x20, 0x12, 0xc6, 0x62,
+- 0x51, 0x6a, 0xda, 0x5a,
+- 0x00, 0x65, 0x2c, 0x5b,
+- 0xff, 0x37, 0xc8, 0x08,
+- 0x00, 0xa1, 0xbe, 0x62,
+- 0x04, 0xa0, 0xbe, 0x7a,
+- 0xfb, 0xa0, 0x40, 0x09,
+- 0x80, 0x36, 0x6c, 0x00,
+- 0x80, 0xa0, 0x34, 0x7a,
+- 0x7f, 0xa0, 0x40, 0x09,
+- 0xff, 0x6a, 0xd6, 0x5a,
+- 0x00, 0x65, 0x34, 0x42,
+- 0x04, 0xa0, 0xc4, 0x7a,
+- 0x00, 0x65, 0x50, 0x5c,
+- 0x00, 0x65, 0xc6, 0x42,
+- 0x00, 0x65, 0x38, 0x5c,
+- 0x31, 0x6a, 0x22, 0x01,
+- 0x0c, 0x6a, 0xd6, 0x5a,
+- 0x00, 0x65, 0x34, 0x42,
+- 0x61, 0x6a, 0x22, 0x01,
+- 0x00, 0x65, 0x34, 0x42,
+- 0x51, 0x6a, 0xda, 0x5a,
+- 0x51, 0x6a, 0x22, 0x01,
+- 0x00, 0x65, 0x34, 0x42,
+- 0x10, 0x3d, 0x06, 0x00,
+- 0xff, 0x65, 0x68, 0x0c,
+- 0xff, 0x06, 0xd4, 0x08,
+- 0x01, 0x0c, 0xdc, 0x7a,
+- 0x04, 0x0c, 0xde, 0x6a,
+- 0xe0, 0x03, 0x7a, 0x08,
+- 0xe0, 0x3d, 0xea, 0x62,
+- 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, 0xfe, 0x6a,
+- 0x10, 0x0c, 0xf0, 0x7a,
+- 0x04, 0x0b, 0xf8, 0x6a,
+- 0xff, 0x6a, 0xca, 0x08,
+- 0x04, 0x93, 0xfc, 0x6a,
+- 0x01, 0x94, 0xfa, 0x7a,
+- 0x10, 0x94, 0xfc, 0x6a,
+- 0x80, 0x3d, 0x02, 0x73,
+- 0x0f, 0x04, 0x06, 0x6b,
+- 0x02, 0x03, 0x06, 0x7b,
+- 0x11, 0x0c, 0x02, 0x7b,
+- 0xc7, 0x93, 0x26, 0x09,
+- 0xff, 0x99, 0xd4, 0x08,
+- 0x38, 0x93, 0x08, 0x6b,
+- 0xff, 0x6a, 0xd4, 0x0c,
+- 0x80, 0x36, 0x0c, 0x6b,
+- 0x21, 0x6a, 0x22, 0x05,
+- 0xff, 0x65, 0x20, 0x09,
+- 0xff, 0x51, 0x1a, 0x63,
+- 0xff, 0x37, 0xc8, 0x08,
+- 0xa1, 0x6a, 0x26, 0x43,
+- 0xff, 0x51, 0xc8, 0x08,
+- 0xb9, 0x6a, 0x26, 0x43,
+- 0xff, 0x90, 0xa4, 0x08,
+- 0xff, 0xba, 0x2a, 0x73,
+- 0xff, 0xba, 0x20, 0x09,
+- 0xff, 0x65, 0xca, 0x18,
+- 0x00, 0x6c, 0x1e, 0x63,
+- 0xff, 0x90, 0xca, 0x0c,
+- 0xff, 0x6a, 0xca, 0x04,
+- 0x20, 0x36, 0x3e, 0x7b,
+- 0x00, 0x90, 0x12, 0x5b,
+- 0xff, 0x65, 0x3e, 0x73,
+- 0xff, 0x52, 0x3c, 0x73,
+- 0xff, 0xba, 0xcc, 0x08,
+- 0xff, 0x52, 0x20, 0x09,
+- 0xff, 0x66, 0x74, 0x09,
+- 0xff, 0x65, 0x20, 0x0d,
+- 0xff, 0xba, 0x7e, 0x0c,
+- 0x00, 0x6a, 0x3e, 0x5c,
+- 0x0d, 0x6a, 0x6a, 0x00,
+- 0x00, 0x51, 0xca, 0x43,
+- 0xff, 0x3f, 0x98, 0x73,
+- 0xff, 0x6a, 0xa2, 0x00,
+- 0x00, 0x3f, 0x12, 0x5b,
+- 0xff, 0x65, 0x98, 0x73,
+- 0x20, 0x36, 0x6c, 0x00,
+- 0x20, 0xa0, 0x52, 0x6b,
+- 0xff, 0xb9, 0xa2, 0x0c,
+- 0xff, 0x6a, 0xa2, 0x04,
+- 0xff, 0x65, 0xa4, 0x08,
+- 0xe0, 0x6a, 0xcc, 0x00,
+- 0x45, 0x6a, 0xbe, 0x5b,
+- 0x01, 0x6a, 0xd0, 0x01,
+- 0x09, 0x6a, 0xd6, 0x01,
+- 0x80, 0xeb, 0x5e, 0x7b,
+- 0x01, 0x6a, 0xd6, 0x01,
+- 0x01, 0xe9, 0xa4, 0x34,
+- 0x88, 0x6a, 0xcc, 0x00,
+- 0x45, 0x6a, 0xbe, 0x5b,
+- 0x01, 0x6a, 0x18, 0x01,
+- 0xff, 0x6a, 0x1a, 0x09,
+- 0xff, 0x6a, 0x1c, 0x09,
+- 0x0d, 0x6a, 0x26, 0x01,
+- 0x00, 0x65, 0x30, 0x5c,
+- 0xff, 0x99, 0xa4, 0x0c,
+- 0xff, 0x65, 0xa4, 0x08,
+- 0xe0, 0x6a, 0xcc, 0x00,
+- 0x45, 0x6a, 0xbe, 0x5b,
+- 0x01, 0x6a, 0xd0, 0x01,
+- 0x01, 0x6a, 0xdc, 0x05,
+- 0x88, 0x6a, 0xcc, 0x00,
+- 0x45, 0x6a, 0xbe, 0x5b,
+- 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, 0x8e, 0x7b,
+- 0xff, 0x6a, 0xdc, 0x0d,
+- 0xff, 0x65, 0x32, 0x09,
+- 0x0a, 0x93, 0x26, 0x01,
+- 0x00, 0x65, 0x30, 0x44,
+- 0xff, 0x37, 0xc8, 0x08,
+- 0x00, 0x6a, 0x54, 0x5b,
+- 0xff, 0x52, 0xa2, 0x0c,
+- 0x01, 0x0c, 0x9e, 0x7b,
+- 0x04, 0x0c, 0x9e, 0x6b,
+- 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, 0xba, 0x5b,
+- 0xff, 0x90, 0xe2, 0x09,
+- 0x20, 0x6a, 0xd0, 0x01,
+- 0x04, 0x35, 0xdc, 0x7b,
+- 0x1d, 0x6a, 0xdc, 0x01,
+- 0xdc, 0xee, 0xd8, 0x63,
+- 0x00, 0x65, 0xe8, 0x43,
+- 0x01, 0x6a, 0xdc, 0x01,
+- 0x20, 0xa0, 0xd8, 0x31,
+- 0x09, 0xee, 0xdc, 0x01,
+- 0x80, 0xee, 0xe2, 0x7b,
+- 0x19, 0x6a, 0xdc, 0x01,
+- 0xd8, 0xee, 0xe6, 0x63,
+- 0xff, 0x6a, 0xdc, 0x09,
+- 0x18, 0xee, 0xea, 0x6b,
+- 0xff, 0x6a, 0xd4, 0x0c,
+- 0x88, 0x6a, 0xcc, 0x00,
+- 0x41, 0x6a, 0xba, 0x5b,
+- 0x20, 0x6a, 0x18, 0x01,
+- 0xff, 0x6a, 0x1a, 0x09,
+- 0xff, 0x6a, 0x1c, 0x09,
+- 0xff, 0x35, 0x26, 0x09,
+- 0x04, 0x35, 0x14, 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, 0x00, 0x64,
+- 0x0a, 0x93, 0x26, 0x01,
+- 0x00, 0x65, 0x30, 0x5c,
+- 0x04, 0x35, 0x0c, 0x7b,
+- 0xa0, 0x6a, 0x20, 0x5c,
+- 0x00, 0x65, 0x22, 0x5c,
+- 0x00, 0x65, 0x22, 0x5c,
+- 0x00, 0x65, 0x22, 0x44,
+- 0xff, 0x65, 0xcc, 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, 0x30, 0x7c,
+- 0xf7, 0x93, 0x26, 0x09,
+- 0x08, 0x93, 0x34, 0x6c,
+- 0xff, 0x6a, 0xd4, 0x0c,
+- 0xff, 0x40, 0x74, 0x09,
+- 0xff, 0x90, 0x80, 0x08,
+- 0xff, 0x6a, 0x72, 0x05,
+- 0xff, 0x40, 0x4c, 0x64,
+- 0xff, 0x3f, 0x44, 0x64,
+- 0xff, 0x6a, 0xca, 0x04,
+- 0xff, 0x3f, 0x20, 0x09,
+- 0x01, 0x6a, 0x6a, 0x00,
+- 0x00, 0xb9, 0xca, 0x5b,
+- 0xff, 0xba, 0x7e, 0x0c,
+- 0xff, 0x40, 0x20, 0x09,
+- 0xff, 0xba, 0x80, 0x0c,
+- 0xff, 0x3f, 0x74, 0x09,
+- 0xff, 0x90, 0x7e, 0x0c,
+-};
+-
+-static int aic7xxx_patch12_func(struct aic7xxx_host *p);
+-
+-static int
+-aic7xxx_patch12_func(struct aic7xxx_host *p)
+-{
+- return ((p->features & AHC_WIDE) != 0);
+-}
+-
+-static int aic7xxx_patch11_func(struct aic7xxx_host *p);
+-
+-static int
+-aic7xxx_patch11_func(struct aic7xxx_host *p)
+-{
+- return ((p->features & AHC_ULTRA2) == 0);
+-}
+-
+-static int aic7xxx_patch10_func(struct aic7xxx_host *p);
+-
+-static int
+-aic7xxx_patch10_func(struct aic7xxx_host *p)
+-{
+- return ((p->features & AHC_CMD_CHAN) == 0);
+-}
+-
+-static int aic7xxx_patch9_func(struct aic7xxx_host *p);
+-
+-static int
+-aic7xxx_patch9_func(struct aic7xxx_host *p)
+-{
+- return ((p->chip & AHC_CHIPID_MASK) == AHC_AIC7895);
+-}
+-
+-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, 102, 1, 2 },
+- { aic7xxx_patch0_func, 103, 2, 1 },
+- { aic7xxx_patch7_func, 107, 2, 1 },
+- { aic7xxx_patch9_func, 109, 1, 1 },
+- { aic7xxx_patch10_func, 110, 2, 1 },
+- { aic7xxx_patch7_func, 113, 1, 2 },
+- { aic7xxx_patch0_func, 114, 1, 1 },
+- { aic7xxx_patch1_func, 118, 1, 1 },
+- { aic7xxx_patch1_func, 121, 3, 2 },
+- { aic7xxx_patch0_func, 124, 5, 1 },
+- { aic7xxx_patch1_func, 132, 2, 3 },
+- { aic7xxx_patch7_func, 132, 1, 1 },
+- { aic7xxx_patch0_func, 134, 3, 1 },
+- { aic7xxx_patch11_func, 138, 1, 2 },
+- { aic7xxx_patch0_func, 139, 1, 1 },
+- { aic7xxx_patch7_func, 140, 7, 2 },
+- { aic7xxx_patch0_func, 147, 1, 1 },
+- { aic7xxx_patch1_func, 152, 14, 3 },
+- { aic7xxx_patch11_func, 165, 1, 1 },
+- { aic7xxx_patch0_func, 166, 9, 1 },
+- { aic7xxx_patch7_func, 180, 2, 1 },
+- { aic7xxx_patch7_func, 182, 1, 1 },
+- { aic7xxx_patch11_func, 183, 6, 3 },
+- { aic7xxx_patch1_func, 183, 2, 2 },
+- { aic7xxx_patch0_func, 185, 4, 1 },
+- { aic7xxx_patch7_func, 190, 1, 1 },
+- { aic7xxx_patch7_func, 194, 20, 1 },
+- { aic7xxx_patch1_func, 215, 3, 3 },
+- { aic7xxx_patch11_func, 217, 1, 1 },
+- { aic7xxx_patch0_func, 218, 5, 1 },
+- { aic7xxx_patch11_func, 223, 1, 2 },
+- { aic7xxx_patch0_func, 224, 9, 1 },
+- { aic7xxx_patch12_func, 240, 1, 2 },
+- { aic7xxx_patch0_func, 241, 1, 1 },
+- { aic7xxx_patch4_func, 302, 1, 2 },
+- { aic7xxx_patch0_func, 303, 1, 1 },
+- { aic7xxx_patch2_func, 306, 1, 1 },
+- { aic7xxx_patch1_func, 316, 3, 2 },
+- { aic7xxx_patch0_func, 319, 5, 1 },
+- { aic7xxx_patch12_func, 327, 1, 2 },
+- { aic7xxx_patch0_func, 328, 1, 1 },
+- { aic7xxx_patch5_func, 333, 1, 1 },
+- { aic7xxx_patch11_func, 375, 15, 1 },
+- { aic7xxx_patch1_func, 427, 7, 2 },
+- { aic7xxx_patch0_func, 434, 8, 1 },
+- { aic7xxx_patch1_func, 443, 4, 2 },
+- { aic7xxx_patch0_func, 447, 6, 1 },
+- { aic7xxx_patch1_func, 453, 4, 2 },
+- { aic7xxx_patch0_func, 457, 3, 1 },
+- { aic7xxx_patch10_func, 467, 10, 1 },
+- { aic7xxx_patch1_func, 486, 17, 4 },
+- { aic7xxx_patch9_func, 494, 4, 2 },
+- { aic7xxx_patch0_func, 498, 2, 1 },
+- { aic7xxx_patch0_func, 503, 33, 1 },
+- { aic7xxx_patch10_func, 536, 4, 1 },
+- { aic7xxx_patch5_func, 540, 2, 1 },
+- { aic7xxx_patch5_func, 543, 9, 1 },
+-
+-};
0x12, 0x6a, 0x00, 0x00,
0xff, 0x6a, 0xd6, 0x09,
0xff, 0x6a, 0xdc, 0x09,
- 0x00, 0x65, 0xcc, 0x58,
+ 0x00, 0x65, 0xca, 0x58,
0xf7, 0x01, 0x02, 0x08,
0xff, 0x4e, 0xc8, 0x08,
0xbf, 0x60, 0xc0, 0x08,
0x00, 0x4d, 0x10, 0x70,
0x01, 0x4e, 0x9c, 0x18,
0xbf, 0x60, 0xc0, 0x08,
- 0x00, 0x6a, 0xce, 0x5c,
+ 0x00, 0x6a, 0x86, 0x5c,
0xff, 0x4e, 0xc8, 0x18,
- 0x02, 0x6a, 0xb8, 0x5b,
+ 0x02, 0x6a, 0x70, 0x5b,
0xff, 0x52, 0x20, 0x09,
0x0d, 0x6a, 0x6a, 0x00,
- 0x00, 0x52, 0x2e, 0x5c,
+ 0x00, 0x52, 0xe6, 0x5b,
0x03, 0xb0, 0x52, 0x31,
0xff, 0xb0, 0x52, 0x09,
0xff, 0xb1, 0x54, 0x09,
0x08, 0x6a, 0x66, 0x58,
0x80, 0x6a, 0x68, 0x00,
0x80, 0x36, 0x6c, 0x00,
- 0x00, 0x65, 0x02, 0x5c,
+ 0x00, 0x65, 0xba, 0x5b,
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,
+ 0xbf, 0x64, 0xe2, 0x78,
+ 0x80, 0x64, 0xc8, 0x71,
+ 0xa0, 0x64, 0xf8, 0x71,
+ 0xc0, 0x64, 0xf0, 0x71,
+ 0xe0, 0x64, 0x38, 0x72,
0x01, 0x6a, 0x22, 0x01,
0x00, 0x65, 0xaa, 0x40,
0xf7, 0x11, 0x22, 0x08,
- 0x00, 0x65, 0xcc, 0x58,
+ 0x00, 0x65, 0xca, 0x58,
0xff, 0x06, 0xd4, 0x08,
0xf7, 0x01, 0x02, 0x08,
- 0x09, 0x0c, 0xc6, 0x78,
+ 0x09, 0x0c, 0xc4, 0x78,
0x08, 0x0c, 0x0c, 0x68,
0x01, 0x6a, 0x22, 0x01,
0xff, 0x6a, 0x26, 0x09,
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,
+ 0xa9, 0x6a, 0xd0, 0x5b,
+ 0x00, 0x65, 0x02, 0x41,
+ 0xa8, 0x6a, 0x6a, 0x00,
0x79, 0x6a, 0x6a, 0x00,
- 0x40, 0x3d, 0x8e, 0x69,
+ 0x40, 0x3d, 0xea, 0x68,
0x04, 0x35, 0x6a, 0x00,
- 0x00, 0x65, 0x72, 0x5b,
+ 0x00, 0x65, 0x2a, 0x5b,
0x80, 0x6a, 0xd4, 0x01,
- 0x10, 0x36, 0x80, 0x69,
+ 0x10, 0x36, 0xd6, 0x68,
0x10, 0x36, 0x6c, 0x00,
0x07, 0xac, 0x10, 0x31,
- 0x03, 0x8c, 0x10, 0x30,
0x05, 0xa3, 0x70, 0x30,
+ 0x03, 0x8c, 0x10, 0x30,
0x88, 0x6a, 0xcc, 0x00,
- 0xac, 0x6a, 0x10, 0x5c,
- 0x00, 0x65, 0x0a, 0x5c,
+ 0xac, 0x6a, 0xc8, 0x5b,
+ 0x00, 0x65, 0xc2, 0x5b,
0x38, 0x6a, 0xcc, 0x00,
- 0xa3, 0x6a, 0x14, 0x5c,
- 0xff, 0x38, 0xb4, 0x69,
+ 0xa3, 0x6a, 0xcc, 0x5b,
+ 0xff, 0x38, 0x12, 0x69,
0x80, 0x02, 0x04, 0x00,
0xe7, 0x35, 0x6a, 0x08,
+ 0x03, 0x69, 0x18, 0x31,
0x03, 0x69, 0x10, 0x30,
0xff, 0x6a, 0x10, 0x00,
0xff, 0x6a, 0x12, 0x00,
0xff, 0x6a, 0x14, 0x00,
- 0x01, 0x38, 0xb8, 0x61,
+ 0x22, 0x38, 0xc8, 0x28,
+ 0x01, 0x38, 0x1c, 0x61,
+ 0x02, 0x64, 0xc8, 0x00,
+ 0x01, 0x38, 0x1c, 0x61,
0xbf, 0x35, 0x6a, 0x08,
- 0x00, 0x35, 0x52, 0x5b,
- 0x80, 0x02, 0x0a, 0x6a,
- 0xff, 0x65, 0xfa, 0x79,
- 0x01, 0x38, 0xfa, 0x71,
+ 0xff, 0x64, 0xf8, 0x09,
+ 0xff, 0x35, 0x26, 0x09,
+ 0x80, 0x02, 0xa4, 0x69,
+ 0x10, 0x0c, 0x7a, 0x69,
+ 0x80, 0x94, 0x22, 0x79,
+ 0x00, 0x35, 0x0a, 0x5b,
+ 0x80, 0x02, 0xa4, 0x69,
+ 0xff, 0x65, 0x94, 0x79,
+ 0x01, 0x38, 0x70, 0x71,
0xff, 0x38, 0x70, 0x18,
- 0x80, 0xea, 0xda, 0x61,
+ 0xff, 0x38, 0x94, 0x79,
+ 0x80, 0xea, 0x4a, 0x61,
0xef, 0x38, 0xc8, 0x18,
0x80, 0x6a, 0xc8, 0x00,
- 0x00, 0x65, 0xcc, 0x49,
+ 0x00, 0x65, 0x3c, 0x49,
0x33, 0x38, 0xc8, 0x28,
0xff, 0x64, 0xd0, 0x09,
0x04, 0x39, 0xc0, 0x31,
0x09, 0x6a, 0xd6, 0x01,
- 0x80, 0xeb, 0xd2, 0x79,
+ 0x80, 0xeb, 0x42, 0x79,
0xf7, 0xeb, 0xd6, 0x09,
- 0x08, 0xeb, 0xd6, 0x69,
+ 0x08, 0xeb, 0x46, 0x69,
0x01, 0x6a, 0xd6, 0x01,
0x08, 0xe9, 0x10, 0x31,
0x03, 0x8c, 0x10, 0x30,
+ 0xff, 0x38, 0x70, 0x18,
0x88, 0x6a, 0xcc, 0x00,
- 0x39, 0x6a, 0x16, 0x5c,
+ 0x39, 0x6a, 0xce, 0x5b,
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,
+ 0x00, 0x65, 0x78, 0x5c,
+ 0x88, 0x6a, 0xcc, 0x00,
+ 0x00, 0x65, 0x6a, 0x5c,
+ 0x00, 0x65, 0xc2, 0x5b,
0xff, 0x6a, 0xc8, 0x08,
0x08, 0x39, 0x72, 0x18,
0x00, 0x3a, 0x74, 0x20,
- 0x01, 0x0c, 0xf6, 0x79,
- 0x10, 0x0c, 0xa6, 0x79,
+ 0x00, 0x65, 0x02, 0x41,
+ 0x01, 0x0c, 0x6c, 0x79,
+ 0x10, 0x0c, 0x02, 0x79,
+ 0x10, 0x0c, 0x7a, 0x69,
+ 0x01, 0xfc, 0x70, 0x79,
0xff, 0x6a, 0x70, 0x08,
+ 0x01, 0x0c, 0x76, 0x79,
+ 0x10, 0x0c, 0x02, 0x79,
+ 0x00, 0x65, 0xae, 0x59,
+ 0x01, 0xfc, 0x94, 0x69,
+ 0x40, 0x0d, 0x84, 0x69,
+ 0xb1, 0x6a, 0x22, 0x01,
+ 0x00, 0x65, 0x94, 0x41,
+ 0x2e, 0xfc, 0xa2, 0x28,
+ 0x3f, 0x38, 0xc8, 0x08,
+ 0x00, 0x51, 0x94, 0x71,
+ 0xff, 0x6a, 0xc8, 0x08,
+ 0xf8, 0x39, 0x72, 0x18,
+ 0xff, 0x3a, 0x74, 0x20,
+ 0x01, 0x38, 0x70, 0x18,
+ 0x00, 0x65, 0x86, 0x41,
0x03, 0x08, 0x52, 0x31,
0xff, 0x38, 0x50, 0x09,
+ 0x12, 0x01, 0x02, 0x00,
0xff, 0x08, 0x52, 0x09,
0xff, 0x09, 0x54, 0x09,
0xff, 0x0a, 0x56, 0x09,
0xff, 0x38, 0x50, 0x09,
0x00, 0x65, 0xaa, 0x40,
+ 0x10, 0x0c, 0xa4, 0x79,
+ 0x00, 0x65, 0xae, 0x59,
0x7f, 0x02, 0x04, 0x08,
0xe1, 0x6a, 0x22, 0x01,
0x00, 0x65, 0xaa, 0x40,
- 0x00, 0x65, 0x72, 0x5b,
+ 0x04, 0x93, 0xc2, 0x69,
+ 0xdf, 0x93, 0x26, 0x09,
+ 0x20, 0x93, 0xb2, 0x69,
+ 0x02, 0x93, 0x26, 0x01,
+ 0x01, 0x94, 0xb6, 0x79,
+ 0x01, 0x94, 0xb6, 0x79,
+ 0x01, 0x94, 0xb6, 0x79,
+ 0x01, 0x94, 0xb6, 0x79,
+ 0x01, 0x94, 0xb6, 0x79,
+ 0x10, 0x94, 0xc0, 0x69,
+ 0xd7, 0x93, 0x26, 0x09,
+ 0x28, 0x93, 0xc4, 0x69,
+ 0xff, 0x6a, 0xd4, 0x0c,
+ 0x00, 0x65, 0x2a, 0x5b,
0x05, 0xb4, 0x10, 0x31,
0x02, 0x6a, 0x1a, 0x31,
0x03, 0x8c, 0x10, 0x30,
0x88, 0x6a, 0xcc, 0x00,
- 0xb4, 0x6a, 0x14, 0x5c,
+ 0xb4, 0x6a, 0xcc, 0x5b,
0xff, 0x6a, 0x1a, 0x09,
0xff, 0x6a, 0x1c, 0x09,
- 0x00, 0x65, 0x0a, 0x5c,
- 0x3d, 0x6a, 0x52, 0x5b,
+ 0x00, 0x65, 0xc2, 0x5b,
+ 0x3d, 0x6a, 0x0a, 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,
+ 0x04, 0x0b, 0xde, 0x69,
+ 0x04, 0x0b, 0xe4, 0x69,
+ 0x10, 0x0c, 0xe0, 0x79,
+ 0x02, 0x03, 0xe8, 0x79,
+ 0x11, 0x0c, 0xe4, 0x79,
0xd7, 0x93, 0x26, 0x09,
- 0x28, 0x93, 0x32, 0x6a,
+ 0x28, 0x93, 0xea, 0x69,
0x12, 0x01, 0x02, 0x00,
0x00, 0x65, 0xaa, 0x40,
- 0x00, 0x65, 0x72, 0x5b,
+ 0x00, 0x65, 0x2a, 0x5b,
0xff, 0x06, 0x44, 0x09,
0x00, 0x65, 0xaa, 0x40,
0x10, 0x3d, 0x06, 0x00,
0xff, 0x34, 0xca, 0x08,
- 0x80, 0x65, 0x64, 0x62,
+ 0x80, 0x65, 0x1c, 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,
+ 0x80, 0xa0, 0x0c, 0x7a,
0xff, 0x65, 0x0c, 0x08,
- 0x00, 0x65, 0x66, 0x42,
- 0x20, 0xa0, 0x6c, 0x7a,
+ 0x00, 0x65, 0x1e, 0x42,
+ 0x20, 0xa0, 0x24, 0x7a,
0xff, 0x65, 0x0c, 0x08,
- 0x00, 0x65, 0x02, 0x5c,
- 0xa0, 0x3d, 0x74, 0x62,
+ 0x00, 0x65, 0xba, 0x5b,
+ 0xa0, 0x3d, 0x2c, 0x62,
0x23, 0xa0, 0x0c, 0x08,
- 0x00, 0x65, 0x02, 0x5c,
- 0xa0, 0x3d, 0x74, 0x62,
- 0x00, 0xb9, 0x6c, 0x42,
- 0xff, 0x65, 0x6c, 0x62,
+ 0x00, 0x65, 0xba, 0x5b,
+ 0xa0, 0x3d, 0x2c, 0x62,
+ 0x00, 0xb9, 0x24, 0x42,
+ 0xff, 0x65, 0x24, 0x62,
0xa1, 0x6a, 0x22, 0x01,
0xff, 0x6a, 0xd4, 0x08,
- 0x10, 0x51, 0x74, 0x72,
+ 0x10, 0x51, 0x2c, 0x72,
0x40, 0x6a, 0x18, 0x00,
0xff, 0x65, 0x0c, 0x08,
- 0x00, 0x65, 0x02, 0x5c,
- 0xa0, 0x3d, 0x3e, 0x72,
+ 0x00, 0x65, 0xba, 0x5b,
+ 0xa0, 0x3d, 0xf6, 0x71,
0x40, 0x6a, 0x18, 0x00,
0xff, 0x34, 0xa6, 0x08,
- 0x80, 0x34, 0x7c, 0x62,
+ 0x80, 0x34, 0x34, 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,
+ 0x64, 0x6a, 0x00, 0x5b,
+ 0x80, 0x64, 0xaa, 0x6a,
+ 0x04, 0x64, 0x8c, 0x72,
+ 0x02, 0x64, 0x92, 0x72,
+ 0x00, 0x6a, 0x54, 0x72,
+ 0x03, 0x64, 0xa6, 0x72,
+ 0x01, 0x64, 0x88, 0x72,
+ 0x07, 0x64, 0xe8, 0x72,
+ 0x08, 0x64, 0x50, 0x72,
+ 0x23, 0x64, 0xec, 0x72,
0x11, 0x6a, 0x22, 0x01,
- 0x07, 0x6a, 0x3a, 0x5b,
+ 0x07, 0x6a, 0xf2, 0x5a,
0xff, 0x06, 0xd4, 0x08,
0x00, 0x65, 0xaa, 0x40,
- 0xff, 0xa8, 0xa0, 0x6a,
- 0xff, 0xa2, 0xb8, 0x7a,
+ 0xff, 0xa8, 0x58, 0x6a,
+ 0xff, 0xa2, 0x70, 0x7a,
0x01, 0x6a, 0x6a, 0x00,
- 0x00, 0xb9, 0x2e, 0x5c,
- 0xff, 0xa2, 0xb8, 0x7a,
+ 0x00, 0xb9, 0xe6, 0x5b,
+ 0xff, 0xa2, 0x70, 0x7a,
0x71, 0x6a, 0x22, 0x01,
0xff, 0x6a, 0xd4, 0x08,
- 0x40, 0x51, 0xb8, 0x62,
+ 0x40, 0x51, 0x70, 0x62,
0x0d, 0x6a, 0x6a, 0x00,
- 0x00, 0xb9, 0x2e, 0x5c,
+ 0x00, 0xb9, 0xe6, 0x5b,
0xff, 0x3e, 0x74, 0x09,
0xff, 0x90, 0x7c, 0x08,
0x00, 0x65, 0x4e, 0x58,
- 0x00, 0x65, 0xbe, 0x40,
- 0x20, 0xa0, 0xc0, 0x6a,
+ 0x00, 0x65, 0xbc, 0x40,
+ 0x20, 0xa0, 0x78, 0x6a,
0xff, 0x37, 0xc8, 0x08,
- 0x00, 0x6a, 0xd8, 0x5b,
- 0xff, 0x6a, 0xee, 0x5b,
+ 0x00, 0x6a, 0x90, 0x5b,
+ 0xff, 0x6a, 0xa6, 0x5b,
0xff, 0xf8, 0xc8, 0x08,
0xff, 0x4f, 0xc8, 0x08,
- 0x01, 0x6a, 0xd8, 0x5b,
- 0x00, 0xb9, 0xee, 0x5b,
+ 0x01, 0x6a, 0x90, 0x5b,
+ 0x00, 0xb9, 0xa6, 0x5b,
0x01, 0x4f, 0x9e, 0x18,
0x02, 0x6a, 0x22, 0x01,
- 0x00, 0x65, 0xc8, 0x5c,
- 0x00, 0x65, 0xbe, 0x40,
+ 0x00, 0x65, 0x80, 0x5c,
+ 0x00, 0x65, 0xbc, 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,
+ 0x00, 0x65, 0x98, 0x5c,
+ 0x00, 0x65, 0xbc, 0x40,
+ 0x10, 0x36, 0x50, 0x7a,
0x05, 0x38, 0x46, 0x31,
0x04, 0x14, 0x58, 0x31,
0x03, 0xa9, 0x60, 0x31,
0xa3, 0x6a, 0xcc, 0x00,
- 0x38, 0x6a, 0x14, 0x5c,
+ 0x38, 0x6a, 0xcc, 0x5b,
0xac, 0x6a, 0xcc, 0x00,
- 0x14, 0x6a, 0x16, 0x5c,
- 0xa9, 0x6a, 0x18, 0x5c,
- 0x00, 0x65, 0x98, 0x42,
+ 0x14, 0x6a, 0xce, 0x5b,
+ 0xa9, 0x6a, 0xd0, 0x5b,
+ 0x00, 0x65, 0x50, 0x42,
0xef, 0x36, 0x6c, 0x08,
- 0x00, 0x65, 0x98, 0x42,
+ 0x00, 0x65, 0x50, 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,
+ 0x00, 0x65, 0x60, 0x5b,
+ 0xff, 0x51, 0xbc, 0x72,
+ 0x20, 0x36, 0xc6, 0x7a,
+ 0x00, 0x90, 0x4e, 0x5b,
+ 0x00, 0x65, 0xc8, 0x42,
0xff, 0x06, 0xd4, 0x08,
- 0x00, 0x65, 0x02, 0x5c,
- 0xe0, 0x3d, 0x2a, 0x63,
- 0x20, 0x12, 0x2a, 0x63,
- 0x51, 0x6a, 0x3e, 0x5b,
- 0x00, 0x65, 0x90, 0x5b,
+ 0x00, 0x65, 0xba, 0x5b,
+ 0xe0, 0x3d, 0xe2, 0x62,
+ 0x20, 0x12, 0xe2, 0x62,
+ 0x51, 0x6a, 0xf6, 0x5a,
+ 0x00, 0x65, 0x48, 0x5b,
0xff, 0x37, 0xc8, 0x08,
- 0x00, 0xa1, 0x22, 0x63,
- 0x04, 0xa0, 0x22, 0x7b,
+ 0x00, 0xa1, 0xda, 0x62,
+ 0x04, 0xa0, 0xda, 0x7a,
0xfb, 0xa0, 0x40, 0x09,
0x80, 0x36, 0x6c, 0x00,
- 0x80, 0xa0, 0x98, 0x7a,
+ 0x80, 0xa0, 0x50, 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,
+ 0xff, 0x6a, 0xf2, 0x5a,
+ 0x00, 0x65, 0x50, 0x42,
+ 0x04, 0xa0, 0xe0, 0x7a,
+ 0x00, 0x65, 0x98, 0x5c,
+ 0x00, 0x65, 0xe2, 0x42,
+ 0x00, 0x65, 0x80, 0x5c,
0x31, 0x6a, 0x22, 0x01,
- 0x0c, 0x6a, 0x3a, 0x5b,
- 0x00, 0x65, 0x98, 0x42,
+ 0x0c, 0x6a, 0xf2, 0x5a,
+ 0x00, 0x65, 0x50, 0x42,
0x61, 0x6a, 0x22, 0x01,
- 0x00, 0x65, 0x98, 0x42,
- 0x51, 0x6a, 0x3e, 0x5b,
+ 0x00, 0x65, 0x50, 0x42,
+ 0x51, 0x6a, 0xf6, 0x5a,
0x51, 0x6a, 0x22, 0x01,
- 0x00, 0x65, 0x98, 0x42,
+ 0x00, 0x65, 0x50, 0x42,
0x10, 0x3d, 0x06, 0x00,
0xff, 0x65, 0x68, 0x0c,
0xff, 0x06, 0xd4, 0x08,
- 0x01, 0x0c, 0x40, 0x7b,
- 0x04, 0x0c, 0x42, 0x6b,
+ 0x01, 0x0c, 0xf8, 0x7a,
+ 0x04, 0x0c, 0xfa, 0x6a,
0xe0, 0x03, 0x7a, 0x08,
- 0xe0, 0x3d, 0x4e, 0x63,
+ 0xe0, 0x3d, 0x06, 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,
+ 0x01, 0x0b, 0x1a, 0x6b,
+ 0x10, 0x0c, 0x0c, 0x7b,
+ 0x04, 0x0b, 0x14, 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,
+ 0x04, 0x93, 0x18, 0x6b,
+ 0x01, 0x94, 0x16, 0x7b,
+ 0x10, 0x94, 0x18, 0x6b,
+ 0x80, 0x3d, 0x1e, 0x73,
+ 0x0f, 0x04, 0x22, 0x6b,
+ 0x02, 0x03, 0x22, 0x7b,
+ 0x11, 0x0c, 0x1e, 0x7b,
0xc7, 0x93, 0x26, 0x09,
0xff, 0x99, 0xd4, 0x08,
- 0x38, 0x93, 0x6c, 0x6b,
+ 0x38, 0x93, 0x24, 0x6b,
0xff, 0x6a, 0xd4, 0x0c,
- 0x80, 0x36, 0x70, 0x6b,
+ 0x80, 0x36, 0x28, 0x6b,
0x21, 0x6a, 0x22, 0x05,
0xff, 0x65, 0x20, 0x09,
- 0xff, 0x51, 0x7e, 0x63,
+ 0xff, 0x51, 0x36, 0x63,
0xff, 0x37, 0xc8, 0x08,
- 0xa1, 0x6a, 0x8a, 0x43,
+ 0xa1, 0x6a, 0x42, 0x43,
0xff, 0x51, 0xc8, 0x08,
- 0xb9, 0x6a, 0x8a, 0x43,
+ 0xb9, 0x6a, 0x42, 0x43,
0xff, 0x90, 0xa4, 0x08,
- 0xff, 0xba, 0x8e, 0x73,
+ 0xff, 0xba, 0x46, 0x73,
0xff, 0xba, 0x20, 0x09,
0xff, 0x65, 0xca, 0x18,
- 0x00, 0x6c, 0x82, 0x63,
+ 0x00, 0x6c, 0x3a, 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,
+ 0x20, 0x36, 0x5a, 0x7b,
+ 0x00, 0x90, 0x2e, 0x5b,
+ 0xff, 0x65, 0x5a, 0x73,
+ 0xff, 0x52, 0x58, 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,
+ 0x00, 0x6a, 0x86, 0x5c,
0x0d, 0x6a, 0x6a, 0x00,
- 0x00, 0x51, 0x2e, 0x44,
- 0xff, 0x3f, 0xfc, 0x73,
+ 0x00, 0x51, 0xe6, 0x43,
+ 0xff, 0x3f, 0xb4, 0x73,
0xff, 0x6a, 0xa2, 0x00,
- 0x00, 0x3f, 0x76, 0x5b,
- 0xff, 0x65, 0xfc, 0x73,
+ 0x00, 0x3f, 0x2e, 0x5b,
+ 0xff, 0x65, 0xb4, 0x73,
0x20, 0x36, 0x6c, 0x00,
- 0x20, 0xa0, 0xb6, 0x6b,
+ 0x20, 0xa0, 0x6e, 0x6b,
0xff, 0xb9, 0xa2, 0x0c,
0xff, 0x6a, 0xa2, 0x04,
0xff, 0x65, 0xa4, 0x08,
0xe0, 0x6a, 0xcc, 0x00,
- 0x45, 0x6a, 0x22, 0x5c,
+ 0x45, 0x6a, 0xda, 0x5b,
0x01, 0x6a, 0xd0, 0x01,
0x09, 0x6a, 0xd6, 0x01,
- 0x80, 0xeb, 0xc2, 0x7b,
+ 0x80, 0xeb, 0x7a, 0x7b,
0x01, 0x6a, 0xd6, 0x01,
0x01, 0xe9, 0xa4, 0x34,
0x88, 0x6a, 0xcc, 0x00,
- 0x45, 0x6a, 0x22, 0x5c,
+ 0x45, 0x6a, 0xda, 0x5b,
0x01, 0x6a, 0x18, 0x01,
0xff, 0x6a, 0x1a, 0x09,
0xff, 0x6a, 0x1c, 0x09,
0x0d, 0x6a, 0x26, 0x01,
- 0x00, 0x65, 0xc0, 0x5c,
+ 0x00, 0x65, 0x78, 0x5c,
0xff, 0x99, 0xa4, 0x0c,
0xff, 0x65, 0xa4, 0x08,
0xe0, 0x6a, 0xcc, 0x00,
- 0x45, 0x6a, 0x22, 0x5c,
+ 0x45, 0x6a, 0xda, 0x5b,
0x01, 0x6a, 0xd0, 0x01,
0x01, 0x6a, 0xdc, 0x05,
0x88, 0x6a, 0xcc, 0x00,
- 0x45, 0x6a, 0x22, 0x5c,
+ 0x45, 0x6a, 0xda, 0x5b,
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,
+ 0x80, 0xee, 0xaa, 0x7b,
0xff, 0x6a, 0xdc, 0x0d,
0xff, 0x65, 0x32, 0x09,
0x0a, 0x93, 0x26, 0x01,
- 0x00, 0x65, 0xc0, 0x44,
+ 0x00, 0x65, 0x78, 0x44,
0xff, 0x37, 0xc8, 0x08,
- 0x00, 0x6a, 0xb8, 0x5b,
+ 0x00, 0x6a, 0x70, 0x5b,
0xff, 0x52, 0xa2, 0x0c,
- 0x01, 0x0c, 0x02, 0x7c,
- 0x04, 0x0c, 0x02, 0x6c,
+ 0x01, 0x0c, 0xba, 0x7b,
+ 0x04, 0x0c, 0xba, 0x6b,
0xe0, 0x03, 0x06, 0x08,
0xe0, 0x03, 0x7a, 0x0c,
0xff, 0x8c, 0x10, 0x08,
0x00, 0x6c, 0xda, 0x24,
0xff, 0x65, 0xc8, 0x08,
0xe0, 0x6a, 0xcc, 0x00,
- 0x41, 0x6a, 0x1e, 0x5c,
+ 0x41, 0x6a, 0xd6, 0x5b,
0xff, 0x90, 0xe2, 0x09,
0x20, 0x6a, 0xd0, 0x01,
- 0x04, 0x35, 0x40, 0x7c,
+ 0x04, 0x35, 0xf8, 0x7b,
0x1d, 0x6a, 0xdc, 0x01,
- 0xdc, 0xee, 0x3c, 0x64,
- 0x00, 0x65, 0x56, 0x44,
+ 0xdc, 0xee, 0xf4, 0x63,
+ 0x00, 0x65, 0x0e, 0x44,
0x01, 0x6a, 0xdc, 0x01,
0x20, 0xa0, 0xd8, 0x31,
0x09, 0xee, 0xdc, 0x01,
- 0x80, 0xee, 0x46, 0x7c,
+ 0x80, 0xee, 0xfe, 0x7b,
0x11, 0x6a, 0xdc, 0x01,
- 0x50, 0xee, 0x4a, 0x64,
+ 0x50, 0xee, 0x02, 0x64,
0x20, 0x6a, 0xd0, 0x01,
0x09, 0x6a, 0xdc, 0x01,
- 0x88, 0xee, 0x50, 0x64,
+ 0x88, 0xee, 0x08, 0x64,
0x19, 0x6a, 0xdc, 0x01,
- 0xd8, 0xee, 0x54, 0x64,
+ 0xd8, 0xee, 0x0c, 0x64,
0xff, 0x6a, 0xdc, 0x09,
- 0x18, 0xee, 0x58, 0x6c,
+ 0x18, 0xee, 0x10, 0x6c,
0xff, 0x6a, 0xd4, 0x0c,
0x88, 0x6a, 0xcc, 0x00,
- 0x41, 0x6a, 0x1e, 0x5c,
+ 0x41, 0x6a, 0xd6, 0x5b,
0x20, 0x6a, 0x18, 0x01,
0xff, 0x6a, 0x1a, 0x09,
0xff, 0x6a, 0x1c, 0x09,
0xff, 0x35, 0x26, 0x09,
- 0x04, 0x35, 0x84, 0x6c,
+ 0x04, 0x35, 0x3c, 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,
- 0x00, 0x65, 0x6e, 0x64,
+ 0x00, 0x65, 0x26, 0x64,
0x0a, 0x93, 0x26, 0x01,
- 0x00, 0x65, 0xc0, 0x44,
+ 0x00, 0x65, 0x78, 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,
+ 0x01, 0x94, 0x40, 0x6c,
+ 0x10, 0x94, 0x42, 0x6c,
+ 0x08, 0x94, 0x54, 0x6c,
+ 0x08, 0x94, 0x54, 0x6c,
+ 0x08, 0x94, 0x54, 0x6c,
+ 0x00, 0x65, 0x68, 0x5c,
0x08, 0x64, 0xc8, 0x18,
0x00, 0x8c, 0xca, 0x18,
- 0x00, 0x65, 0x92, 0x4c,
- 0x00, 0x65, 0x88, 0x44,
+ 0x00, 0x65, 0x4a, 0x4c,
+ 0x00, 0x65, 0x40, 0x44,
0xf7, 0x93, 0x26, 0x09,
- 0x08, 0x93, 0x9e, 0x6c,
- 0x00, 0x65, 0xb0, 0x5c,
+ 0x08, 0x93, 0x56, 0x6c,
+ 0x00, 0x65, 0x68, 0x5c,
0x08, 0x64, 0xc8, 0x18,
- 0x08, 0x64, 0xa0, 0x64,
+ 0x08, 0x64, 0x58, 0x64,
0xff, 0x6a, 0xd4, 0x0c,
- 0x00, 0x65, 0xc0, 0x5c,
- 0x00, 0x65, 0xb0, 0x5c,
- 0x00, 0x65, 0xb0, 0x5c,
- 0x00, 0x65, 0xb0, 0x5c,
+ 0x00, 0x65, 0x78, 0x5c,
+ 0x00, 0x65, 0x68, 0x5c,
+ 0x00, 0x65, 0x68, 0x5c,
+ 0x00, 0x65, 0x68, 0x5c,
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,
+ 0x08, 0x94, 0x78, 0x7c,
0xf7, 0x93, 0x26, 0x09,
- 0x08, 0x93, 0xc4, 0x6c,
+ 0x08, 0x93, 0x7c, 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, 0x40, 0x94, 0x64,
+ 0xff, 0x3f, 0x8c, 0x64,
0xff, 0x6a, 0xca, 0x04,
0xff, 0x3f, 0x20, 0x09,
0x01, 0x6a, 0x6a, 0x00,
- 0x00, 0xb9, 0x2e, 0x5c,
+ 0x00, 0xb9, 0xe6, 0x5b,
0xff, 0xba, 0x7e, 0x0c,
0xff, 0x40, 0x20, 0x09,
0xff, 0xba, 0x80, 0x0c,
0xff, 0x90, 0x7e, 0x0c,
};
+static int aic7xxx_patch15_func(struct aic7xxx_host *p);
+
+static int
+aic7xxx_patch15_func(struct aic7xxx_host *p)
+{
+ return ((p->bugs & AHC_BUG_SCBCHAN_UPLOAD) != 0);
+}
+
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);
+ return ((p->bugs & AHC_BUG_PCI_2_1_RETRY) != 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);
+ return ((p->features & AHC_WIDE) != 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);
+ return ((p->bugs & AHC_BUG_AUTOFLUSH) != 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);
+ return ((p->features & AHC_ULTRA2) == 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);
+ return ((p->features & AHC_CMD_CHAN) == 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);
+ return ((p->chip & AHC_CHIPID_MASK) == AHC_AIC7895);
}
static int aic7xxx_patch8_func(struct aic7xxx_host *p);
{ 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 },
+ { aic7xxx_patch7_func, 102, 1, 2 },
+ { aic7xxx_patch0_func, 103, 2, 1 },
+ { aic7xxx_patch7_func, 107, 2, 1 },
+ { aic7xxx_patch9_func, 109, 1, 1 },
+ { aic7xxx_patch10_func, 110, 2, 1 },
+ { aic7xxx_patch7_func, 113, 1, 2 },
+ { aic7xxx_patch0_func, 114, 1, 1 },
+ { aic7xxx_patch1_func, 118, 1, 1 },
+ { aic7xxx_patch1_func, 121, 3, 3 },
+ { aic7xxx_patch11_func, 123, 1, 1 },
+ { aic7xxx_patch0_func, 124, 5, 1 },
+ { aic7xxx_patch7_func, 132, 1, 1 },
+ { aic7xxx_patch9_func, 133, 1, 1 },
+ { aic7xxx_patch10_func, 134, 3, 1 },
+ { aic7xxx_patch7_func, 137, 3, 2 },
+ { aic7xxx_patch0_func, 140, 2, 1 },
+ { aic7xxx_patch7_func, 142, 5, 2 },
+ { aic7xxx_patch0_func, 147, 3, 1 },
+ { aic7xxx_patch7_func, 150, 1, 2 },
+ { aic7xxx_patch0_func, 151, 2, 1 },
+ { aic7xxx_patch1_func, 153, 15, 4 },
+ { aic7xxx_patch11_func, 166, 1, 2 },
+ { aic7xxx_patch0_func, 167, 1, 1 },
+ { aic7xxx_patch0_func, 168, 10, 1 },
+ { aic7xxx_patch7_func, 181, 1, 2 },
+ { aic7xxx_patch0_func, 182, 2, 1 },
+ { aic7xxx_patch7_func, 184, 18, 1 },
+ { aic7xxx_patch1_func, 202, 3, 3 },
+ { aic7xxx_patch7_func, 204, 1, 1 },
+ { aic7xxx_patch0_func, 205, 4, 1 },
+ { aic7xxx_patch7_func, 210, 2, 1 },
+ { aic7xxx_patch7_func, 215, 13, 3 },
+ { aic7xxx_patch12_func, 218, 1, 1 },
+ { aic7xxx_patch12_func, 219, 4, 1 },
+ { aic7xxx_patch1_func, 229, 3, 3 },
+ { aic7xxx_patch11_func, 231, 1, 1 },
+ { aic7xxx_patch0_func, 232, 5, 1 },
+ { aic7xxx_patch11_func, 237, 1, 2 },
+ { aic7xxx_patch0_func, 238, 9, 1 },
+ { aic7xxx_patch13_func, 254, 1, 2 },
+ { aic7xxx_patch0_func, 255, 1, 1 },
+ { aic7xxx_patch4_func, 316, 1, 2 },
+ { aic7xxx_patch0_func, 317, 1, 1 },
+ { aic7xxx_patch2_func, 320, 1, 1 },
+ { aic7xxx_patch1_func, 330, 3, 2 },
+ { aic7xxx_patch0_func, 333, 5, 1 },
+ { aic7xxx_patch13_func, 341, 1, 2 },
+ { aic7xxx_patch0_func, 342, 1, 1 },
+ { aic7xxx_patch5_func, 347, 1, 1 },
+ { aic7xxx_patch11_func, 389, 15, 2 },
+ { aic7xxx_patch14_func, 402, 1, 1 },
+ { aic7xxx_patch1_func, 441, 7, 2 },
+ { aic7xxx_patch0_func, 448, 8, 1 },
+ { aic7xxx_patch1_func, 457, 4, 2 },
+ { aic7xxx_patch0_func, 461, 6, 1 },
+ { aic7xxx_patch1_func, 467, 4, 2 },
+ { aic7xxx_patch0_func, 471, 3, 1 },
+ { aic7xxx_patch10_func, 481, 10, 1 },
+ { aic7xxx_patch1_func, 500, 22, 5 },
+ { aic7xxx_patch11_func, 508, 4, 1 },
+ { aic7xxx_patch7_func, 512, 7, 3 },
+ { aic7xxx_patch15_func, 512, 5, 2 },
+ { aic7xxx_patch0_func, 517, 2, 1 },
+ { aic7xxx_patch10_func, 522, 50, 3 },
+ { aic7xxx_patch14_func, 543, 17, 2 },
+ { aic7xxx_patch0_func, 560, 4, 1 },
+ { aic7xxx_patch10_func, 572, 4, 1 },
+ { aic7xxx_patch5_func, 576, 2, 1 },
+ { aic7xxx_patch5_func, 579, 9, 1 },
};