## Automatically generated incremental diff
## From:   linux-2.2.19-pre10
## To:     linux-2.2.19-pre11
## Robot:  $Id: make-incremental-diff,v 1.6 2001/12/04 04:41:15 hpa Exp $

diff -urN linux-2.2.19-pre10/Documentation/isdn/README.diversion linux/Documentation/isdn/README.diversion
--- linux-2.2.19-pre10/Documentation/isdn/README.diversion	Sun Dec 10 16:49:41 2000
+++ linux/Documentation/isdn/README.diversion	Mon Dec  3 21:02:58 2001
@@ -6,7 +6,7 @@
 the HiSax driver.
 The diversion kernel interface and controlling tool divertctrl were written
 by Werner Cornelius (werner@isdn4linux.de or werner@titro.de) under the
-GNU Public License.
+GNU General Public License.
 
     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
diff -urN linux-2.2.19-pre10/Documentation/isdn/README.hysdn linux/Documentation/isdn/README.hysdn
--- linux-2.2.19-pre10/Documentation/isdn/README.hysdn	Wed Dec 31 16:00:00 1969
+++ linux/Documentation/isdn/README.hysdn	Mon Dec  3 21:02:58 2001
@@ -0,0 +1,195 @@
+$Id: README.hysdn,v 1.3.6.1 2001/02/10 14:41:19 kai Exp $
+The hysdn driver has been written by
+by Werner Cornelius (werner@isdn4linux.de or werner@titro.de) 
+for Hypercope GmbH Aachen Germany. Hypercope agreed to publish this driver
+under the GNU General Public License.
+
+The CAPI 2.0-support was added by Ulrich Albrecht (ualbrecht@hypercope.de)
+for Hypercope GmbH Aachen, Germany.
+
+
+    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 of the License, 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; if not, write to the Free Software
+    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+Table of contents
+=================
+
+1. About the driver
+
+2. Loading/Unloading the driver
+
+3. Entries in the /proc filesystem
+
+4. The /proc/net/hysdn/cardconfX file
+
+5. The /proc/net/hysdn/cardlogX file
+
+6. Where to get additional info and help
+
+
+1. About the driver
+
+   The drivers/isdn/hysdn subdir contains a driver for HYPERCOPEs active 
+   PCI isdn cards Champ, Ergo and Metro. To enable support for this cards
+   enable ISDN support in the kernel config and support for HYSDN cards in
+   the active cards submenu. The driver may only be compiled and used if 
+   support for loadable modules and the process filesystem have been enabled.
+
+   These cards provide two different interfaces to the kernel. Without the
+   optional CAPI 2.0 support, they register as ethernet card. IP-routing
+   to a ISDN-destination is performed on the card itself. All necessary
+   handlers for various protocols like ppp and others as well as config info
+   and firmware may be fetched from Hypercopes WWW-Site www.hypercope.de.
+
+   With CAPI 2.0 support enabled, the card can also be used as a CAPI 2.0 
+   compliant devices with either CAPI 2.0 applications 
+   (check isdn4k-utils) or -using the capidrv module- as a regular
+   isdn4linux device. This is done via the same mechanism as with the 
+   active AVM cards and in fact uses the same module.
+   
+
+2. Loading/Unloading the driver
+
+   The module has no command line parameters and auto detects up to 10 cards
+   in the id-range 0-9.
+   If a loaded driver shall be unloaded all open files in the /proc/net/hysdn
+   subdir need to be closed and all ethernet interfaces allocated by this 
+   driver must be shut down. Otherwise the module counter will avoid a module
+   unload.
+   
+   If you are using the CAPI 2.0-interface, make sure to load/modprobe the
+   kernelcapi-module first.
+
+   If you plan to use the capidrv-link to isdn4linux, make sure to load
+   capidrv.o after all modules using this driver (i.e. after hysdn and
+   any avm-specific modules).
+
+3. Entries in the /proc filesystem
+
+   When the module has been loaded it adds the directory hysdn in the 
+   /proc/net tree. This directory contains exactly 2 file entries for each 
+   card. One is called cardconfX and the other cardlogX, where X is the
+   card id number from 0 to 9. 
+   The cards are numbered in the order found in the PCI config data.
+
+4. The /proc/net/hysdn/cardconfX file
+
+   This file may be read to get by everyone to get info about the cards type, 
+   actual state, available features and used resources.
+   The first 3 entries (id, bus and slot) are PCI info fields, the following
+   type field gives the information about the cards type:
+
+   4 -> Ergo card (server card with 2 b-chans)
+   5 -> Metro card (server card with 4 or 8 b-chans)
+   6 -> Champ card (client card with 2 b-chans)   
+
+   The following 3 fields show the hardware assignments for irq, iobase and the
+   dual ported memory (dp-mem).
+   The fields b-chans and fax-chans announce the available card resources of
+   this types for the user.
+   The state variable indicates the actual drivers state for this card with the
+   following assignments.
+
+   0 -> card has not been booted since driver load
+   1 -> card booting is actually in progess
+   2 -> card is in an error state due to a previous boot failure
+   3 -> card is booted and active
+
+   And the last field (device) shows the name of the ethernet device assigned
+   to this card. Up to the first successful boot this field only shows a -
+   to tell that no net device has been allocated up to now. Once a net device
+   has been allocated it remains assigned to this card, even if a card is
+   rebooted and an boot error occurs. 
+
+   Writing to the cardconfX file boots the card or transfers config lines to 
+   the cards firmware. The type of data is automatically detected when the 
+   first data is written. Only root has write access to this file.
+   The firmware boot files are normally called hyclient.pof for client cards
+   and hyserver.pof for server cards.
+   After successfully writing the boot file, complete config files or single
+   config lines may be copied to this file.
+   If an error occurs the return value given to the writing process has the 
+   following additional codes (decimal):
+
+   1000 Another process is currently bootng the card
+   1001 Invalid firmware header
+   1002 Boards dual-port RAM test failed
+   1003 Internal firmware handler error
+   1004 Boot image size invalid
+   1005 First boot stage (bootstrap loader) failed
+   1006 Second boot stage failure
+   1007 Timeout waiting for card ready during boot
+   1008 Operation only allowed in booted state
+   1009 Config line to long 
+   1010 Invalid channel number 
+   1011 Timeout sending config data
+
+   Additional info about error reasons may be fetched from the log output. 
+
+5. The /proc/net/hysdn/cardlogX file
+   	  
+   The cardlogX file entry may be opened multiple for reading by everyone to 
+   get the cards and drivers log data. Card messages always start with the
+   keyword LOG. All other lines are output from the driver. 
+   The driver log data may be redirected to the syslog by selecting the 
+   appropriate bitmask. The cards log messages will always be send to this
+   interface but never to the syslog.
+
+   A root user may write a decimal or hex (with 0x) value t this file to select
+   desired output options. As mentioned above the cards log dat is always 
+   written to the cardlog file independent of the following options only used
+   to check and debug the driver itself:
+
+   For example: 
+   echo "0x34560078" > /proc/net/hysdn/cardlog0
+   to output the hex log mask 34560078 for card 0.
+ 
+   The written value is regarded as an unsigned 32-Bit value, bit ored for 
+   desired output. The following bits are already assigned:
+
+   0x80000000   All driver log data is alternatively via syslog 
+   0x00000001   Log memory allocation errors
+   0x00000010   Firmware load start and close are logged
+   0x00000020   Log firmware record parser
+   0x00000040   Log every firmware write actions
+   0x00000080   Log all card related boot messages
+   0x00000100   Output all config data sent for debugging purposes
+   0x00000200   Only non comment config lines are shown wth channel
+   0x00000400   Additional conf log output
+   0x00001000   Log the asynchronous scheduler actions (config and log)
+   0x00100000   Log all open and close actions to /proc/net/hysdn/card files
+   0x00200000   Log all actions from /proc file entries
+   0x00010000   Log network interface init and deinit
+   
+6. Where to get additional info and help
+
+   If you have any problems concerning the driver or configuration contact 
+   the Hypercope support team (support@hypercope.de) and or the authors
+   Werner Cornelius (werner@isdn4linux or cornelius@titro.de) or
+   Ulrich Albrecht (ualbrecht@hypercope.de).
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff -urN linux-2.2.19-pre10/Makefile linux/Makefile
--- linux-2.2.19-pre10/Makefile	Mon Dec  3 21:02:11 2001
+++ linux/Makefile	Mon Dec  3 21:02:58 2001
@@ -1,7 +1,7 @@
 VERSION = 2
 PATCHLEVEL = 2
 SUBLEVEL = 19
-EXTRAVERSION = pre10
+EXTRAVERSION = pre11
 
 ARCH := $(shell uname -m | sed -e s/i.86/i386/ -e s/sun4u/sparc64/ -e s/arm.*/arm/ -e s/sa110/arm/)
 
diff -urN linux-2.2.19-pre10/aic7xxx-5.1.32.patch linux/aic7xxx-5.1.32.patch
--- linux-2.2.19-pre10/aic7xxx-5.1.32.patch	Mon Dec  3 21:02:11 2001
+++ linux/aic7xxx-5.1.32.patch	Wed Dec 31 16:00:00 1969
@@ -1,7633 +0,0 @@
-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 },
--
--};
diff -urN linux-2.2.19-pre10/drivers/isdn/Config.in linux/drivers/isdn/Config.in
--- linux-2.2.19-pre10/drivers/isdn/Config.in	Mon Dec  3 21:02:15 2001
+++ linux/drivers/isdn/Config.in	Mon Dec  3 21:02:58 2001
@@ -1,11 +1,15 @@
 #
 # ISDN device configuration
 #
+
+# only included if CONFIG_ISDN != n
+
 if [ "$CONFIG_INET" != "n" ]; then
    bool '  Support synchronous PPP' CONFIG_ISDN_PPP
    if [ "$CONFIG_ISDN_PPP" != "n" ]; then
-      bool '    Use VJ-compression with synchronous PPP' CONFIG_ISDN_PPP_VJ
-      bool '    Support generic MP (RFC 1717)' CONFIG_ISDN_MPP
+      bool         '    Use VJ-compression with synchronous PPP' CONFIG_ISDN_PPP_VJ
+      bool         '    Support generic MP (RFC 1717)' CONFIG_ISDN_MPP
+      dep_tristate '    Support BSD compression' CONFIG_ISDN_PPP_BSDCOMP $CONFIG_ISDN
    fi
 fi
 bool '  Support audio via ISDN' CONFIG_ISDN_AUDIO
@@ -19,7 +23,7 @@
 mainmenu_option next_comment
 comment 'ISDN feature submodules'
    dep_tristate 'isdnloop support' CONFIG_ISDN_DRV_LOOP $CONFIG_ISDN
-   bool 'Support isdn diversion services' CONFIG_ISDN_DIVERSION
+   dep_tristate 'Support isdn diversion services' CONFIG_ISDN_DIVERSION $CONFIG_ISDN
 endmenu
 
 comment 'low-level hardware drivers'
@@ -45,6 +49,7 @@
    bool '  Teles S0Box' CONFIG_HISAX_S0BOX 
    bool '  AVM A1 (Fritz)' CONFIG_HISAX_AVM_A1
    bool '  AVM PnP/PCI (Fritz!PnP/PCI)' CONFIG_HISAX_FRITZPCI
+   bool '  AVM A1 PCMCIA (Fritz)' CONFIG_HISAX_AVM_A1_PCMCIA
    bool '  Elsa cards' CONFIG_HISAX_ELSA
    bool '  ITK ix1-micro Revision 2' CONFIG_HISAX_IX1MICROR2
    bool '  Eicon.Diehl Diva cards' CONFIG_HISAX_DIEHLDIVA
@@ -74,39 +79,53 @@
 fi
 endmenu
 
+### Active ISDN cards
+
 mainmenu_option next_comment
 comment 'Active ISDN cards'
-dep_tristate 'ICN 2B and 4B support' CONFIG_ISDN_DRV_ICN $CONFIG_ISDN
-dep_tristate 'PCBIT-D support' CONFIG_ISDN_DRV_PCBIT $CONFIG_ISDN
-if [ "$CONFIG_EXPERIMENTAL" != "n" ]; then
-   dep_tristate 'Spellcaster support (EXPERIMENTAL)' CONFIG_ISDN_DRV_SC $CONFIG_ISDN
-   dep_tristate 'IBM Active 2000 support (EXPERIMENTAL)' CONFIG_ISDN_DRV_ACT2000 $CONFIG_ISDN
-fi
+
+dep_tristate       'ICN 2B and 4B support' CONFIG_ISDN_DRV_ICN $CONFIG_ISDN
+dep_tristate       'PCBIT-D support' CONFIG_ISDN_DRV_PCBIT $CONFIG_ISDN
+dep_tristate       'Spellcaster support' CONFIG_ISDN_DRV_SC $CONFIG_ISDN
+dep_tristate       'IBM Active 2000 support' CONFIG_ISDN_DRV_ACT2000 $CONFIG_ISDN
+
 dep_tristate 'Eicon active card support' CONFIG_ISDN_DRV_EICON $CONFIG_ISDN
 if [ "$CONFIG_ISDN_DRV_EICON" != "n" ]; then
    bool '  Eicon S,SX,SCOM,Quadro,S2M support' CONFIG_ISDN_DRV_EICON_ISA
 fi
-dep_tristate 'CAPI2.0 support' CONFIG_ISDN_CAPI $CONFIG_ISDN
-if [ "$CONFIG_EXPERIMENTAL" != "n" ]; then
-   bool 'CAPI2.0 Middleware support' CONFIG_ISDN_CAPI_MIDDLEWARE
-   if [ "$CONFIG_ISDN_CAPI_MIDDLEWARE" != "n" ]; then
-   	bool 'CAPI2.0 filesystem support' CONFIG_ISDN_CAPIFS
-   fi
-fi
+
+# CAPI subsystem
+
+tristate           'CAPI2.0 support' CONFIG_ISDN_CAPI
 if [ "$CONFIG_ISDN_CAPI" != "n" ]; then
-   bool '  AVM B1 ISA support' CONFIG_ISDN_DRV_AVMB1_B1ISA
-   bool '  AVM B1 PCI support' CONFIG_ISDN_DRV_AVMB1_B1PCI
-   if [ "$CONFIG_ISDN_DRV_AVMB1_B1PCI" != "n" ]; then
-      if [ "$CONFIG_EXPERIMENTAL" != "n" ]; then
-         bool '  AVM B1 PCI V4 support' CONFIG_ISDN_DRV_AVMB1_B1PCIV4
+   bool            '  Verbose reason code reporting (kernel size +=7K)' CONFIG_ISDN_DRV_AVMB1_VERBOSE_REASON
+   dep_bool        '  CAPI2.0 Middleware support (EXPERIMENTAL)' CONFIG_ISDN_CAPI_MIDDLEWARE $CONFIG_EXPERIMENTAL
+   dep_tristate    '  CAPI2.0 /dev/capi support' CONFIG_ISDN_CAPI_CAPI20 $CONFIG_ISDN_CAPI
+   if [ "$CONFIG_ISDN_CAPI_MIDDLEWARE" = "y" ]; then
+      dep_mbool    '    CAPI2.0 filesystem support' CONFIG_ISDN_CAPI_CAPIFS_BOOL $CONFIG_ISDN_CAPI_CAPI20
+      if [ "$CONFIG_ISDN_CAPI_CAPIFS_BOOL" = "y" ]; then
+	 define_tristate CONFIG_ISDN_CAPI_CAPIFS $CONFIG_ISDN_CAPI_CAPI20
+      else
+	 define_tristate CONFIG_ISDN_CAPI_CAPIFS n
       fi
    fi
-   bool '  AVM T1/T1-B ISA support' CONFIG_ISDN_DRV_AVMB1_T1ISA
-   bool '  AVM B1/M1/M2 PCMCIA support' CONFIG_ISDN_DRV_AVMB1_B1PCMCIA
-   bool '  AVM T1/T1-B PCI support' CONFIG_ISDN_DRV_AVMB1_T1PCI
-   if [ "$CONFIG_EXPERIMENTAL" != "n" ]; then
-      bool '  AVM C4 support' CONFIG_ISDN_DRV_AVMB1_C4
-   fi
-   bool '  Verbose reason code reporting (kernel size +=7K)' CONFIG_ISDN_DRV_AVMB1_VERBOSE_REASON
+   dep_tristate    '  CAPI2.0 capidrv interface support' CONFIG_ISDN_CAPI_CAPIDRV $CONFIG_ISDN_CAPI $CONFIG_ISDN
 fi
+
+# CAPI drivers
+
+if [ "$CONFIG_ISDN_CAPI" != "n" ]; then
+   dep_tristate '  AVM B1 ISA support' CONFIG_ISDN_DRV_AVMB1_B1ISA $CONFIG_ISDN_CAPI
+   dep_tristate '  AVM B1 PCI support' CONFIG_ISDN_DRV_AVMB1_B1PCI $CONFIG_ISDN_CAPI $CONFIG_PCI
+   dep_mbool    '    AVM B1 PCI V4 support' CONFIG_ISDN_DRV_AVMB1_B1PCIV4 $CONFIG_ISDN_DRV_AVMB1_B1PCI
+   dep_tristate '  AVM T1/T1-B ISA support' CONFIG_ISDN_DRV_AVMB1_T1ISA $CONFIG_ISDN_CAPI
+   dep_tristate '  AVM B1/M1/M2 PCMCIA support' CONFIG_ISDN_DRV_AVMB1_B1PCMCIA $CONFIG_ISDN_CAPI $CONFIG_PCMCIA
+   dep_tristate '  AVM T1/T1-B PCI support' CONFIG_ISDN_DRV_AVMB1_T1PCI $CONFIG_ISDN_CAPI $CONFIG_PCI
+   dep_tristate '  AVM C4 support' CONFIG_ISDN_DRV_AVMB1_C4 $CONFIG_ISDN_CAPI $CONFIG_PCI
+fi
+
+# HYSDN
+
+dep_tristate '  Hypercope HYSDN cards (Champ, Ergo, Metro) support (module only)' CONFIG_HYSDN m $CONFIG_PROC_FS
+dep_mbool    '    HYSDN CAPI 2.0 support' CONFIG_HYSDN_CAPI $CONFIG_HYSDN $CONFIG_ISDN_CAPI
 endmenu
diff -urN linux-2.2.19-pre10/drivers/isdn/Makefile linux/drivers/isdn/Makefile
--- linux-2.2.19-pre10/drivers/isdn/Makefile	Mon Dec  3 21:02:15 2001
+++ linux/drivers/isdn/Makefile	Mon Dec  3 21:02:58 2001
@@ -1,141 +1,56 @@
-SUB_DIRS     :=
-MOD_SUB_DIRS :=
-ALL_SUB_DIRS := icn pcbit hisax avmb1 act2000 eicon divert
-
-L_OBJS :=
-LX_OBJS :=
-M_OBJS :=
-MX_OBJS :=
-O_OBJS :=
-OX_OBJS :=
-L_TARGET :=
-O_TARGET :=
-
-ifeq ($(CONFIG_ISDN),y)
-  L_TARGET := isdn.a
-  L_OBJS += isdn_net.o isdn_tty.o isdn_cards.o isdn_v110.o
-  LX_OBJS += isdn_common.o 
-  ifdef CONFIG_ISDN_PPP
-    L_OBJS += isdn_ppp.o
-  endif
-  ifdef CONFIG_ISDN_X25
-    L_OBJS += isdn_x25iface.o
-    L_OBJS += isdn_concap.o
-  endif
-  ifdef CONFIG_ISDN_AUDIO
-    L_OBJS += isdn_audio.o
-    ifdef CONFIG_ISDN_TTY_FAX
-      L_OBJS += isdn_ttyfax.o
-    endif
-  endif
-else
-  ifeq ($(CONFIG_ISDN),m)
-    M_OBJS += isdn.o
-    O_TARGET += isdn.o
-    O_OBJS += isdn_net.o isdn_tty.o isdn_v110.o
-    OX_OBJS += isdn_common.o
-    ifdef CONFIG_ISDN_PPP
-      O_OBJS += isdn_ppp.o
-      M_OBJS += isdn_bsdcomp.o
-    endif
-    ifdef CONFIG_ISDN_X25
-      O_OBJS += isdn_x25iface.o
-      O_OBJS += isdn_concap.o
-    endif  
-    ifdef CONFIG_ISDN_AUDIO
-      O_OBJS += isdn_audio.o
-      ifdef CONFIG_ISDN_TTY_FAX
-        O_OBJS += isdn_ttyfax.o
-      endif
-    endif
-  endif
-endif
-
-ifeq ($(CONFIG_ISDN_DIVERSION),y)
- ifeq ($(CONFIG_MODULES),y)
-    MOD_SUB_DIRS += divert
- endif
-endif
-
-ifeq ($(CONFIG_ISDN_DRV_HISAX),y)
-  L_OBJS += hisax/hisax.o
-  SUB_DIRS += hisax
-  MOD_SUB_DIRS += hisax
-else
-  ifeq ($(CONFIG_ISDN_DRV_HISAX),m)
-    MOD_SUB_DIRS += hisax
-  endif
-endif
-
-ifeq ($(CONFIG_ISDN_DRV_ICN),y)
-  L_OBJS += icn/icn_obj.o
-  SUB_DIRS += icn
-  MOD_SUB_DIRS += icn
-else
-  ifeq ($(CONFIG_ISDN_DRV_ICN),m)
-    MOD_SUB_DIRS += icn
-  endif
-endif
-
-ifeq ($(CONFIG_ISDN_DRV_PCBIT),y)
-  L_OBJS += pcbit/pcbit.o
-  SUB_DIRS += pcbit
-  MOD_SUB_DIRS += pcbit
-else
-  ifeq ($(CONFIG_ISDN_DRV_PCBIT),m)
-    MOD_SUB_DIRS += pcbit
-  endif
-endif
-
-ifeq ($(CONFIG_ISDN_DRV_SC),y)
-  L_OBJS += sc/sc.o
-  SUB_DIRS += sc
-  MOD_SUB_DIRS += sc
-else
-  ifeq ($(CONFIG_ISDN_DRV_SC),m)
-    MOD_SUB_DIRS += sc
-  endif
-endif
-
-ifeq ($(CONFIG_ISDN_CAPI),y)
-  L_OBJS += avmb1/avmb1.o
-  SUB_DIRS += avmb1
-  MOD_SUB_DIRS += avmb1
-else
-  ifeq ($(CONFIG_ISDN_CAPI),m)
-    MOD_SUB_DIRS += avmb1
-  endif
-endif
-
-ifeq ($(CONFIG_ISDN_DRV_LOOP),y)
-  L_OBJS += isdnloop/isdnloop.o
-  SUB_DIRS += isdnloop
-  MOD_SUB_DIRS += isdnloop
-else
-  ifeq ($(CONFIG_ISDN_DRV_LOOP),m)
-    MOD_SUB_DIRS += isdnloop
-  endif
-endif
-
-ifeq ($(CONFIG_ISDN_DRV_ACT2000),y)
-  L_OBJS += act2000/act2000.o
-  SUB_DIRS += act2000
-  MOD_SUB_DIRS += act2000
-else
-  ifeq ($(CONFIG_ISDN_DRV_ACT2000),m)
-    MOD_SUB_DIRS += act2000
-  endif
-endif
-
-ifeq ($(CONFIG_ISDN_DRV_EICON),y)
-  L_OBJS += eicon/eicon.o
-  SUB_DIRS += eicon
-  MOD_SUB_DIRS += eicon
-else
-  ifeq ($(CONFIG_ISDN_DRV_EICON),m)
-    MOD_SUB_DIRS += eicon
-  endif
-endif
+# Makefile for the kernel ISDN subsystem and device drivers.
 
-include $(TOPDIR)/Rules.make
+# The target object and module list name.
 
+O_TARGET	:= isdn.a
+
+# Objects that export symbols.
+
+export-objs	:= isdn_common.o
+
+# Multipart objects.
+
+list-multi	:= isdn.o
+isdn-objs	:= isdn_net.o isdn_tty.o isdn_v110.o isdn_common.o
+
+# Optional parts of multipart objects.
+
+isdn-objs-$(CONFIG_ISDN_PPP)		+= isdn_ppp.o
+isdn-objs-$(CONFIG_ISDN_X25)		+= isdn_concap.o isdn_x25iface.o
+isdn-objs-$(CONFIG_ISDN_AUDIO)		+= isdn_audio.o
+isdn-objs-$(CONFIG_ISDN_TTY_FAX)	+= isdn_ttyfax.o
+isdn-objs-$(CONFIG_ISDN_WITH_ABC)	+= isdn_dwabc.o
+
+isdn-objs				+= $(isdn-objs-y)
+
+# Ordering constraints: isdn.o first, rest doesn't matter
+
+# Each configuration option enables a list of files.
+
+obj-$(CONFIG_ISDN)			+= isdn.o
+obj-$(CONFIG_ISDN_PPP_BSDCOMP)		+= isdn_bsdcomp.o
+
+# Object files in subdirectories
+
+mod-subdirs				:= avmb1
+subdir-$(CONFIG_ISDN_DIVERSION)		+= divert
+subdir-$(CONFIG_ISDN_DRV_HISAX)		+= hisax
+subdir-$(CONFIG_ISDN_DRV_ICN)		+= icn
+subdir-$(CONFIG_ISDN_DRV_PCBIT)		+= pcbit
+subdir-$(CONFIG_ISDN_DRV_SC)		+= sc
+subdir-$(CONFIG_ISDN_CAPI)		+= avmb1
+subdir-$(CONFIG_ISDN_DRV_LOOP)		+= isdnloop
+subdir-$(CONFIG_ISDN_DRV_ACT2000)	+= act2000
+subdir-$(CONFIG_ISDN_DRV_EICON)		+= eicon
+subdir-$(CONFIG_HYSDN)			+= hysdn
+
+obj-y += $(addsuffix /vmlinux-obj.o, $(subdir-y))
+
+# The global Rules.make.
+
+include $(TOPDIR)/drivers/isdn/Rules.make
+
+# Link rules for multi-part drivers.
+
+isdn.o: $(isdn-objs)
+	$(LD) -r -o $@ $(isdn-objs)
diff -urN linux-2.2.19-pre10/drivers/isdn/Rules.make linux/drivers/isdn/Rules.make
--- linux-2.2.19-pre10/drivers/isdn/Rules.make	Wed Dec 31 16:00:00 1969
+++ linux/drivers/isdn/Rules.make	Mon Dec  3 21:02:58 2001
@@ -0,0 +1,32 @@
+# Extract lists of the multi-part drivers.
+# The 'int-*' lists are the intermediate files used to build the multi's.
+
+multi-y		:= $(filter $(list-multi), $(obj-y))
+multi-m		:= $(filter $(list-multi), $(obj-m))
+int-y		:= $(sort $(foreach m, $(multi-y), $($(basename $(m))-objs)))
+int-m		:= $(sort $(foreach m, $(multi-m), $($(basename $(m))-objs)))
+
+# Files that are both resident and modular: remove from modular.
+
+obj-m		:= $(filter-out $(obj-y), $(obj-m))
+int-m		:= $(filter-out $(int-y), $(int-m))
+
+# Take multi-part drivers out of obj-y and put components in.
+
+obj-y		:= $(filter-out $(list-multi), $(obj-y)) $(int-y)
+
+# Translate to Rules.make lists.
+
+O_OBJS		:= $(sort $(filter-out $(export-objs), $(obj-y)))
+OX_OBJS		:= $(sort $(filter     $(export-objs), $(obj-y)))
+M_OBJS		:= $(sort $(filter-out $(export-objs), $(obj-m)))
+MX_OBJS		:= $(sort $(filter     $(export-objs), $(obj-m)))
+MI_OBJS		:= $(sort $(filter-out $(export-objs), $(int-m)))
+MIX_OBJS	:= $(sort $(filter     $(export-objs), $(int-m)))
+
+both-m		:= $(filter $(mod-subdirs), $(subdir-y))
+SUB_DIRS	:= $(subdir-y)
+MOD_SUB_DIRS	:= $(sort $(subdir-m) $(both-m))
+ALL_SUB_DIRS	:= $(sort $(subdir-y) $(subdir-m) $(subdir-n) $(subdir-))
+
+include $(TOPDIR)/Rules.make
diff -urN linux-2.2.19-pre10/drivers/isdn/act2000/Makefile linux/drivers/isdn/act2000/Makefile
--- linux-2.2.19-pre10/drivers/isdn/act2000/Makefile	Mon Dec  3 21:02:15 2001
+++ linux/drivers/isdn/act2000/Makefile	Mon Dec  3 21:02:58 2001
@@ -1,15 +1,21 @@
-L_OBJS :=
-M_OBJS :=
-O_OBJS := module.o capi.o act2000_isa.o
-
-O_TARGET :=
-ifeq ($(CONFIG_ISDN_DRV_ACT2000),y)
-  O_TARGET += act2000.o
-else
-  ifeq ($(CONFIG_ISDN_DRV_ACT2000),m)
-	O_TARGET += act2000.o
-	M_OBJS = act2000.o
-  endif
-endif
+# Makefile for the act2000 ISDN device driver
 
-include $(TOPDIR)/Rules.make
+# The target object and module list name.
+
+O_TARGET	:= vmlinux-obj.o
+
+# Multipart objects.
+
+list-multi	:= act2000.o
+act2000-objs	:= module.o capi.o act2000_isa.o
+
+# Each configuration option enables a list of files.
+
+obj-$(CONFIG_ISDN_DRV_ACT2000)	+= act2000.o
+
+include $(TOPDIR)/drivers/isdn/Rules.make
+
+# Link rules for multi-part drivers.
+
+act2000.o: $(act2000-objs)
+	$(LD) -r -o $@ $(act2000-objs)
diff -urN linux-2.2.19-pre10/drivers/isdn/act2000/act2000.h linux/drivers/isdn/act2000/act2000.h
--- linux-2.2.19-pre10/drivers/isdn/act2000/act2000.h	Mon Dec  3 21:02:15 2001
+++ linux/drivers/isdn/act2000/act2000.h	Mon Dec  3 21:02:58 2001
@@ -1,4 +1,4 @@
-/* $Id: act2000.h,v 1.8 2000/11/12 16:32:06 kai Exp $
+/* $Id: act2000.h,v 1.8.6.1 2001/02/10 14:41:20 kai Exp $
  *
  * ISDN lowlevel-module for the IBM ISDN-S0 Active 2000.
  *
@@ -88,7 +88,7 @@
 #include <asm/io.h>
 #include <linux/kernel.h>
 #include <linux/signal.h>
-#include <linux/malloc.h>
+#include <linux/slab.h>
 #include <linux/mm.h>
 #include <linux/mman.h>
 #include <linux/ioport.h>
diff -urN linux-2.2.19-pre10/drivers/isdn/act2000/module.c linux/drivers/isdn/act2000/module.c
--- linux-2.2.19-pre10/drivers/isdn/act2000/module.c	Mon Dec  3 21:02:15 2001
+++ linux/drivers/isdn/act2000/module.c	Mon Dec  3 21:02:59 2001
@@ -1,4 +1,4 @@
-/* $Id: module.c,v 1.14 2000/11/12 16:32:06 kai Exp $
+/* $Id: module.c,v 1.14.6.2 2000/12/18 22:14:10 kai Exp $
  *
  * ISDN lowlevel-module for the IBM ISDN-S0 Active 2000.
  *
@@ -24,6 +24,7 @@
 #include "act2000.h"
 #include "act2000_isa.h"
 #include "capi.h"
+#include <linux/init.h>
 
 static unsigned short act2000_isa_ports[] =
 {
@@ -820,12 +821,7 @@
 
 #define DRIVERNAME "IBM Active 2000 ISDN driver"
 
-#ifdef MODULE
-#define act2000_init init_module
-#endif
-
-int
-act2000_init(void)
+static int __init act2000_init(void)
 {
         printk(KERN_INFO "%s\n", DRIVERNAME);
         if (!cards)
@@ -837,9 +833,7 @@
         return 0;
 }
 
-#ifdef MODULE
-void
-cleanup_module(void)
+static void  act2000_exit(void)
 {
         act2000_card *card = cards;
         act2000_card *last;
@@ -858,34 +852,5 @@
         printk(KERN_INFO "%s unloaded\n", DRIVERNAME);
 }
 
-#else
-void
-act2000_setup(char *str, int *ints)
-{
-        int i, j, argc, port, irq, bus;
-	
-        argc = ints[0];
-        i = 1;
-        if (argc)
-                while (argc) {
-                        port = irq = -1;
-			bus = 0;
-                        if (argc) {
-                                bus = ints[i];
-                                i++;
-                                argc--;
-                        }
-                        if (argc) {
-                                port = ints[i];
-                                i++;
-                                argc--;
-                        }
-                        if (argc) {
-                                irq = ints[i];
-                                i++;
-                                argc--;
-                        }
-			act2000_addcard(bus, port, irq, act_id);
-		}
-}
-#endif
+module_init(act2000_init);
+module_exit(act2000_exit);
diff -urN linux-2.2.19-pre10/drivers/isdn/avmb1/Makefile linux/drivers/isdn/avmb1/Makefile
--- linux-2.2.19-pre10/drivers/isdn/avmb1/Makefile	Mon Dec  3 21:02:15 2001
+++ linux/drivers/isdn/avmb1/Makefile	Mon Dec  3 21:02:59 2001
@@ -1,187 +1,40 @@
-#
-# $Id: Makefile,v 1.18 2000/04/03 16:39:25 calle Exp $
-#
-# Makefile for the CAPI and AVM-B1 device drivers.
-#
-# Note! Dependencies are done automagically by 'make dep', which also
-# removes any old dependencies. DON'T put your own dependencies here
-# unless it's something special (ie not a .c file).
-#
-# Note 2! The CFLAGS definitions are now inherited from the
-# parent makes..
-#
-# $Log: Makefile,v $
-# Revision 1.18  2000/04/03 16:39:25  calle
-# Makefile checked in with future things :-(
-#
-# Revision 1.17  2000/04/03 16:38:05  calle
-# made suppress_pollack static.
-#
-# Revision 1.16  2000/03/17 12:15:44  calle
-# ALL_SUB_DIRS were wrong.
-#
-# Revision 1.15  2000/03/16 15:21:03  calle
-# Bugfix in c4_remove: loop 5 times instead of 4 :-(
-#
-# Revision 1.14  2000/03/13 17:50:55  calle
-# Added avm_cs.c for 2.3.x PCMCIA support.
-#
-# Revision 1.13  2000/03/08 17:06:33  calle
-# - changes for devfs and 2.3.49
-# - capifs now configurable (no need with devfs)
-# - New Middleware ioctl CAPI_NCCI_GETUNIT
-# - Middleware again tested with 2.2.14 and 2.3.49 (with and without devfs)
-#
-# Revision 1.12  2000/03/06 18:00:23  calle
-# - Middleware extention now working with 2.3.49 (capifs).
-# - Fixed typos in debug section of capi.c
-# - Bugfix: Makefile corrected for b1pcmcia.c
-#
-# Revision 1.11  2000/03/06 09:17:07  calle
-# - capifs: fileoperations now in inode (change for 2.3.49)
-# - Config.in: Middleware extention not a tristate, uups.
-#
-# Revision 1.10  2000/03/03 16:48:38  calle
-# - Added CAPI2.0 Middleware support (CONFIG_ISDN_CAPI)
-#   It is now possible to create a connection with a CAPI2.0 applikation
-#   and than to handle the data connection from /dev/capi/ (capifs) and also
-#   using async or sync PPP on this connection.
-#   The two major device number 190 and 191 are not confirmed yet,
-#   but I want to save the code in cvs, before I go on.
-#
-# Revision 1.9  2000/03/03 15:50:42  calle
-# - kernel CAPI:
-#   - Changed parameter "param" in capi_signal from __u32 to void *.
-#   - rewrote notifier handling in kcapi.c
-#   - new notifier NCCI_UP and NCCI_DOWN
-# - User CAPI:
-#   - /dev/capi20 is now a cloning device.
-#   - middleware extentions prepared.
-# - capidrv.c
-#   - locking of list operations and module count updates.
-#
-# Revision 1.8  2000/01/25 14:33:38  calle
-# - Added Support AVM B1 PCI V4.0 (tested with prototype)
-#   - splitted up t1pci.c into b1dma.c for common function with b1pciv4
-#   - support for revision register
-#
-# Revision 1.7  1999/09/15 08:16:03  calle
-# Implementation of 64Bit extention complete.
-#
-# Revision 1.6  1999/07/20 06:41:44  calle
-# Bugfix: After the redesign of the AVM B1 driver, the driver didn't even
-#         compile, if not selected as modules.
-#
-# Revision 1.5  1999/07/01 15:26:20  calle
-# complete new version (I love it):
-# + new hardware independed "capi_driver" interface that will make it easy to:
-#   - support other controllers with CAPI-2.0 (i.e. USB Controller)
-#   - write a CAPI-2.0 for the passive cards
-#   - support serial link CAPI-2.0 boxes.
-# + wrote "capi_driver" for all supported cards.
-# + "capi_driver" (supported cards) now have to be configured with
-#   make menuconfig, in the past all supported cards where included
-#   at once.
-# + new and better informations in /proc/capi/
-# + new ioctl to switch trace of capi messages per controller
-#   using "avmcapictrl trace [contr] on|off|...."
-# + complete testcircle with all supported cards and also the
-#   PCMCIA cards (now patch for pcmcia-cs-3.0.13 needed) done.
-#
-# Revision 1.4  1997/03/30 17:10:40  calle
-# added support for AVM-B1-PCI card.
-#
-# Revision 1.3  1997/03/22 02:00:57  fritz
-# -Reworked toplevel Makefile. From now on, no different Makefiles
-#  for standalone- and in-kernel-compilation are needed any more.
-# -Added local Rules.make for above reason.
-# -Experimental changes in teles3.c for enhanced IRQ-checking with
-#  2.1.X and SMP kernels.
-# -Removed diffstd-script, same functionality is in stddiff -r.
-# -Enhanced scripts std2kern and stddiff.
-#
-# Revision 1.1  1997/03/05 21:26:14  fritz
-# Renamed, according naming conventions in CVS tree.
-#
-# Revision 1.1  1997/03/04 21:50:26  calle
-# Frirst version in isdn4linux
-#
-# Revision 2.2  1997/02/12 09:31:39  calle
-#
-# Revision 1.1  1997/01/31 10:32:20  calle
-# Initial revision
-#
-#
-
-SUB_DIRS     :=
-MOD_SUB_DIRS :=
-ALL_SUB_DIRS :=
-#
-# Objects that don't export a symtab
-#
-L_OBJS := # used as component of an L_TARGET
-O_OBJS := # used as component of an O_TARGET
-M_OBJS := # used as module
-#
-# Objects that do export a symtab
-#
-LX_OBJS := # used as component of an L_TARGET
-OX_OBJS := # used as component of an O_TARGET
-MX_OBJS := # used as module
-#
-# Targets, created by linking others
-#
-O_TARGET := # used for .o targets (from O and OX objects)
-L_TARGET := # used for .a targets (from L and LX objects)
-
-ifeq ($(CONFIG_ISDN_CAPI),y)
-  O_TARGET += avmb1.o
-  OX_OBJS  += kcapi.o
-  O_OBJS   += capi.o
-  ifdef CONFIG_ISDN_CAPIFS
-  	OX_OBJS   += capifs.o
-  endif
-  ifdef CONFIG_ISDN_DRV_AVMB1_B1ISA
-  	O_OBJS   += b1isa.o
-  endif
-  ifdef CONFIG_ISDN_DRV_AVMB1_B1PCI
-  	O_OBJS  += b1pci.o
-  endif
-  ifdef CONFIG_ISDN_DRV_AVMB1_T1ISA
-  	O_OBJS   += t1isa.o
-  endif
-  ifdef CONFIG_ISDN_DRV_AVMB1_T1PCI
-  	O_OBJS   += t1pci.o
-  endif
-  ifdef CONFIG_ISDN_DRV_AVMB1_C4
-  	O_OBJS   += c4.o
-  endif
-  OX_OBJS  += capiutil.o capidrv.o b1.o b1dma.o
-else
-  ifeq ($(CONFIG_ISDN_CAPI),m)
-  	O_TARGET += kernelcapi.o
-  	OX_OBJS  += kcapi.o
-  	M_OBJS   += capi.o kernelcapi.o
-  	ifdef CONFIG_ISDN_CAPIFS
-  		MX_OBJS   += capifs.o
-  	endif
-  	ifdef CONFIG_ISDN_DRV_AVMB1_B1ISA
-  		M_OBJS   += b1isa.o
-  	endif
-  	ifdef CONFIG_ISDN_DRV_AVMB1_B1PCI
-  		M_OBJS  += b1pci.o
-  	endif
-  	ifdef CONFIG_ISDN_DRV_AVMB1_T1ISA
-  		M_OBJS   += t1isa.o
-  	endif
-  	ifdef CONFIG_ISDN_DRV_AVMB1_T1PCI
-  		M_OBJS   += t1pci.o
-  	endif
-  	ifdef CONFIG_ISDN_DRV_AVMB1_C4
-  		M_OBJS   += c4.o
-  	endif
-  	MX_OBJS  += capiutil.o capidrv.o b1.o b1dma.o
-  endif
-endif
+# Makefile for the AVM ISDN device drivers and CAPI subsystem.
+
+# The target object and module list name.
+
+O_TARGET	:= vmlinux-obj.o
+
+# Objects that export symbols.
+
+export-objs	:= kcapi.o capiutil.o b1dma.o b1pcmcia.o b1.o capifs.o
+
+# Multipart objects.
+
+list-multi	:= kernelcapi.o
+kernelcapi-objs	:= kcapi.o
+
+# Ordering constraints: kernelcapi.o first
+
+# Each configuration option enables a list of files.
+
+obj-$(CONFIG_ISDN_CAPI)			+= kernelcapi.o capiutil.o
+obj-$(CONFIG_ISDN_CAPI_CAPI20)		+= capi.o 
+obj-$(CONFIG_ISDN_CAPI_CAPIDRV)		+= capidrv.o
+obj-$(CONFIG_ISDN_CAPI_CAPIFS)		+= capifs.o
+obj-$(CONFIG_ISDN_DRV_AVMB1_B1ISA)	+= b1isa.o b1.o
+obj-$(CONFIG_ISDN_DRV_AVMB1_B1PCI)	+= b1pci.o b1.o b1dma.o
+obj-$(CONFIG_ISDN_DRV_AVMB1_B1PCMCIA)	+= b1pcmcia.o b1.o
+obj-$(CONFIG_ISDN_DRV_AVMB1_AVM_CS)	+= avm_cs.o
+obj-$(CONFIG_ISDN_DRV_AVMB1_T1ISA)	+= t1isa.o b1.o
+obj-$(CONFIG_ISDN_DRV_AVMB1_T1PCI)	+= t1pci.o b1.o b1dma.o
+obj-$(CONFIG_ISDN_DRV_AVMB1_C4)		+= c4.o b1.o
+
+# The global Rules.make.
+
+include $(TOPDIR)/drivers/isdn/Rules.make
+
+# Link rules for multi-part drivers.
+
+kernelcapi.o: $(kernelcapi-objs)
+	$(LD) -r -o $@ $(kernelcapi-objs)
 
-include $(TOPDIR)/Rules.make
diff -urN linux-2.2.19-pre10/drivers/isdn/avmb1/avm_cs.c linux/drivers/isdn/avmb1/avm_cs.c
--- linux-2.2.19-pre10/drivers/isdn/avmb1/avm_cs.c	Mon Dec  3 21:02:15 2001
+++ linux/drivers/isdn/avmb1/avm_cs.c	Wed Dec 31 16:00:00 1969
@@ -1,527 +0,0 @@
-/*======================================================================
-
-    A PCMCIA client driver for AVM B1/M1/M2
-
-    Written by Carsten Paeth, calle@calle.in-berlin.de
-    
-======================================================================*/
-
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/sched.h>
-#include <linux/ptrace.h>
-#include <linux/malloc.h>
-#include <linux/string.h>
-#include <linux/timer.h>
-#include <linux/tty.h>
-#include <linux/serial.h>
-#include <linux/major.h>
-#include <asm/io.h>
-#include <asm/system.h>
-
-#include <pcmcia/version.h>
-#include <pcmcia/cs_types.h>
-#include <pcmcia/cs.h>
-#include <pcmcia/cistpl.h>
-#include <pcmcia/ciscode.h>
-#include <pcmcia/ds.h>
-#include <pcmcia/cisreg.h>
-
-#include <linux/skbuff.h>
-#include <linux/capi.h>
-#include <linux/b1lli.h>
-#include <linux/b1pcmcia.h>
-
-/*====================================================================*/
-
-/* Parameters that can be set with 'insmod' */
-
-/* This means pick from 15, 12, 11, 10, 9, 7, 5, 4, and 3 */
-static int default_irq_list[10] = { 15, 12, 11, 10, 9, 7, 5, 4, 3, -1 };
-static int irq_list[10] = { -1 };
-
-MODULE_PARM(irq_list, "1-10i");
-
-/*====================================================================*/
-
-/*
-   The event() function is this driver's Card Services event handler.
-   It will be called by Card Services when an appropriate card status
-   event is received.  The config() and release() entry points are
-   used to configure or release a socket, in response to card insertion
-   and ejection events.  They are invoked from the skeleton event
-   handler.
-*/
-
-static void avmcs_config(dev_link_t *link);
-static void avmcs_release(u_long arg);
-static int avmcs_event(event_t event, int priority,
-			  event_callback_args_t *args);
-
-/*
-   The attach() and detach() entry points are used to create and destroy
-   "instances" of the driver, where each instance represents everything
-   needed to manage one actual PCMCIA card.
-*/
-
-static dev_link_t *avmcs_attach(void);
-static void avmcs_detach(dev_link_t *);
-
-/*
-   The dev_info variable is the "key" that is used to match up this
-   device driver with appropriate cards, through the card configuration
-   database.
-*/
-
-static dev_info_t dev_info = "avm_cs";
-
-/*
-   A linked list of "instances" of the skeleton device.  Each actual
-   PCMCIA card corresponds to one device instance, and is described
-   by one dev_link_t structure (defined in ds.h).
-
-   You may not want to use a linked list for this -- for example, the
-   memory card driver uses an array of dev_link_t pointers, where minor
-   device numbers are used to derive the corresponding array index.
-*/
-
-static dev_link_t *dev_list = NULL;
-
-/*
-   A dev_link_t structure has fields for most things that are needed
-   to keep track of a socket, but there will usually be some device
-   specific information that also needs to be kept track of.  The
-   'priv' pointer in a dev_link_t structure can be used to point to
-   a device-specific private data structure, like this.
-
-   A driver needs to provide a dev_node_t structure for each device
-   on a card.  In some cases, there is only one device per card (for
-   example, ethernet cards, modems).  In other cases, there may be
-   many actual or logical devices (SCSI adapters, memory cards with
-   multiple partitions).  The dev_node_t structures need to be kept
-   in a linked list starting at the 'dev' field of a dev_link_t
-   structure.  We allocate them in the card's private data structure,
-   because they generally can't be allocated dynamically.
-*/
-   
-typedef struct local_info_t {
-    dev_node_t	node;
-} local_info_t;
-
-/*====================================================================*/
-
-static void cs_error(client_handle_t handle, int func, int ret)
-{
-    error_info_t err = { func, ret };
-    CardServices(ReportError, handle, &err);
-}
-
-/*======================================================================
-
-    avmcs_attach() creates an "instance" of the driver, allocating
-    local data structures for one device.  The device is registered
-    with Card Services.
-
-    The dev_link structure is initialized, but we don't actually
-    configure the card at this point -- we wait until we receive a
-    card insertion event.
-    
-======================================================================*/
-
-static dev_link_t *avmcs_attach(void)
-{
-    client_reg_t client_reg;
-    dev_link_t *link;
-    local_info_t *local;
-    int ret, i;
-    
-    /* Initialize the dev_link_t structure */
-    link = kmalloc(sizeof(struct dev_link_t), GFP_KERNEL);
-    memset(link, 0, sizeof(struct dev_link_t));
-    link->release.function = &avmcs_release;
-    link->release.data = (u_long)link;
-
-    /* The io structure describes IO port mapping */
-    link->io.NumPorts1 = 16;
-    link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
-    link->io.NumPorts2 = 0;
-
-    /* Interrupt setup */
-    link->irq.Attributes = IRQ_TYPE_EXCLUSIVE;
-    link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING|IRQ_FIRST_SHARED;
-
-    link->irq.IRQInfo1 = IRQ_INFO2_VALID|IRQ_LEVEL_ID;
-    if (irq_list[0] != -1) {
-	    for (i = 0; i < 10 && irq_list[i] > 0; i++)
-	       link->irq.IRQInfo2 |= 1 << irq_list[i];
-    } else {
-	    for (i = 0; i < 10 && default_irq_list[i] > 0; i++)
-	       link->irq.IRQInfo2 |= 1 << default_irq_list[i];
-    }
-    
-    /* General socket configuration */
-    link->conf.Attributes = CONF_ENABLE_IRQ;
-    link->conf.Vcc = 50;
-    link->conf.IntType = INT_MEMORY_AND_IO;
-    link->conf.ConfigIndex = 1;
-    link->conf.Present = PRESENT_OPTION;
-
-    /* Allocate space for private device-specific data */
-    local = kmalloc(sizeof(local_info_t), GFP_KERNEL);
-    memset(local, 0, sizeof(local_info_t));
-    link->priv = local;
-    
-    /* Register with Card Services */
-    link->next = dev_list;
-    dev_list = link;
-    client_reg.dev_info = &dev_info;
-    client_reg.Attributes = INFO_IO_CLIENT | INFO_CARD_SHARE;
-    client_reg.EventMask =
-	CS_EVENT_CARD_INSERTION | CS_EVENT_CARD_REMOVAL |
-	CS_EVENT_RESET_PHYSICAL | CS_EVENT_CARD_RESET |
-	CS_EVENT_PM_SUSPEND | CS_EVENT_PM_RESUME;
-    client_reg.event_handler = &avmcs_event;
-    client_reg.Version = 0x0210;
-    client_reg.event_callback_args.client_data = link;
-    ret = CardServices(RegisterClient, &link->handle, &client_reg);
-    if (ret != 0) {
-	cs_error(link->handle, RegisterClient, ret);
-	avmcs_detach(link);
-	return NULL;
-    }
-
-    return link;
-} /* avmcs_attach */
-
-/*======================================================================
-
-    This deletes a driver "instance".  The device is de-registered
-    with Card Services.  If it has been released, all local data
-    structures are freed.  Otherwise, the structures will be freed
-    when the device is released.
-
-======================================================================*/
-
-static void avmcs_detach(dev_link_t *link)
-{
-    dev_link_t **linkp;
-
-    /* Locate device structure */
-    for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next)
-	if (*linkp == link) break;
-    if (*linkp == NULL)
-	return;
-
-    /*
-       If the device is currently configured and active, we won't
-       actually delete it yet.  Instead, it is marked so that when
-       the release() function is called, that will trigger a proper
-       detach().
-    */
-    if (link->state & DEV_CONFIG) {
-	link->state |= DEV_STALE_LINK;
-	return;
-    }
-
-    /* Break the link with Card Services */
-    if (link->handle)
-	CardServices(DeregisterClient, link->handle);
-    
-    /* Unlink device structure, free pieces */
-    *linkp = link->next;
-    if (link->priv) {
-	kfree(link->priv);
-    }
-    kfree(link);
-    
-} /* avmcs_detach */
-
-/*======================================================================
-
-    avmcs_config() is scheduled to run after a CARD_INSERTION event
-    is received, to configure the PCMCIA socket, and to make the
-    ethernet device available to the system.
-    
-======================================================================*/
-
-static int get_tuple(int fn, client_handle_t handle, tuple_t *tuple,
-		     cisparse_t *parse)
-{
-    int i;
-    i = CardServices(fn, handle, tuple);
-    if (i != CS_SUCCESS) return i;
-    i = CardServices(GetTupleData, handle, tuple);
-    if (i != CS_SUCCESS) return i;
-    return CardServices(ParseTuple, handle, tuple, parse);
-}
-
-#define first_tuple(a, b, c) get_tuple(GetFirstTuple, a, b, c)
-#define next_tuple(a, b, c) get_tuple(GetNextTuple, a, b, c)
-
-static void avmcs_config(dev_link_t *link)
-{
-    client_handle_t handle;
-    tuple_t tuple;
-    cisparse_t parse;
-    cistpl_cftable_entry_t *cf = &parse.cftable_entry;
-    local_info_t *dev;
-    int i;
-    u_char buf[64];
-    char devname[128];
-    int cardtype;
-    int (*addcard)(unsigned int port, unsigned irq);
-    
-    handle = link->handle;
-    dev = link->priv;
-
-    /*
-       This reads the card's CONFIG tuple to find its configuration
-       registers.
-    */
-    do {
-	tuple.DesiredTuple = CISTPL_CONFIG;
-	i = CardServices(GetFirstTuple, handle, &tuple);
-	if (i != CS_SUCCESS) break;
-	tuple.TupleData = buf;
-	tuple.TupleDataMax = 64;
-	tuple.TupleOffset = 0;
-	i = CardServices(GetTupleData, handle, &tuple);
-	if (i != CS_SUCCESS) break;
-	i = CardServices(ParseTuple, handle, &tuple, &parse);
-	if (i != CS_SUCCESS) break;
-	link->conf.ConfigBase = parse.config.base;
-    } while (0);
-    if (i != CS_SUCCESS) {
-	cs_error(link->handle, ParseTuple, i);
-	link->state &= ~DEV_CONFIG_PENDING;
-	return;
-    }
-    
-    /* Configure card */
-    link->state |= DEV_CONFIG;
-
-    do {
-
-	tuple.Attributes = 0;
-	tuple.TupleData = buf;
-	tuple.TupleDataMax = 254;
-	tuple.TupleOffset = 0;
-	tuple.DesiredTuple = CISTPL_VERS_1;
-
-	devname[0] = 0;
-	if( !first_tuple(handle, &tuple, &parse) && parse.version_1.ns > 1 ) {
-	    strncpy(devname,parse.version_1.str + parse.version_1.ofs[1], 
-			sizeof(devname));
-	}
-	/*
-         * find IO port
-         */
-	tuple.TupleData = (cisdata_t *)buf;
-	tuple.TupleOffset = 0; tuple.TupleDataMax = 255;
-	tuple.Attributes = 0;
-	tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
-	i = first_tuple(handle, &tuple, &parse);
-	while (i == CS_SUCCESS) {
-	    if (cf->io.nwin > 0) {
-		link->conf.ConfigIndex = cf->index;
-		link->io.BasePort1 = cf->io.win[0].base;
-		link->io.NumPorts1 = cf->io.win[0].len;
-		link->io.NumPorts2 = 0;
-                printk(KERN_INFO "avm_cs: testing i/o %#x-%#x\n",
-			link->io.BasePort1,
-		        link->io.BasePort1+link->io.NumPorts1-1);
-		i = CardServices(RequestIO, link->handle, &link->io);
-		if (i == CS_SUCCESS) goto found_port;
-	    }
-	    i = next_tuple(handle, &tuple, &parse);
-	}
-
-found_port:
-	if (i != CS_SUCCESS) {
-	    cs_error(link->handle, RequestIO, i);
-	    break;
-	}
-	
-	/*
-	 * allocate an interrupt line
-	 */
-	i = CardServices(RequestIRQ, link->handle, &link->irq);
-	if (i != CS_SUCCESS) {
-	    cs_error(link->handle, RequestIRQ, i);
-	    CardServices(ReleaseIO, link->handle, &link->io);
-	    break;
-	}
-	
-	/*
-         * configure the PCMCIA socket
-	  */
-	i = CardServices(RequestConfiguration, link->handle, &link->conf);
-	if (i != CS_SUCCESS) {
-	    cs_error(link->handle, RequestConfiguration, i);
-	    CardServices(ReleaseIO, link->handle, &link->io);
-	    CardServices(ReleaseIRQ, link->handle, &link->irq);
-	    break;
-	}
-
-    } while (0);
-
-    /* At this point, the dev_node_t structure(s) should be
-       initialized and arranged in a linked list at link->dev. */
-
-    if (devname[0]) {
-	char *s = strrchr(devname, ' ');
-	if (!s)
-	   s = devname;
-	else s++;
-	strcpy(dev->node.dev_name, s);
-        if (strcmp("M1", s) == 0) {
-           cardtype = AVM_CARDTYPE_M1;
-        } else if (strcmp("M2", s) == 0) {
-           cardtype = AVM_CARDTYPE_M2;
-	} else {
-           cardtype = AVM_CARDTYPE_B1;
-	}
-    } else {
-        strcpy(dev->node.dev_name, "b1");
-        cardtype = AVM_CARDTYPE_B1;
-    }
-
-    dev->node.major = 64;
-    dev->node.minor = 0;
-    link->dev = &dev->node;
-    
-    link->state &= ~DEV_CONFIG_PENDING;
-    /* If any step failed, release any partially configured state */
-    if (i != 0) {
-	avmcs_release((u_long)link);
-	return;
-    }
-
-
-    switch (cardtype) {
-        case AVM_CARDTYPE_M1: addcard = b1pcmcia_addcard_m1; break;
-        case AVM_CARDTYPE_M2: addcard = b1pcmcia_addcard_m2; break;
-	default:
-        case AVM_CARDTYPE_B1: addcard = b1pcmcia_addcard_b1; break;
-    }
-    if ((i = (*addcard)(link->io.BasePort1, link->irq.AssignedIRQ)) < 0) {
-        printk(KERN_ERR "avm_cs: failed to add AVM-%s-Controller at i/o %#x, irq %d\n",
-		dev->node.dev_name, link->io.BasePort1, link->irq.AssignedIRQ);
-	avmcs_release((u_long)link);
-	return;
-    }
-    dev->node.minor = i;
-
-} /* avmcs_config */
-
-/*======================================================================
-
-    After a card is removed, avmcs_release() will unregister the net
-    device, and release the PCMCIA configuration.  If the device is
-    still open, this will be postponed until it is closed.
-    
-======================================================================*/
-
-static void avmcs_release(u_long arg)
-{
-    dev_link_t *link = (dev_link_t *)arg;
-
-    /*
-       If the device is currently in use, we won't release until it
-       is actually closed.
-    */
-    if (link->open) {
-	link->state |= DEV_STALE_CONFIG;
-	return;
-    }
-
-    b1pcmcia_delcard(link->io.BasePort1, link->irq.AssignedIRQ);
-
-    /* Unlink the device chain */
-    link->dev = NULL;
-    
-    /* Don't bother checking to see if these succeed or not */
-    CardServices(ReleaseConfiguration, link->handle);
-    CardServices(ReleaseIO, link->handle, &link->io);
-    CardServices(ReleaseIRQ, link->handle, &link->irq);
-    link->state &= ~DEV_CONFIG;
-    
-    if (link->state & DEV_STALE_LINK)
-	avmcs_detach(link);
-    
-} /* avmcs_release */
-
-/*======================================================================
-
-    The card status event handler.  Mostly, this schedules other
-    stuff to run after an event is received.  A CARD_REMOVAL event
-    also sets some flags to discourage the net drivers from trying
-    to talk to the card any more.
-
-    When a CARD_REMOVAL event is received, we immediately set a flag
-    to block future accesses to this device.  All the functions that
-    actually access the device should check this flag to make sure
-    the card is still present.
-    
-======================================================================*/
-
-static int avmcs_event(event_t event, int priority,
-			  event_callback_args_t *args)
-{
-    dev_link_t *link = args->client_data;
-
-    switch (event) {
-    case CS_EVENT_CARD_REMOVAL:
-	link->state &= ~DEV_PRESENT;
-	if (link->state & DEV_CONFIG) {
-	    link->release.expires = jiffies + (HZ/20);
-	    add_timer(&link->release);
-	}
-	break;
-    case CS_EVENT_CARD_INSERTION:
-	link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
-	avmcs_config(link);
-	break;
-    case CS_EVENT_PM_SUSPEND:
-	link->state |= DEV_SUSPEND;
-	/* Fall through... */
-    case CS_EVENT_RESET_PHYSICAL:
-	if (link->state & DEV_CONFIG)
-	    CardServices(ReleaseConfiguration, link->handle);
-	break;
-    case CS_EVENT_PM_RESUME:
-	link->state &= ~DEV_SUSPEND;
-	/* Fall through... */
-    case CS_EVENT_CARD_RESET:
-	if (link->state & DEV_CONFIG)
-	    CardServices(RequestConfiguration, link->handle, &link->conf);
-	break;
-    }
-    return 0;
-} /* avmcs_event */
-
-/*====================================================================*/
-
-int init_module(void)
-{
-    servinfo_t serv;
-    CardServices(GetCardServicesInfo, &serv);
-    if (serv.Revision != CS_RELEASE_CODE) {
-	printk(KERN_NOTICE "avm_cs: Card Services release "
-	       "does not match!\n");
-	return -1;
-    }
-    register_pccard_driver(&dev_info, &avmcs_attach, &avmcs_detach);
-    return 0;
-}
-
-void cleanup_module(void)
-{
-    unregister_pccard_driver(&dev_info);
-    while (dev_list != NULL) {
-	if (dev_list->state & DEV_CONFIG)
-	    avmcs_release((u_long)dev_list);
-	avmcs_detach(dev_list);
-    }
-}
diff -urN linux-2.2.19-pre10/drivers/isdn/avmb1/b1.c linux/drivers/isdn/avmb1/b1.c
--- linux-2.2.19-pre10/drivers/isdn/avmb1/b1.c	Mon Dec  3 21:02:15 2001
+++ linux/drivers/isdn/avmb1/b1.c	Mon Dec  3 21:02:59 2001
@@ -1,11 +1,32 @@
 /*
- * $Id: b1.c,v 1.14 2000/06/19 16:51:53 keil Exp $
+ * $Id: b1.c,v 1.20 2000/11/23 20:45:14 kai Exp $
  * 
  * Common module for AVM B1 cards.
  * 
  * (c) Copyright 1999 by Carsten Paeth (calle@calle.in-berlin.de)
  * 
  * $Log: b1.c,v $
+ * Revision 1.20  2000/11/23 20:45:14  kai
+ * fixed module_init/exit stuff
+ * Note: compiled-in kernel doesn't work pre 2.2.18 anymore.
+ *
+ * Revision 1.19  2000/11/19 17:02:47  kai
+ * compatibility cleanup - part 3
+ *
+ * Revision 1.18  2000/11/19 17:01:53  kai
+ * compatibility cleanup - part 2
+ *
+ * Revision 1.17  2000/11/01 14:05:02  calle
+ * - use module_init/module_exit from linux/init.h.
+ * - all static struct variables are initialized with "membername:" now.
+ * - avm_cs.c, let it work with newer pcmcia-cs.
+ *
+ * Revision 1.16  2000/08/04 15:36:31  calle
+ * copied wrong from file to file :-(
+ *
+ * Revision 1.15  2000/08/04 12:20:08  calle
+ * - Fix unsigned/signed warning in the right way ...
+ *
  * Revision 1.14  2000/06/19 16:51:53  keil
  * don't free skb in irq context
  *
@@ -88,13 +109,14 @@
 #include <linux/ioport.h>
 #include <linux/capi.h>
 #include <asm/io.h>
+#include <linux/init.h>
 #include <asm/uaccess.h>
 #include "capilli.h"
 #include "avmcard.h"
 #include "capicmd.h"
 #include "capiutil.h"
 
-static char *revision = "$Revision: 1.20 $";
+static char *revision = "$Revision: 1.20.6.1 $";
 
 /* ------------------------------------------------------------- */
 
@@ -721,12 +743,7 @@
 
 EXPORT_SYMBOL(b1ctl_read_proc);
 
-#ifdef MODULE
-#define b1_init init_module
-void cleanup_module(void);
-#endif
-
-int b1_init(void)
+static int __init b1_init(void)
 {
 	char *p;
 	char rev[10];
@@ -743,8 +760,9 @@
 	return 0;
 }
 
-#ifdef MODULE
-void cleanup_module(void)
+static void  b1_exit(void)
 {
 }
-#endif
+
+module_init(b1_init);
+module_exit(b1_exit);
diff -urN linux-2.2.19-pre10/drivers/isdn/avmb1/b1dma.c linux/drivers/isdn/avmb1/b1dma.c
--- linux-2.2.19-pre10/drivers/isdn/avmb1/b1dma.c	Mon Dec  3 21:02:15 2001
+++ linux/drivers/isdn/avmb1/b1dma.c	Mon Dec  3 21:02:59 2001
@@ -1,11 +1,31 @@
 /*
- * $Id: b1dma.c,v 1.5 2000/06/19 16:51:53 keil Exp $
+ * $Id: b1dma.c,v 1.11 2000/11/19 17:02:47 kai Exp $
  * 
  * Common module for AVM B1 cards that support dma with AMCC
  * 
  * (c) Copyright 2000 by Carsten Paeth (calle@calle.in-berlin.de)
  * 
  * $Log: b1dma.c,v $
+ * Revision 1.11  2000/11/19 17:02:47  kai
+ * compatibility cleanup - part 3
+ *
+ * Revision 1.10  2000/11/19 17:01:53  kai
+ * compatibility cleanup - part 2
+ *
+ * Revision 1.9  2000/11/01 14:05:02  calle
+ * - use module_init/module_exit from linux/init.h.
+ * - all static struct variables are initialized with "membername:" now.
+ * - avm_cs.c, let it work with newer pcmcia-cs.
+ *
+ * Revision 1.8  2000/10/10 17:44:19  kai
+ * changes from/for 2.2.18
+ *
+ * Revision 1.7  2000/08/04 12:20:08  calle
+ * - Fix unsigned/signed warning in the right way ...
+ *
+ * Revision 1.6  2000/06/29 13:59:06  calle
+ * Bugfix: reinit txdma without interrupt will confuse some AMCC chips.
+ *
  * Revision 1.5  2000/06/19 16:51:53  keil
  * don't free skb in irq context
  *
@@ -34,13 +54,14 @@
 #include <linux/ioport.h>
 #include <linux/capi.h>
 #include <asm/io.h>
+#include <linux/init.h>
 #include <asm/uaccess.h>
 #include "capilli.h"
 #include "avmcard.h"
 #include "capicmd.h"
 #include "capiutil.h"
 
-static char *revision = "$Revision: 1.11 $";
+static char *revision = "$Revision: 1.11.6.1 $";
 
 /* ------------------------------------------------------------- */
 
@@ -963,11 +984,6 @@
 EXPORT_SYMBOL(b1dma_send_message);
 EXPORT_SYMBOL(b1dmactl_read_proc);
 
-#ifdef MODULE
-#define b1dma_init init_module
-void cleanup_module(void);
-#endif
-
 int b1dma_init(void)
 {
 	char *p;
@@ -985,8 +1001,9 @@
 	return 0;
 }
 
-#ifdef MODULE
-void cleanup_module(void)
+void b1dma_exit(void)
 {
 }
-#endif
+
+module_init(b1dma_init);
+module_exit(b1dma_exit);
diff -urN linux-2.2.19-pre10/drivers/isdn/avmb1/b1isa.c linux/drivers/isdn/avmb1/b1isa.c
--- linux-2.2.19-pre10/drivers/isdn/avmb1/b1isa.c	Mon Dec  3 21:02:15 2001
+++ linux/drivers/isdn/avmb1/b1isa.c	Mon Dec  3 21:02:59 2001
@@ -1,11 +1,20 @@
 /*
- * $Id: b1isa.c,v 1.8 2000/04/03 13:29:24 calle Exp $
+ * $Id: b1isa.c,v 1.10 2000/11/23 20:45:14 kai Exp $
  * 
  * Module for AVM B1 ISA-card.
  * 
  * (c) Copyright 1999 by Carsten Paeth (calle@calle.in-berlin.de)
  * 
  * $Log: b1isa.c,v $
+ * Revision 1.10  2000/11/23 20:45:14  kai
+ * fixed module_init/exit stuff
+ * Note: compiled-in kernel doesn't work pre 2.2.18 anymore.
+ *
+ * Revision 1.9  2000/11/01 14:05:02  calle
+ * - use module_init/module_exit from linux/init.h.
+ * - all static struct variables are initialized with "membername:" now.
+ * - avm_cs.c, let it work with newer pcmcia-cs.
+ *
  * Revision 1.8  2000/04/03 13:29:24  calle
  * make Tim Waugh happy (module unload races in 2.3.99-pre3).
  * no real problem there, but now it is much cleaner ...
@@ -67,13 +76,14 @@
 #include <linux/interrupt.h>
 #include <linux/ioport.h>
 #include <linux/capi.h>
+#include <linux/init.h>
 #include <asm/io.h>
 #include "capicmd.h"
 #include "capiutil.h"
 #include "capilli.h"
 #include "avmcard.h"
 
-static char *revision = "$Revision: 1.10 $";
+static char *revision = "$Revision: 1.10.6.1 $";
 
 /* ------------------------------------------------------------- */
 
@@ -260,12 +270,7 @@
     add_card: b1isa_add_card,
 };
 
-#ifdef MODULE
-#define b1isa_init init_module
-void cleanup_module(void);
-#endif
-
-int b1isa_init(void)
+static int __init b1isa_init(void)
 {
 	struct capi_driver *driver = &b1isa_driver;
 	char *p;
@@ -292,9 +297,10 @@
 	return retval;
 }
 
-#ifdef MODULE
-void cleanup_module(void)
+static void  b1isa_exit(void)
 {
     detach_capi_driver(&b1isa_driver);
 }
-#endif
+
+module_init(b1isa_init);
+module_exit(b1isa_exit);
diff -urN linux-2.2.19-pre10/drivers/isdn/avmb1/b1pci.c linux/drivers/isdn/avmb1/b1pci.c
--- linux-2.2.19-pre10/drivers/isdn/avmb1/b1pci.c	Mon Dec  3 21:02:15 2001
+++ linux/drivers/isdn/avmb1/b1pci.c	Mon Dec  3 21:02:59 2001
@@ -1,11 +1,37 @@
 /*
- * $Id: b1pci.c,v 1.25 2000/05/29 12:29:18 keil Exp $
+ * $Id: b1pci.c,v 1.29.6.1 2000/11/28 12:02:45 kai Exp $
  * 
  * Module for AVM B1 PCI-card.
  * 
  * (c) Copyright 1999 by Carsten Paeth (calle@calle.in-berlin.de)
  * 
  * $Log: b1pci.c,v $
+ * Revision 1.29.6.1  2000/11/28 12:02:45  kai
+ * MODULE_DEVICE_TABLE for 2.4
+ *
+ * Revision 1.29.2.2  2000/11/26 17:47:53  kai
+ * added PCI_DEV_TABLE for 2.4
+ *
+ * Revision 1.29.2.1  2000/11/26 17:14:19  kai
+ * fix device ids
+ * also needs patches to include/linux/pci_ids.h
+ *
+ * Revision 1.29  2000/11/23 20:45:14  kai
+ * fixed module_init/exit stuff
+ * Note: compiled-in kernel doesn't work pre 2.2.18 anymore.
+ *
+ * Revision 1.28  2000/11/01 14:05:02  calle
+ * - use module_init/module_exit from linux/init.h.
+ * - all static struct variables are initialized with "membername:" now.
+ * - avm_cs.c, let it work with newer pcmcia-cs.
+ *
+ * Revision 1.27  2000/08/08 09:24:19  calle
+ * calls to pci_enable_device surounded by #ifndef COMPAT_HAS_2_2_PCI
+ *
+ * Revision 1.26  2000/07/20 10:21:21  calle
+ * Bugfix: driver will not be unregistered, if not cards were detected.
+ *         this result in an oops in kcapi.c
+ *
  * Revision 1.25  2000/05/29 12:29:18  keil
  * make pci_enable_dev compatible to 2.2 kernel versions
  *
@@ -87,7 +113,8 @@
 #include <linux/pci.h>
 #include <linux/capi.h>
 #include <asm/io.h>
-#include <linux/isdn.h>
+#include <linux/init.h>
+#include <linux/isdn_compat.h>
 #include "capicmd.h"
 #include "capiutil.h"
 #include "capilli.h"
@@ -465,11 +492,6 @@
 
 #endif /* CONFIG_ISDN_DRV_AVMB1_B1PCIV4 */
 
-#ifdef MODULE
-#define b1pci_init init_module
-void cleanup_module(void);
-#endif
-
 static int ncards = 0;
 
 static int add_card(struct pci_dev *dev)
@@ -491,9 +513,6 @@
 		        printk(KERN_ERR
 			"%s: failed to enable AVM-B1 V4 at i/o %#x, irq %d, mem %#x err=%d\n",
 			driver->name, param.port, param.irq, param.membase, retval);
-#ifdef MODULE
-			cleanup_module();
-#endif
 			MOD_DEC_USE_COUNT;
 			return -EIO;
 		}
@@ -521,9 +540,6 @@
 		        printk(KERN_ERR
 			"%s: failed to enable AVM-B1 at i/o %#x, irq %d, err=%d\n",
 			driver->name, param.port, param.irq, retval);
-#ifdef MODULE
-			cleanup_module();
-#endif
 			MOD_DEC_USE_COUNT;
 			return -EIO;
 		}
@@ -540,7 +556,7 @@
 	return retval;
 }
 
-int b1pci_init(void)
+static int __init b1pci_init(void)
 {
 	struct capi_driver *driver = &b1pci_driver;
 #ifdef CONFIG_ISDN_DRV_AVMB1_B1PCIV4
@@ -603,9 +619,6 @@
 	while ((dev = pci_find_device(PCI_VENDOR_ID_AVM, PCI_DEVICE_ID_AVM_B1, dev))) {
 		retval = add_card(dev);
 		if (retval != 0) {
-#ifdef MODULE
-			cleanup_module();
-#endif
 			MOD_DEC_USE_COUNT;
 			return retval;
 		}
@@ -627,12 +640,13 @@
 #endif
 }
 
-#ifdef MODULE
-void cleanup_module(void)
+static void  b1pci_exit(void)
 {
     detach_capi_driver(&b1pci_driver);
 #ifdef CONFIG_ISDN_DRV_AVMB1_B1PCIV4
     detach_capi_driver(&b1pciv4_driver);
 #endif
 }
-#endif
+
+module_init(b1pci_init);
+module_exit(b1pci_exit);
diff -urN linux-2.2.19-pre10/drivers/isdn/avmb1/b1pcmcia.c linux/drivers/isdn/avmb1/b1pcmcia.c
--- linux-2.2.19-pre10/drivers/isdn/avmb1/b1pcmcia.c	Mon Dec  3 21:02:15 2001
+++ linux/drivers/isdn/avmb1/b1pcmcia.c	Mon Dec  3 21:02:59 2001
@@ -1,11 +1,20 @@
 /*
- * $Id: b1pcmcia.c,v 1.10 2000/05/06 00:52:36 kai Exp $
+ * $Id: b1pcmcia.c,v 1.12 2000/11/23 20:45:14 kai Exp $
  * 
  * Module for AVM B1/M1/M2 PCMCIA-card.
  * 
  * (c) Copyright 1999 by Carsten Paeth (calle@calle.in-berlin.de)
  * 
  * $Log: b1pcmcia.c,v $
+ * Revision 1.12  2000/11/23 20:45:14  kai
+ * fixed module_init/exit stuff
+ * Note: compiled-in kernel doesn't work pre 2.2.18 anymore.
+ *
+ * Revision 1.11  2000/11/01 14:05:02  calle
+ * - use module_init/module_exit from linux/init.h.
+ * - all static struct variables are initialized with "membername:" now.
+ * - avm_cs.c, let it work with newer pcmcia-cs.
+ *
  * Revision 1.10  2000/05/06 00:52:36  kai
  * merged changes from kernel tree
  * fixed timer and net_device->name breakage
@@ -75,6 +84,7 @@
 #include <linux/mm.h>
 #include <linux/interrupt.h>
 #include <linux/ioport.h>
+#include <linux/init.h>
 #include <asm/io.h>
 #include <linux/capi.h>
 #include <linux/b1pcmcia.h>
@@ -300,12 +310,7 @@
 
 /* ------------------------------------------------------------- */
 
-#ifdef MODULE
-#define b1pcmcia_init init_module
-void cleanup_module(void);
-#endif
-
-int b1pcmcia_init(void)
+static int __init b1pcmcia_init(void)
 {
 	struct capi_driver *driver = &b1pcmcia_driver;
 	char *p;
@@ -332,9 +337,10 @@
 	return retval;
 }
 
-#ifdef MODULE
-void cleanup_module(void)
+static void  b1pcmcia_exit(void)
 {
     detach_capi_driver(&b1pcmcia_driver);
 }
-#endif
+
+module_init(b1pcmcia_init);
+module_exit(b1pcmcia_exit);
diff -urN linux-2.2.19-pre10/drivers/isdn/avmb1/c4.c linux/drivers/isdn/avmb1/c4.c
--- linux-2.2.19-pre10/drivers/isdn/avmb1/c4.c	Mon Dec  3 21:02:15 2001
+++ linux/drivers/isdn/avmb1/c4.c	Mon Dec  3 21:02:59 2001
@@ -1,11 +1,49 @@
 /*
- * $Id: c4.c,v 1.12 2000/06/19 16:51:53 keil Exp $
+ * $Id: c4.c,v 1.20.6.1 2000/11/28 12:02:45 kai Exp $
  * 
  * Module for AVM C4 card.
  * 
  * (c) Copyright 1999 by Carsten Paeth (calle@calle.in-berlin.de)
  * 
  * $Log: c4.c,v $
+ * Revision 1.20.6.1  2000/11/28 12:02:45  kai
+ * MODULE_DEVICE_TABLE for 2.4
+ *
+ * Revision 1.20.2.2  2000/11/26 17:47:53  kai
+ * added PCI_DEV_TABLE for 2.4
+ *
+ * Revision 1.20.2.1  2000/11/26 17:14:19  kai
+ * fix device ids
+ * also needs patches to include/linux/pci_ids.h
+ *
+ * Revision 1.20  2000/11/23 20:45:14  kai
+ * fixed module_init/exit stuff
+ * Note: compiled-in kernel doesn't work pre 2.2.18 anymore.
+ *
+ * Revision 1.19  2000/11/19 17:02:47  kai
+ * compatibility cleanup - part 3
+ *
+ * Revision 1.18  2000/11/01 14:05:02  calle
+ * - use module_init/module_exit from linux/init.h.
+ * - all static struct variables are initialized with "membername:" now.
+ * - avm_cs.c, let it work with newer pcmcia-cs.
+ *
+ * Revision 1.17  2000/10/10 17:44:19  kai
+ * changes from/for 2.2.18
+ *
+ * Revision 1.16  2000/08/20 07:30:13  keil
+ * changes for 2.4
+ *
+ * Revision 1.15  2000/08/08 09:24:19  calle
+ * calls to pci_enable_device surounded by #ifndef COMPAT_HAS_2_2_PCI
+ *
+ * Revision 1.14  2000/08/04 12:20:08  calle
+ * - Fix unsigned/signed warning in the right way ...
+ *
+ * Revision 1.13  2000/07/20 10:21:21  calle
+ * Bugfix: driver will not be unregistered, if not cards were detected.
+ *         this result in an oops in kcapi.c
+ *
  * Revision 1.12  2000/06/19 16:51:53  keil
  * don't free skb in irq context
  *
@@ -58,8 +96,9 @@
 #include <linux/interrupt.h>
 #include <linux/ioport.h>
 #include <linux/pci.h>
+#include <linux/isdn_compat.h>
 #include <linux/capi.h>
-#include <linux/isdn.h>
+#include <linux/init.h>
 #include <asm/io.h>
 #include <asm/uaccess.h>
 #include "capicmd.h"
@@ -1286,35 +1325,9 @@
     add_card: 0, /* no add_card function */
 };
 
-#ifdef MODULE
-#define c4_init init_module
-void cleanup_module(void);
-#endif
-
-#ifndef PCI_ANY_ID
-#define PCI_ANY_ID (~0)
-#endif
-
-static struct pci_dev *
-pci_find_subsys(unsigned int vendor, unsigned int device,
-		unsigned int ss_vendor, unsigned int ss_device,
-		struct pci_dev *from)
-{
-	unsigned short subsystem_vendor, subsystem_device;
-
-	while ((from = pci_find_device(vendor, device, from))) {
-		pci_read_config_word(from, PCI_SUBSYSTEM_VENDOR_ID, &subsystem_vendor);
-		pci_read_config_word(from, PCI_SUBSYSTEM_ID, &subsystem_device);
-		if ((ss_vendor == PCI_ANY_ID || subsystem_vendor == ss_vendor) &&
-		    (ss_device == PCI_ANY_ID || subsystem_device == ss_device))
-			return from;
-	}
-	return NULL;
-}
-
 static int ncards = 0;
 
-int c4_init(void)
+static int __init c4_init(void)
 {
 	struct capi_driver *driver = &c4_driver;
 	struct pci_dev *dev = NULL;
@@ -1362,9 +1375,6 @@
 		        printk(KERN_ERR
 			"%s: failed to enable AVM-C4 at i/o %#x, irq %d, mem %#x err=%d\n",
 			driver->name, param.port, param.irq, param.membase, retval);
-#ifdef MODULE
-			cleanup_module();
-#endif
 			MOD_DEC_USE_COUNT;
 			return -EIO;
 		}
@@ -1377,9 +1387,6 @@
 		        printk(KERN_ERR
 			"%s: no AVM-C4 at i/o %#x, irq %d detected, mem %#x\n",
 			driver->name, param.port, param.irq, param.membase);
-#ifdef MODULE
-			cleanup_module();
-#endif
 			MOD_DEC_USE_COUNT;
 			return retval;
 		}
@@ -1401,9 +1408,10 @@
 #endif
 }
 
-#ifdef MODULE
-void cleanup_module(void)
+static void  c4_exit(void)
 {
     detach_capi_driver(&c4_driver);
 }
-#endif
+
+module_init(c4_init);
+module_exit(c4_exit);
diff -urN linux-2.2.19-pre10/drivers/isdn/avmb1/capi.c linux/drivers/isdn/avmb1/capi.c
--- linux-2.2.19-pre10/drivers/isdn/avmb1/capi.c	Mon Dec  3 21:02:15 2001
+++ linux/drivers/isdn/avmb1/capi.c	Mon Dec  3 21:02:59 2001
@@ -1,11 +1,14 @@
 /*
- * $Id: capi.c,v 1.44.6.3 2000/12/17 22:45:08 kai Exp $
+ * $Id: capi.c,v 1.44.6.4 2001/02/10 14:41:20 kai Exp $
  *
  * CAPI 2.0 Interface for Linux
  *
  * Copyright 1996 by Carsten Paeth (calle@calle.in-berlin.de)
  *
  * $Log: capi.c,v $
+ * Revision 1.44.6.4  2001/02/10 14:41:20  kai
+ * Changes from kernel tree
+ *
  * Revision 1.44.6.3  2000/12/17 22:45:08  kai
  * That's hopefully it for test13-4
  *
@@ -217,16 +220,18 @@
  *
  */
 
+#include <linux/config.h>
 #include <linux/module.h>
 #include <linux/errno.h>
 #include <linux/kernel.h>
 #include <linux/major.h>
 #include <linux/sched.h>
-#include <linux/malloc.h>
+#include <linux/slab.h>
 #include <linux/fcntl.h>
 #include <linux/fs.h>
 #include <linux/signal.h>
 #include <linux/mm.h>
+#include <linux/smp_lock.h>
 #include <linux/timer.h>
 #include <linux/wait.h>
 #ifdef CONFIG_ISDN_CAPI_MIDDLEWARE
@@ -243,13 +248,14 @@
 #include <linux/poll.h>
 #include <linux/capi.h>
 #include <linux/kernelcapi.h>
+#include <linux/init.h>
 #include "capiutil.h"
 #include "capicmd.h"
-#ifdef CONFIG_ISDN_CAPI_MIDDLEWARE
+#if defined(CONFIG_ISDN_CAPI_CAPIFS) || defined(CONFIG_ISDN_CAPI_CAPIFS_MODULE)
 #include "capifs.h"
-#endif /* CONFIG_ISDN_CAPI_MIDDLEWARE */
+#endif
 
-static char *revision = "$Revision: 1.44.6.3 $";
+static char *revision = "$Revision: 1.44.6.4 $";
 
 MODULE_AUTHOR("Carsten Paeth (calle@calle.in-berlin.de)");
 
@@ -308,8 +314,8 @@
 
 	/* for raw device */
 	struct sk_buff_head recvqueue;
-	struct wait_queue *recvwait;
-	struct wait_queue *sendwait;
+	wait_queue_head_t recvwait;
+	wait_queue_head_t sendwait;
 	
 	/* transmit path */
 	struct datahandle_queue {
@@ -339,7 +345,7 @@
 	unsigned        userflags;
 
 	struct sk_buff_head recvqueue;
-	struct wait_queue *recvwait;
+	wait_queue_head_t recvwait;
 
 	/* Statistic */
 	unsigned long	nrecvctlpkt;
@@ -400,7 +406,8 @@
 {
 	struct datahandle_queue **pp, *p;
 
-	for (pp = &mp->ackqueue; *pp; pp = &(*pp)->next) {
+	pp = &mp->ackqueue;
+	while (*pp) {
 		p = *pp;
 		*pp = (*pp)->next;
 		kfree(p);
@@ -436,6 +443,8 @@
 	skb_queue_head_init(&mp->outqueue);
 
 	skb_queue_head_init(&mp->recvqueue);
+	init_waitqueue_head(&mp->recvwait);
+	init_waitqueue_head(&mp->sendwait);
 
 	for (pp = &minors; *pp; pp = &(*pp)->next) {
 		if ((*pp)->minor < minor)
@@ -517,7 +526,7 @@
 #ifdef _DEBUG_REFCOUNT
 		printk(KERN_DEBUG "set mp->nccip\n");
 #endif
-#ifdef CONFIG_ISDN_CAPIFS
+#if defined(CONFIG_ISDN_CAPI_CAPIFS) || defined(CONFIG_ISDN_CAPI_CAPIFS_MODULE)
 		kdev = MKDEV(capi_rawmajor, mp->minor);
 		capifs_new_ncci('r', mp->minor, kdev);
 		kdev = MKDEV(capi_ttymajor, mp->minor);
@@ -542,7 +551,7 @@
 			*pp = (*pp)->next;
 #ifdef CONFIG_ISDN_CAPI_MIDDLEWARE
 			if ((mp = np->minorp) != 0) {
-#ifdef CONFIG_ISDN_CAPIFS
+#if defined(CONFIG_ISDN_CAPI_CAPIFS) || defined(CONFIG_ISDN_CAPI_CAPIFS_MODULE)
 				capifs_free_ncci('r', mp->minor);
 				capifs_free_ncci(0, mp->minor);
 #endif
@@ -598,6 +607,7 @@
 	cdev->minor = MINOR(file->f_dentry->d_inode->i_rdev);
 
 	skb_queue_head_init(&cdev->recvqueue);
+	init_waitqueue_head(&cdev->recvwait);
 	pp=&capidev_openlist;
 	while (*pp) pp = &(*pp)->next;
 	*pp = cdev;
@@ -1258,6 +1268,7 @@
 {
 	struct capidev *cdev = (struct capidev *)file->private_data;
 
+	lock_kernel();
 	capincci_free(cdev, 0xffffffff);
 	capidev_free(cdev);
 	file->private_data = NULL;
@@ -1266,6 +1277,7 @@
 #ifdef _DEBUG_REFCOUNT
 	printk(KERN_DEBUG "capi_release %d\n", GET_USE_COUNT(&__this_module));
 #endif
+	unlock_kernel();
 	return 0;
 }
 
@@ -1447,11 +1459,13 @@
 	struct capiminor *mp = (struct capiminor *)file->private_data;
 
 	if (mp) {
+		lock_kernel();
 		mp->file = 0;
 		if (mp->nccip == 0) {
 			capiminor_free(mp);
 			file->private_data = NULL;
 		}
+		unlock_kernel();
 	}
 
 #ifdef _DEBUG_REFCOUNT
@@ -1485,6 +1499,8 @@
 		return -EBUSY;
 
 	skb_queue_head_init(&mp->recvqueue);
+	init_waitqueue_head(&mp->recvwait);
+	init_waitqueue_head(&mp->sendwait);
 	tty->driver_data = (void *)mp;
 #ifdef _DEBUG_REFCOUNT
 	printk(KERN_DEBUG "capi_tty_open %d\n", GET_USE_COUNT(&__this_module));
@@ -1943,7 +1959,7 @@
    { "capi/capi20ncci",   0	 , proc_capincci_read_proc },
 };
 
-static void proc_init(void)
+static void __init proc_init(void)
 {
     int nelem = sizeof(procfsentries)/sizeof(procfsentries[0]);
     int i;
@@ -1955,7 +1971,7 @@
     }
 }
 
-static void proc_exit(void)
+static void  proc_exit(void)
 {
     int nelem = sizeof(procfsentries)/sizeof(procfsentries[0]);
     int i;
@@ -1999,18 +2015,14 @@
 	}
 }
 
-#ifdef MODULE
-#define	 capi_init	init_module
-#endif
-
 static struct capi_interface_user cuser = {
-	"capi20",
-	lower_callback,
+	name: "capi20",
+	callback: lower_callback,
 };
 
 static char rev[10];
 
-int capi_init(void)
+static int __init capi_init(void)
 {
 	char *p;
 
@@ -2069,8 +2081,7 @@
 	return 0;
 }
 
-#ifdef MODULE
-void cleanup_module(void)
+static void  capi_exit(void)
 {
 #ifdef CONFIG_ISDN_CAPI_MIDDLEWARE
 #endif
@@ -2086,4 +2097,5 @@
 	printk(KERN_NOTICE "capi: Rev%s: unloaded\n", rev);
 }
 
-#endif
+module_init(capi_init);
+module_exit(capi_exit);
diff -urN linux-2.2.19-pre10/drivers/isdn/avmb1/capidev.h linux/drivers/isdn/avmb1/capidev.h
--- linux-2.2.19-pre10/drivers/isdn/avmb1/capidev.h	Mon Dec  3 21:02:15 2001
+++ linux/drivers/isdn/avmb1/capidev.h	Mon Dec  3 21:02:59 2001
@@ -61,7 +61,7 @@
 	unsigned int    minor;
 
 	struct sk_buff_head recv_queue;
-	struct wait_queue *recv_wait;
+	wait_queue_head_t recv_wait;
 
 	/* Statistic */
 	unsigned long	nrecvctlpkt;
diff -urN linux-2.2.19-pre10/drivers/isdn/avmb1/capidrv.c linux/drivers/isdn/avmb1/capidrv.c
--- linux-2.2.19-pre10/drivers/isdn/avmb1/capidrv.c	Mon Dec  3 21:02:15 2001
+++ linux/drivers/isdn/avmb1/capidrv.c	Mon Dec  3 21:02:59 2001
@@ -1,11 +1,14 @@
 /*
- * $Id: capidrv.c,v 1.39 2000/11/23 20:45:14 kai Exp $
+ * $Id: capidrv.c,v 1.39.6.1 2001/02/10 14:41:20 kai Exp $
  *
  * ISDN4Linux Driver, using capi20 interface (kernelcapi)
  *
  * Copyright 1997 by Carsten Paeth (calle@calle.in-berlin.de)
  *
  * $Log: capidrv.c,v $
+ * Revision 1.39.6.1  2001/02/10 14:41:20  kai
+ * Changes from kernel tree
+ *
  * Revision 1.39  2000/11/23 20:45:14  kai
  * fixed module_init/exit stuff
  * Note: compiled-in kernel doesn't work pre 2.2.18 anymore.
@@ -198,7 +201,7 @@
 #include <linux/kernel.h>
 #include <linux/major.h>
 #include <linux/sched.h>
-#include <linux/malloc.h>
+#include <linux/slab.h>
 #include <linux/fcntl.h>
 #include <linux/fs.h>
 #include <linux/signal.h>
@@ -212,13 +215,14 @@
 #include <linux/capi.h>
 #include <linux/kernelcapi.h>
 #include <linux/ctype.h>
+#include <linux/init.h>
 #include <asm/segment.h>
 
 #include "capiutil.h"
 #include "capicmd.h"
 #include "capidrv.h"
 
-static char *revision = "$Revision: 1.39 $";
+static char *revision = "$Revision: 1.39.6.1 $";
 static int debugmode = 0;
 
 MODULE_AUTHOR("Carsten Paeth <calle@calle.in-berlin.de>");
@@ -2448,7 +2452,7 @@
    { "capi/capidrv", 	  0	 , proc_capidrv_read_proc },
 };
 
-static void proc_init(void)
+static void __init proc_init(void)
 {
     int nelem = sizeof(procfsentries)/sizeof(procfsentries[0]);
     int i;
@@ -2460,7 +2464,7 @@
     }
 }
 
-static void proc_exit(void)
+static void  proc_exit(void)
 {
     int nelem = sizeof(procfsentries)/sizeof(procfsentries[0]);
     int i;
@@ -2479,11 +2483,7 @@
 	callback: lower_callback
 };
 
-#ifdef MODULE
-#define capidrv_init init_module
-#endif
-
-int capidrv_init(void)
+static int __init capidrv_init(void)
 {
 	struct capi_register_params rparam;
 	capi_profile profile;
@@ -2543,8 +2543,7 @@
 	return 0;
 }
 
-#ifdef MODULE
-void cleanup_module(void)
+static void  capidrv_exit(void)
 {
 	char rev[10];
 	char *p;
@@ -2566,4 +2565,5 @@
 	printk(KERN_NOTICE "capidrv: Rev%s: unloaded\n", rev);
 }
 
-#endif
+module_init(capidrv_init);
+module_exit(capidrv_exit);
diff -urN linux-2.2.19-pre10/drivers/isdn/avmb1/capifs.c linux/drivers/isdn/avmb1/capifs.c
--- linux-2.2.19-pre10/drivers/isdn/avmb1/capifs.c	Mon Dec  3 21:02:15 2001
+++ linux/drivers/isdn/avmb1/capifs.c	Mon Dec  3 21:02:59 2001
@@ -1,11 +1,44 @@
 /*
- * $Id: capifs.c,v 1.7 2000/06/18 16:09:54 keil Exp $
+ * $Id: capifs.c,v 1.14.6.2 2001/02/10 14:41:20 kai Exp $
  * 
  * (c) Copyright 2000 by Carsten Paeth (calle@calle.de)
  *
  * Heavily based on devpts filesystem from H. Peter Anvin
  * 
  * $Log: capifs.c,v $
+ * Revision 1.14.6.2  2001/02/10 14:41:20  kai
+ * Changes from kernel tree
+ *
+ * Revision 1.14.6.1  2000/11/28 12:02:45  kai
+ * MODULE_DEVICE_TABLE for 2.4
+ *
+ * Revision 1.14.2.1  2000/11/26 17:47:53  kai
+ * added PCI_DEV_TABLE for 2.4
+ *
+ * Revision 1.14  2000/11/23 20:45:14  kai
+ * fixed module_init/exit stuff
+ * Note: compiled-in kernel doesn't work pre 2.2.18 anymore.
+ *
+ * Revision 1.13  2000/11/18 16:17:25  kai
+ * change from 2.4 tree
+ *
+ * Revision 1.12  2000/11/01 14:05:02  calle
+ * - use module_init/module_exit from linux/init.h.
+ * - all static struct variables are initialized with "membername:" now.
+ * - avm_cs.c, let it work with newer pcmcia-cs.
+ *
+ * Revision 1.11  2000/10/24 15:08:47  calle
+ * Too much includes.
+ *
+ * Revision 1.10  2000/10/12 10:12:35  calle
+ * Bugfix: second iput(inode) on umount, destroies a foreign inode.
+ *
+ * Revision 1.9  2000/08/20 07:30:13  keil
+ * changes for 2.4
+ *
+ * Revision 1.8  2000/07/20 10:23:13  calle
+ * Include isdn_compat.h for people that don't use -p option of std2kern.
+ *
  * Revision 1.7  2000/06/18 16:09:54  keil
  * more changes for 2.4
  *
@@ -56,14 +89,14 @@
 #include <linux/kernel.h>
 #include <linux/locks.h>
 #include <linux/major.h>
-#include <linux/malloc.h>
+#include <linux/slab.h>
 #include <linux/ctype.h>
 #include <asm/bitops.h>
 #include <asm/uaccess.h>
 
 MODULE_AUTHOR("Carsten Paeth <calle@calle.de>");
 
-static char *revision = "$Revision: 1.14.6.1 $";
+static char *revision = "$Revision: 1.14.6.2 $";
 
 struct capifs_ncci {
 	struct inode *inode;
@@ -552,7 +585,7 @@
 	}
 }
 
-int __init capifs_init(void)
+static int __init capifs_init(void)
 {
 	char rev[10];
 	char *p;
@@ -581,7 +614,7 @@
 	return 0;
 }
 
-void capifs_exit(void)
+static void  capifs_exit(void)
 {
 	unregister_filesystem(&capifs_fs_type);
 }
@@ -589,16 +622,5 @@
 EXPORT_SYMBOL(capifs_new_ncci);
 EXPORT_SYMBOL(capifs_free_ncci);
 
-#ifdef MODULE
-
-int init_module(void)
-{
-	return capifs_init();
-}
-
-void cleanup_module(void)
-{
-	capifs_exit();
-}
-
-#endif
+module_init(capifs_init);
+module_exit(capifs_exit);
diff -urN linux-2.2.19-pre10/drivers/isdn/avmb1/capiutil.c linux/drivers/isdn/avmb1/capiutil.c
--- linux-2.2.19-pre10/drivers/isdn/avmb1/capiutil.c	Mon Dec  3 21:02:15 2001
+++ linux/drivers/isdn/avmb1/capiutil.c	Mon Dec  3 21:02:59 2001
@@ -90,6 +90,7 @@
 #include <linux/stddef.h>
 #include <linux/kernel.h>
 #include <linux/mm.h>
+#include <linux/init.h>
 #include <asm/segment.h>
 #include <linux/config.h>
 
@@ -995,15 +996,14 @@
 EXPORT_SYMBOL(capi_message2str);
 EXPORT_SYMBOL(capi_info2str);
 
-#ifdef MODULE
-
-int init_module(void)
-{
-	return 0;
+static int __init capiutil_init(void)
+{ 
+	return 0; 
 }
 
-void cleanup_module(void)
+static void  capiutil_exit(void)
 {
 }
 
-#endif
+module_init(capiutil_init);
+module_exit(capiutil_exit);
diff -urN linux-2.2.19-pre10/drivers/isdn/avmb1/kcapi.c linux/drivers/isdn/avmb1/kcapi.c
--- linux-2.2.19-pre10/drivers/isdn/avmb1/kcapi.c	Mon Dec  3 21:02:15 2001
+++ linux/drivers/isdn/avmb1/kcapi.c	Mon Dec  3 21:02:59 2001
@@ -1,11 +1,31 @@
 /*
- * $Id: kcapi.c,v 1.17 2000/04/21 13:00:56 calle Exp $
+ * $Id: kcapi.c,v 1.21.6.1 2000/12/10 23:39:19 kai Exp $
  * 
  * Kernel CAPI 2.0 Module
  * 
  * (c) Copyright 1999 by Carsten Paeth (calle@calle.in-berlin.de)
  * 
  * $Log: kcapi.c,v $
+ * Revision 1.21.6.1  2000/12/10 23:39:19  kai
+ * in 2.4 we don't have tq_scheduler anymore.
+ * also add one supported card to hfc_pci.c
+ * (from main branch)
+ *
+ * Revision 1.21  2000/11/23 20:45:14  kai
+ * fixed module_init/exit stuff
+ * Note: compiled-in kernel doesn't work pre 2.2.18 anymore.
+ *
+ * Revision 1.20  2000/11/19 17:01:53  kai
+ * compatibility cleanup - part 2
+ *
+ * Revision 1.19  2000/11/01 14:05:02  calle
+ * - use module_init/module_exit from linux/init.h.
+ * - all static struct variables are initialized with "membername:" now.
+ * - avm_cs.c, let it work with newer pcmcia-cs.
+ *
+ * Revision 1.18  2000/07/20 10:22:27  calle
+ * - Made procfs function cleaner and removed variable "begin".
+ *
  * Revision 1.17  2000/04/21 13:00:56  calle
  * Bugfix: driver_proc_info was also wrong.
  *
@@ -107,6 +127,7 @@
 #include <linux/capi.h>
 #include <linux/kernelcapi.h>
 #include <linux/locks.h>
+#include <linux/init.h>
 #include <asm/uaccess.h>
 #include "capicmd.h"
 #include "capiutil.h"
@@ -1487,7 +1508,7 @@
 
 		while (card->cardstate != CARD_RUNNING) {
 
-			current->state = TASK_INTERRUPTIBLE;
+			set_current_state(TASK_INTERRUPTIBLE);
 			schedule_timeout(HZ/10);	/* 0.1 sec */
 
 			if (signal_pending(current))
@@ -1512,7 +1533,7 @@
 
 		while (card->cardstate > CARD_DETECTED) {
 
-			current->state = TASK_INTERRUPTIBLE;
+			set_current_state(TASK_INTERRUPTIBLE);
 			schedule_timeout(HZ/10);	/* 0.1 sec */
 
 			if (signal_pending(current))
@@ -1563,7 +1584,7 @@
 
 		while (card->cardstate != CARD_FREE) {
 
-			current->state = TASK_INTERRUPTIBLE;
+			set_current_state(TASK_INTERRUPTIBLE);
 			schedule_timeout(HZ/10);	/* 0.1 sec */
 
 			if (signal_pending(current))
@@ -1721,36 +1742,11 @@
 EXPORT_SYMBOL(attach_capi_driver);
 EXPORT_SYMBOL(detach_capi_driver);
 
-#ifndef MODULE
-#ifdef CONFIG_ISDN_DRV_AVMB1_B1ISA
-extern int b1isa_init(void);
-#endif
-#ifdef CONFIG_ISDN_DRV_AVMB1_B1PCI
-extern int b1pci_init(void);
-#endif
-#ifdef CONFIG_ISDN_DRV_AVMB1_T1ISA
-extern int t1isa_init(void);
-#endif
-#ifdef CONFIG_ISDN_DRV_AVMB1_B1PCMCIA
-extern int b1pcmcia_init(void);
-#endif
-#ifdef CONFIG_ISDN_DRV_AVMB1_T1PCI
-extern int t1pci_init(void);
-#endif
-#ifdef CONFIG_ISDN_DRV_AVMB1_C4
-extern int c4_init(void);
-#endif
-#endif
-
 /*
  * init / exit functions
  */
 
-#ifdef MODULE
-#define kcapi_init init_module
-#endif
-
-int kcapi_init(void)
+static int __init kcapi_init(void)
 {
 	char *p;
 	char rev[10];
@@ -1778,31 +1774,12 @@
         printk(KERN_NOTICE "CAPI-driver Rev%s: loaded\n", rev);
 #else
 	printk(KERN_NOTICE "CAPI-driver Rev%s: started\n", rev);
-#ifdef CONFIG_ISDN_DRV_AVMB1_B1ISA
-	(void)b1isa_init();
-#endif
-#ifdef CONFIG_ISDN_DRV_AVMB1_B1PCI
-	(void)b1pci_init();
-#endif
-#ifdef CONFIG_ISDN_DRV_AVMB1_T1ISA
-	(void)t1isa_init();
-#endif
-#ifdef CONFIG_ISDN_DRV_AVMB1_B1PCMCIA
-	(void)b1pcmcia_init();
-#endif
-#ifdef CONFIG_ISDN_DRV_AVMB1_T1PCI
-	(void)t1pci_init();
-#endif
-#ifdef CONFIG_ISDN_DRV_AVMB1_C4
-	(void)c4_init();
-#endif
 #endif
 	MOD_DEC_USE_COUNT;
 	return 0;
 }
 
-#ifdef MODULE
-void cleanup_module(void)
+static void  kcapi_exit(void)
 {
 	char rev[10];
 	char *p;
@@ -1818,4 +1795,6 @@
         proc_capi_exit();
 	printk(KERN_NOTICE "CAPI-driver Rev%s: unloaded\n", rev);
 }
-#endif
+
+module_init(kcapi_init);
+module_exit(kcapi_exit);
diff -urN linux-2.2.19-pre10/drivers/isdn/avmb1/t1isa.c linux/drivers/isdn/avmb1/t1isa.c
--- linux-2.2.19-pre10/drivers/isdn/avmb1/t1isa.c	Mon Dec  3 21:02:15 2001
+++ linux/drivers/isdn/avmb1/t1isa.c	Mon Dec  3 21:02:59 2001
@@ -1,11 +1,29 @@
 /*
- * $Id: t1isa.c,v 1.11 2000/04/03 13:29:25 calle Exp $
+ * $Id: t1isa.c,v 1.16 2000/11/23 20:45:14 kai Exp $
  * 
  * Module for AVM T1 HEMA-card.
  * 
  * (c) Copyright 1999 by Carsten Paeth (calle@calle.in-berlin.de)
  * 
  * $Log: t1isa.c,v $
+ * Revision 1.16  2000/11/23 20:45:14  kai
+ * fixed module_init/exit stuff
+ * Note: compiled-in kernel doesn't work pre 2.2.18 anymore.
+ *
+ * Revision 1.15  2000/11/01 14:05:02  calle
+ * - use module_init/module_exit from linux/init.h.
+ * - all static struct variables are initialized with "membername:" now.
+ * - avm_cs.c, let it work with newer pcmcia-cs.
+ *
+ * Revision 1.14  2000/10/10 17:44:19  kai
+ * changes from/for 2.2.18
+ *
+ * Revision 1.13  2000/08/04 15:36:31  calle
+ * copied wrong from file to file :-(
+ *
+ * Revision 1.12  2000/08/04 12:20:08  calle
+ * - Fix unsigned/signed warning in the right way ...
+ *
  * Revision 1.11  2000/04/03 13:29:25  calle
  * make Tim Waugh happy (module unload races in 2.3.99-pre3).
  * no real problem there, but now it is much cleaner ...
@@ -79,6 +97,7 @@
 #include <linux/interrupt.h>
 #include <linux/ioport.h>
 #include <linux/capi.h>
+#include <linux/init.h>
 #include <asm/io.h>
 #include "capicmd.h"
 #include "capiutil.h"
@@ -598,12 +617,7 @@
     add_card: t1isa_add_card,
 };
 
-#ifdef MODULE
-#define t1isa_init init_module
-void cleanup_module(void);
-#endif
-
-int t1isa_init(void)
+static int __init t1isa_init(void)
 {
 	struct capi_driver *driver = &t1isa_driver;
 	char *p;
@@ -631,9 +645,10 @@
 	return retval;
 }
 
-#ifdef MODULE
-void cleanup_module(void)
+static void  t1isa_exit(void)
 {
     detach_capi_driver(&t1isa_driver);
 }
-#endif
+
+module_init(t1isa_init);
+module_exit(t1isa_exit);
diff -urN linux-2.2.19-pre10/drivers/isdn/avmb1/t1pci.c linux/drivers/isdn/avmb1/t1pci.c
--- linux-2.2.19-pre10/drivers/isdn/avmb1/t1pci.c	Mon Dec  3 21:02:15 2001
+++ linux/drivers/isdn/avmb1/t1pci.c	Mon Dec  3 21:02:59 2001
@@ -1,11 +1,37 @@
 /*
- * $Id: t1pci.c,v 1.9 2000/05/19 15:43:22 calle Exp $
+ * $Id: t1pci.c,v 1.13.6.1 2000/11/28 12:02:45 kai Exp $
  * 
  * Module for AVM T1 PCI-card.
  * 
  * (c) Copyright 1999 by Carsten Paeth (calle@calle.in-berlin.de)
  * 
  * $Log: t1pci.c,v $
+ * Revision 1.13.6.1  2000/11/28 12:02:45  kai
+ * MODULE_DEVICE_TABLE for 2.4
+ *
+ * Revision 1.13.2.2  2000/11/26 17:47:53  kai
+ * added PCI_DEV_TABLE for 2.4
+ *
+ * Revision 1.13.2.1  2000/11/26 17:14:19  kai
+ * fix device ids
+ * also needs patches to include/linux/pci_ids.h
+ *
+ * Revision 1.13  2000/11/23 20:45:14  kai
+ * fixed module_init/exit stuff
+ * Note: compiled-in kernel doesn't work pre 2.2.18 anymore.
+ *
+ * Revision 1.12  2000/11/01 14:05:02  calle
+ * - use module_init/module_exit from linux/init.h.
+ * - all static struct variables are initialized with "membername:" now.
+ * - avm_cs.c, let it work with newer pcmcia-cs.
+ *
+ * Revision 1.11  2000/08/08 09:24:19  calle
+ * calls to pci_enable_device surounded by #ifndef COMPAT_HAS_2_2_PCI
+ *
+ * Revision 1.10  2000/07/20 10:21:21  calle
+ * Bugfix: driver will not be unregistered, if not cards were detected.
+ *         this result in an oops in kcapi.c
+ *
  * Revision 1.9  2000/05/19 15:43:22  calle
  * added calls to pci_device_start().
  *
@@ -54,9 +80,10 @@
 #include <linux/interrupt.h>
 #include <linux/ioport.h>
 #include <linux/pci.h>
+#include <linux/isdn_compat.h>
 #include <linux/capi.h>
+#include <linux/init.h>
 #include <asm/io.h>
-#include <linux/isdn.h>
 #include "capicmd.h"
 #include "capiutil.h"
 #include "capilli.h"
@@ -259,14 +286,9 @@
     add_card: 0, /* no add_card function */
 };
 
-#ifdef MODULE
-#define t1pci_init init_module
-void cleanup_module(void);
-#endif
-
 static int ncards = 0;
 
-int t1pci_init(void)
+static int __init t1pci_init(void)
 {
 	struct capi_driver *driver = &t1pci_driver;
 	struct pci_dev *dev = NULL;
@@ -312,9 +334,6 @@
 		        printk(KERN_ERR
 			"%s: failed to enable AVM-T1-PCI at i/o %#x, irq %d, mem %#x err=%d\n",
 			driver->name, param.port, param.irq, param.membase, retval);
-#ifdef MODULE
-			cleanup_module();
-#endif
 			MOD_DEC_USE_COUNT;
 			return -EIO;
 		}
@@ -327,9 +346,6 @@
 		        printk(KERN_ERR
 			"%s: no AVM-T1-PCI at i/o %#x, irq %d detected, mem %#x\n",
 			driver->name, param.port, param.irq, param.membase);
-#ifdef MODULE
-			cleanup_module();
-#endif
 			MOD_DEC_USE_COUNT;
 			return retval;
 		}
@@ -351,9 +367,10 @@
 #endif
 }
 
-#ifdef MODULE
-void cleanup_module(void)
+static void  t1pci_exit(void)
 {
     detach_capi_driver(&t1pci_driver);
 }
-#endif
+
+module_init(t1pci_init);
+module_exit(t1pci_exit);
diff -urN linux-2.2.19-pre10/drivers/isdn/divert/Makefile linux/drivers/isdn/divert/Makefile
--- linux-2.2.19-pre10/drivers/isdn/divert/Makefile	Mon Aug  9 12:04:39 1999
+++ linux/drivers/isdn/divert/Makefile	Mon Dec  3 21:02:59 2001
@@ -1,18 +1,26 @@
-L_OBJS :=
-LX_OBJS :=
-M_OBJS :=
-MX_OBJS :=
-O_OBJS :=
-OX_OBJS :=
-L_TARGET :=
-O_TARGET :=
-
-O_OBJS += isdn_divert.o divert_procfs.o
-O_TARGET := dss1_divert.o
-M_OBJS += dss1_divert.o
-OX_OBJS += divert_init.o
+#
+# Makefile for the dss1_divert ISDN module
+#
 
-include $(TOPDIR)/Rules.make
+# The target object and module list name.
+
+O_TARGET	:= vmlinux-obj.o
+
+# Multipart objects.
+
+list-multi		:= dss1_divert.o
+dss1_divert-objs	:= isdn_divert.o divert_procfs.o divert_init.o
+
+# Each configuration option enables a list of files.
+
+obj-$(CONFIG_ISDN_DIVERSION)	+= dss1_divert.o
+
+include $(TOPDIR)/drivers/isdn/Rules.make
+
+# Link rules for multi-part drivers.
+
+dss1_divert.o: $(dss1_divert-objs)
+	$(LD) -r -o $@ $(dss1_divert-objs)
 
 
 
diff -urN linux-2.2.19-pre10/drivers/isdn/divert/divert_init.c linux/drivers/isdn/divert/divert_init.c
--- linux-2.2.19-pre10/drivers/isdn/divert/divert_init.c	Mon Dec  3 21:02:15 2001
+++ linux/drivers/isdn/divert/divert_init.c	Mon Dec  3 21:02:59 2001
@@ -1,5 +1,5 @@
 /* 
- * $Id: divert_init.c,v 1.5.6.1 2000/12/17 16:47:16 kai Exp $
+ * $Id: divert_init.c,v 1.5.6.2 2001/01/24 22:18:17 kai Exp $
  *
  * Module init for DSS1 diversion services for i4l.
  *
@@ -23,6 +23,7 @@
 
 #include <linux/module.h>
 #include <linux/version.h>
+#include <linux/init.h>
 #include "isdn_divert.h"
 
 /********************/
@@ -46,7 +47,7 @@
 /* Module interface code */
 /* no cmd line parms     */
 /*************************/
-int init_module(void)
+static int __init divert_init(void)
 { int i;
 
   if (divert_dev_init())
@@ -63,12 +64,12 @@
 #endif
   printk(KERN_INFO "dss1_divert module successfully installed\n");
   return(0);
-} /* init_module */
+}
 
 /**********************/
 /* Module deinit code */
 /**********************/
-void cleanup_module(void)
+static void  divert_exit(void)
 { int flags;
   int i;
 
@@ -89,6 +90,8 @@
   deleterule(-1); /* delete all rules and free mem */
   deleteprocs();
   printk(KERN_INFO "dss1_divert module successfully removed \n");
-} /* cleanup_module */
+}
 
+module_init(divert_init);
+module_exit(divert_exit);
 
diff -urN linux-2.2.19-pre10/drivers/isdn/divert/divert_procfs.c linux/drivers/isdn/divert/divert_procfs.c
--- linux-2.2.19-pre10/drivers/isdn/divert/divert_procfs.c	Mon Dec  3 21:02:15 2001
+++ linux/drivers/isdn/divert/divert_procfs.c	Mon Dec  3 21:02:59 2001
@@ -32,6 +32,7 @@
 #include <linux/fs.h>
 #endif
 #include <linux/isdnif.h>
+#include <linux/isdn_compat.h>
 #include "isdn_divert.h"
 
 /*********************************/
diff -urN linux-2.2.19-pre10/drivers/isdn/eicon/Makefile linux/drivers/isdn/eicon/Makefile
--- linux-2.2.19-pre10/drivers/isdn/eicon/Makefile	Mon Aug  9 12:04:39 1999
+++ linux/drivers/isdn/eicon/Makefile	Mon Dec  3 21:02:59 2001
@@ -1,13 +1,25 @@
-L_OBJS :=
-M_OBJS :=
-O_OBJS := eicon_mod.o eicon_isa.o eicon_pci.o eicon_idi.o eicon_io.o
-
-O_TARGET :=
-ifeq ($(CONFIG_ISDN_DRV_EICON),y)
-  O_TARGET += eicon.o
-else
-  O_TARGET += eicon.o
-  M_OBJS   = eicon.o
-endif
+# Makefile for the eicon ISDN device driver
+
+# The target object and module list name.
+
+O_TARGET	:= vmlinux-obj.o
+
+# Objects that export symbols.
+
+export-objs	:= eicon_mod.o
+
+# Multipart objects.
+
+list-multi	:= eicon.o
+eicon-objs	:= eicon_mod.o eicon_isa.o eicon_pci.o eicon_idi.o eicon_io.o
+
+# Each configuration option enables a list of files.
+
+obj-$(CONFIG_ISDN_DRV_EICON)    	+= eicon.o
 
 include $(TOPDIR)/Rules.make
+
+# Link rules for multi-part drivers.
+
+eicon.o: $(eicon-objs)
+	$(LD) -r -o $@ $(eicon-objs)
diff -urN linux-2.2.19-pre10/drivers/isdn/hisax/Makefile linux/drivers/isdn/hisax/Makefile
--- linux-2.2.19-pre10/drivers/isdn/hisax/Makefile	Mon Dec  3 21:02:15 2001
+++ linux/drivers/isdn/hisax/Makefile	Mon Dec  3 21:02:59 2001
@@ -1,225 +1,70 @@
-L_OBJS :=
-M_OBJS :=
-LX_OBJS :=
-MX_OBJS :=
-O_OBJS :=
-OX_OBJS :=
-L_TARGET :=
-O_TARGET :=
-
-O_OBJS := isdnl1.o tei.o isdnl2.o isdnl3.o \
-          lmgr.o q931.o callc.o fsm.o cert.o
-
-# EXTRA_CFLAGS += -S
-
-ifeq ($(CONFIG_HISAX_EURO),y)
-	 O_OBJS += l3dss1.o
-endif
-
-ifeq ($(CONFIG_HISAX_NI1),y)
-       O_OBJS += l3ni1.o
-endif
-
-ifeq ($(CONFIG_HISAX_1TR6),y)
-	 O_OBJS += l3_1tr6.o
-endif
-
-ISAC_OBJ :=
-HSCX_OBJ :=
-ISAR_OBJ :=
-HFC_OBJ :=
-HFC_2BDS0 :=
-JADE_OBJ :=
-W6692_OBJ :=
-NETJ_OBJ :=
-ICC_OBJ :=
-
-ifeq ($(CONFIG_HISAX_16_0),y)
-	 O_OBJS += teles0.o
-	 ISAC_OBJ := isac.o
-	 HSCX_OBJ := hscx.o
-endif
-
-ifeq ($(CONFIG_HISAX_16_3),y)
-	 O_OBJS += teles3.o
-	 ISAC_OBJ := isac.o
-	 HSCX_OBJ := hscx.o
-endif
-
-ifeq ($(CONFIG_HISAX_TELESPCI),y)
-	 O_OBJS += telespci.o
-	 ISAC_OBJ := isac.o
-	 HSCX_OBJ := hscx.o
-endif
-
-ifeq ($(CONFIG_HISAX_S0BOX),y)
-	 O_OBJS += s0box.o
-	 ISAC_OBJ := isac.o
-	 HSCX_OBJ := hscx.o
-endif
-
-ifeq ($(CONFIG_HISAX_AVM_A1),y)
-	 O_OBJS += avm_a1.o
-	 ISAC_OBJ := isac.o
-	 HSCX_OBJ := hscx.o
-endif
-
-ifeq ($(CONFIG_HISAX_AVM_A1_PCMCIA),y)
-	 O_OBJS += avm_a1p.o
- 	 ISAC_OBJ := isac.o
-	 HSCX_OBJ := hscx.o
-endif
- 
-ifeq ($(CONFIG_HISAX_FRITZPCI),y)
-	 O_OBJS += avm_pci.o
- 	 ISAC_OBJ := isac.o
-endif
-
-
-ifeq ($(CONFIG_HISAX_ELSA),y)
-	 O_OBJS += elsa.o
-	 ISAC_OBJ := isac.o
-	 HSCX_OBJ := hscx.o
-endif
-
-ifeq ($(CONFIG_HISAX_IX1MICROR2),y)
-	 O_OBJS += ix1_micro.o
-	 ISAC_OBJ := isac.o
-	 HSCX_OBJ := hscx.o
-endif
-
-ifeq ($(CONFIG_HISAX_DIEHLDIVA),y)
-	 O_OBJS += diva.o
-	 ISAC_OBJ := isac.o
-	 HSCX_OBJ := hscx.o
-endif
-
-ifeq ($(CONFIG_HISAX_ASUSCOM),y)
-	 O_OBJS += asuscom.o
-	 ISAC_OBJ := isac.o
-	 HSCX_OBJ := hscx.o
-endif
-
-ifeq ($(CONFIG_HISAX_TELEINT),y)
-	 O_OBJS += teleint.o
-	 ISAC_OBJ := isac.o
-	 HFC_OBJ := hfc_2bs0.o
-endif
-
-ifeq ($(CONFIG_HISAX_SEDLBAUER),y)
-	 O_OBJS += sedlbauer.o
-	 ISAC_OBJ := isac.o
-	 HSCX_OBJ := hscx.o
-	 ISAR_OBJ := isar.o
-endif
-
-ifeq ($(CONFIG_HISAX_SPORTSTER),y)
-	 O_OBJS += sportster.o
-	 ISAC_OBJ := isac.o
-	 HSCX_OBJ := hscx.o
-endif
-
-ifeq ($(CONFIG_HISAX_MIC),y)
-	 O_OBJS += mic.o
-	 ISAC_OBJ := isac.o
-	 HSCX_OBJ := hscx.o
-endif
-
-ifeq ($(CONFIG_HISAX_NETJET),y)
-	 O_OBJS += nj_s.o
-	 NETJ_OBJ := netjet.o
-	 ISAC_OBJ := isac.o
-endif
-
-ifeq ($(CONFIG_HISAX_NETJET_U),y)
-	 O_OBJS += nj_u.o
-	 NETJ_OBJ := netjet.o
-	 ICC_OBJ := icc.o
-endif
-
-ifeq ($(CONFIG_HISAX_HFCS),y)
-	 O_OBJS += hfcscard.o
-	 HFC_2BDS0 := hfc_2bds0.o
-endif
-
-ifeq ($(CONFIG_HISAX_HFC_PCI),y)
-	 HFC_2BDS0 += hfc_pci.o
-endif
-
-ifeq ($(CONFIG_HISAX_HFC_SX),y)
-	 HFC_2BDS0 += hfc_sx.o
-endif
-
-ifeq ($(CONFIG_HISAX_NICCY),y)
-	 O_OBJS += niccy.o
-	 ISAC_OBJ := isac.o
-	 HSCX_OBJ := hscx.o
-endif
-
-ifeq ($(CONFIG_HISAX_ISURF),y)
-	 O_OBJS += isurf.o
-	 ISAC_OBJ := isac.o
-	 ISAR_OBJ := isar.o
-endif
-
-ifeq ($(CONFIG_HISAX_HSTSAPHIR),y)
-	 O_OBJS += saphir.o
-	 ISAC_OBJ := isac.o
-	 HSCX_OBJ := hscx.o
-endif
-
-ifeq ($(CONFIG_HISAX_BKM_A4T),y)
-	 O_OBJS += bkm_a4t.o
-	 ISAC_OBJ := isac.o
-	 JADE_OBJ := jade.o
-endif
-ifeq ($(CONFIG_HISAX_SCT_QUADRO),y)
-	 O_OBJS += bkm_a8.o
-	 ISAC_OBJ := isac.o
-	 HSCX_OBJ := hscx.o
-endif
-
-ifeq ($(CONFIG_HISAX_GAZEL),y)
-	 O_OBJS += gazel.o
-	 ISAC_OBJ := isac.o
-	 HSCX_OBJ := hscx.o
-endif
-
-ifeq ($(CONFIG_HISAX_W6692),y)
-	W6692_OBJ := w6692.o
-endif
-
-# ifeq ($(CONFIG_HISAX_TESTEMU),y)
-#	 O_OBJS += testemu.o
-# endif
-
-ifeq ($(ISAC_OBJ), isac.o)
-	ISAC_OBJ += arcofi.o
-endif
-
-O_OBJS += $(ISAC_OBJ) $(HSCX_OBJ) $(ISAR_OBJ) $(JADE_OBJ)
-O_OBJS += $(HFC_OBJ) $(HFC_2BDS0) $(W6692_OBJ) $(NETJ_OBJ) $(ICC_OBJ)
-OX_OBJS += config.o
-
-O_TARGET :=
-
-ifeq ($(CONFIG_ISDN_DRV_HISAX),y)
-  O_TARGET += hisax.o
-else
-  ifeq ($(CONFIG_ISDN_DRV_HISAX),m)
-    O_TARGET += hisax.o
-    M_OBJS += hisax.o
-  endif
-endif
-
-
-include $(TOPDIR)/Rules.make
-
-MD5FILES += isac.c isdnl1.c isdnl2.c isdnl3.c \
-	    tei.c callc.c cert.c l3dss1.c l3_1tr6.c \
-	    elsa.c diva.c sedlbauer.c
+# Makefile for the hisax ISDN device driver
 
-CERT = $(shell md5sum -c md5sums.asc >> /dev/null;echo $$?)
+# The target object and module list name.
 
-cert.o:	$(MD5FILES) md5sums.asc
-	$(CC) $(CFLAGS) $(EXTRA_CFLAGS) -D CERTIFICATION=$(CERT) -c -o cert.o cert.c
+O_TARGET	:= vmlinux-obj.o
+
+# Objects that export symbols.
+
+export-objs	:= config.o
+
+# Multipart objects.
+
+list-multi	:= hisax.o
+hisax-objs	:= config.o isdnl1.o tei.o isdnl2.o isdnl3.o \
+		   lmgr.o q931.o callc.o fsm.o cert.o
+
+# Optional parts of multipart objects.
+
+hisax-objs-$(CONFIG_HISAX_EURO) += l3dss1.o
+hisax-objs-$(CONFIG_HISAX_NI1) += l3ni1.o
+hisax-objs-$(CONFIG_HISAX_1TR6) += l3_1tr6.o
+
+hisax-objs-$(CONFIG_HISAX_16_0) += teles0.o isac.o arcofi.o hscx.o
+hisax-objs-$(CONFIG_HISAX_16_3) += teles3.o isac.o arcofi.o hscx.o
+hisax-objs-$(CONFIG_HISAX_TELESPCI) += telespci.o isac.o arcofi.o hscx.o
+hisax-objs-$(CONFIG_HISAX_S0BOX) += s0box.o isac.o arcofi.o hscx.o
+hisax-objs-$(CONFIG_HISAX_AVM_A1) += avm_a1.o isac.o arcofi.o hscx.o
+hisax-objs-$(CONFIG_HISAX_AVM_A1_PCMCIA) += avm_a1p.o isac.o arcofi.o hscx.o
+hisax-objs-$(CONFIG_HISAX_FRITZPCI) += avm_pci.o isac.o arcofi.o
+hisax-objs-$(CONFIG_HISAX_AVM_A1) += avm_a1.o isac.o arcofi.o hscx.o
+hisax-objs-$(CONFIG_HISAX_ELSA) += elsa.o isac.o arcofi.o hscx.o
+hisax-objs-$(CONFIG_HISAX_IX1MICROR2) += ix1_micro.o isac.o arcofi.o hscx.o
+hisax-objs-$(CONFIG_HISAX_DIEHLDIVA) += diva.o isac.o arcofi.o hscx.o
+hisax-objs-$(CONFIG_HISAX_ASUSCOM) += asuscom.o isac.o arcofi.o hscx.o
+hisax-objs-$(CONFIG_HISAX_TELEINT) += teleint.o isac.o arcofi.o hfc_2bs0.o
+hisax-objs-$(CONFIG_HISAX_SEDLBAUER) += sedlbauer.o isac.o arcofi.o hscx.o isar.o
+hisax-objs-$(CONFIG_HISAX_SPORTSTER) += sportster.o isac.o arcofi.o hscx.o
+hisax-objs-$(CONFIG_HISAX_MIC) += mic.o isac.o arcofi.o hscx.o
+hisax-objs-$(CONFIG_HISAX_NETJET) += nj_s.o netjet.o isac.o arcofi.o
+hisax-objs-$(CONFIG_HISAX_NETJET_U) += nj_u.o netjet.o icc.o
+hisax-objs-$(CONFIG_HISAX_HFCS) += hfcscard.o hfc_2bds0.o
+hisax-objs-$(CONFIG_HISAX_HFC_PCI) += hfc_pci.o
+hisax-objs-$(CONFIG_HISAX_HFC_SX) += hfc_sx.o
+hisax-objs-$(CONFIG_HISAX_NICCY) += niccy.o isac.o arcofi.o hscx.o
+hisax-objs-$(CONFIG_HISAX_ISURF) += isurf.o isac.o arcofi.o isar.o
+hisax-objs-$(CONFIG_HISAX_HSTSAPHIR) += saphir.o isac.o arcofi.o hscx.o
+hisax-objs-$(CONFIG_HISAX_BKM_A4T) += bkm_a4t.o isac.o arcofi.o jade.o
+hisax-objs-$(CONFIG_HISAX_SCT_QUADRO) += bkm_a8.o isac.o arcofi.o hscx.o
+hisax-objs-$(CONFIG_HISAX_GAZEL) += gazel.o isac.o arcofi.o hscx.o
+hisax-objs-$(CONFIG_HISAX_W6692) += w6692.o
+#hisax-objs-$(CONFIG_HISAX_TESTEMU) += testemu.o
+
+hisax-objs += $(sort $(hisax-objs-y))
+
+# Each configuration option enables a list of files.
+
+obj-$(CONFIG_ISDN_DRV_HISAX)	+= hisax.o
+
+MD5FILES 	:= isac.c isdnl1.c isdnl2.c isdnl3.c \
+		   tei.c callc.c cert.c l3dss1.c l3_1tr6.c \
+		   elsa.c diva.c sedlbauer.c
+CERT := $(shell md5sum -c md5sums.asc >> /dev/null;echo $$?)
+CFLAGS_cert.o := -DCERTIFICATION=$(CERT)
+
+include $(TOPDIR)/drivers/isdn/Rules.make
+
+# Link rules for multi-part drivers.
+
+hisax.o: $(hisax-objs)
+	$(LD) -r -o $@ $(hisax-objs)
diff -urN linux-2.2.19-pre10/drivers/isdn/hisax/avm_pci.c linux/drivers/isdn/hisax/avm_pci.c
--- linux-2.2.19-pre10/drivers/isdn/hisax/avm_pci.c	Mon Dec  3 21:02:15 2001
+++ linux/drivers/isdn/hisax/avm_pci.c	Mon Dec  3 21:02:59 2001
@@ -1,4 +1,4 @@
-/* $Id: avm_pci.c,v 1.22.6.2 2000/11/29 16:00:14 kai Exp $
+/* $Id: avm_pci.c,v 1.22.6.3 2001/02/13 10:33:58 kai Exp $
  *
  * avm_pci.c    low level stuff for AVM Fritz!PCI and ISA PnP isdn cards
  *              Thanks to AVM, Berlin for informations
@@ -15,10 +15,11 @@
 #include "isac.h"
 #include "isdnl1.h"
 #include <linux/pci.h>
+#include <linux/isdn_compat.h>
 #include <linux/interrupt.h>
 
 extern const char *CardType[];
-static const char *avm_pci_rev = "$Revision: 1.22.6.2 $";
+static const char *avm_pci_rev = "$Revision: 1.22.6.3 $";
 
 #define  AVM_FRITZ_PCI		1
 #define  AVM_FRITZ_PNP		2
diff -urN linux-2.2.19-pre10/drivers/isdn/hisax/bkm_a4t.c linux/drivers/isdn/hisax/bkm_a4t.c
--- linux-2.2.19-pre10/drivers/isdn/hisax/bkm_a4t.c	Mon Dec  3 21:02:15 2001
+++ linux/drivers/isdn/hisax/bkm_a4t.c	Mon Dec  3 21:02:59 2001
@@ -1,4 +1,4 @@
-/* $Id: bkm_a4t.c,v 1.13.6.2 2000/11/29 16:00:14 kai Exp $
+/* $Id: bkm_a4t.c,v 1.13.6.3 2001/02/13 10:33:58 kai Exp $
  * bkm_a4t.c    low level stuff for T-Berkom A4T
  *              derived from the original file sedlbauer.c
  *              derived from the original file niccy.c
@@ -20,11 +20,12 @@
 #include "jade.h"
 #include "isdnl1.h"
 #include <linux/pci.h>
+#include <linux/isdn_compat.h>
 #include "bkm_ax.h"
 
 extern const char *CardType[];
 
-const char *bkm_a4t_revision = "$Revision: 1.13.6.2 $";
+const char *bkm_a4t_revision = "$Revision: 1.13.6.3 $";
 
 
 static inline u_char
diff -urN linux-2.2.19-pre10/drivers/isdn/hisax/bkm_a8.c linux/drivers/isdn/hisax/bkm_a8.c
--- linux-2.2.19-pre10/drivers/isdn/hisax/bkm_a8.c	Mon Dec  3 21:02:15 2001
+++ linux/drivers/isdn/hisax/bkm_a8.c	Mon Dec  3 21:02:59 2001
@@ -1,4 +1,4 @@
-/* $Id: bkm_a8.c,v 1.14.6.2 2000/11/29 16:00:14 kai Exp $
+/* $Id: bkm_a8.c,v 1.14.6.3 2001/02/13 10:33:58 kai Exp $
  * bkm_a8.c     low level stuff for Scitel Quadro (4*S0, passive)
  *              derived from the original file sedlbauer.c
  *              derived from the original file niccy.c
@@ -19,6 +19,7 @@
 #include "hscx.h"
 #include "isdnl1.h"
 #include <linux/pci.h>
+#include <linux/isdn_compat.h>
 #include "bkm_ax.h"
 
 #if CONFIG_PCI
@@ -27,7 +28,7 @@
 
 extern const char *CardType[];
 
-const char sct_quadro_revision[] = "$Revision: 1.14.6.2 $";
+const char sct_quadro_revision[] = "$Revision: 1.14.6.3 $";
 
 static const char *sct_quadro_subtypes[] =
 {
diff -urN linux-2.2.19-pre10/drivers/isdn/hisax/callc.c linux/drivers/isdn/hisax/callc.c
--- linux-2.2.19-pre10/drivers/isdn/hisax/callc.c	Mon Dec  3 21:02:15 2001
+++ linux/drivers/isdn/hisax/callc.c	Mon Dec  3 21:02:59 2001
@@ -878,6 +878,7 @@
 				releasestack_isdnl2(st);
 				break;
 			case (ISDN_PROTO_L2_HDLC):
+			case (ISDN_PROTO_L2_HDLC_56K):
 			case (ISDN_PROTO_L2_TRANS):
 			case (ISDN_PROTO_L2_MODEM):
 			case (ISDN_PROTO_L2_FAX):
@@ -1271,6 +1272,9 @@
 		case (ISDN_PROTO_L2_HDLC):
 			st->l1.mode = L1_MODE_HDLC;
 			break;
+		case (ISDN_PROTO_L2_HDLC_56K):
+			st->l1.mode = L1_MODE_HDLC_56K;
+			break;
 		case (ISDN_PROTO_L2_TRANS):
 			st->l1.mode = L1_MODE_TRANS;
 			break;
@@ -1307,6 +1311,7 @@
 			st->l2.debug = chanp->debug & 64;
 			break;
 		case (ISDN_PROTO_L2_HDLC):
+		case (ISDN_PROTO_L2_HDLC_56K):
 		case (ISDN_PROTO_L2_TRANS):
 		case (ISDN_PROTO_L2_MODEM):
 		case (ISDN_PROTO_L2_FAX):
diff -urN linux-2.2.19-pre10/drivers/isdn/hisax/config.c linux/drivers/isdn/hisax/config.c
--- linux-2.2.19-pre10/drivers/isdn/hisax/config.c	Mon Dec  3 21:02:15 2001
+++ linux/drivers/isdn/hisax/config.c	Mon Dec  3 21:02:59 2001
@@ -1,5 +1,4 @@
-/* $Id: config.c,v 2.57.6.7 2000/12/17 16:47:17 kai Exp $
- *
+/* $Id: config.c,v 2.57.6.8 2001/01/23 17:45:02 kai Exp $
  * Author       Karsten Keil (keil@isdn4linux.de)
  *              based on the teles driver from Jan den Ouden
  *
@@ -435,11 +434,9 @@
 	MOD_INC_USE_COUNT;
 }
 
-#ifdef MODULE
-#define HiSax_init init_module
-#else
-__initfunc(void
-HiSax_setup(char *str, int *ints))
+#ifndef MODULE
+static void __init
+HiSax_setup(char *str, int *ints)
 {
 	int i, j, argc;
 	argc = ints[0];
@@ -961,6 +958,7 @@
 		cs->iif.features =
 			ISDN_FEATURE_L2_X75I |
 			ISDN_FEATURE_L2_HDLC |
+			ISDN_FEATURE_L2_HDLC_56K |
 			ISDN_FEATURE_L2_TRANS |
 			ISDN_FEATURE_L3_TRANS |
 #ifdef	CONFIG_HISAX_1TR6
@@ -1318,21 +1316,21 @@
 #endif
 }
 
-
-__initfunc(int
-HiSax_init(void))
+static int __init HiSax_init(void)
 {
 	int i,j;
+	int nzproto = 0;
+
+	HiSaxVersion();
+	CallcNew();
+	Isdnl3New();
+	Isdnl2New();
+	TeiNew();
+	Isdnl1New();
 
 #ifdef MODULE
-	int nzproto = 0;
 	if (!type[0]) {
 		/* We 'll register drivers later, but init basic functions*/
-		CallcNew();
-		Isdnl3New();
-		Isdnl2New();
-		TeiNew();
-		Isdnl1New();
 		return 0;
 	}
 #ifdef CONFIG_HISAX_ELSA
@@ -1361,7 +1359,6 @@
 #endif
 #endif
 	nrcards = 0;
-	HiSaxVersion();
 #ifdef MODULE
 	if (id)			/* If id= string used */
 		HiSax_id = id;
@@ -1463,7 +1460,6 @@
 	}
 	if (!nzproto) {
 		printk(KERN_WARNING "HiSax: Warning - no protocol specified\n");
-		printk(KERN_WARNING "HiSax: Note! module load syntax has changed.\n");
 		printk(KERN_WARNING "HiSax: using protocol %s\n", DEFAULT_PROTO_NAME);
 	}
 #endif
@@ -1477,15 +1473,8 @@
 	printk(KERN_DEBUG "HiSax: Total %d card%s defined\n",
 	       nrcards, (nrcards > 1) ? "s" : "");
 
-	CallcNew();
-	Isdnl3New();
-	Isdnl2New();
-	TeiNew();
-	Isdnl1New();
 	if (HiSax_inithardware(NULL)) {
 		/* Install only, if at least one card found */
-#ifdef MODULE
-#endif /* MODULE */
 		return (0);
 	} else {
 		Isdnl1Free();
@@ -1497,9 +1486,7 @@
 	}
 }
 
-#ifdef MODULE
-void
-cleanup_module(void)
+static void  HiSax_exit(void)
 {
 	int cardnr = nrcards -1;
 	long flags;
@@ -1516,17 +1503,14 @@
 	restore_flags(flags);
 	printk(KERN_INFO "HiSax module removed\n");
 }
-#endif
 
 #ifdef CONFIG_HISAX_ELSA
 int elsa_init_pcmcia(void *pcm_iob, int pcm_irq, int *busy_flag, int prot)
 {
 #ifdef MODULE
 	int i;
-	int nzproto = 0;
 
 	nrcards = 0;
-	HiSaxVersion();
 	/* Initialize all structs, even though we only accept
 	   two pcmcia cards
 	   */
@@ -1536,14 +1520,12 @@
 		cards[i].typ = type[i];
 		if (protocol[i]) {
 			cards[i].protocol = protocol[i];
-			nzproto++;
 		}
 	}
 	cards[0].para[0] = pcm_irq;
 	cards[0].para[1] = (int)pcm_iob;
 	cards[0].protocol = prot;
-	cards[0].typ = 10;
-	nzproto = 1;
+	cards[0].typ = ISDN_CTYPE_ELSA_PCMCIA;
 
 	if (!HiSax_id)
 		HiSax_id = HiSaxID;
@@ -1555,11 +1537,6 @@
 	printk(KERN_DEBUG "HiSax: Total %d card%s defined\n",
 	       nrcards, (nrcards > 1) ? "s" : "");
 
-	Isdnl1New();
-	CallcNew();
-	Isdnl3New();
-	Isdnl2New();
-	TeiNew();
 	HiSax_inithardware(busy_flag);
 	printk(KERN_NOTICE "HiSax: module installed\n");
 #endif
@@ -1575,7 +1552,6 @@
 	int nzproto = 0;
 
 	nrcards = 0;
-	HiSaxVersion();
 	/* Initialize all structs, even though we only accept
 	   two pcmcia cards
 	   */
@@ -1604,11 +1580,6 @@
 	printk(KERN_DEBUG "HiSax: Total %d card%s defined\n",
 	       nrcards, (nrcards > 1) ? "s" : "");
 
-	Isdnl1New();
-	CallcNew();
-	Isdnl3New();
-	Isdnl2New();
-	TeiNew();
 	HiSax_inithardware(busy_flag);
 	printk(KERN_NOTICE "HiSax: module installed\n");
 #endif
@@ -1624,7 +1595,6 @@
 	int nzproto = 0;
 
 	nrcards = 0;
-	HiSaxVersion();
 	/* Initialize all structs, even though we only accept
 	   two pcmcia cards
 	   */
@@ -1653,11 +1623,6 @@
 	printk(KERN_DEBUG "HiSax: Total %d card%s defined\n",
 	       nrcards, (nrcards > 1) ? "s" : "");
 
-	CallcNew();
-	Isdnl3New();
-	Isdnl2New();
-	Isdnl1New();
-	TeiNew();
 	HiSax_inithardware(busy_flag);
 	printk(KERN_NOTICE "HiSax: module installed\n");
 #endif
@@ -1673,7 +1638,6 @@
 	int nzproto = 0;
 
 	nrcards = 0;
-	HiSaxVersion();
 	/* Initialize all structs, even though we only accept
 	   two pcmcia cards
 	   */
@@ -1702,11 +1666,6 @@
 	printk(KERN_DEBUG "HiSax: Total %d card%s defined\n",
 	       nrcards, (nrcards > 1) ? "s" : "");
 
-	Isdnl1New();
-	CallcNew();
-	Isdnl3New();
-	Isdnl2New();
-	TeiNew();
 	HiSax_inithardware(busy_flag);
 	printk(KERN_NOTICE "HiSax: module installed\n");
 #endif
@@ -1714,7 +1673,7 @@
 }
 #endif
 
-int hisax_init_pcmcia(void *pcm_iob, int *busy_flag, struct IsdnCard *card)
+int  hisax_init_pcmcia(void *pcm_iob, int *busy_flag, struct IsdnCard *card)
 {
 	u_char ids[16];
 	int ret = -1;
@@ -1731,3 +1690,7 @@
 	nrcards++;
 	return (ret);
 }
+
+
+module_init(HiSax_init);
+module_exit(HiSax_exit);
diff -urN linux-2.2.19-pre10/drivers/isdn/hisax/diva.c linux/drivers/isdn/hisax/diva.c
--- linux-2.2.19-pre10/drivers/isdn/hisax/diva.c	Mon Dec  3 21:02:15 2001
+++ linux/drivers/isdn/hisax/diva.c	Mon Dec  3 21:02:59 2001
@@ -1,4 +1,4 @@
-/* $Id: diva.c,v 1.25.6.2 2000/11/29 16:00:14 kai Exp $
+/* $Id: diva.c,v 1.25.6.3 2001/02/13 10:33:58 kai Exp $
  *
  * diva.c     low level stuff for Eicon.Diehl Diva Family ISDN cards
  *
@@ -21,10 +21,11 @@
 #include "ipac.h"
 #include "isdnl1.h"
 #include <linux/pci.h>
+#include <linux/isdn_compat.h>
 
 extern const char *CardType[];
 
-const char *Diva_revision = "$Revision: 1.25.6.2 $";
+const char *Diva_revision = "$Revision: 1.25.6.3 $";
 
 #define byteout(addr,val) outb(val,addr)
 #define bytein(addr) inb(addr)
diff -urN linux-2.2.19-pre10/drivers/isdn/hisax/elsa.c linux/drivers/isdn/hisax/elsa.c
--- linux-2.2.19-pre10/drivers/isdn/hisax/elsa.c	Mon Dec  3 21:02:15 2001
+++ linux/drivers/isdn/hisax/elsa.c	Mon Dec  3 21:02:59 2001
@@ -1,4 +1,4 @@
-/* $Id: elsa.c,v 2.26.6.1 2000/11/28 12:02:46 kai Exp $
+/* $Id: elsa.c,v 2.26.6.2 2001/02/13 10:33:58 kai Exp $
  *
  * elsa.c     low level stuff for Elsa isdn cards
  *
@@ -25,12 +25,13 @@
 #include "hscx.h"
 #include "isdnl1.h"
 #include <linux/pci.h>
+#include <linux/isdn_compat.h>
 #include <linux/serial.h>
 #include <linux/serial_reg.h>
 
 extern const char *CardType[];
 
-const char *Elsa_revision = "$Revision: 2.26.6.1 $";
+const char *Elsa_revision = "$Revision: 2.26.6.2 $";
 const char *Elsa_Types[] =
 {"None", "PC", "PCC-8", "PCC-16", "PCF", "PCF-Pro",
  "PCMCIA", "QS 1000", "QS 3000", "Microlink PCI", "QS 3000 PCI", 
diff -urN linux-2.2.19-pre10/drivers/isdn/hisax/gazel.c linux/drivers/isdn/hisax/gazel.c
--- linux-2.2.19-pre10/drivers/isdn/hisax/gazel.c	Mon Dec  3 21:02:15 2001
+++ linux/drivers/isdn/hisax/gazel.c	Mon Dec  3 21:02:59 2001
@@ -1,4 +1,4 @@
-/* $Id: gazel.c,v 2.11.6.2 2000/11/29 16:00:14 kai Exp $
+/* $Id: gazel.c,v 2.11.6.3 2001/02/13 10:33:58 kai Exp $
  *
  * gazel.c     low level stuff for Gazel isdn cards
  *
@@ -17,9 +17,10 @@
 #include "isdnl1.h"
 #include "ipac.h"
 #include <linux/pci.h>
+#include <linux/isdn_compat.h>
 
 extern const char *CardType[];
-const char *gazel_revision = "$Revision: 2.11.6.2 $";
+const char *gazel_revision = "$Revision: 2.11.6.3 $";
 
 #define R647      1
 #define R685      2
diff -urN linux-2.2.19-pre10/drivers/isdn/hisax/hfc_pci.c linux/drivers/isdn/hisax/hfc_pci.c
--- linux-2.2.19-pre10/drivers/isdn/hisax/hfc_pci.c	Mon Dec  3 21:02:15 2001
+++ linux/drivers/isdn/hisax/hfc_pci.c	Mon Dec  3 21:02:59 2001
@@ -1,4 +1,4 @@
-/* $Id: hfc_pci.c,v 1.34.6.3 2000/12/10 23:39:19 kai Exp $
+/* $Id: hfc_pci.c,v 1.34.6.4 2001/02/13 10:33:58 kai Exp $
 
  * hfc_pci.c     low level driver for CCD´s hfc-pci based cards
  *
@@ -31,11 +31,12 @@
 #include "hfc_pci.h"
 #include "isdnl1.h"
 #include <linux/pci.h>
+#include <linux/isdn_compat.h>
 #include <linux/interrupt.h>
 
 extern const char *CardType[];
 
-static const char *hfcpci_revision = "$Revision: 1.34.6.3 $";
+static const char *hfcpci_revision = "$Revision: 1.34.6.4 $";
 
 /* table entry in the PCI devices list */
 typedef struct {
@@ -1636,7 +1637,6 @@
 int __init setup_hfcpci(struct IsdnCard *card)
 {
 	struct IsdnCardState *cs = card->cs;
-	unsigned short cmd;
 	char tmp[64];
 	int i;
 	struct pci_dev *tmp_hfcpci = NULL;
@@ -1646,15 +1646,11 @@
 #endif
 	strcpy(tmp, hfcpci_revision);
 	printk(KERN_INFO "HiSax: HFC-PCI driver Rev. %s\n", HiSax_getrev(tmp));
-#if CONFIG_PCI
+#ifdef CONFIG_PCI
 	cs->hw.hfcpci.int_s1 = 0;
 	cs->dc.hfcpci.ph_state = 0;
 	cs->hw.hfcpci.fifo = 255;
 	if (cs->typ == ISDN_CTYPE_HFC_PCI) {
-		if (!pci_present()) {
-			printk(KERN_ERR "HFC-PCI: no PCI bus present\n");
-			return (0);
-		}
 		i = 0;
 		while (id_list[i].vendor_id) {
 			tmp_hfcpci = pci_find_device(id_list[i].vendor_id,
@@ -1686,39 +1682,6 @@
 		} else {
 			printk(KERN_WARNING "HFC-PCI: No PCI card found\n");
 			return (0);
-		}
-		if (((int) cs->hw.hfcpci.pci_io & (PAGE_SIZE - 1))) {
-			printk(KERN_WARNING "HFC-PCI shared mem address will be corrected\n");
-			pcibios_write_config_word(cs->hw.hfcpci.pci_bus,
-					     cs->hw.hfcpci.pci_device_fn,
-						  PCI_COMMAND,
-						  0x0103);	/* set SERR */
-			pcibios_read_config_word(cs->hw.hfcpci.pci_bus,
-					     cs->hw.hfcpci.pci_device_fn,
-						 PCI_COMMAND,
-						 &cmd);
-			pcibios_write_config_word(cs->hw.hfcpci.pci_bus,
-					     cs->hw.hfcpci.pci_device_fn,
-						  PCI_COMMAND,
-						  cmd & ~2);
-			(int) cs->hw.hfcpci.pci_io &= ~(PAGE_SIZE - 1);
-			pcibios_write_config_dword(cs->hw.hfcpci.pci_bus,
-					     cs->hw.hfcpci.pci_device_fn,
-						   PCI_BASE_ADDRESS_1,
-					     (int) cs->hw.hfcpci.pci_io);
-			pcibios_write_config_word(cs->hw.hfcpci.pci_bus,
-					     cs->hw.hfcpci.pci_device_fn,
-						  PCI_COMMAND,
-						  cmd);
-			pcibios_read_config_dword(cs->hw.hfcpci.pci_bus,
-					     cs->hw.hfcpci.pci_device_fn,
-						  PCI_BASE_ADDRESS_1,
-					 (void *) &cs->hw.hfcpci.pci_io);
-			if (((int) cs->hw.hfcpci.pci_io & (PAGE_SIZE - 1))) {
-				printk(KERN_WARNING "HFC-PCI unable to align address %x\n", (unsigned) cs->hw.hfcpci.pci_io);
-				return (0);
-			}
-			dev_hfcpci->base_address[1] = (int) cs->hw.hfcpci.pci_io;
 		}
 		if (!cs->hw.hfcpci.pci_io) {
 			printk(KERN_WARNING "HFC-PCI: No IO-Mem for PCI card found\n");
diff -urN linux-2.2.19-pre10/drivers/isdn/hisax/hisax.h linux/drivers/isdn/hisax/hisax.h
--- linux-2.2.19-pre10/drivers/isdn/hisax/hisax.h	Mon Dec  3 21:02:16 2001
+++ linux/drivers/isdn/hisax/hisax.h	Mon Dec  3 21:02:59 2001
@@ -1,4 +1,4 @@
-/* $Id: hisax.h,v 2.52.6.1 2000/12/06 16:59:19 kai Exp $
+/* $Id: hisax.h,v 2.52.6.2 2001/02/10 14:41:22 kai Exp $
  *
  *   Basic declarations, defines and prototypes
  *
@@ -16,7 +16,7 @@
 #include <linux/delay.h>
 #include <linux/kernel.h>
 #include <linux/signal.h>
-#include <linux/malloc.h>
+#include <linux/slab.h>
 #include <linux/mm.h>
 #include <linux/mman.h>
 #include <linux/ioport.h>
@@ -475,6 +475,7 @@
 #define L1_MODE_TRANS	1
 #define L1_MODE_HDLC	2
 #define L1_MODE_EXTRN	3
+#define L1_MODE_HDLC_56K 4
 #define L1_MODE_MODEM	7
 #define L1_MODE_V32	8
 #define L1_MODE_FAX	9
@@ -1348,17 +1349,3 @@
 void TeiNew(void);
 void TeiFree(void);
 int certification_check(int output);
-#ifdef __powerpc__
-#include <linux/pci.h>
-static inline int pci_enable_device(struct pci_dev *dev)
-{
-	u16 cmd;
-	pci_read_config_word(dev, PCI_COMMAND, &cmd);
-	cmd |= PCI_COMMAND_MEMORY | PCI_COMMAND_IO | PCI_COMMAND_SERR;
-	cmd &= ~PCI_COMMAND_FAST_BACK;
-	pci_write_config_word(dev, PCI_COMMAND, cmd);
-	return(0);
-}
-#else
-#define pci_enable_device(dev)	!dev
-#endif /* __powerpc__ */
diff -urN linux-2.2.19-pre10/drivers/isdn/hisax/isdnl3.c linux/drivers/isdn/hisax/isdnl3.c
--- linux-2.2.19-pre10/drivers/isdn/hisax/isdnl3.c	Mon Dec  3 21:02:16 2001
+++ linux/drivers/isdn/hisax/isdnl3.c	Mon Dec  3 21:02:59 2001
@@ -1,4 +1,4 @@
-/* $Id: isdnl3.c,v 2.17 2000/11/24 17:05:38 kai Exp $
+/* $Id: isdnl3.c,v 2.17.6.1 2001/01/08 17:09:20 kai Exp $
  *
  * Author       Karsten Keil (keil@isdn4linux.de)
  *              based on the teles driver from Jan den Ouden
@@ -303,7 +303,10 @@
 				if (!skb_queue_len(&p->st->l3.squeue)) {
 					if (p->debug)
 						l3_debug(p->st, "release_l3_process: release link");
-					FsmEvent(&p->st->l3.l3m, EV_RELEASE_REQ, NULL);
+					if (p->st->protocol != ISDN_PTYPE_NI1)
+						FsmEvent(&p->st->l3.l3m, EV_RELEASE_REQ, NULL);
+					else
+						FsmEvent(&p->st->l3.l3m, EV_RELEASE_IND, NULL);
 				} else {
 					if (p->debug)
 						l3_debug(p->st, "release_l3_process: not release link");
@@ -483,6 +486,18 @@
 }
 
 static void
+lc_start_delay_check(struct FsmInst *fi, int event, void *arg)
+/* 20/09/00 - GE timer not user for NI-1 as layer 2 should stay up */
+{
+       struct PStack *st = fi->userdata;
+
+       FsmChangeState(fi, ST_L3_LC_REL_DELAY);
+       /* 19/09/00 - GE timer not user for NI-1 */
+       if (st->protocol != ISDN_PTYPE_NI1) 
+       		FsmAddTimer(&st->l3.l3m_timer, DREL_TIMER_VALUE, EV_TIMEOUT, NULL, 50);
+}
+
+static void
 lc_release_req(struct FsmInst *fi, int event, void *arg)
 {
 	struct PStack *st = fi->userdata;
@@ -530,7 +545,7 @@
 	{ST_L3_LC_ESTAB_WAIT,	EV_RELEASE_REQ,		lc_start_delay},
 	{ST_L3_LC_ESTAB_WAIT,	EV_RELEASE_IND,		lc_release_ind},
 	{ST_L3_LC_ESTAB,	EV_RELEASE_IND,		lc_release_ind},
-	{ST_L3_LC_ESTAB,	EV_RELEASE_REQ,		lc_start_delay},
+	{ST_L3_LC_ESTAB,	EV_RELEASE_REQ,		lc_start_delay_check},
         {ST_L3_LC_REL_DELAY,    EV_RELEASE_IND,         lc_release_ind},
         {ST_L3_LC_REL_DELAY,    EV_ESTABLISH_REQ,       lc_connected},
         {ST_L3_LC_REL_DELAY,    EV_TIMEOUT,             lc_release_req},
@@ -551,7 +566,7 @@
 			} else {
 				struct sk_buff *skb = arg;
 
-				skb_queue_head(&st->l3.squeue, skb);
+				skb_queue_tail(&st->l3.squeue, skb);
 				FsmEvent(&st->l3.l3m, EV_ESTABLISH_REQ, NULL); 
 			}
 			break;
diff -urN linux-2.2.19-pre10/drivers/isdn/hisax/l3ni1.c linux/drivers/isdn/hisax/l3ni1.c
--- linux-2.2.19-pre10/drivers/isdn/hisax/l3ni1.c	Mon Dec  3 21:02:16 2001
+++ linux/drivers/isdn/hisax/l3ni1.c	Mon Dec  3 21:02:59 2001
@@ -10,8 +10,8 @@
 //
 // 2000.6.6 Initial implementation of routines for US NI1 
 // Layer 3 protocol based on the EURO/DSS1 D-channel protocol 
-// driver written by Karsten Keil et al.
-// NI-1 Hall of Fame - Thanks to....
+// driver written by Karsten Keil et al.  
+// NI-1 Hall of Fame - Thanks to.... 
 // Ragnar Paulson - for some handy code fragments
 // Will Scales - beta tester extraordinaire
 // Brett Whittacre - beta tester and remote devel system in Vegas
@@ -447,6 +447,27 @@
 }
 
 static void
+l3ni1_message_plus_chid(struct l3_process *pc, u_char mt)
+/* sends an l3 messages plus channel id -  added GE 05/09/00 */
+{
+	struct sk_buff *skb;
+	u_char tmp[16];
+	u_char *p = tmp;
+	u_char chid;
+
+	chid = (u_char)(pc->para.bchannel & 0x03) | 0x88;
+	MsgHead(p, pc->callref, mt);
+	*p++ = IE_CHANNEL_ID;
+	*p++ = 0x01;
+	*p++ = chid;
+
+	if (!(skb = l3_alloc_skb(7)))
+		return;
+	memcpy(skb_put(skb, 7), tmp, 7);
+	l3_msg(pc->st, DL_DATA | REQUEST, skb);
+}
+
+static void
 l3ni1_message_cause(struct l3_process *pc, u_char mt, u_char cause)
 {
 	struct sk_buff *skb;
@@ -1179,9 +1200,9 @@
 	case 1:	                  /* Telephony                                */
 		*p++ = IE_BEARER;
 		*p++ = 0x3;	  /* Length                                   */
-		*p++ = 0x90;	  /* Coding Std. CCITT, 3.1 kHz audio         */
+		*p++ = 0x90;	  /* 3.1khz Audio      			      */
 		*p++ = 0x90;	  /* Circuit-Mode 64kbps                      */
-		*p++ = 0xa3;	  /* A-Law Audio                              */
+		*p++ = 0xa2;	  /* u-Law Audio                              */
 		break;
 	case 5:	                  /* Datatransmission 64k, BTX                */
 	case 7:	                  /* Datatransmission 64k                     */
@@ -1244,7 +1265,7 @@
 			*p++ = 0x3;	/* Length                                   */
 			*p++ = 0x90;	/* Coding Std. CCITT, 3.1 kHz audio         */
 			*p++ = 0x90;	/* Circuit-Mode 64kbps                      */
-			*p++ = 0xa3;	/* A-Law Audio                              */
+			*p++ = 0xa2;	/* u-Law Audio                              */
 			break;
 		case 5:	                /* Datatransmission 64k, BTX                */
 		case 7:	                /* Datatransmission 64k                     */
@@ -1645,7 +1666,9 @@
            return;
          }
 	newl3state(pc, 8);
-	l3ni1_message(pc, MT_CONNECT);
+	if (pc->debug & L3_DEB_WARN)
+		l3_debug(pc->st, "D-chan connect for waiting call");
+	l3ni1_message_plus_chid(pc, MT_CONNECT); /* GE 05/09/00 */ 
 	L3DelTimer(&pc->timer);
 	L3AddTimer(&pc->timer, T313, CC_T313);
 }
@@ -2548,6 +2571,7 @@
 			up->st->lli.l4l3(up->st, CC_RESTART | REQUEST, up);
 		else if (up->para.bchannel == chan)
 			up->st->lli.l4l3(up->st, CC_RESTART | REQUEST, up);
+		
 		up = up->next;
 	}
 	p = tmp;
diff -urN linux-2.2.19-pre10/drivers/isdn/hisax/netjet.c linux/drivers/isdn/hisax/netjet.c
--- linux-2.2.19-pre10/drivers/isdn/hisax/netjet.c	Mon Dec  3 21:02:16 2001
+++ linux/drivers/isdn/hisax/netjet.c	Mon Dec  3 21:02:59 2001
@@ -1,4 +1,4 @@
-/* $Id: netjet.c,v 1.24.6.2 2000/12/17 22:45:11 kai Exp $
+/* $Id: netjet.c,v 1.24.6.3 2001/02/13 10:33:58 kai Exp $
  *
  * netjet.c     low level stuff for Traverse Technologie NETJet ISDN cards
  *
@@ -16,13 +16,12 @@
 #include "isac.h"
 #include "hscx.h"
 #include "isdnl1.h"
-#include <linux/pci.h>
 #include <linux/interrupt.h>
 #include <linux/ppp_defs.h>
 #include <asm/io.h>
 #include "netjet.h"
 
-const char *NETjet_revision = "$Revision: 1.24.6.2 $";
+const char *NETjet_revision = "$Revision: 1.24.6.3 $";
 
 /* Interface functions */
 
@@ -155,7 +154,8 @@
 			break;
 		case (L1_MODE_TRANS):
 			break;
-		case (L1_MODE_HDLC): 
+		case (L1_MODE_HDLC_56K):
+		case (L1_MODE_HDLC):
 			fill_mem(bcs, bcs->hw.tiger.send,
 				NETJET_DMA_TXSIZE, bc, 0xff);
 			bcs->hw.tiger.r_state = HDLC_ZERO_SEARCH;
@@ -170,7 +170,8 @@
 				cs->hw.njet.dmactrl = 1;
 				byteout(cs->hw.njet.base + NETJET_DMACTRL,
 					cs->hw.njet.dmactrl);
-				byteout(cs->hw.njet.base + NETJET_IRQMASK0, 0x3f);
+				byteout(cs->hw.njet.base + NETJET_IRQMASK0, 0x0f);
+			/* was 0x3f now 0x0f for TJ300 and TJ320  GE 13/07/00 */
 			}
 			bcs->hw.tiger.sendp = bcs->hw.tiger.send;
 			bcs->hw.tiger.free = NETJET_DMA_TXSIZE;
@@ -208,6 +209,8 @@
 	}
 }
 
+// macro for 64k
+
 #define MAKE_RAW_BYTE for (j=0; j<8; j++) { \
 			bitcnt++;\
 			s_val >>= 1;\
@@ -236,6 +239,7 @@
 		}
 
 static int make_raw_data(struct BCState *bcs) {
+// this make_raw is for 64k
 	register u_int i,s_cnt=0;
 	register u_char j;
 	register u_char val;
@@ -291,6 +295,113 @@
 	return(0);
 }
 
+// macro for 56k
+
+#define MAKE_RAW_BYTE_56K for (j=0; j<8; j++) { \
+			bitcnt++;\
+			s_val >>= 1;\
+			if (val & 1) {\
+				s_one++;\
+				s_val |= 0x80;\
+			} else {\
+				s_one = 0;\
+				s_val &= 0x7f;\
+			}\
+			if (bitcnt==7) {\
+				s_val >>= 1;\
+				s_val |= 0x80;\
+				bcs->hw.tiger.sendbuf[s_cnt++] = s_val;\
+				bitcnt = 0;\
+			}\
+			if (s_one == 5) {\
+				s_val >>= 1;\
+				s_val &= 0x7f;\
+				bitcnt++;\
+				s_one = 0;\
+			}\
+			if (bitcnt==7) {\
+				s_val >>= 1;\
+				s_val |= 0x80;\
+				bcs->hw.tiger.sendbuf[s_cnt++] = s_val;\
+				bitcnt = 0;\
+			}\
+			val >>= 1;\
+		}
+
+static int make_raw_data_56k(struct BCState *bcs) {
+// this make_raw is for 56k
+	register u_int i,s_cnt=0;
+	register u_char j;
+	register u_char val;
+	register u_char s_one = 0;
+	register u_char s_val = 0;
+	register u_char bitcnt = 0;
+	u_int fcs;
+	
+	if (!bcs->tx_skb) {
+		debugl1(bcs->cs, "tiger make_raw_56k: NULL skb");
+		return(1);
+	}
+	val = HDLC_FLAG_VALUE;
+	for (j=0; j<8; j++) { 
+		bitcnt++;
+		s_val >>= 1;
+		if (val & 1)
+			s_val |= 0x80;
+		else
+			s_val &= 0x7f;
+		if (bitcnt==7) {
+			s_val >>= 1;
+			s_val |= 0x80;
+			bcs->hw.tiger.sendbuf[s_cnt++] = s_val;
+			bitcnt = 0;
+		}
+		val >>= 1;
+	};
+	fcs = PPP_INITFCS;
+	for (i=0; i<bcs->tx_skb->len; i++) {
+		val = bcs->tx_skb->data[i];
+		fcs = PPP_FCS (fcs, val);
+		MAKE_RAW_BYTE_56K;
+	}
+	fcs ^= 0xffff;
+	val = fcs & 0xff;
+	MAKE_RAW_BYTE_56K;
+	val = (fcs>>8) & 0xff;
+	MAKE_RAW_BYTE_56K;
+	val = HDLC_FLAG_VALUE;
+	for (j=0; j<8; j++) { 
+		bitcnt++;
+		s_val >>= 1;
+		if (val & 1)
+			s_val |= 0x80;
+		else
+			s_val &= 0x7f;
+		if (bitcnt==7) {
+			s_val >>= 1;
+			s_val |= 0x80;
+			bcs->hw.tiger.sendbuf[s_cnt++] = s_val;
+			bitcnt = 0;
+		}
+		val >>= 1;
+	}
+	if (bcs->cs->debug & L1_DEB_HSCX)
+		debugl1(bcs->cs,"tiger make_raw_56k: in %ld out %d.%d",
+			bcs->tx_skb->len, s_cnt, bitcnt);
+	if (bitcnt) {
+		while (8>bitcnt++) {
+			s_val >>= 1;
+			s_val |= 0x80;
+		}
+		bcs->hw.tiger.sendbuf[s_cnt++] = s_val;
+		bcs->hw.tiger.sendbuf[s_cnt++] = 0xff;	// NJ<->NJ thoughput bug fix
+	}
+	bcs->hw.tiger.sendcnt = s_cnt;
+	bcs->tx_cnt -= bcs->tx_skb->len;
+	bcs->hw.tiger.sp = bcs->hw.tiger.sendbuf;
+	return(0);
+}
+
 static void got_frame(struct BCState *bcs, int count) {
 	struct sk_buff *skb;
 		
@@ -320,20 +431,30 @@
 	register u_char r_val = bcs->hw.tiger.r_val;
 	register u_int bitcnt = bcs->hw.tiger.r_bitcnt;
 	u_int *p = buf;
-        
+	int bits;
+	u_char mask;
+
+        if (bcs->mode == L1_MODE_HDLC) { // it's 64k
+		mask = 0xff;
+		bits = 8;
+	}
+	else { // it's 56K
+		mask = 0x7f;
+		bits = 7;
+	};
 	for (i=0;i<cnt;i++) {
 		val = bcs->channel ? ((*p>>8) & 0xff) : (*p & 0xff);
 		p++;
 		if (p > pend)
 			p = bcs->hw.tiger.rec;
-		if (val == 0xff) {
+		if ((val & mask) == mask) {
 			state = HDLC_ZERO_SEARCH;
 			bcs->hw.tiger.r_tot++;
 			bitcnt = 0;
 			r_one = 0;
 			continue;
 		}
-		for (j=0;j<8;j++) {
+		for (j=0;j<bits;j++) {
 			if (state == HDLC_ZERO_SEARCH) {
 				if (val & 1) {
 					r_one++;
@@ -499,9 +620,10 @@
 		p = cs->bcs[0].hw.tiger.rec + NETJET_DMA_RXSIZE - 1;
 	else
 		p = cs->bcs[0].hw.tiger.rec + cnt - 1;
-	if (cs->bcs[0].mode == L1_MODE_HDLC)
+	if ((cs->bcs[0].mode == L1_MODE_HDLC) || (cs->bcs[0].mode == L1_MODE_HDLC_56K))
 		read_raw(cs->bcs, p, cnt);
-	if (cs->bcs[1].mode == L1_MODE_HDLC)
+
+	if ((cs->bcs[1].mode == L1_MODE_HDLC) || (cs->bcs[1].mode == L1_MODE_HDLC_56K))
 		read_raw(cs->bcs + 1, p, cnt);
 	cs->hw.njet.irqstat0 &= ~NETJET_IRQM0_READ;
 }
@@ -520,8 +642,14 @@
 			bcs->Flag);
 	if (test_and_set_bit(BC_FLG_BUSY, &bcs->Flag))
 		return;
-	if (make_raw_data(bcs))
-		return;		
+	if (bcs->mode == L1_MODE_HDLC) { // it's 64k
+		if (make_raw_data(bcs))
+			return;		
+	}
+	else { // it's 56k
+		if (make_raw_data_56k(bcs))
+			return;		
+	};
 	if (bcs->cs->debug & L1_DEB_HSCX)
 		debugl1(bcs->cs,"tiger fill_dma2: c%d %4x", bcs->channel,
 			bcs->Flag);
@@ -676,9 +804,9 @@
 		p = cs->bcs[0].hw.tiger.send + NETJET_DMA_TXSIZE - 1;
 	else
 		p = cs->bcs[0].hw.tiger.send + cnt - 1;
-	if (cs->bcs[0].mode == L1_MODE_HDLC)
+	if ((cs->bcs[0].mode == L1_MODE_HDLC) || (cs->bcs[0].mode == L1_MODE_HDLC_56K))
 		write_raw(cs->bcs, p, cnt);
-	if (cs->bcs[1].mode == L1_MODE_HDLC)
+	if ((cs->bcs[1].mode == L1_MODE_HDLC) || (cs->bcs[1].mode == L1_MODE_HDLC_56K))
 		write_raw(cs->bcs + 1, p, cnt);
 	cs->hw.njet.irqstat0 &= ~NETJET_IRQM0_WRITE;
 }
diff -urN linux-2.2.19-pre10/drivers/isdn/hisax/niccy.c linux/drivers/isdn/hisax/niccy.c
--- linux-2.2.19-pre10/drivers/isdn/hisax/niccy.c	Mon Dec  3 21:02:16 2001
+++ linux/drivers/isdn/hisax/niccy.c	Mon Dec  3 21:02:59 2001
@@ -1,4 +1,4 @@
-/* $Id: niccy.c,v 1.15.6.2 2000/11/29 16:00:14 kai Exp $
+/* $Id: niccy.c,v 1.15.6.3 2001/02/13 10:33:58 kai Exp $
  *
  * niccy.c  low level stuff for Dr. Neuhaus NICCY PnP and NICCY PCI and
  *          compatible (SAGEM cybermodem)
@@ -20,9 +20,10 @@
 #include "hscx.h"
 #include "isdnl1.h"
 #include <linux/pci.h>
+#include <linux/isdn_compat.h>
 
 extern const char *CardType[];
-const char *niccy_revision = "$Revision: 1.15.6.2 $";
+const char *niccy_revision = "$Revision: 1.15.6.3 $";
 
 #define byteout(addr,val) outb(val,addr)
 #define bytein(addr) inb(addr)
diff -urN linux-2.2.19-pre10/drivers/isdn/hisax/nj_s.c linux/drivers/isdn/hisax/nj_s.c
--- linux-2.2.19-pre10/drivers/isdn/hisax/nj_s.c	Mon Dec  3 21:02:16 2001
+++ linux/drivers/isdn/hisax/nj_s.c	Mon Dec  3 21:02:59 2001
@@ -1,20 +1,21 @@
-// $Id: nj_s.c,v 2.7.6.1 2000/11/29 16:00:14 kai Exp $
+// $Id: nj_s.c,v 2.7.6.3 2001/02/13 10:33:58 kai Exp $
 //
 // This file is (c) under GNU PUBLIC LICENSE
 //
 
 #define __NO_VERSION__
-#include <linux/init.h>
 #include <linux/config.h>
+#include <linux/init.h>
 #include "hisax.h"
 #include "isac.h"
 #include "isdnl1.h"
 #include <linux/pci.h>
+#include <linux/isdn_compat.h>
 #include <linux/interrupt.h>
 #include <linux/ppp_defs.h>
 #include "netjet.h"
 
-const char *NETjet_S_revision = "$Revision: 2.7.6.1 $";
+const char *NETjet_S_revision = "$Revision: 2.7.6.3 $";
 
 static u_char dummyrr(struct IsdnCardState *cs, int chan, u_char off)
 {
@@ -49,28 +50,37 @@
 	}
 	save_flags(flags);
 	cli();
-	if ((sval = bytein(cs->hw.njet.base + NETJET_IRQSTAT0))) {
+	/* start new code 13/07/00 GE */
+	/* set bits in sval to indicate which page is free */
+	if (inl(cs->hw.njet.base + NETJET_DMA_WRITE_ADR) <
+		inl(cs->hw.njet.base + NETJET_DMA_WRITE_IRQ))
+		/* the 2nd write page is free */
+		sval = 0x08;
+	else	/* the 1st write page is free */
+		sval = 0x04;	
+	if (inl(cs->hw.njet.base + NETJET_DMA_READ_ADR) <
+		inl(cs->hw.njet.base + NETJET_DMA_READ_IRQ))
+		/* the 2nd read page is free */
+		sval = sval | 0x02;
+	else	/* the 1st read page is free */
+		sval = sval | 0x01;	
+	if (sval != cs->hw.njet.last_is0) /* we have a DMA interrupt */
+	{
 		if (test_and_set_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags)) {
 			restore_flags(flags);
 			return;
 		}
 		cs->hw.njet.irqstat0 = sval;
 		restore_flags(flags);
-/*		debugl1(cs, "tiger: ist0 %x  %x %x  %x/%x  pulse=%d",
-			sval, 
-			bytein(cs->hw.njet.base + NETJET_DMACTRL),
-			bytein(cs->hw.njet.base + NETJET_IRQMASK0),
-			inl(cs->hw.njet.base + NETJET_DMA_READ_ADR),
-			inl(cs->hw.njet.base + NETJET_DMA_WRITE_ADR),
-			bytein(cs->hw.njet.base + NETJET_PULSE_CNT));
-*/
-/*		cs->hw.njet.irqmask0 = ((0x0f & cs->hw.njet.irqstat0) ^ 0x0f) | 0x30;
-*/		byteout(cs->hw.njet.base + NETJET_IRQSTAT0, cs->hw.njet.irqstat0);
-/*		byteout(cs->hw.njet.base + NETJET_IRQMASK0, cs->hw.njet.irqmask0);
-*/		if (cs->hw.njet.irqstat0 & NETJET_IRQM0_READ)
+		if ((cs->hw.njet.irqstat0 & NETJET_IRQM0_READ) != 
+			(cs->hw.njet.last_is0 & NETJET_IRQM0_READ))
+			/* we have a read dma int */
 			read_tiger(cs);
-		if (cs->hw.njet.irqstat0 & NETJET_IRQM0_WRITE)
+		if ((cs->hw.njet.irqstat0 & NETJET_IRQM0_WRITE) !=
+			(cs->hw.njet.last_is0 & NETJET_IRQM0_WRITE))
+			/* we have a write dma int */
 			write_tiger(cs);
+		/* end new code 13/07/00 GE */
 		test_and_clear_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags);
 	} else
 		restore_flags(flags);
@@ -95,7 +105,8 @@
 	byteout(cs->hw.njet.base + NETJET_CTRL, cs->hw.njet.ctrl_reg);
 	set_current_state(TASK_UNINTERRUPTIBLE);
 	schedule_timeout((10*HZ)/1000);	/* Timeout 10ms */
-	cs->hw.njet.ctrl_reg = 0x00;  /* Reset Off and status read clear */
+	cs->hw.njet.ctrl_reg = 0x40;  /* Reset Off and status read clear */
+	/* now edge triggered for TJ320 GE 13/07/00 */
 	byteout(cs->hw.njet.base + NETJET_CTRL, cs->hw.njet.ctrl_reg);
 	set_current_state(TASK_UNINTERRUPTIBLE);
 	schedule_timeout((10*HZ)/1000);	/* Timeout 10ms */
@@ -139,8 +150,7 @@
 	struct IsdnCardState *cs = card->cs;
 	char tmp[64];
 	long flags;
-#if CONFIG_PCI
-#endif
+
 #ifdef __BIG_ENDIAN
 #error "not running on big endian machines now"
 #endif
@@ -151,10 +161,9 @@
 	test_and_clear_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags);
 
 #if CONFIG_PCI
+
 	for ( ;; )
 	{
-
-
 		if (!pci_present()) {
 			printk(KERN_ERR "Netjet: no PCI bus present\n");
 			return(0);
@@ -163,6 +172,7 @@
 			PCI_DEVICE_ID_TIGERJET_300,  dev_netjet))) {
 			if (pci_enable_device(dev_netjet))
 				return(0);
+			pci_set_master(dev_netjet);
 			cs->irq = dev_netjet->irq;
 			if (!cs->irq) {
 				printk(KERN_WARNING "NETjet-S: No IRQ for PCI card found\n");
diff -urN linux-2.2.19-pre10/drivers/isdn/hisax/nj_u.c linux/drivers/isdn/hisax/nj_u.c
--- linux-2.2.19-pre10/drivers/isdn/hisax/nj_u.c	Mon Dec  3 21:02:16 2001
+++ linux/drivers/isdn/hisax/nj_u.c	Mon Dec  3 21:02:59 2001
@@ -1,21 +1,22 @@
-/* $Id: nj_u.c,v 2.8.6.1 2000/11/29 16:00:14 kai Exp $
+/* $Id: nj_u.c,v 2.8.6.3 2001/02/13 10:33:58 kai Exp $ 
  *
  * This file is (c) under GNU PUBLIC LICENSE
  *
  */
 
 #define __NO_VERSION__
-#include <linux/init.h>
 #include <linux/config.h>
+#include <linux/init.h>
 #include "hisax.h"
 #include "icc.h"
 #include "isdnl1.h"
 #include <linux/pci.h>
+#include <linux/isdn_compat.h>
 #include <linux/interrupt.h>
 #include <linux/ppp_defs.h>
 #include "netjet.h"
 
-const char *NETjet_U_revision = "$Revision: 2.8.6.1 $";
+const char *NETjet_U_revision = "$Revision: 2.8.6.3 $";
 
 static u_char dummyrr(struct IsdnCardState *cs, int chan, u_char off)
 {
@@ -50,28 +51,37 @@
 	}
 	save_flags(flags);
 	cli();
-	if ((sval = bytein(cs->hw.njet.base + NETJET_IRQSTAT0))) {
+	/* start new code 13/07/00 GE */
+	/* set bits in sval to indicate which page is free */
+	if (inl(cs->hw.njet.base + NETJET_DMA_WRITE_ADR) <
+		inl(cs->hw.njet.base + NETJET_DMA_WRITE_IRQ))
+		/* the 2nd write page is free */
+		sval = 0x08;
+	else	/* the 1st write page is free */
+		sval = 0x04;	
+	if (inl(cs->hw.njet.base + NETJET_DMA_READ_ADR) <
+		inl(cs->hw.njet.base + NETJET_DMA_READ_IRQ))
+		/* the 2nd read page is free */
+		sval = sval | 0x02;
+	else	/* the 1st read page is free */
+		sval = sval | 0x01;	
+	if (sval != cs->hw.njet.last_is0) /* we have a DMA interrupt */
+	{
 		if (test_and_set_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags)) {
 			restore_flags(flags);
 			return;
 		}
 		cs->hw.njet.irqstat0 = sval;
 		restore_flags(flags);
-/*		debugl1(cs, "tiger: ist0 %x  %x %x  %x/%x  pulse=%d",
-			sval, 
-			bytein(cs->hw.njet.base + NETJET_DMACTRL),
-			bytein(cs->hw.njet.base + NETJET_IRQMASK0),
-			inl(cs->hw.njet.base + NETJET_DMA_READ_ADR),
-			inl(cs->hw.njet.base + NETJET_DMA_WRITE_ADR),
-			bytein(cs->hw.njet.base + NETJET_PULSE_CNT));
-*/
-/*		cs->hw.njet.irqmask0 = ((0x0f & cs->hw.njet.irqstat0) ^ 0x0f) | 0x30;
-*/		byteout(cs->hw.njet.base + NETJET_IRQSTAT0, cs->hw.njet.irqstat0);
-/*		byteout(cs->hw.njet.base + NETJET_IRQMASK0, cs->hw.njet.irqmask0);
-*/		if (cs->hw.njet.irqstat0 & NETJET_IRQM0_READ)
+		if ((cs->hw.njet.irqstat0 & NETJET_IRQM0_READ) != 
+			(cs->hw.njet.last_is0 & NETJET_IRQM0_READ))
+			/* we have a read dma int */
 			read_tiger(cs);
-		if (cs->hw.njet.irqstat0 & NETJET_IRQM0_WRITE)
+		if ((cs->hw.njet.irqstat0 & NETJET_IRQM0_WRITE) !=
+			(cs->hw.njet.last_is0 & NETJET_IRQM0_WRITE))
+			/* we have a write dma int */
 			write_tiger(cs);
+		/* end new code 13/07/00 GE */
 		test_and_clear_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags);
 	} else
 		restore_flags(flags);
@@ -96,7 +106,8 @@
 	byteout(cs->hw.njet.base + NETJET_CTRL, cs->hw.njet.ctrl_reg);
 	set_current_state(TASK_UNINTERRUPTIBLE);
 	schedule_timeout((10*HZ)/1000);	/* Timeout 10ms */
-	cs->hw.njet.ctrl_reg = 0x00;  /* Reset Off and status read clear */
+	cs->hw.njet.ctrl_reg = 0x40;  /* Reset Off and status read clear */
+	/* now edge triggered for TJ320 GE 13/07/00 */
 	byteout(cs->hw.njet.base + NETJET_CTRL, cs->hw.njet.ctrl_reg);
 	set_current_state(TASK_UNINTERRUPTIBLE);
 	schedule_timeout((10*HZ)/1000);	/* Timeout 10ms */
@@ -153,18 +164,18 @@
 	test_and_clear_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags);
 
 #if CONFIG_PCI
+
 	for ( ;; )
 	{
-
-
 		if (!pci_present()) {
-			printk(KERN_ERR "NETspider-U: no PCI bus present\n");
+			printk(KERN_ERR "Netjet: no PCI bus present\n");
 			return(0);
 		}
 		if ((dev_netjet = pci_find_device(PCI_VENDOR_ID_TIGERJET,
 			PCI_DEVICE_ID_TIGERJET_300,  dev_netjet))) {
 			if (pci_enable_device(dev_netjet))
 				return(0);
+			pci_set_master(dev_netjet);
 			cs->irq = dev_netjet->irq;
 			if (!cs->irq) {
 				printk(KERN_WARNING "NETspider-U: No IRQ for PCI card found\n");
@@ -244,7 +255,7 @@
 		       cs->hw.njet.base + bytecnt);
 		return (0);
 	} else {
-		request_region(cs->hw.njet.base, bytecnt, "netjet-u isdn");
+		request_region(cs->hw.njet.base, bytecnt, "netspider-u isdn");
 	}
 	reset_netjet_u(cs);
 	cs->readisac  = &NETjet_ReadIC;
diff -urN linux-2.2.19-pre10/drivers/isdn/hisax/sedlbauer.c linux/drivers/isdn/hisax/sedlbauer.c
--- linux-2.2.19-pre10/drivers/isdn/hisax/sedlbauer.c	Mon Dec  3 21:02:16 2001
+++ linux/drivers/isdn/hisax/sedlbauer.c	Mon Dec  3 21:02:59 2001
@@ -1,4 +1,4 @@
-/* $Id: sedlbauer.c,v 1.25.6.2 2000/11/29 17:48:59 kai Exp $
+/* $Id: sedlbauer.c,v 1.25.6.3 2001/02/13 10:33:58 kai Exp $
  *
  * sedlbauer.c  low level stuff for Sedlbauer cards
  *              includes support for the Sedlbauer speed star (speed star II),
@@ -49,10 +49,11 @@
 #include "isar.h"
 #include "isdnl1.h"
 #include <linux/pci.h>
+#include <linux/isdn_compat.h>
 
 extern const char *CardType[];
 
-const char *Sedlbauer_revision = "$Revision: 1.25.6.2 $";
+const char *Sedlbauer_revision = "$Revision: 1.25.6.3 $";
 
 const char *Sedlbauer_Types[] =
 	{"None", "speed card/win", "speed star", "speed fax+", 
@@ -529,7 +530,7 @@
 	return(0);
 }
 
-static 	struct pci_dev *dev_sedl  = NULL;
+static struct pci_dev *dev_sedl  = NULL;
 
 int 
 setup_sedlbauer(struct IsdnCard *card)
diff -urN linux-2.2.19-pre10/drivers/isdn/hisax/sportster.c linux/drivers/isdn/hisax/sportster.c
--- linux-2.2.19-pre10/drivers/isdn/hisax/sportster.c	Mon Dec  3 21:02:16 2001
+++ linux/drivers/isdn/hisax/sportster.c	Mon Dec  3 21:02:59 2001
@@ -208,8 +208,8 @@
 	}
 }
 
-__initfunc(int
-setup_sportster(struct IsdnCard *card))
+int __init
+setup_sportster(struct IsdnCard *card)
 {
 	struct IsdnCardState *cs = card->cs;
 	char tmp[64];
diff -urN linux-2.2.19-pre10/drivers/isdn/hisax/tei.c linux/drivers/isdn/hisax/tei.c
--- linux-2.2.19-pre10/drivers/isdn/hisax/tei.c	Mon Dec  3 21:02:16 2001
+++ linux/drivers/isdn/hisax/tei.c	Mon Dec  3 21:02:59 2001
@@ -12,9 +12,9 @@
  *
  */
 #define __NO_VERSION__
-#include <linux/init.h>
 #include "hisax.h"
 #include "isdnl2.h"
+#include <linux/init.h>
 #include <linux/random.h>
 
 const char *tei_revision = "$Revision: 2.17 $";
diff -urN linux-2.2.19-pre10/drivers/isdn/hisax/telespci.c linux/drivers/isdn/hisax/telespci.c
--- linux-2.2.19-pre10/drivers/isdn/hisax/telespci.c	Mon Dec  3 21:02:16 2001
+++ linux/drivers/isdn/hisax/telespci.c	Mon Dec  3 21:02:59 2001
@@ -1,4 +1,4 @@
-/* $Id: telespci.c,v 2.16.6.2 2000/11/29 16:00:14 kai Exp $
+/* $Id: telespci.c,v 2.16.6.3 2001/02/13 10:33:58 kai Exp $
  *
  * telespci.c     low level stuff for Teles PCI isdn cards
  *
@@ -16,9 +16,10 @@
 #include "hscx.h"
 #include "isdnl1.h"
 #include <linux/pci.h>
+#include <linux/isdn_compat.h>
 
 extern const char *CardType[];
-const char *telespci_revision = "$Revision: 2.16.6.2 $";
+const char *telespci_revision = "$Revision: 2.16.6.3 $";
 
 #define ZORAN_PO_RQ_PEN	0x02000000
 #define ZORAN_PO_WR	0x00800000
@@ -275,7 +276,7 @@
 	return(0);
 }
 
-static 	struct pci_dev *dev_tel __initdata = NULL;
+static struct pci_dev *dev_tel __initdata = NULL;
 
 int __init
 setup_telespci(struct IsdnCard *card)
diff -urN linux-2.2.19-pre10/drivers/isdn/hisax/w6692.c linux/drivers/isdn/hisax/w6692.c
--- linux-2.2.19-pre10/drivers/isdn/hisax/w6692.c	Mon Dec  3 21:02:16 2001
+++ linux/drivers/isdn/hisax/w6692.c	Mon Dec  3 21:02:59 2001
@@ -1,4 +1,4 @@
-/* $Id: w6692.c,v 1.12.6.2 2000/11/29 16:00:14 kai Exp $
+/* $Id: w6692.c,v 1.12.6.3 2001/02/13 10:33:58 kai Exp $
  *
  * w6692.c   Winbond W6692 specific routines
  *
@@ -17,6 +17,7 @@
 #include "isdnl1.h"
 #include <linux/interrupt.h>
 #include <linux/pci.h>
+#include <linux/isdn_compat.h>
 
 /* table entry in the PCI devices list */
 typedef struct {
@@ -35,7 +36,7 @@
 
 extern const char *CardType[];
 
-const char *w6692_revision = "$Revision: 1.12.6.2 $";
+const char *w6692_revision = "$Revision: 1.12.6.3 $";
 
 #define DBUSY_TIMER_VALUE 80
 
@@ -955,11 +956,12 @@
 	return (0);
 }
 
-static int id_idx = 0;
+static int id_idx ;
 
 static struct pci_dev *dev_w6692 __initdata = NULL;
 
-__initfunc(int setup_w6692(struct IsdnCard *card))
+int __init 
+setup_w6692(struct IsdnCard *card)
 {
 	struct IsdnCardState *cs = card->cs;
 	char tmp[64];
diff -urN linux-2.2.19-pre10/drivers/isdn/hysdn/Makefile linux/drivers/isdn/hysdn/Makefile
--- linux-2.2.19-pre10/drivers/isdn/hysdn/Makefile	Wed Dec 31 16:00:00 1969
+++ linux/drivers/isdn/hysdn/Makefile	Mon Dec  3 21:03:00 2001
@@ -0,0 +1,29 @@
+# Makefile for the hysdn ISDN device driver
+
+# The target object and module list name.
+
+O_TARGET	:= vmlinux-obj.o
+
+# Multipart objects.
+
+list-multi	:= hysdn.o
+hysdn-objs	:= hysdn_procconf.o hysdn_proclog.o boardergo.o hysdn_boot.o \
+		   hysdn_sched.o hysdn_net.o hysdn_init.o
+
+# Optional parts of multipart objects.
+
+hysdn-objs-$(CONFIG_HYSDN_CAPI) += hycapi.o
+
+hysdn-objs 	+= $(hysdn-objs-y)
+
+# Each configuration option enables a list of files.
+
+obj-$(CONFIG_HYSDN)	+= hysdn.o
+
+include $(TOPDIR)/drivers/isdn/Rules.make
+
+# Link rules for multi-part drivers.
+
+hysdn.o: $(hysdn-objs)
+	$(LD) -r -o $@ $(hysdn-objs)
+
diff -urN linux-2.2.19-pre10/drivers/isdn/hysdn/boardergo.c linux/drivers/isdn/hysdn/boardergo.c
--- linux-2.2.19-pre10/drivers/isdn/hysdn/boardergo.c	Wed Dec 31 16:00:00 1969
+++ linux/drivers/isdn/hysdn/boardergo.c	Mon Dec  3 21:03:00 2001
@@ -0,0 +1,466 @@
+/* $Id: boardergo.c,v 1.5.6.1 2000/12/10 22:01:04 kai Exp $
+
+ * Linux driver for HYSDN cards, specific routines for ergo type boards.
+ *
+ * As all Linux supported cards Champ2, Ergo and Metro2/4 use the same
+ * DPRAM interface and layout with only minor differences all related
+ * stuff is done here, not in separate modules.
+ *
+ * written by Werner Cornelius (werner@titro.de) for Hypercope GmbH
+ *
+ * Copyright 1999  by Werner Cornelius (werner@titro.de)
+ *
+ * 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; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+#define __NO_VERSION__
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/version.h>
+#include <asm/io.h>
+#include <linux/signal.h>
+#include <linux/kernel.h>
+#include <linux/ioport.h>
+#include <linux/interrupt.h>
+
+#include "hysdn_defs.h"
+#include "boardergo.h"
+
+#define byteout(addr,val) outb(val,addr)
+#define bytein(addr) inb(addr)
+
+/***************************************************/
+/* The cards interrupt handler. Called from system */
+/***************************************************/
+static void
+ergo_interrupt(int intno, void *dev_id, struct pt_regs *regs)
+{
+	hysdn_card *card = dev_id;	/* parameter from irq */
+	tErgDpram *dpr;
+	ulong flags;
+	uchar volatile b;
+
+	if (!card)
+		return;		/* error -> spurious interrupt */
+	if (!card->irq_enabled)
+		return;		/* other device interrupting or irq switched off */
+
+	save_flags(flags);
+	cli();			/* no further irqs allowed */
+
+	if (!(bytein(card->iobase + PCI9050_INTR_REG) & PCI9050_INTR_REG_STAT1)) {
+		restore_flags(flags);	/* restore old state */
+		return;		/* no interrupt requested by E1 */
+	}
+	/* clear any pending ints on the board */
+	dpr = card->dpram;
+	b = dpr->ToPcInt;	/* clear for ergo */
+	b |= dpr->ToPcIntMetro;	/* same for metro */
+	b |= dpr->ToHyInt;	/* and for champ */
+
+	/* start kernel task immediately after leaving all interrupts */
+	if (!card->hw_lock) {
+		queue_task(&card->irq_queue, &tq_immediate);
+		mark_bh(IMMEDIATE_BH);
+	}
+	restore_flags(flags);
+}				/* ergo_interrupt */
+
+/******************************************************************************/
+/* ergo_irq_bh is the function called by the immediate kernel task list after */
+/* being activated with queue_task and no interrupts active. This task is the */
+/* only one handling data transfer from or to the card after booting. The task */
+/* may be queued from everywhere (interrupts included).                       */
+/******************************************************************************/
+static void
+ergo_irq_bh(hysdn_card * card)
+{
+	tErgDpram *dpr;
+	int again;
+	ulong flags;
+
+	if (card->state != CARD_STATE_RUN)
+		return;		/* invalid call */
+
+	dpr = card->dpram;	/* point to DPRAM */
+
+	save_flags(flags);
+	cli();
+	if (card->hw_lock) {
+		restore_flags(flags);	/* hardware currently unavailable */
+		return;
+	}
+	card->hw_lock = 1;	/* we now lock the hardware */
+
+	do {
+		sti();		/* reenable other ints */
+		again = 0;	/* assume loop not to be repeated */
+
+		if (!dpr->ToHyFlag) {
+			/* we are able to send a buffer */
+
+			if (hysdn_sched_tx(card, dpr->ToHyBuf, &dpr->ToHySize, &dpr->ToHyChannel,
+					   ERG_TO_HY_BUF_SIZE)) {
+				dpr->ToHyFlag = 1;	/* enable tx */
+				again = 1;	/* restart loop */
+			}
+		}		/* we are able to send a buffer */
+		if (dpr->ToPcFlag) {
+			/* a message has arrived for us, handle it */
+
+			if (hysdn_sched_rx(card, dpr->ToPcBuf, dpr->ToPcSize, dpr->ToPcChannel)) {
+				dpr->ToPcFlag = 0;	/* we worked the data */
+				again = 1;	/* restart loop */
+			}
+		}		/* a message has arrived for us */
+		cli();		/* no further ints */
+		if (again) {
+			dpr->ToHyInt = 1;
+			dpr->ToPcInt = 1;	/* interrupt to E1 for all cards */
+		} else
+			card->hw_lock = 0;	/* free hardware again */
+	} while (again);	/* until nothing more to do */
+
+	restore_flags(flags);
+}				/* ergo_irq_bh */
+
+
+/*********************************************************/
+/* stop the card (hardware reset) and disable interrupts */
+/*********************************************************/
+static void
+ergo_stopcard(hysdn_card * card)
+{
+	ulong flags;
+	uchar val;
+
+	hysdn_net_release(card);	/* first release the net device if existing */
+#ifdef CONFIG_HYSDN_CAPI
+	hycapi_capi_stop(card);
+#endif /* CONFIG_HYSDN_CAPI */
+	save_flags(flags);
+	cli();
+	val = bytein(card->iobase + PCI9050_INTR_REG);	/* get actual value */
+	val &= ~(PCI9050_INTR_REG_ENPCI | PCI9050_INTR_REG_EN1);	/* mask irq */
+	byteout(card->iobase + PCI9050_INTR_REG, val);
+	card->irq_enabled = 0;
+	byteout(card->iobase + PCI9050_USER_IO, PCI9050_E1_RESET);	/* reset E1 processor */
+	card->state = CARD_STATE_UNUSED;
+	card->err_log_state = ERRLOG_STATE_OFF;		/* currently no log active */
+
+	restore_flags(flags);
+}				/* ergo_stopcard */
+
+/**************************************************************************/
+/* enable or disable the cards error log. The event is queued if possible */
+/**************************************************************************/
+static void
+ergo_set_errlog_state(hysdn_card * card, int on)
+{
+	ulong flags;
+
+	if (card->state != CARD_STATE_RUN) {
+		card->err_log_state = ERRLOG_STATE_OFF;		/* must be off */
+		return;
+	}
+	save_flags(flags);
+	cli();
+
+	if (((card->err_log_state == ERRLOG_STATE_OFF) && !on) ||
+	    ((card->err_log_state == ERRLOG_STATE_ON) && on)) {
+		restore_flags(flags);
+		return;		/* nothing to do */
+	}
+	if (on)
+		card->err_log_state = ERRLOG_STATE_START;	/* request start */
+	else
+		card->err_log_state = ERRLOG_STATE_STOP;	/* request stop */
+
+	restore_flags(flags);
+	queue_task(&card->irq_queue, &tq_immediate);
+	mark_bh(IMMEDIATE_BH);
+}				/* ergo_set_errlog_state */
+
+/******************************************/
+/* test the cards RAM and return 0 if ok. */
+/******************************************/
+static const char TestText[36] = "This Message is filler, why read it";
+
+static int
+ergo_testram(hysdn_card * card)
+{
+	tErgDpram *dpr = card->dpram;
+
+	memset(dpr->TrapTable, 0, sizeof(dpr->TrapTable));	/* clear all Traps */
+	dpr->ToHyInt = 1;	/* E1 INTR state forced */
+
+	memcpy(&dpr->ToHyBuf[ERG_TO_HY_BUF_SIZE - sizeof(TestText)], TestText,
+	       sizeof(TestText));
+	if (memcmp(&dpr->ToHyBuf[ERG_TO_HY_BUF_SIZE - sizeof(TestText)], TestText,
+		   sizeof(TestText)))
+		return (-1);
+
+	memcpy(&dpr->ToPcBuf[ERG_TO_PC_BUF_SIZE - sizeof(TestText)], TestText,
+	       sizeof(TestText));
+	if (memcmp(&dpr->ToPcBuf[ERG_TO_PC_BUF_SIZE - sizeof(TestText)], TestText,
+		   sizeof(TestText)))
+		return (-1);
+
+	return (0);
+}				/* ergo_testram */
+
+/*****************************************************************************/
+/* this function is intended to write stage 1 boot image to the cards buffer */
+/* this is done in two steps. First the 1024 hi-words are written (offs=0),  */
+/* then the 1024 lo-bytes are written. The remaining DPRAM is cleared, the   */
+/* PCI-write-buffers flushed and the card is taken out of reset.             */
+/* The function then waits for a reaction of the E1 processor or a timeout.  */
+/* Negative return values are interpreted as errors.                         */
+/*****************************************************************************/
+static int
+ergo_writebootimg(struct HYSDN_CARD *card, uchar * buf, ulong offs)
+{
+	uchar *dst;
+	tErgDpram *dpram;
+	int cnt = (BOOT_IMG_SIZE >> 2);		/* number of words to move and swap (byte order!) */
+	
+	if (card->debug_flags & LOG_POF_CARD)
+		hysdn_addlog(card, "ERGO: write bootldr offs=0x%lx ", offs);
+
+	dst = card->dpram;	/* pointer to start of DPRAM */
+	dst += (offs + ERG_DPRAM_FILL_SIZE);	/* offset in the DPRAM */
+	while (cnt--) {
+		*dst++ = *(buf + 1);	/* high byte */
+		*dst++ = *buf;	/* low byte */
+		dst += 2;	/* point to next longword */
+		buf += 2;	/* buffer only filled with words */
+	}
+
+	/* if low words (offs = 2) have been written, clear the rest of the DPRAM, */
+	/* flush the PCI-write-buffer and take the E1 out of reset */
+	if (offs) {
+		memset(card->dpram, 0, ERG_DPRAM_FILL_SIZE);	/* fill the DPRAM still not cleared */
+		dpram = card->dpram;	/* get pointer to dpram structure */
+		dpram->ToHyNoDpramErrLog = 0xFF;	/* write a dpram register */
+		while (!dpram->ToHyNoDpramErrLog);	/* reread volatile register to flush PCI */
+
+		byteout(card->iobase + PCI9050_USER_IO, PCI9050_E1_RUN);	/* start E1 processor */
+		/* the interrupts are still masked */
+
+		sti();
+		set_current_state(TASK_INTERRUPTIBLE);
+		schedule_timeout((20 * HZ) / 1000);	/* Timeout 20ms */
+
+		if (((tDpramBootSpooler *) card->dpram)->Len != DPRAM_SPOOLER_DATA_SIZE) {
+			if (card->debug_flags & LOG_POF_CARD)
+				hysdn_addlog(card, "ERGO: write bootldr no answer");
+			return (-ERR_BOOTIMG_FAIL);
+		}
+	}			/* start_boot_img */
+	return (0);		/* successfull */
+}				/* ergo_writebootimg */
+
+/********************************************************************************/
+/* ergo_writebootseq writes the buffer containing len bytes to the E1 processor */
+/* using the boot spool mechanism. If everything works fine 0 is returned. In   */
+/* case of errors a negative error value is returned.                           */
+/********************************************************************************/
+static int
+ergo_writebootseq(struct HYSDN_CARD *card, uchar * buf, int len)
+{
+	tDpramBootSpooler *sp = (tDpramBootSpooler *) card->dpram;
+	uchar *dst;
+	uchar buflen;
+	int nr_write;
+	uchar tmp_rdptr;
+	uchar wr_mirror;
+	int i;
+
+	if (card->debug_flags & LOG_POF_CARD)
+		hysdn_addlog(card, "ERGO: write boot seq len=%d ", len);
+
+	dst = sp->Data;		/* point to data in spool structure */
+	buflen = sp->Len;	/* maximum len of spooled data */
+	wr_mirror = sp->WrPtr;	/* only once read */
+	sti();
+
+	/* try until all bytes written or error */
+	i = 0x1000;		/* timeout value */
+	while (len) {
+
+		/* first determine the number of bytes that may be buffered */
+		do {
+			tmp_rdptr = sp->RdPtr;	/* first read the pointer */
+			i--;	/* decrement timeout */
+		} while (i && (tmp_rdptr != sp->RdPtr));	/* wait for stable pointer */
+
+		if (!i) {
+			if (card->debug_flags & LOG_POF_CARD)
+				hysdn_addlog(card, "ERGO: write boot seq timeout");
+			return (-ERR_BOOTSEQ_FAIL);	/* value not stable -> timeout */
+		}
+		if ((nr_write = tmp_rdptr - wr_mirror - 1) < 0)
+			nr_write += buflen;	/* now we got number of free bytes - 1 in buffer */
+
+		if (!nr_write)
+			continue;	/* no free bytes in buffer */
+
+		if (nr_write > len)
+			nr_write = len;		/* limit if last few bytes */
+		i = 0x1000;	/* reset timeout value */
+
+		/* now we know how much bytes we may put in the puffer */
+		len -= nr_write;	/* we savely could adjust len before output */
+		while (nr_write--) {
+			*(dst + wr_mirror) = *buf++;	/* output one byte */
+			if (++wr_mirror >= buflen)
+				wr_mirror = 0;
+			sp->WrPtr = wr_mirror;	/* announce the next byte to E1 */
+		}		/* while (nr_write) */
+
+	}			/* while (len) */
+	return (0);
+}				/* ergo_writebootseq */
+
+/***********************************************************************************/
+/* ergo_waitpofready waits for a maximum of 10 seconds for the completition of the */
+/* boot process. If the process has been successfull 0 is returned otherwise a     */
+/* negative error code is returned.                                                */
+/***********************************************************************************/
+static int
+ergo_waitpofready(struct HYSDN_CARD *card)
+{
+	tErgDpram *dpr = card->dpram;	/* pointer to DPRAM structure */
+	int timecnt = 10000 / 50;	/* timeout is 10 secs max. */
+	ulong flags;
+	int msg_size;
+	int i;
+
+	if (card->debug_flags & LOG_POF_CARD)
+		hysdn_addlog(card, "ERGO: waiting for pof ready");
+	while (timecnt--) {
+		/* wait until timeout  */
+
+		if (dpr->ToPcFlag) {
+			/* data has arrived */
+
+			if ((dpr->ToPcChannel != CHAN_SYSTEM) ||
+			    (dpr->ToPcSize < MIN_RDY_MSG_SIZE) ||
+			    (dpr->ToPcSize > MAX_RDY_MSG_SIZE) ||
+			    ((*(ulong *) dpr->ToPcBuf) != RDY_MAGIC))
+				break;	/* an error occured */
+
+			/* Check for additional data delivered during SysReady */
+			msg_size = dpr->ToPcSize - RDY_MAGIC_SIZE;
+			if (msg_size > 0)
+				if (EvalSysrTokData(card, dpr->ToPcBuf + RDY_MAGIC_SIZE, msg_size))
+					break;
+
+			if (card->debug_flags & LOG_POF_RECORD)
+				hysdn_addlog(card, "ERGO: pof boot success");
+			save_flags(flags);
+			cli();
+
+			card->state = CARD_STATE_RUN;	/* now card is running */
+			/* enable the cards interrupt */
+			byteout(card->iobase + PCI9050_INTR_REG,
+				bytein(card->iobase + PCI9050_INTR_REG) |
+			(PCI9050_INTR_REG_ENPCI | PCI9050_INTR_REG_EN1));
+			card->irq_enabled = 1;	/* we are ready to receive interrupts */
+
+			dpr->ToPcFlag = 0;	/* reset data indicator */
+			dpr->ToHyInt = 1;
+			dpr->ToPcInt = 1;	/* interrupt to E1 for all cards */
+
+			restore_flags(flags);
+			if ((i = hysdn_net_create(card))) {
+				ergo_stopcard(card);
+				card->state = CARD_STATE_BOOTERR;
+				return (i);
+			}
+#ifdef CONFIG_HYSDN_CAPI
+			if((i = hycapi_capi_create(card))) {
+				printk(KERN_WARNING "HYSDN: failed to create capi-interface.\n");
+			}
+#endif /* CONFIG_HYSDN_CAPI */
+			return (0);	/* success */
+		}		/* data has arrived */
+		sti();
+		set_current_state(TASK_INTERRUPTIBLE);
+		schedule_timeout((50 * HZ) / 1000);	/* Timeout 50ms */
+	}			/* wait until timeout */
+
+	if (card->debug_flags & LOG_POF_CARD)
+		hysdn_addlog(card, "ERGO: pof boot ready timeout");
+	return (-ERR_POF_TIMEOUT);
+}				/* ergo_waitpofready */
+
+
+
+/************************************************************************************/
+/* release the cards hardware. Before releasing do a interrupt disable and hardware */
+/* reset. Also unmap dpram.                                                         */
+/* Use only during module release.                                                  */
+/************************************************************************************/
+static void
+ergo_releasehardware(hysdn_card * card)
+{
+	ergo_stopcard(card);	/* first stop the card if not already done */
+	free_irq(card->irq, card);	/* release interrupt */
+	release_region(card->iobase + PCI9050_INTR_REG, 1);	/* release all io ports */
+	release_region(card->iobase + PCI9050_USER_IO, 1);
+	vfree(card->dpram);
+	card->dpram = NULL;	/* release shared mem */
+}				/* ergo_releasehardware */
+
+
+/*********************************************************************************/
+/* acquire the needed hardware ports and map dpram. If an error occurs a nonzero */
+/* value is returned.                                                            */
+/* Use only during module init.                                                  */
+/*********************************************************************************/
+int
+ergo_inithardware(hysdn_card * card)
+{
+	if (check_region(card->iobase + PCI9050_INTR_REG, 1) ||
+	    check_region(card->iobase + PCI9050_USER_IO, 1))
+		return (-1);	/* ports already in use */
+
+	card->memend = card->membase + ERG_DPRAM_PAGE_SIZE - 1;
+	if (!(card->dpram = ioremap(card->membase, ERG_DPRAM_PAGE_SIZE)))
+		return (-1);
+
+	request_region(card->iobase + PCI9050_INTR_REG, 1, "HYSDN");
+	request_region(card->iobase + PCI9050_USER_IO, 1, "HYSDN");
+	ergo_stopcard(card);	/* disable interrupts */
+	if (request_irq(card->irq, ergo_interrupt, SA_SHIRQ, "HYSDN", card)) {
+		ergo_releasehardware(card); /* return the acquired hardware */
+		return (-1);
+	}
+	/* success, now setup the function pointers */
+	card->stopcard = ergo_stopcard;
+	card->releasehardware = ergo_releasehardware;
+	card->testram = ergo_testram;
+	card->writebootimg = ergo_writebootimg;
+	card->writebootseq = ergo_writebootseq;
+	card->waitpofready = ergo_waitpofready;
+	card->set_errlog_state = ergo_set_errlog_state;
+	card->irq_queue.sync = 0;
+	card->irq_queue.data = card;	/* init task queue for interrupt */
+	card->irq_queue.routine = (void *) (void *) ergo_irq_bh;
+
+	return (0);
+}				/* ergo_inithardware */
diff -urN linux-2.2.19-pre10/drivers/isdn/hysdn/boardergo.h linux/drivers/isdn/hysdn/boardergo.h
--- linux-2.2.19-pre10/drivers/isdn/hysdn/boardergo.h	Wed Dec 31 16:00:00 1969
+++ linux/drivers/isdn/hysdn/boardergo.h	Mon Dec  3 21:03:00 2001
@@ -0,0 +1,112 @@
+/* $Id: boardergo.h,v 1.2 2000/11/13 22:51:47 kai Exp $
+
+ * Linux driver for HYSDN cards, definitions for ergo type boards (buffers..).
+ * written by Werner Cornelius (werner@titro.de) for Hypercope GmbH
+ *
+ * Copyright 1999  by Werner Cornelius (werner@titro.de)
+ *
+ * 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; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+#include <linux/isdn_compat.h>
+
+/************************************************/
+/* defines for the dual port memory of the card */
+/************************************************/
+#define ERG_DPRAM_PAGE_SIZE 0x2000	/* DPRAM occupies a 8K page */
+#define BOOT_IMG_SIZE 4096
+#define ERG_DPRAM_FILL_SIZE (ERG_DPRAM_PAGE_SIZE - BOOT_IMG_SIZE)
+
+#define ERG_TO_HY_BUF_SIZE  0x0E00	/* 3072 bytes buffer size to card */
+#define ERG_TO_PC_BUF_SIZE  0x0E00	/* 3072 bytes to PC, too */
+
+/* following DPRAM layout copied from OS2-driver boarderg.h */
+typedef struct ErgDpram_tag {
+/*0000 */ uchar ToHyBuf[ERG_TO_HY_BUF_SIZE];
+/*0E00 */ uchar ToPcBuf[ERG_TO_PC_BUF_SIZE];
+
+	/*1C00 */ uchar bSoftUart[SIZE_RSV_SOFT_UART];
+	/* size 0x1B0 */
+
+	/*1DB0 *//* tErrLogEntry */ uchar volatile ErrLogMsg[64];
+	/* size 64 bytes */
+	/*1DB0  ulong ulErrType;               */
+	/*1DB4  ulong ulErrSubtype;            */
+	/*1DB8  ulong ucTextSize;              */
+	/*1DB9  ulong ucText[ERRLOG_TEXT_SIZE]; *//* ASCIIZ of len ucTextSize-1 */
+	/*1DF0 */
+
+/*1DF0 */ word volatile ToHyChannel;
+/*1DF2 */ word volatile ToHySize;
+	/*1DF4 */ uchar volatile ToHyFlag;
+	/* !=0: msg for Hy waiting */
+	/*1DF5 */ uchar volatile ToPcFlag;
+	/* !=0: msg for PC waiting */
+/*1DF6 */ word volatile ToPcChannel;
+/*1DF8 */ word volatile ToPcSize;
+	/*1DFA */ uchar bRes1DBA[0x1E00 - 0x1DFA];
+	/* 6 bytes */
+
+/*1E00 */ uchar bRestOfEntryTbl[0x1F00 - 0x1E00];
+/*1F00 */ ulong TrapTable[62];
+	/*1FF8 */ uchar bRes1FF8[0x1FFB - 0x1FF8];
+	/* low part of reset vetor */
+/*1FFB */ uchar ToPcIntMetro;
+	/* notes:
+	 * - metro has 32-bit boot ram - accessing
+	 *   ToPcInt and ToHyInt would be the same;
+	 *   so we moved ToPcInt to 1FFB.
+	 *   Because on the PC side both vars are
+	 *   readonly (reseting on int from E1 to PC),
+	 *   we can read both vars on both cards
+	 *   without destroying anything.
+	 * - 1FFB is the high byte of the reset vector,
+	 *   so E1 side should NOT change this byte
+	 *   when writing!
+	 */
+/*1FFC */ uchar volatile ToHyNoDpramErrLog;
+	/* note: ToHyNoDpramErrLog is used to inform
+	 *       boot loader, not to use DPRAM based
+	 *       ErrLog; when DOS driver is rewritten
+	 *       this becomes obsolete
+	 */
+/*1FFD */ uchar bRes1FFD;
+	/*1FFE */ uchar ToPcInt;
+	/* E1_intclear; on CHAMP2: E1_intset   */
+	/*1FFF */ uchar ToHyInt;
+	/* E1_intset;   on CHAMP2: E1_intclear */
+} tErgDpram;
+
+/**********************************************/
+/* PCI9050 controller local register offsets: */
+/* copied from boarderg.c                     */
+/**********************************************/
+#define PCI9050_INTR_REG    0x4C	/* Interrupt register */
+#define PCI9050_USER_IO     0x51	/* User I/O  register */
+
+				    /* bitmask for PCI9050_INTR_REG: */
+#define PCI9050_INTR_REG_EN1    0x01	/* 1= enable (def.), 0= disable */
+#define PCI9050_INTR_REG_POL1   0x02	/* 1= active high (def.), 0= active low */
+#define PCI9050_INTR_REG_STAT1  0x04	/* 1= intr. active, 0= intr. not active (def.) */
+#define PCI9050_INTR_REG_ENPCI  0x40	/* 1= PCI interrupts enable (def.) */
+
+				    /* bitmask for PCI9050_USER_IO: */
+#define PCI9050_USER_IO_EN3     0x02	/* 1= disable      , 0= enable (def.) */
+#define PCI9050_USER_IO_DIR3    0x04	/* 1= output (def.), 0= input         */
+#define PCI9050_USER_IO_DAT3    0x08	/* 1= high (def.)  , 0= low           */
+
+#define PCI9050_E1_RESET    (                     PCI9050_USER_IO_DIR3)		/* 0x04 */
+#define PCI9050_E1_RUN      (PCI9050_USER_IO_DAT3|PCI9050_USER_IO_DIR3)		/* 0x0C */
diff -urN linux-2.2.19-pre10/drivers/isdn/hysdn/hycapi.c linux/drivers/isdn/hysdn/hycapi.c
--- linux-2.2.19-pre10/drivers/isdn/hysdn/hycapi.c	Wed Dec 31 16:00:00 1969
+++ linux/drivers/isdn/hysdn/hycapi.c	Mon Dec  3 21:03:00 2001
@@ -0,0 +1,839 @@
+/* $Id: hycapi.c,v 1.8 2000/11/22 17:13:13 kai Exp $
+ *
+ * Linux driver for HYSDN cards, CAPI2.0-Interface.
+ * written by Ulrich Albrecht (u.albrecht@hypercope.de) for Hypercope GmbH
+ *
+ * Copyright 2000 by Hypercope GmbH
+ *
+ * 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; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+#define __NO_VERSION__
+#include <linux/module.h>
+#include <linux/version.h>
+#include <linux/signal.h>
+#include <linux/kernel.h>
+#include <linux/skbuff.h>
+
+
+#define	VER_DRIVER	0
+#define	VER_CARDTYPE	1
+#define	VER_HWID	2
+#define	VER_SERIAL	3
+#define	VER_OPTION	4
+#define	VER_PROTO	5
+#define	VER_PROFILE	6
+#define	VER_CAPI	7
+
+#include "hysdn_defs.h"
+#include <linux/kernelcapi.h>
+
+static char hycapi_revision[]="$Revision: 1.8 $";
+
+typedef struct _hycapi_appl {
+	unsigned int ctrl_mask;
+	capi_register_params rp;
+	struct sk_buff *listen_req[CAPI_MAXCONTR];
+} hycapi_appl;
+
+static hycapi_appl hycapi_applications[CAPI_MAXAPPL];
+
+static inline int _hycapi_appCheck(int app_id, int ctrl_no)
+{
+	if((ctrl_no <= 0) || (ctrl_no > CAPI_MAXCONTR) || (app_id <= 0) ||
+	   (app_id > CAPI_MAXAPPL))
+	{
+		printk(KERN_ERR "HYCAPI: Invalid request app_id %d for controller %d", app_id, ctrl_no);
+		return -1;
+	}
+	return ((hycapi_applications[app_id-1].ctrl_mask & (1 << (ctrl_no-1))) != 0);
+}
+
+struct capi_driver_interface *hy_di = NULL;
+
+/******************************
+Kernel-Capi callback reset_ctr
+******************************/     
+
+void 
+hycapi_reset_ctr(struct capi_ctr *ctrl)
+{
+#ifdef HYCAPI_PRINTFNAMES
+	printk(KERN_NOTICE "HYCAPI hycapi_reset_ctr\n");
+#endif
+	ctrl->reseted(ctrl);
+}
+
+/******************************
+Kernel-Capi callback remove_ctr
+******************************/     
+
+void 
+hycapi_remove_ctr(struct capi_ctr *ctrl)
+{
+	int i;
+	hycapictrl_info *cinfo = NULL;
+	hysdn_card *card = NULL;
+#ifdef HYCAPI_PRINTFNAMES
+	printk(KERN_NOTICE "HYCAPI hycapi_remove_ctr\n");
+#endif 
+	if(!hy_di) {
+		printk(KERN_ERR "No capi_driver_interface set!");
+		return;
+	}
+	cinfo = (hycapictrl_info *)(ctrl->driverdata);
+	if(!cinfo) {
+		printk(KERN_ERR "No hycapictrl_info set!");
+		return;
+	}    
+	card = cinfo->card;
+	ctrl->suspend_output(ctrl);
+	for(i=0; i<CAPI_MAXAPPL;i++) {
+		if(hycapi_applications[i].listen_req[ctrl->cnr-1]) {
+			kfree_skb(hycapi_applications[i].listen_req[ctrl->cnr-1]);
+			hycapi_applications[i].listen_req[ctrl->cnr-1] = NULL;
+		}
+	}
+	hy_di->detach_ctr(ctrl);
+	ctrl->driverdata = 0;
+	kfree(card->hyctrlinfo);
+
+		
+	card->hyctrlinfo = NULL;
+}
+
+/***********************************************************
+
+Queue a CAPI-message to the controller.
+
+***********************************************************/
+
+static void
+hycapi_sendmsg_internal(struct capi_ctr *ctrl, struct sk_buff *skb)
+{
+	hycapictrl_info *cinfo = (hycapictrl_info *)(ctrl->driverdata);
+	hysdn_card *card = cinfo->card;
+
+	spin_lock_irq(&cinfo->lock);
+#ifdef HYCAPI_PRINTFNAMES
+	printk(KERN_NOTICE "hycapi_send_message\n");    
+#endif
+	cinfo->skbs[cinfo->in_idx++] = skb;	/* add to buffer list */
+	if (cinfo->in_idx >= HYSDN_MAX_CAPI_SKB)
+		cinfo->in_idx = 0;	/* wrap around */
+	cinfo->sk_count++;		/* adjust counter */
+	if (cinfo->sk_count >= HYSDN_MAX_CAPI_SKB) {
+		/* inform upper layers we're full */
+		printk(KERN_ERR "HYSDN Card%d: CAPI-buffer overrun!\n",
+		       card->myid);	
+		ctrl->suspend_output(ctrl);
+	}
+	cinfo->tx_skb = skb;
+	spin_unlock_irq(&cinfo->lock);
+	queue_task(&card->irq_queue, &tq_immediate);
+	mark_bh(IMMEDIATE_BH);
+}
+
+/***********************************************************
+hycapi_register_internal
+
+Send down the CAPI_REGISTER-Command to the controller.
+This functions will also be used if the adapter has been rebooted to
+re-register any applications in the private list.
+
+************************************************************/
+
+static void 
+hycapi_register_internal(struct capi_ctr *ctrl, __u16 appl,
+			 capi_register_params *rp)
+{
+	char ExtFeatureDefaults[] = "49  /0/0/0/0,*/1,*/2,*/3,*/4,*/5,*/6,*/7,*/8,*/9,*";
+	hycapictrl_info *cinfo = (hycapictrl_info *)(ctrl->driverdata);
+	hysdn_card *card = cinfo->card;
+	struct sk_buff *skb;
+	__u16 len;
+	__u8 _command = 0xa0, _subcommand = 0x80;
+	__u16 MessageNumber = 0x0000;
+	__u16 MessageBufferSize = 0;
+	int slen = strlen(ExtFeatureDefaults);
+#ifdef HYCAPI_PRINTFNAMES
+	printk(KERN_NOTICE "hycapi_register_appl\n"); 
+#endif
+	MessageBufferSize = rp->level3cnt * rp->datablkcnt * rp->datablklen; 
+
+	len = CAPI_MSG_BASELEN + 8 + slen + 1;
+	if (!(skb = alloc_skb(len, GFP_ATOMIC))) {
+		printk(KERN_ERR "HYSDN card%d: memory squeeze in hycapi_register_appl\n",
+		       card->myid);
+		return;
+	}
+	memcpy(skb_put(skb,sizeof(__u16)), &len, sizeof(__u16));
+	memcpy(skb_put(skb,sizeof(__u16)), &appl, sizeof(__u16));
+	memcpy(skb_put(skb,sizeof(__u8)), &_command, sizeof(_command));
+	memcpy(skb_put(skb,sizeof(__u8)), &_subcommand, sizeof(_subcommand));
+	memcpy(skb_put(skb,sizeof(__u16)), &MessageNumber, sizeof(__u16));
+	memcpy(skb_put(skb,sizeof(__u16)), &MessageBufferSize, sizeof(__u16)); 
+	memcpy(skb_put(skb,sizeof(__u16)), &(rp->level3cnt), sizeof(__u16));
+	memcpy(skb_put(skb,sizeof(__u16)), &(rp->datablkcnt), sizeof(__u16));
+	memcpy(skb_put(skb,sizeof(__u16)), &(rp->datablklen), sizeof(__u16));
+	memcpy(skb_put(skb,slen), ExtFeatureDefaults, slen);
+	hycapi_applications[appl-1].ctrl_mask |= (1 << (ctrl->cnr-1));    
+	hycapi_send_message(ctrl, skb);    
+}
+
+/************************************************************
+hycapi_restart_internal
+
+After an adapter has been rebootet, re-register all applications and
+send a LISTEN_REQ (if there has been such a thing )
+
+*************************************************************/
+
+static void hycapi_restart_internal(struct capi_ctr *ctrl)
+{
+	int i;
+	struct sk_buff *skb;
+#ifdef HYCAPI_PRINTFNAMES
+	printk(KERN_WARNING "HYSDN: hycapi_restart_internal");
+#endif
+	for(i=0; i<CAPI_MAXAPPL; i++) {
+		if(_hycapi_appCheck(i+1, ctrl->cnr) == 1) {
+			hycapi_register_internal(ctrl, i+1, 
+						 &hycapi_applications[i].rp);
+			if(hycapi_applications[i].listen_req[ctrl->cnr-1]) {
+				skb = skb_copy(hycapi_applications[i].listen_req[ctrl->cnr-1], GFP_ATOMIC);
+				hycapi_sendmsg_internal(ctrl, skb);
+			}
+		}
+	}
+}
+
+/*************************************************************
+Register an application.
+Error-checking is done for CAPI-compliance.
+
+The application is recorded in the internal list.
+*************************************************************/
+
+void 
+hycapi_register_appl(struct capi_ctr *ctrl, __u16 appl, 
+		     capi_register_params *rp)
+{
+	int MaxLogicalConnections = 0, MaxBDataBlocks = 0, MaxBDataLen = 0;
+	hycapictrl_info *cinfo = (hycapictrl_info *)(ctrl->driverdata);
+	hysdn_card *card = cinfo->card;
+	int chk = _hycapi_appCheck(appl, ctrl->cnr);
+	if(chk < 0) {
+		return;
+	}
+	if(chk == 1) {
+		printk(KERN_INFO "HYSDN: apl %d allready registered\n", appl);
+		return;
+	}
+	MaxBDataBlocks = rp->datablkcnt > CAPI_MAXDATAWINDOW ? CAPI_MAXDATAWINDOW : rp->datablkcnt;
+	rp->datablkcnt = MaxBDataBlocks;
+	MaxBDataLen = rp->datablklen < 1024 ? 1024 : rp->datablklen ;
+	rp->datablklen = MaxBDataLen;
+	
+	MaxLogicalConnections = rp->level3cnt;
+	if (MaxLogicalConnections < 0) {
+		MaxLogicalConnections = card->bchans * -MaxLogicalConnections; 
+	}
+	if (MaxLogicalConnections == 0) {
+		MaxLogicalConnections = card->bchans;
+	}
+	
+	rp->level3cnt = MaxLogicalConnections;
+	memcpy(&hycapi_applications[appl-1].rp, 
+	       rp, sizeof(capi_register_params));
+	
+/*        MOD_INC_USE_COUNT; */
+	ctrl->appl_registered(ctrl, appl);
+}
+
+/*********************************************************************
+
+hycapi_release_internal
+
+Send down a CAPI_RELEASE to the controller.
+*********************************************************************/
+
+static void hycapi_release_internal(struct capi_ctr *ctrl, __u16 appl)
+{
+	hycapictrl_info *cinfo = (hycapictrl_info *)(ctrl->driverdata);
+	hysdn_card *card = cinfo->card;
+	struct sk_buff *skb;
+	__u16 len;
+	__u8 _command = 0xa1, _subcommand = 0x80;
+	__u16 MessageNumber = 0x0000;
+#ifdef HYCAPI_PRINTFNAMES
+	printk(KERN_NOTICE "hycapi_release_appl\n");
+#endif
+	len = CAPI_MSG_BASELEN;
+	if (!(skb = alloc_skb(len, GFP_ATOMIC))) {
+		printk(KERN_ERR "HYSDN card%d: memory squeeze in hycapi_register_appl\n",
+		       card->myid);
+		return;
+	}
+	memcpy(skb_put(skb,sizeof(__u16)), &len, sizeof(__u16));
+	memcpy(skb_put(skb,sizeof(__u16)), &appl, sizeof(__u16));
+	memcpy(skb_put(skb,sizeof(__u8)), &_command, sizeof(_command));
+	memcpy(skb_put(skb,sizeof(__u8)), &_subcommand, sizeof(_subcommand));
+	memcpy(skb_put(skb,sizeof(__u16)), &MessageNumber, sizeof(__u16));    
+	hycapi_send_message(ctrl, skb);    
+	hycapi_applications[appl-1].ctrl_mask &= ~(1 << (ctrl->cnr-1));    
+}
+
+/******************************************************************
+hycapi_release_appl
+
+Release the application from the internal list an remove it's 
+registration at controller-level
+******************************************************************/
+
+void 
+hycapi_release_appl(struct capi_ctr *ctrl, __u16 appl)
+{
+	int chk;
+
+	chk = _hycapi_appCheck(appl, ctrl->cnr);
+	if(chk<0) {
+		printk(KERN_ERR "HYCAPI: Releasing invalid appl %d on controller %d\n", appl, ctrl->cnr);
+		return;
+	}
+	if(hycapi_applications[appl-1].listen_req[ctrl->cnr-1]) {
+		kfree_skb(hycapi_applications[appl-1].listen_req[ctrl->cnr-1]);
+		hycapi_applications[appl-1].listen_req[ctrl->cnr-1] = NULL;
+	}
+	if(chk == 1)
+	{
+		hycapi_release_internal(ctrl, appl);
+	}
+	ctrl->appl_released(ctrl, appl);
+/*        MOD_DEC_USE_COUNT;  */
+}
+
+
+/**************************************************************
+Kill a single controller.
+**************************************************************/
+
+int hycapi_capi_release(hysdn_card *card)
+{
+	hycapictrl_info *cinfo = card->hyctrlinfo;
+	struct capi_ctr *ctrl;
+#ifdef HYCAPI_PRINTFNAMES
+	printk(KERN_NOTICE "hycapi_capi_release\n");
+#endif
+	if(cinfo) {
+		ctrl = cinfo->capi_ctrl;
+		hycapi_remove_ctr(ctrl);
+	}
+	return 0;
+}
+
+/**************************************************************
+hycapi_capi_stop
+
+Stop CAPI-Output on a card. (e.g. during reboot)
+***************************************************************/
+
+int hycapi_capi_stop(hysdn_card *card)
+{
+	hycapictrl_info *cinfo = card->hyctrlinfo;
+	struct capi_ctr *ctrl;
+#ifdef HYCAPI_PRINTFNAMES
+	printk(KERN_NOTICE "hycapi_capi_stop\n");
+#endif
+	if(cinfo) {
+		if(cinfo->capi_ctrl) {
+			ctrl = cinfo->capi_ctrl;
+/*			ctrl->suspend_output(ctrl); */
+			ctrl->reseted(ctrl);
+
+		} else {
+			printk(KERN_NOTICE "hycapi_capi_stop: cinfo but no capi_ctrl\n");
+		}
+	}
+	return 0;
+}
+
+/***************************************************************
+hycapi_send_message
+
+Send a message to the controller.
+
+Messages are parsed for their Command/Subcommand-type, and appropriate
+action's are performed.
+
+Note that we have to muck around with a 64Bit-DATA_REQ as there are
+firmware-releases that do not check the MsgLen-Indication!
+
+***************************************************************/
+
+void hycapi_send_message(struct capi_ctr *ctrl, struct sk_buff *skb)
+{
+	__u16 appl_id;
+	int _len, _len2;
+	__u8 msghead[64];
+	
+	appl_id = CAPIMSG_APPID(skb->data);
+	switch(_hycapi_appCheck(appl_id, ctrl->cnr))
+	{
+		case 0:
+/*			printk(KERN_INFO "Need to register\n"); */
+			hycapi_register_internal(ctrl, 
+						 appl_id,
+						 &(hycapi_applications[appl_id-1].rp));
+			break;
+		case 1:
+			break;
+		default:
+			printk(KERN_ERR "HYCAPI: Controller mixup!\n");
+			return;
+	}
+	switch(CAPIMSG_CMD(skb->data)) {		
+		case CAPI_DISCONNECT_B3_RESP:
+			ctrl->free_ncci(ctrl, appl_id, 
+					CAPIMSG_NCCI(skb->data));
+			break;
+		case CAPI_DATA_B3_REQ:
+			_len = CAPIMSG_LEN(skb->data);
+			if (_len > 22) {
+				_len2 = _len - 22;
+				memcpy(msghead, skb->data, 22);
+				memcpy(skb->data + _len2, msghead, 22);
+				skb_pull(skb, _len2);
+				CAPIMSG_SETLEN(skb->data, 22);
+			}
+			break;
+		case CAPI_LISTEN_REQ:
+			if(hycapi_applications[appl_id-1].listen_req[ctrl->cnr-1])
+			{
+				kfree_skb(hycapi_applications[appl_id-1].listen_req[ctrl->cnr-1]);
+				hycapi_applications[appl_id-1].listen_req[ctrl->cnr-1] = NULL;
+			}
+			if (!(hycapi_applications[appl_id-1].listen_req[ctrl->cnr-1] = skb_copy(skb, GFP_ATOMIC))) 
+			{
+				printk(KERN_ERR "HYSDN: memory squeeze in private_listen\n");
+			} 
+			break;
+		default:
+			break;
+	}
+	hycapi_sendmsg_internal(ctrl, skb);
+}
+
+/*********************************************************************
+hycapi_read_proc
+
+Informations provided in the /proc/capi-entries.
+
+*********************************************************************/
+
+int hycapi_read_proc(char *page, char **start, off_t off,
+		     int count, int *eof, struct capi_ctr *ctrl)
+{
+	hycapictrl_info *cinfo = (hycapictrl_info *)(ctrl->driverdata);
+	hysdn_card *card = cinfo->card;
+	int len = 0;
+	char *s;
+#ifdef HYCAPI_PRINTFNAMES
+	printk(KERN_NOTICE "hycapi_read_proc\n");    
+#endif
+	len += sprintf(page+len, "%-16s %s\n", "name", cinfo->cardname);
+	len += sprintf(page+len, "%-16s 0x%x\n", "io", card->iobase);
+	len += sprintf(page+len, "%-16s %d\n", "irq", card->irq);
+    
+	switch (card->brdtype) {
+		case BD_PCCARD:  s = "HYSDN Hycard"; break;
+		case BD_ERGO: s = "HYSDN Ergo2"; break;
+		case BD_METRO: s = "HYSDN Metro4"; break;
+		case BD_CHAMP2: s = "HYSDN Champ2";	break;
+		case BD_PLEXUS: s = "HYSDN Plexus30"; break;
+		default: s = "???"; break;
+	}
+	len += sprintf(page+len, "%-16s %s\n", "type", s);
+	if ((s = cinfo->version[VER_DRIVER]) != 0)
+		len += sprintf(page+len, "%-16s %s\n", "ver_driver", s);
+	if ((s = cinfo->version[VER_CARDTYPE]) != 0)
+		len += sprintf(page+len, "%-16s %s\n", "ver_cardtype", s);
+	if ((s = cinfo->version[VER_SERIAL]) != 0)
+		len += sprintf(page+len, "%-16s %s\n", "ver_serial", s);
+    
+	len += sprintf(page+len, "%-16s %s\n", "cardname", cinfo->cardname);
+    
+	if (off+count >= len)
+		*eof = 1;
+	if (len < off)
+		return 0;
+	*start = page + off;
+	return ((count < len-off) ? count : len-off);
+}
+
+/**************************************************************
+hycapi_load_firmware
+
+This does NOT load any firmware, but the callback somehow is needed
+on capi-interface registration.
+
+**************************************************************/
+
+int hycapi_load_firmware(struct capi_ctr *ctrl, capiloaddata *data)
+{
+#ifdef HYCAPI_PRINTFNAMES
+	printk(KERN_NOTICE "hycapi_load_firmware\n");    
+#endif
+	return 0;
+}
+
+
+char *hycapi_procinfo(struct capi_ctr *ctrl)
+{
+	hycapictrl_info *cinfo = (hycapictrl_info *)(ctrl->driverdata);
+#ifdef HYCAPI_PRINTFNAMES
+	printk(KERN_NOTICE "hycapi_proc_info\n");    
+#endif
+	if (!cinfo)
+		return "";
+	sprintf(cinfo->infobuf, "%s %s 0x%x %d %s",
+		cinfo->cardname[0] ? cinfo->cardname : "-",
+		cinfo->version[VER_DRIVER] ? cinfo->version[VER_DRIVER] : "-",
+		cinfo->card ? cinfo->card->iobase : 0x0,
+		cinfo->card ? cinfo->card->irq : 0,
+		hycapi_revision
+		);
+	return cinfo->infobuf;
+}
+
+/******************************************************************
+hycapi_rx_capipkt
+
+Recieve a capi-message.
+
+All B3_DATA_IND are converted to 64K-extension compatible format.
+New nccis are created if neccessary.
+*******************************************************************/
+
+void
+hycapi_rx_capipkt(hysdn_card * card, uchar * buf, word len)
+{
+	struct sk_buff *skb;
+	hycapictrl_info *cinfo = card->hyctrlinfo;
+	struct capi_ctr *ctrl;
+	__u16 ApplId;
+	__u16 MsgLen, info;
+	__u16 len2, CapiCmd;
+	__u32 CP64[2] = {0,0};
+#ifdef HYCAPI_PRINTFNAMES
+	printk(KERN_NOTICE "hycapi_rx_capipkt\n");    
+#endif
+	if(!cinfo) {
+		printk(KERN_ERR "HYSDN Card%d: no HYCAPI-controller!\n",
+		       card->myid);
+		return;
+	}
+	ctrl = cinfo->capi_ctrl;
+	if(!ctrl)
+	{
+		printk(KERN_ERR "HYSDN Card%d: no CAPI-controller (1)!\n",
+		       card->myid);
+		return;
+	}
+	if(len < CAPI_MSG_BASELEN) {
+		printk(KERN_ERR "HYSDN Card%d: invalid CAPI-message, lenght %d!\n",
+		       card->myid, len);
+		return;
+	}	
+	MsgLen = CAPIMSG_LEN(buf);
+	ApplId = CAPIMSG_APPID(buf);
+	CapiCmd = CAPIMSG_CMD(buf);
+	
+	if((CapiCmd == CAPI_DATA_B3_IND) && (MsgLen < 30)) {
+		len2 = len + (30 - MsgLen);
+		if (!(skb = alloc_skb(len2, GFP_ATOMIC))) {
+			printk(KERN_ERR "HYSDN Card%d: incoming packet dropped\n",
+			       card->myid);
+			return;
+		}
+		memcpy(skb_put(skb, MsgLen), buf, MsgLen);
+		memcpy(skb_put(skb, 2*sizeof(__u32)), CP64, 2* sizeof(__u32));
+		memcpy(skb_put(skb, len - MsgLen), buf + MsgLen,
+		       len - MsgLen);
+		CAPIMSG_SETLEN(skb->data, 30);
+	} else {
+		if (!(skb = alloc_skb(len, GFP_ATOMIC))) {
+			printk(KERN_ERR "HYSDN Card%d: incoming packet dropped\n",
+			       card->myid);
+			return;
+		}
+		memcpy(skb_put(skb, len), buf, len);
+	}
+	switch(CAPIMSG_CMD(skb->data)) 
+	{
+		case CAPI_CONNECT_B3_CONF:
+/* Check info-field for error-indication: */
+			info = CAPIMSG_U16(skb->data, 12);
+			switch(info)
+			{
+				case 0:
+					ctrl->new_ncci(ctrl, ApplId, CAPIMSG_NCCI(skb->data), 
+						       hycapi_applications[ApplId-1].rp.datablkcnt); 
+					
+					break;
+				case 0x0001:
+					printk(KERN_ERR "HYSDN Card%d: NCPI not supported by current "
+					       "protocol. NCPI ignored.\n", card->myid);
+					break;
+				case 0x2001:
+					printk(KERN_ERR "HYSDN Card%d: Message not supported in"
+					       " current state\n", card->myid);
+					break;
+				case 0x2002:
+					printk(KERN_ERR "HYSDN Card%d: illegal PLCI\n", card->myid);
+					break;		
+				case 0x2004:
+					printk(KERN_ERR "HYSDN Card%d: out of NCCI\n", card->myid);
+					break;				
+				case 0x3008:
+					printk(KERN_ERR "HYSDN Card%d: NCPI not supported\n", 
+					       card->myid);
+					break;	
+				default:
+					printk(KERN_ERR "HYSDN Card%d: Info in CONNECT_B3_CONF: %d\n", 
+					       card->myid, info);
+					break;			
+			}
+			break;
+		case CAPI_CONNECT_B3_IND:
+			ctrl->new_ncci(ctrl, ApplId, 
+				       CAPIMSG_NCCI(skb->data), 
+				       hycapi_applications[ApplId-1].rp.datablkcnt);
+			break;
+		default:
+			break;
+	}
+	ctrl->handle_capimsg(ctrl, ApplId, skb);
+}
+
+/******************************************************************
+hycapi_tx_capiack
+
+Internally acknowledge a msg sent. This will remove the msg from the
+internal queue.
+
+*******************************************************************/
+
+void hycapi_tx_capiack(hysdn_card * card)
+{
+	hycapictrl_info *cinfo = card->hyctrlinfo;
+#ifdef HYCAPI_PRINTFNAMES
+	printk(KERN_NOTICE "hycapi_tx_capiack\n");    
+#endif
+	if(!cinfo) {
+		printk(KERN_ERR "HYSDN Card%d: no CAPI-controller (2)!\n",
+		       card->myid);
+		return;
+	}
+	spin_lock_irq(&cinfo->lock);
+	kfree_skb(cinfo->skbs[cinfo->out_idx]);		/* free skb */
+	cinfo->skbs[cinfo->out_idx++] = NULL;
+	if (cinfo->out_idx >= HYSDN_MAX_CAPI_SKB)
+		cinfo->out_idx = 0;	/* wrap around */
+
+	if (cinfo->sk_count-- == HYSDN_MAX_CAPI_SKB)	/* dec usage count */
+		cinfo->capi_ctrl->resume_output(cinfo->capi_ctrl);
+	spin_unlock_irq(&cinfo->lock);
+}
+
+/***************************************************************
+hycapi_tx_capiget(hysdn_card *card)
+
+This is called when polling for messages to SEND.
+
+****************************************************************/
+
+struct sk_buff *
+hycapi_tx_capiget(hysdn_card *card)
+{
+	hycapictrl_info *cinfo = card->hyctrlinfo;
+	if(!cinfo) {
+		printk(KERN_ERR "HYSDN Card%d: no CAPI-controller! (3)\n",
+		       card->myid);
+		return (struct sk_buff *)NULL;
+	}
+	if (!cinfo->sk_count)
+		return (struct sk_buff *)NULL;	/* nothing available */
+
+	return (cinfo->skbs[cinfo->out_idx]);		/* next packet to send */
+}
+
+
+static struct capi_driver hycapi_driver = {
+	"hysdn",
+	"0.0",
+	hycapi_load_firmware, 
+	hycapi_reset_ctr,
+	hycapi_remove_ctr,
+	hycapi_register_appl,
+	hycapi_release_appl,
+	hycapi_send_message,
+	hycapi_procinfo,
+	hycapi_read_proc,
+	0,	/* use standard driver_read_proc */
+	0, /* no add_card function */
+};
+
+
+/**********************************************************
+int hycapi_init()
+
+attach the capi-driver to the kernel-capi.
+
+***********************************************************/
+
+int hycapi_init()
+{
+	struct capi_driver *driver;
+	int i;
+	if(hy_di) {
+		printk(KERN_NOTICE "HyDI allready set\n");
+		return 0;
+	}
+	driver = &hycapi_driver;
+	printk(KERN_NOTICE "HYSDN: Attaching capi-driver\n");
+	hy_di = attach_capi_driver(driver);
+	if (!hy_di) {
+		printk(KERN_ERR "HYCAPI: failed to attach capi_driver\n");
+		return(-1);
+	}
+	for(i=0;i<CAPI_MAXAPPL;i++) {
+		memset(&(hycapi_applications[i]), 0, sizeof(hycapi_appl));
+	}
+	return(0);
+}
+
+/**************************************************************
+hycapi_cleanup(void)
+
+detach the capi-driver to the kernel-capi. Actually this should
+free some more ressources. Do that later.
+**************************************************************/
+
+void 
+hycapi_cleanup(void)
+{
+	struct capi_driver *driver;
+	driver = &hycapi_driver;
+	if (!hy_di) {
+		printk(KERN_ERR "HYSDN: no capi-driver to detach (???)\n");
+		return;
+	}
+	printk(KERN_NOTICE "HYSDN: Detaching capi-driver\n");
+	detach_capi_driver(driver);
+	hy_di = 0;
+	return;
+}
+
+/********************************************************************
+hycapi_capi_create(hysdn_card *card)
+
+Attach the card with it's capi-ctrl.
+*********************************************************************/
+
+static void hycapi_fill_profile(hysdn_card *card)
+{
+	hycapictrl_info *cinfo = NULL;
+	struct capi_ctr *ctrl = NULL;
+	cinfo = card->hyctrlinfo;
+	if(!cinfo) return;
+	ctrl = cinfo->capi_ctrl;
+	if(!ctrl) return;
+	strcpy(ctrl->manu, "Hypercope");	
+	ctrl->version.majorversion = 2;
+	ctrl->version.minorversion = 0;
+	ctrl->version.majormanuversion = 3;
+	ctrl->version.minormanuversion = 2;
+	ctrl->profile.ncontroller = card->myid;
+	ctrl->profile.nbchannel = card->bchans;
+	ctrl->profile.goptions = GLOBAL_OPTION_INTERNAL_CONTROLLER |
+		GLOBAL_OPTION_B_CHANNEL_OPERATION;
+	ctrl->profile.support1 =  B1_PROT_64KBIT_HDLC |
+		(card->faxchans ? B1_PROT_T30 : 0) |
+		B1_PROT_64KBIT_TRANSPARENT;
+	ctrl->profile.support2 = B2_PROT_ISO7776 |
+		(card->faxchans ? B2_PROT_T30 : 0) |
+		B2_PROT_TRANSPARENT;
+	ctrl->profile.support3 = B3_PROT_TRANSPARENT |
+		B3_PROT_T90NL |
+		(card->faxchans ? B3_PROT_T30 : 0) |
+		(card->faxchans ? B3_PROT_T30EXT : 0) |
+		B3_PROT_ISO8208;
+}	
+
+int 
+hycapi_capi_create(hysdn_card *card)
+{
+	hycapictrl_info *cinfo = NULL;
+	struct capi_ctr *ctrl = NULL;
+#ifdef HYCAPI_PRINTFNAMES
+	printk(KERN_NOTICE "hycapi_capi_create\n");        
+#endif
+	if (!card->hyctrlinfo) {
+		cinfo = (hycapictrl_info *) kmalloc(sizeof(hycapictrl_info), GFP_ATOMIC);
+		if (!cinfo) {
+			printk(KERN_WARNING "HYSDN: no memory for capi-ctrl.\n");
+			return -ENOMEM;
+		}
+		memset(cinfo, 0, sizeof(hycapictrl_info));
+		card->hyctrlinfo = cinfo;
+		cinfo->card = card;
+		spin_lock_init(&cinfo->lock);
+
+		switch (card->brdtype) {
+			case BD_PCCARD:  strcpy(cinfo->cardname,"HYSDN Hycard"); break;
+			case BD_ERGO: strcpy(cinfo->cardname,"HYSDN Ergo2"); break;
+			case BD_METRO: strcpy(cinfo->cardname,"HYSDN Metro4"); break;
+			case BD_CHAMP2: strcpy(cinfo->cardname,"HYSDN Champ2"); break;
+			case BD_PLEXUS: strcpy(cinfo->cardname,"HYSDN Plexus30"); break;
+			default: strcpy(cinfo->cardname,"HYSDN ???"); break;
+		}
+
+		cinfo->capi_ctrl = hy_di->attach_ctr(&hycapi_driver, 
+						     cinfo->cardname, cinfo);
+		ctrl = cinfo->capi_ctrl;
+		if (!ctrl) {
+			printk(KERN_ERR "%s: attach controller failed.\n",
+			       hycapi_driver.name);
+			return -EBUSY;
+		}
+		/* fill in the blanks: */
+		hycapi_fill_profile(card);
+		ctrl->ready(ctrl);
+	} else {
+		/* resume output on stopped ctrl */
+		ctrl = card->hyctrlinfo->capi_ctrl;
+		if(ctrl) {
+			hycapi_fill_profile(card);
+			ctrl->ready(ctrl);
+			hycapi_restart_internal(ctrl); 
+/*			ctrl->resume_output(ctrl); */
+		} else {
+			printk(KERN_WARNING "HYSDN: No ctrl???? How come?\n");
+		}
+	}
+	return 0;
+}
diff -urN linux-2.2.19-pre10/drivers/isdn/hysdn/hysdn_boot.c linux/drivers/isdn/hysdn/hysdn_boot.c
--- linux-2.2.19-pre10/drivers/isdn/hysdn/hysdn_boot.c	Wed Dec 31 16:00:00 1969
+++ linux/drivers/isdn/hysdn/hysdn_boot.c	Mon Dec  3 21:03:00 2001
@@ -0,0 +1,413 @@
+/* $Id: hysdn_boot.c,v 1.4.6.1 2001/02/10 14:41:22 kai Exp $
+
+ * Linux driver for HYSDN cards, specific routines for booting and pof handling.
+ *
+ * written by Werner Cornelius (werner@titro.de) for Hypercope GmbH
+ *
+ * Copyright 1999  by Werner Cornelius (werner@titro.de)
+ *
+ * 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; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+#define __NO_VERSION__
+#include <linux/module.h>
+#include <linux/version.h>
+#include <linux/vmalloc.h>
+#include <linux/slab.h>
+#include <asm/uaccess.h>
+
+#include "hysdn_defs.h"
+#include "hysdn_pof.h"
+
+/********************************/
+/* defines for pof read handler */
+/********************************/
+#define POF_READ_FILE_HEAD  0
+#define POF_READ_TAG_HEAD   1
+#define POF_READ_TAG_DATA   2
+
+/************************************************************/
+/* definition of boot specific data area. This data is only */
+/* needed during boot and so allocated dynamically.         */
+/************************************************************/
+struct boot_data {
+	word Cryptor;		/* for use with Decrypt function */
+	word Nrecs;		/* records remaining in file */
+	uchar pof_state;	/* actual state of read handler */
+	uchar is_crypted;	/* card data is crypted */
+	int BufSize;		/* actual number of bytes bufferd */
+	int last_error;		/* last occured error */
+	word pof_recid;		/* actual pof recid */
+	ulong pof_reclen;	/* total length of pof record data */
+	ulong pof_recoffset;	/* actual offset inside pof record */
+	union {
+		uchar BootBuf[BOOT_BUF_SIZE];	/* buffer as byte count */
+		tPofRecHdr PofRecHdr;	/* header for actual record/chunk */
+		tPofFileHdr PofFileHdr;		/* header from POF file */
+		tPofTimeStamp PofTime;	/* time information */
+	} buf;
+};
+
+/*****************************************************/
+/*  start decryption of sucessive POF file chuncks.  */
+/*                                                   */
+/*  to be called at start of POF file reading,       */
+/*  before starting any decryption on any POF record. */
+/*****************************************************/
+void
+StartDecryption(struct boot_data *boot)
+{
+	boot->Cryptor = CRYPT_STARTTERM;
+}				/* StartDecryption */
+
+
+/***************************************************************/
+/* decrypt complete BootBuf                                    */
+/* NOTE: decryption must be applied to all or none boot tags - */
+/*       to HI and LO boot loader and (all) seq tags, because  */
+/*       global Cryptor is started for whole POF.              */
+/***************************************************************/
+void
+DecryptBuf(struct boot_data *boot, int cnt)
+{
+	uchar *bufp = boot->buf.BootBuf;
+
+	while (cnt--) {
+		boot->Cryptor = (boot->Cryptor >> 1) ^ ((boot->Cryptor & 1U) ? CRYPT_FEEDTERM : 0);
+		*bufp++ ^= (uchar) boot->Cryptor;
+	}
+}				/* DecryptBuf */
+
+/********************************************************************************/
+/* pof_handle_data executes the required actions dependant on the active record */
+/* id. If successfull 0 is returned, a negative value shows an error.           */
+/********************************************************************************/
+static int
+pof_handle_data(hysdn_card * card, int datlen)
+{
+	struct boot_data *boot = card->boot;	/* pointer to boot specific data */
+	long l;
+	uchar *imgp;
+	int img_len;
+
+	/* handle the different record types */
+	switch (boot->pof_recid) {
+
+		case TAG_TIMESTMP:
+			if (card->debug_flags & LOG_POF_RECORD)
+				hysdn_addlog(card, "POF created %s", boot->buf.PofTime.DateTimeText);
+			break;
+
+		case TAG_CBOOTDTA:
+			DecryptBuf(boot, datlen);	/* we need to encrypt the buffer */
+		case TAG_BOOTDTA:
+			if (card->debug_flags & LOG_POF_RECORD)
+				hysdn_addlog(card, "POF got %s len=%d offs=0x%lx",
+					     (boot->pof_recid == TAG_CBOOTDTA) ? "CBOOTDATA" : "BOOTDTA",
+					     datlen, boot->pof_recoffset);
+
+			if (boot->pof_reclen != POF_BOOT_LOADER_TOTAL_SIZE) {
+				boot->last_error = EPOF_BAD_IMG_SIZE;	/* invalid length */
+				return (boot->last_error);
+			}
+			imgp = boot->buf.BootBuf;	/* start of buffer */
+			img_len = datlen;	/* maximum length to transfer */
+
+			l = POF_BOOT_LOADER_OFF_IN_PAGE -
+			    (boot->pof_recoffset & (POF_BOOT_LOADER_PAGE_SIZE - 1));
+			if (l > 0) {
+				/* buffer needs to be truncated */
+				imgp += l;	/* advance pointer */
+				img_len -= l;	/* adjust len */
+			}
+			/* at this point no special handling for data wrapping over buffer */
+			/* is necessary, because the boot image always will be adjusted to */
+			/* match a page boundary inside the buffer.                        */
+			/* The buffer for the boot image on the card is filled in 2 cycles */
+			/* first the 1024 hi-words are put in the buffer, then the low 1024 */
+			/* word are handled in the same way with different offset.         */
+
+			if (img_len > 0) {
+				/* data available for copy */
+				if ((boot->last_error =
+				     card->writebootimg(card, imgp,
+							(boot->pof_recoffset > POF_BOOT_LOADER_PAGE_SIZE) ? 2 : 0)) < 0)
+					return (boot->last_error);
+			}
+			break;	/* end of case boot image hi/lo */
+
+		case TAG_CABSDATA:
+			DecryptBuf(boot, datlen);	/* we need to encrypt the buffer */
+		case TAG_ABSDATA:
+			if (card->debug_flags & LOG_POF_RECORD)
+				hysdn_addlog(card, "POF got %s len=%d offs=0x%lx",
+					     (boot->pof_recid == TAG_CABSDATA) ? "CABSDATA" : "ABSDATA",
+					     datlen, boot->pof_recoffset);
+
+			if ((boot->last_error = card->writebootseq(card, boot->buf.BootBuf, datlen) < 0))
+				return (boot->last_error);	/* error writing data */
+
+			if (boot->pof_recoffset + datlen >= boot->pof_reclen)
+				return (card->waitpofready(card));	/* data completely spooled, wait for ready */
+
+			break;	/* end of case boot seq data */
+
+		default:
+			if (card->debug_flags & LOG_POF_RECORD)
+				hysdn_addlog(card, "POF got data(id=0x%lx) len=%d offs=0x%lx", boot->pof_recid,
+					     datlen, boot->pof_recoffset);
+
+			break;	/* simply skip record */
+	}			/* switch boot->pof_recid */
+
+	return (0);
+}				/* pof_handle_data */
+
+
+/******************************************************************************/
+/* pof_write_buffer is called when the buffer has been filled with the needed */
+/* number of data bytes. The number delivered is additionally supplied for    */
+/* verification. The functions handles the data and returns the needed number */
+/* of bytes for the next action. If the returned value is 0 or less an error  */
+/* occured and booting must be aborted.                                       */
+/******************************************************************************/
+int
+pof_write_buffer(hysdn_card * card, int datlen)
+{
+	struct boot_data *boot = card->boot;	/* pointer to boot specific data */
+
+	if (!boot)
+		return (-EFAULT);	/* invalid call */
+	if (boot->last_error < 0)
+		return (boot->last_error);	/* repeated error */
+
+	if (card->debug_flags & LOG_POF_WRITE)
+		hysdn_addlog(card, "POF write: got %d bytes ", datlen);
+
+	switch (boot->pof_state) {
+		case POF_READ_FILE_HEAD:
+			if (card->debug_flags & LOG_POF_WRITE)
+				hysdn_addlog(card, "POF write: checking file header");
+
+			if (datlen != sizeof(tPofFileHdr)) {
+				boot->last_error = -EPOF_INTERNAL;
+				break;
+			}
+			if (boot->buf.PofFileHdr.Magic != TAGFILEMAGIC) {
+				boot->last_error = -EPOF_BAD_MAGIC;
+				break;
+			}
+			/* Setup the new state and vars */
+			boot->Nrecs = (word) (boot->buf.PofFileHdr.N_PofRecs);	/* limited to 65535 */
+			boot->pof_state = POF_READ_TAG_HEAD;	/* now start with single tags */
+			boot->last_error = sizeof(tPofRecHdr);	/* new length */
+			break;
+
+		case POF_READ_TAG_HEAD:
+			if (card->debug_flags & LOG_POF_WRITE)
+				hysdn_addlog(card, "POF write: checking tag header");
+
+			if (datlen != sizeof(tPofRecHdr)) {
+				boot->last_error = -EPOF_INTERNAL;
+				break;
+			}
+			boot->pof_recid = boot->buf.PofRecHdr.PofRecId;		/* actual pof recid */
+			boot->pof_reclen = boot->buf.PofRecHdr.PofRecDataLen;	/* total length */
+			boot->pof_recoffset = 0;	/* no starting offset */
+
+			if (card->debug_flags & LOG_POF_RECORD)
+				hysdn_addlog(card, "POF: got record id=0x%lx length=%ld ",
+				      boot->pof_recid, boot->pof_reclen);
+
+			boot->pof_state = POF_READ_TAG_DATA;	/* now start with tag data */
+			if (boot->pof_reclen < BOOT_BUF_SIZE)
+				boot->last_error = boot->pof_reclen;	/* limit size */
+			else
+				boot->last_error = BOOT_BUF_SIZE;	/* maximum */
+
+			if (!boot->last_error) {	/* no data inside record */
+				boot->pof_state = POF_READ_TAG_HEAD;	/* now start with single tags */
+				boot->last_error = sizeof(tPofRecHdr);	/* new length */
+			}
+			break;
+
+		case POF_READ_TAG_DATA:
+			if (card->debug_flags & LOG_POF_WRITE)
+				hysdn_addlog(card, "POF write: getting tag data");
+
+			if (datlen != boot->last_error) {
+				boot->last_error = -EPOF_INTERNAL;
+				break;
+			}
+			if ((boot->last_error = pof_handle_data(card, datlen)) < 0)
+				return (boot->last_error);	/* an error occured */
+			boot->pof_recoffset += datlen;
+			if (boot->pof_recoffset >= boot->pof_reclen) {
+				boot->pof_state = POF_READ_TAG_HEAD;	/* now start with single tags */
+				boot->last_error = sizeof(tPofRecHdr);	/* new length */
+			} else {
+				if (boot->pof_reclen - boot->pof_recoffset < BOOT_BUF_SIZE)
+					boot->last_error = boot->pof_reclen - boot->pof_recoffset;	/* limit size */
+				else
+					boot->last_error = BOOT_BUF_SIZE;	/* maximum */
+			}
+			break;
+
+		default:
+			boot->last_error = -EPOF_INTERNAL;	/* unknown state */
+			break;
+	}			/* switch (boot->pof_state) */
+
+	return (boot->last_error);
+}				/* pof_write_buffer */
+
+
+/*******************************************************************************/
+/* pof_write_open is called when an open for boot on the cardlog device occurs. */
+/* The function returns the needed number of bytes for the next operation. If  */
+/* the returned number is less or equal 0 an error specified by this code      */
+/* occurred. Additionally the pointer to the buffer data area is set on success */
+/*******************************************************************************/
+int
+pof_write_open(hysdn_card * card, uchar ** bufp)
+{
+	struct boot_data *boot;	/* pointer to boot specific data */
+
+	if (card->boot) {
+		if (card->debug_flags & LOG_POF_OPEN)
+			hysdn_addlog(card, "POF open: already opened for boot");
+		return (-ERR_ALREADY_BOOT);	/* boot already active */
+	}
+	/* error no mem available */
+	if (!(boot = kmalloc(sizeof(struct boot_data), GFP_KERNEL))) {
+		if (card->debug_flags & LOG_MEM_ERR)
+			hysdn_addlog(card, "POF open: unable to allocate mem");
+		return (-EFAULT);
+	}
+	card->boot = boot;
+	card->state = CARD_STATE_BOOTING;
+	memset(boot, 0, sizeof(struct boot_data));
+
+	card->stopcard(card);	/* first stop the card */
+	if (card->testram(card)) {
+		if (card->debug_flags & LOG_POF_OPEN)
+			hysdn_addlog(card, "POF open: DPRAM test failure");
+		boot->last_error = -ERR_BOARD_DPRAM;
+		card->state = CARD_STATE_BOOTERR;	/* show boot error */
+		return (boot->last_error);
+	}
+	boot->BufSize = 0;	/* Buffer is empty */
+	boot->pof_state = POF_READ_FILE_HEAD;	/* read file header */
+	StartDecryption(boot);	/* if POF File should be encrypted */
+
+	if (card->debug_flags & LOG_POF_OPEN)
+		hysdn_addlog(card, "POF open: success");
+
+	*bufp = boot->buf.BootBuf;	/* point to buffer */
+	return (sizeof(tPofFileHdr));
+}				/* pof_write_open */
+
+/********************************************************************************/
+/* pof_write_close is called when an close of boot on the cardlog device occurs. */
+/* The return value must be 0 if everything has happened as desired.            */
+/********************************************************************************/
+int
+pof_write_close(hysdn_card * card)
+{
+	struct boot_data *boot = card->boot;	/* pointer to boot specific data */
+
+	if (!boot)
+		return (-EFAULT);	/* invalid call */
+
+	card->boot = NULL;	/* no boot active */
+	kfree(boot);
+
+	if (card->state == CARD_STATE_RUN)
+		card->set_errlog_state(card, 1);	/* activate error log */
+
+	if (card->debug_flags & LOG_POF_OPEN)
+		hysdn_addlog(card, "POF close: success");
+
+	return (0);
+}				/* pof_write_close */
+
+/*********************************************************************************/
+/* EvalSysrTokData checks additional records delivered with the Sysready Message */
+/* when POF has been booted. A return value of 0 is used if no error occured.    */
+/*********************************************************************************/
+int
+EvalSysrTokData(hysdn_card * card, uchar * cp, int len)
+{
+	u_char *p;
+	u_char crc;
+
+	if (card->debug_flags & LOG_POF_RECORD)
+		hysdn_addlog(card, "SysReady Token data length %d", len);
+
+	if (len < 2) {
+		hysdn_addlog(card, "SysReady Token Data to short");
+		return (1);
+	}
+	for (p = cp, crc = 0; p < (cp + len - 2); p++)
+		if ((crc & 0x80))
+			crc = (((u_char) (crc << 1)) + 1) + *p;
+		else
+			crc = ((u_char) (crc << 1)) + *p;
+	crc = ~crc;
+	if (crc != *(cp + len - 1)) {
+		hysdn_addlog(card, "SysReady Token Data invalid CRC");
+		return (1);
+	}
+	len--;			/* dont check CRC byte */
+	while (len > 0) {
+
+		if (*cp == SYSR_TOK_END)
+			return (0);	/* End of Token stream */
+
+		if (len < (*(cp + 1) + 2)) {
+			hysdn_addlog(card, "token 0x%x invalid length %d", *cp, *(cp + 1));
+			return (1);
+		}
+		switch (*cp) {
+			case SYSR_TOK_B_CHAN:	/* 1 */
+				if (*(cp + 1) != 1)
+					return (1);	/* length invalid */
+				card->bchans = *(cp + 2);
+				break;
+
+			case SYSR_TOK_FAX_CHAN:	/* 2 */
+				if (*(cp + 1) != 1)
+					return (1);	/* length invalid */
+				card->faxchans = *(cp + 2);
+				break;
+
+			case SYSR_TOK_MAC_ADDR:	/* 3 */
+				if (*(cp + 1) != 6)
+					return (1);	/* length invalid */
+				memcpy(card->mac_addr, cp + 2, 6);
+				break;
+
+			default:
+				hysdn_addlog(card, "unknown token 0x%02x length %d", *cp, *(cp + 1));
+				break;
+		}
+		len -= (*(cp + 1) + 2);		/* adjust len */
+		cp += (*(cp + 1) + 2);	/* and pointer */
+	}
+
+	hysdn_addlog(card, "no end token found");
+	return (1);
+}				/* EvalSysrTokData */
diff -urN linux-2.2.19-pre10/drivers/isdn/hysdn/hysdn_defs.h linux/drivers/isdn/hysdn/hysdn_defs.h
--- linux-2.2.19-pre10/drivers/isdn/hysdn/hysdn_defs.h	Wed Dec 31 16:00:00 1969
+++ linux/drivers/isdn/hysdn/hysdn_defs.h	Mon Dec  3 21:03:00 2001
@@ -0,0 +1,307 @@
+/* $Id: hysdn_defs.h,v 1.5.6.1 2000/11/28 12:02:47 kai Exp $
+
+ * Linux driver for HYSDN cards, global definitions and exported vars and functions.
+ * written by Werner Cornelius (werner@titro.de) for Hypercope GmbH
+ *
+ * Copyright 1999  by Werner Cornelius (werner@titro.de)
+ *
+ * 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; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+#ifndef HYSDN_DEFS_H
+#define HYSDN_DEFS_H
+
+#include <linux/config.h>
+#include <linux/hysdn_if.h>
+#include <linux/interrupt.h>
+#include <linux/tqueue.h>
+#include <linux/skbuff.h>
+#include <linux/isdn_compat.h>
+
+/****************************/
+/* storage type definitions */
+/****************************/
+#define uchar unsigned char
+#define uint unsigned int
+#define ulong unsigned long
+#define word unsigned short
+
+#include "ince1pc.h"
+
+#ifdef CONFIG_HYSDN_CAPI
+#include <linux/capi.h>
+#include "../avmb1/capicmd.h"
+#include "../avmb1/capiutil.h"
+#include "../avmb1/capilli.h"
+
+/***************************/
+/*   CAPI-Profile values.  */
+/***************************/
+
+#define GLOBAL_OPTION_INTERNAL_CONTROLLER 0x0001
+#define GLOBAL_OPTION_EXTERNAL_CONTROLLER 0x0002
+#define GLOBAL_OPTION_HANDSET             0x0004
+#define GLOBAL_OPTION_DTMF                0x0008
+#define GLOBAL_OPTION_SUPPL_SERVICES      0x0010
+#define GLOBAL_OPTION_CHANNEL_ALLOCATION  0x0020
+#define GLOBAL_OPTION_B_CHANNEL_OPERATION 0x0040
+
+#define B1_PROT_64KBIT_HDLC        0x0001
+#define B1_PROT_64KBIT_TRANSPARENT 0x0002
+#define B1_PROT_V110_ASYNCH        0x0004 
+#define B1_PROT_V110_SYNCH         0x0008
+#define B1_PROT_T30                0x0010
+#define B1_PROT_64KBIT_INV_HDLC    0x0020
+#define B1_PROT_56KBIT_TRANSPARENT 0x0040
+
+#define B2_PROT_ISO7776            0x0001
+#define B2_PROT_TRANSPARENT        0x0002
+#define B2_PROT_SDLC               0x0004
+#define B2_PROT_LAPD               0x0008
+#define B2_PROT_T30                0x0010
+#define B2_PROT_PPP                0x0020
+#define B2_PROT_TRANSPARENT_IGNORE_B1_FRAMING_ERRORS 0x0040
+
+#define B3_PROT_TRANSPARENT        0x0001
+#define B3_PROT_T90NL              0x0002
+#define B3_PROT_ISO8208            0x0004
+#define B3_PROT_X25_DCE            0x0008
+#define B3_PROT_T30                0x0010
+#define B3_PROT_T30EXT             0x0020
+
+#define HYSDN_MAXVERSION		8
+
+/* Number of sendbuffers in CAPI-queue */
+#define HYSDN_MAX_CAPI_SKB             20
+
+#endif /* CONFIG_HYSDN_CAPI*/
+
+/************************************************/
+/* constants and bits for debugging/log outputs */
+/************************************************/
+#define LOG_MAX_LINELEN 120
+#define DEB_OUT_SYSLOG  0x80000000	/* output to syslog instead of proc fs */
+#define LOG_MEM_ERR     0x00000001	/* log memory errors like kmalloc failure */
+#define LOG_POF_OPEN    0x00000010	/* log pof open and close activities */
+#define LOG_POF_RECORD  0x00000020	/* log pof record parser */
+#define LOG_POF_WRITE   0x00000040	/* log detailed pof write operation */
+#define LOG_POF_CARD    0x00000080	/* log pof related card functions */
+#define LOG_CNF_LINE    0x00000100	/* all conf lines are put to procfs */
+#define LOG_CNF_DATA    0x00000200	/* non comment conf lines are shown with channel */
+#define LOG_CNF_MISC    0x00000400	/* additional conf line debug outputs */
+#define LOG_SCHED_ASYN  0x00001000	/* debug schedulers async tx routines */
+#define LOG_PROC_OPEN   0x00100000	/* open and close from procfs are logged */
+#define LOG_PROC_ALL    0x00200000	/* all actions from procfs are logged */
+#define LOG_NET_INIT    0x00010000	/* network init and deinit logging */
+
+#define DEF_DEB_FLAGS   0x7fff000f	/* everything is logged to procfs */
+
+/**********************************/
+/* proc filesystem name constants */
+/**********************************/
+#define PROC_SUBDIR_NAME "hysdn"
+#define PROC_CONF_BASENAME "cardconf"
+#define PROC_LOG_BASENAME "cardlog"
+
+/***********************************/
+/* PCI 32 bit parms for IO and MEM */
+/***********************************/
+#define PCI_REG_PLX_MEM_BASE    0
+#define PCI_REG_PLX_IO_BASE     1
+#define PCI_REG_MEMORY_BASE     3
+
+/**************/
+/* card types */
+/**************/
+#define BD_NONE         0U
+#define BD_PERFORMANCE  1U
+#define BD_VALUE        2U
+#define BD_PCCARD       3U
+#define BD_ERGO         4U
+#define BD_METRO        5U
+#define BD_CHAMP2       6U
+#define BD_PLEXUS       7U
+
+/******************************************************/
+/* defined states for cards shown by reading cardconf */
+/******************************************************/
+#define CARD_STATE_UNUSED   0	/* never been used or booted */
+#define CARD_STATE_BOOTING  1	/* booting is in progress */
+#define CARD_STATE_BOOTERR  2	/* a previous boot was aborted */
+#define CARD_STATE_RUN      3	/* card is active */
+
+/*******************************/
+/* defines for error_log_state */
+/*******************************/
+#define ERRLOG_STATE_OFF   0	/* error log is switched off, nothing to do */
+#define ERRLOG_STATE_ON    1	/* error log is switched on, wait for data */
+#define ERRLOG_STATE_START 2	/* start error logging */
+#define ERRLOG_STATE_STOP  3	/* stop error logging */
+
+/*******************************/
+/* data structure for one card */
+/*******************************/
+typedef struct HYSDN_CARD {
+
+	/* general variables for the cards */
+	int myid;		/* own driver card id */
+	uchar bus;		/* pci bus the card is connected to */
+	uchar devfn;		/* slot+function bit encoded */
+	word subsysid;		/* PCI subsystem id */
+	uchar brdtype;		/* type of card */
+	uint bchans;		/* number of available B-channels */
+	uint faxchans;		/* number of available fax-channels */
+	uchar mac_addr[6];	/* MAC Address read from card */
+	uint irq;		/* interrupt number */
+	uint iobase;		/* IO-port base address */
+	ulong plxbase;		/* PLX memory base */
+	ulong membase;		/* DPRAM memory base */
+	ulong memend;		/* DPRAM memory end */
+	void *dpram;		/* mapped dpram */
+	int state;		/* actual state of card -> CARD_STATE_** */
+	struct HYSDN_CARD *next;	/* pointer to next card */
+
+	/* data areas for the /proc file system */
+	void *proclog;		/* pointer to proclog filesystem specific data */
+	void *procconf;		/* pointer to procconf filesystem specific data */
+
+	/* debugging and logging */
+	uchar err_log_state;	/* actual error log state of the card */
+	ulong debug_flags;	/* tells what should be debugged and where */
+	void (*set_errlog_state) (struct HYSDN_CARD *, int);
+
+	/* interrupt handler + interrupt synchronisation */
+	struct tq_struct irq_queue;	/* interrupt task queue */
+	uchar volatile irq_enabled;	/* interrupt enabled if != 0 */
+	uchar volatile hw_lock;	/* hardware is currently locked -> no access */
+
+	/* boot process */
+	void *boot;		/* pointer to boot private data */
+	int (*writebootimg) (struct HYSDN_CARD *, uchar *, ulong);
+	int (*writebootseq) (struct HYSDN_CARD *, uchar *, int);
+	int (*waitpofready) (struct HYSDN_CARD *);
+	int (*testram) (struct HYSDN_CARD *);
+
+	/* scheduler for data transfer (only async parts) */
+	uchar async_data[256];	/* async data to be sent (normally for config) */
+	word volatile async_len;	/* length of data to sent */
+	word volatile async_channel;	/* channel number for async transfer */
+	int volatile async_busy;	/* flag != 0 sending in progress */
+	int volatile net_tx_busy;	/* a network packet tx is in progress */
+
+	/* network interface */
+	void *netif;		/* pointer to network structure */
+
+	/* init and deinit stopcard for booting, too */
+	void (*stopcard) (struct HYSDN_CARD *);
+	void (*releasehardware) (struct HYSDN_CARD *);
+#ifdef CONFIG_HYSDN_CAPI
+	struct hycapictrl_info {
+		char cardname[32];
+		spinlock_t lock;
+		int versionlen;
+		char versionbuf[1024];
+		char *version[HYSDN_MAXVERSION];
+
+		char infobuf[128];	/* for function procinfo */
+		
+		struct HYSDN_CARD  *card;
+		struct capi_ctr *capi_ctrl;
+		struct sk_buff *skbs[HYSDN_MAX_CAPI_SKB];
+		int in_idx, out_idx;	/* indexes to buffer ring */
+		int sk_count;		/* number of buffers currently in ring */
+		struct sk_buff *tx_skb;	/* buffer for tx operation */
+	} *hyctrlinfo;
+#endif /* CONFIG_HYSDN_CAPI */
+} hysdn_card;
+
+#ifdef CONFIG_HYSDN_CAPI
+typedef struct hycapictrl_info hycapictrl_info;
+#endif /* CONFIG_HYSDN_CAPI */
+
+
+/*****************/
+/* exported vars */
+/*****************/
+extern int cardmax;		/* number of found cards */
+extern hysdn_card *card_root;	/* pointer to first card */
+
+
+
+/*************************/
+/* im/exported functions */
+/*************************/
+extern int printk(const char *fmt,...);
+extern char *hysdn_getrev(const char *);
+
+/* hysdn_procconf.c */
+extern int hysdn_procconf_init(void);	/* init proc config filesys */
+extern void hysdn_procconf_release(void);	/* deinit proc config filesys */
+
+/* hysdn_proclog.c */
+extern int hysdn_proclog_init(hysdn_card *);	/* init proc log entry */
+extern void hysdn_proclog_release(hysdn_card *);	/* deinit proc log entry */
+extern void put_log_buffer(hysdn_card *, char *);	/* output log data */
+extern void hysdn_addlog(hysdn_card *, char *,...);	/* output data to log */
+extern void hysdn_card_errlog(hysdn_card *, tErrLogEntry *, int);	/* output card log */
+
+/* boardergo.c */
+extern int ergo_inithardware(hysdn_card * card);	/* get hardware -> module init */
+
+/* hysdn_boot.c */
+extern int pof_write_close(hysdn_card *);	/* close proc file after writing pof */
+extern int pof_write_open(hysdn_card *, uchar **);	/* open proc file for writing pof */
+extern int pof_write_buffer(hysdn_card *, int);		/* write boot data to card */
+extern int EvalSysrTokData(hysdn_card *, uchar *, int);		/* Check Sysready Token Data */
+
+/* hysdn_sched.c */
+extern int hysdn_sched_tx(hysdn_card *, uchar *, word volatile *, word volatile *,
+			  word);
+extern int hysdn_sched_rx(hysdn_card *, uchar *, word, word);
+extern int hysdn_tx_cfgline(hysdn_card *, uchar *, word);	/* send one cfg line */
+
+/* hysdn_net.c */
+extern char *hysdn_net_revision;
+extern int hysdn_net_create(hysdn_card *);	/* create a new net device */
+extern int hysdn_net_release(hysdn_card *);	/* delete the device */
+extern char *hysdn_net_getname(hysdn_card *);	/* get name of net interface */
+extern void hysdn_tx_netack(hysdn_card *);	/* acknowledge a packet tx */
+extern struct sk_buff *hysdn_tx_netget(hysdn_card *);	/* get next network packet */
+extern void hysdn_rx_netpkt(hysdn_card *, uchar *, word);	/* rxed packet from network */
+
+#ifdef CONFIG_HYSDN_CAPI
+extern struct capi_driver_interface *hy_di;
+extern int hycapi_capi_create(hysdn_card *);	/* create a new capi device */
+extern int hycapi_capi_release(hysdn_card *);	/* delete the device */
+extern int hycapi_capi_stop(hysdn_card *card);   /* suspend */
+extern int hycapi_load_firmware(struct capi_ctr *, capiloaddata *);
+extern void hycapi_reset_ctr(struct capi_ctr *);
+extern void hycapi_remove_ctr(struct capi_ctr *);
+extern void hycapi_register_appl(struct capi_ctr *, __u16 appl,
+				 capi_register_params *);
+extern void hycapi_release_appl(struct capi_ctr *, __u16 appl);
+extern void hycapi_send_message(struct capi_ctr *, struct sk_buff *skb);
+extern char *hycapi_procinfo(struct capi_ctr *);
+extern int hycapi_read_proc(char *page, char **start, off_t off,
+			    int count, int *eof, struct capi_ctr *card);
+extern void hycapi_rx_capipkt(hysdn_card * card, uchar * buf, word len);
+extern void hycapi_tx_capiack(hysdn_card * card);
+extern struct sk_buff *hycapi_tx_capiget(hysdn_card *card);
+extern int hycapi_init(void);
+extern void hycapi_cleanup(void);
+#endif /* CONFIG_HYSDN_CAPI */
+
+#endif /* HYSDN_DEFS_H */
diff -urN linux-2.2.19-pre10/drivers/isdn/hysdn/hysdn_init.c linux/drivers/isdn/hysdn/hysdn_init.c
--- linux-2.2.19-pre10/drivers/isdn/hysdn/hysdn_init.c	Wed Dec 31 16:00:00 1969
+++ linux/drivers/isdn/hysdn/hysdn_init.c	Mon Dec  3 21:03:00 2001
@@ -0,0 +1,257 @@
+/* $Id: hysdn_init.c,v 1.6.6.4 2001/02/10 14:41:22 kai Exp $
+
+ * Linux driver for HYSDN cards, init functions.
+ * written by Werner Cornelius (werner@titro.de) for Hypercope GmbH
+ *
+ * Copyright 1999  by Werner Cornelius (werner@titro.de)
+ *
+ * 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; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/version.h>
+#include <linux/poll.h>
+#include <linux/vmalloc.h>
+#include <linux/slab.h>
+#include <linux/pci.h>
+
+#include "hysdn_defs.h"
+
+static char *hysdn_init_revision = "$Revision: 1.6.6.4 $";
+int cardmax;			/* number of found cards */
+hysdn_card *card_root = NULL;	/* pointer to first card */
+
+/**********************************************/
+/* table assigning PCI-sub ids to board types */
+/* the last entry contains all 0              */
+/**********************************************/
+static struct {
+	word subid;		/* PCI sub id */
+	uchar cardtyp;		/* card type assigned */
+} pci_subid_map[] = {
+
+	{
+		PCI_SUBDEVICE_ID_HYPERCOPE_METRO, BD_METRO
+	},
+	{
+		PCI_SUBDEVICE_ID_HYPERCOPE_CHAMP2, BD_CHAMP2
+	},
+	{
+		PCI_SUBDEVICE_ID_HYPERCOPE_ERGO, BD_ERGO
+	},
+	{
+		PCI_SUBDEVICE_ID_HYPERCOPE_OLD_ERGO, BD_ERGO
+	},
+	{
+		0, 0
+	}			/* terminating entry */
+};
+
+
+/*********************************************************************/
+/* search_cards searches for available cards in the pci config data. */
+/* If a card is found, the card structure is allocated and the cards */
+/* ressources are reserved. cardmax is incremented.                  */
+/*********************************************************************/
+static void
+search_cards(void)
+{
+	struct pci_dev *akt_pcidev = NULL;
+	hysdn_card *card, *card_last;
+	int i;
+
+	card_root = NULL;
+	card_last = NULL;
+	while ((akt_pcidev = pci_find_device(PCI_VENDOR_ID_HYPERCOPE, PCI_DEVICE_ID_HYPERCOPE_PLX,
+					     akt_pcidev)) != NULL) {
+		if (pci_enable_device(akt_pcidev))
+			continue;
+
+		if (!(card = kmalloc(sizeof(hysdn_card), GFP_KERNEL))) {
+			printk(KERN_ERR "HYSDN: unable to alloc device mem \n");
+			return;
+		}
+		memset(card, 0, sizeof(hysdn_card));
+		card->myid = cardmax;	/* set own id */
+		card->bus = akt_pcidev->bus->number;
+		card->devfn = akt_pcidev->devfn;	/* slot + function */
+		pci_read_config_word(akt_pcidev, PCI_SUBSYSTEM_ID, &card->subsysid);
+		card->irq = akt_pcidev->irq;
+		card->iobase = akt_pcidev->base_address[ PCI_REG_PLX_IO_BASE] & PCI_BASE_ADDRESS_IO_MASK;
+		card->plxbase = akt_pcidev->base_address[ PCI_REG_PLX_MEM_BASE] & PCI_BASE_ADDRESS_MEM_MASK;
+		card->membase = akt_pcidev->base_address[ PCI_REG_MEMORY_BASE] & PCI_BASE_ADDRESS_MEM_MASK;
+		card->brdtype = BD_NONE;	/* unknown */
+		card->debug_flags = DEF_DEB_FLAGS;	/* set default debug */
+		card->faxchans = 0;	/* default no fax channels */
+		card->bchans = 2;	/* and 2 b-channels */
+		for (i = 0; pci_subid_map[i].subid; i++)
+			if (pci_subid_map[i].subid == card->subsysid) {
+				card->brdtype = pci_subid_map[i].cardtyp;
+				break;
+			}
+		if (card->brdtype != BD_NONE) {
+			if (ergo_inithardware(card)) {
+				printk(KERN_WARNING "HYSDN: card at io 0x%04x already in use\n", card->iobase);
+				kfree(card);
+				continue;
+			}
+		} else {
+			printk(KERN_WARNING "HYSDN: unknown card id 0x%04x\n", card->subsysid);
+			kfree(card);	/* release mem */
+			continue;
+		}
+		cardmax++;
+		card->next = NULL;	/*end of chain */
+		if (card_last)
+			card_last->next = card;		/* pointer to next card */
+		else
+			card_root = card;
+		card_last = card;	/* new chain end */
+	}			/* device found */
+}				/* search_cards */
+
+/************************************************************************************/
+/* free_resources frees the acquired PCI resources and returns the allocated memory */
+/************************************************************************************/
+static void
+free_resources(void)
+{
+	hysdn_card *card;
+
+	while (card_root) {
+		card = card_root;
+		if (card->releasehardware)
+			card->releasehardware(card);	/* free all hardware resources */
+		card_root = card_root->next;	/* remove card from chain */
+		kfree(card);	/* return mem */
+
+	}			/* while card_root */
+}				/* free_resources */
+
+/**************************************************************************/
+/* stop_cards disables (hardware resets) all cards and disables interrupt */
+/**************************************************************************/
+static void
+stop_cards(void)
+{
+	hysdn_card *card;
+
+	card = card_root;	/* first in chain */
+	while (card) {
+		if (card->stopcard)
+			card->stopcard(card);
+		card = card->next;	/* remove card from chain */
+	}			/* while card */
+}				/* stop_cards */
+
+
+/****************************************************************************/
+/* The module startup and shutdown code. Only compiled when used as module. */
+/* Using the driver as module is always advisable, because the booting      */
+/* image becomes smaller and the driver code is only loaded when needed.    */
+/* Additionally newer versions may be activated without rebooting.          */
+/****************************************************************************/
+
+/******************************************************/
+/* extract revision number from string for log output */
+/******************************************************/
+char *
+hysdn_getrev(const char *revision)
+{
+	char *rev;
+	char *p;
+
+	if ((p = strchr(revision, ':'))) {
+		rev = p + 2;
+		p = strchr(rev, '$');
+		*--p = 0;
+	} else
+		rev = "???";
+	return rev;
+}
+
+
+/****************************************************************************/
+/* init_module is called once when the module is loaded to do all necessary */
+/* things like autodetect...                                                */
+/* If the return value of this function is 0 the init has been successfull  */
+/* and the module is added to the list in /proc/modules, otherwise an error */
+/* is assumed and the module will not be kept in memory.                    */
+/****************************************************************************/
+static int __init
+hysdn_init(void)
+{
+	char tmp[50];
+
+	strcpy(tmp, hysdn_init_revision);
+	printk(KERN_NOTICE "HYSDN: module Rev: %s loaded\n", hysdn_getrev(tmp));
+	strcpy(tmp, hysdn_net_revision);
+	printk(KERN_NOTICE "HYSDN: network interface Rev: %s \n", hysdn_getrev(tmp));
+	if (!pci_present()) {
+		printk(KERN_ERR "HYSDN: no PCI bus present, module not loaded\n");
+		return (-1);
+	}
+	search_cards();
+	printk(KERN_INFO "HYSDN: %d card(s) found.\n", cardmax);
+
+	if (hysdn_procconf_init()) {
+		free_resources();	/* proc file_sys not created */
+		return (-1);
+	}
+#ifdef CONFIG_HYSDN_CAPI
+	if(cardmax > 0) {
+		if(hycapi_init()) {
+			printk(KERN_ERR "HYCAPI: init failed\n");
+			return(-1);
+		}
+	}
+#endif /* CONFIG_HYSDN_CAPI */
+	return (0);		/* no error */
+}				/* init_module */
+
+
+/***********************************************************************/
+/* cleanup_module is called when the module is released by the kernel. */
+/* The routine is only called if init_module has been successfull and  */
+/* the module counter has a value of 0. Otherwise this function will   */
+/* not be called. This function must release all resources still allo- */
+/* cated as after the return from this function the module code will   */
+/* be removed from memory.                                             */
+/***********************************************************************/
+static void 
+hysdn_exit(void)
+{
+#ifdef CONFIG_HYSDN_CAPI
+	hysdn_card *card;
+#endif /* CONFIG_HYSDN_CAPI */
+	stop_cards();
+#ifdef CONFIG_HYSDN_CAPI
+	card = card_root;	/* first in chain */
+	while (card) {
+		hycapi_capi_release(card);
+		card = card->next;	/* remove card from chain */
+	}			/* while card */
+	hycapi_cleanup();
+#endif /* CONFIG_HYSDN_CAPI */
+	hysdn_procconf_release();
+	free_resources();
+	printk(KERN_NOTICE "HYSDN: module unloaded\n");
+}				/* cleanup_module */
+
+module_init(hysdn_init);
+module_exit(hysdn_exit);
diff -urN linux-2.2.19-pre10/drivers/isdn/hysdn/hysdn_net.c linux/drivers/isdn/hysdn/hysdn_net.c
--- linux-2.2.19-pre10/drivers/isdn/hysdn/hysdn_net.c	Wed Dec 31 16:00:00 1969
+++ linux/drivers/isdn/hysdn/hysdn_net.c	Mon Dec  3 21:03:00 2001
@@ -0,0 +1,336 @@
+/* $Id: hysdn_net.c,v 1.8 2000/11/13 22:51:47 kai Exp $
+
+ * Linux driver for HYSDN cards, net (ethernet type) handling routines.
+ *
+ * written by Werner Cornelius (werner@titro.de) for Hypercope GmbH
+ *
+ * Copyright 1999  by Werner Cornelius (werner@titro.de)
+ *
+ * This net module has been inspired by the skeleton driver from
+ * Donald Becker (becker@CESDIS.gsfc.nasa.gov)
+ *
+ * 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; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+#define __NO_VERSION__
+#include <linux/module.h>
+#include <linux/version.h>
+#include <linux/signal.h>
+#include <linux/kernel.h>
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/skbuff.h>
+#include <linux/inetdevice.h>
+
+#include "hysdn_defs.h"
+
+/* store the actual version for log reporting */
+char *hysdn_net_revision = "$Revision: 1.8 $";
+
+#define MAX_SKB_BUFFERS 20	/* number of buffers for keeping TX-data */
+
+/****************************************************************************/
+/* structure containing the complete network data. The structure is aligned */
+/* in a way that both, the device and statistics are kept inside it.        */
+/* for proper access, the device structure MUST be the first var/struct     */
+/* inside the definition.                                                   */
+/****************************************************************************/
+struct net_local {
+	struct device netdev;	/* the network device */
+	struct net_device_stats stats;
+	/* additional vars may be added here */
+	char dev_name[9];	/* our own device name */
+
+	struct sk_buff *tx_skb;	/* buffer for tx operation */
+
+};				/* net_local */
+
+
+/*****************************************************/
+/* Get the current statistics for this card.         */
+/* This may be called with the card open or closed ! */
+/*****************************************************/
+static struct net_device_stats *
+net_get_stats(struct device *dev)
+{
+	return (&((struct net_local *) dev)->stats);
+}				/* net_device_stats */
+
+/*********************************************************************/
+/* Open/initialize the board. This is called (in the current kernel) */
+/* sometime after booting when the 'ifconfig' program is run.        */
+/* This routine should set everything up anew at each open, even     */
+/* registers that "should" only need to be set once at boot, so that */
+/* there is non-reboot way to recover if something goes wrong.       */
+/*********************************************************************/
+static int
+net_open(struct device *dev)
+{
+	struct in_device *in_dev;
+	hysdn_card *card = dev->priv;
+	int i;
+
+	dev->tbusy = 0;		/* non busy state */
+	dev->interrupt = 0;
+	if (!dev->start)
+		MOD_INC_USE_COUNT;	/* increment only if device is down */
+	dev->start = 1;		/* and started */
+
+	/* Fill in the MAC-level header (if not already set) */
+	if (!card->mac_addr[0]) {
+		for (i = 0; i < ETH_ALEN - sizeof(ulong); i++)
+			dev->dev_addr[i] = 0xfc;
+		if ((in_dev = dev->ip_ptr) != NULL) {
+			struct in_ifaddr *ifa = in_dev->ifa_list;
+			if (ifa != NULL)
+				memcpy(dev->dev_addr + (ETH_ALEN - sizeof(ulong)), &ifa->ifa_local, sizeof(ulong));
+		}
+	} else
+		memcpy(dev->dev_addr, card->mac_addr, ETH_ALEN);
+
+	return (0);
+}				/* net_open */
+
+
+
+/*********************************************************************/
+/* close/decativate the device. The device is not removed, but only  */
+/* deactivated.                                                      */
+/*********************************************************************/
+static int
+net_close(struct device *dev)
+{
+
+	dev->tbusy = 1;		/* we are busy */
+
+	if (dev->start)
+		MOD_DEC_USE_COUNT;	/* dec only if device has been active */
+
+	dev->start = 0;		/* and not started */
+
+	return (0);		/* success */
+}				/* net_close */
+
+/************************************/
+/* send a packet on this interface. */
+/* only for kernel versions < 2.3.33 */
+/************************************/
+static int
+net_send_packet(struct sk_buff *skb, struct device *dev)
+{
+	struct net_local *lp = (struct net_local *) dev;
+
+	if (dev->tbusy) {
+		/*
+		 * If we get here, some higher level has decided we are broken.
+		 * There should really be a "kick me" function call instead.
+		 * As ISDN may have higher timeouts than real ethernet 10s timeout
+		 */
+		int tickssofar = jiffies - dev->trans_start;
+		if (tickssofar < (10000 * HZ) / 1000)
+			return 1;
+		printk(KERN_WARNING "%s: transmit timed out. \n", dev->name);
+		dev->tbusy = 0;
+		dev->trans_start = jiffies;
+	}
+	/*
+	 * Block a timer-based transmit from overlapping. This could better be
+	 * done with atomic_swap(1, dev->tbusy), but set_bit() works as well.
+	 */
+	if (test_and_set_bit(0, (void *) &dev->tbusy) != 0)
+		printk(KERN_WARNING "%s: Transmitter access conflict.\n", dev->name);
+
+	else {
+		lp->stats.tx_bytes += skb->len;
+		dev->trans_start = jiffies;
+		lp->tx_skb = skb;	/* remember skb pointer */
+		queue_task(&((hysdn_card *) dev->priv)->irq_queue, &tq_immediate);
+		mark_bh(IMMEDIATE_BH);
+	}
+
+	return (0);		/* success */
+}				/* net_send_packet */
+
+
+
+/***********************************************************************/
+/* acknowlegde a packet send. The network layer will be informed about */
+/* completion                                                          */
+/***********************************************************************/
+void
+hysdn_tx_netack(hysdn_card * card)
+{
+	struct net_local *lp = card->netif;
+
+	if (!lp)
+		return;		/* non existing device */
+
+	if (lp->tx_skb)
+		dev_kfree_skb(lp->tx_skb);	/* free tx pointer */
+	lp->tx_skb = NULL;	/* reset pointer */
+
+	lp->stats.tx_packets++;
+	lp->netdev.tbusy = 0;
+	mark_bh(NET_BH);	/* Inform upper layers. */
+}				/* hysdn_tx_netack */
+
+/*****************************************************/
+/* we got a packet from the network, go and queue it */
+/*****************************************************/
+void
+hysdn_rx_netpkt(hysdn_card * card, uchar * buf, word len)
+{
+	struct net_local *lp = card->netif;
+	struct sk_buff *skb;
+
+	if (!lp)
+		return;		/* non existing device */
+
+	lp->stats.rx_bytes += len;
+
+	skb = dev_alloc_skb(len);
+	if (skb == NULL) {
+		printk(KERN_NOTICE "%s: Memory squeeze, dropping packet.\n",
+		       lp->netdev.name);
+		lp->stats.rx_dropped++;
+		return;
+	}
+	skb->dev = &lp->netdev;
+
+	/* copy the data */
+	memcpy(skb_put(skb, len), buf, len);
+
+	/* determine the used protocol */
+	skb->protocol = eth_type_trans(skb, &lp->netdev);
+
+	netif_rx(skb);
+	lp->stats.rx_packets++;	/* adjust packet count */
+
+}				/* hysdn_rx_netpkt */
+
+/*****************************************************/
+/* return the pointer to a network packet to be send */
+/*****************************************************/
+struct sk_buff *
+hysdn_tx_netget(hysdn_card * card)
+{
+	struct net_local *lp = card->netif;
+
+	if (!lp)
+		return (NULL);	/* non existing device */
+
+	return (lp->tx_skb);	/* return packet pointer */
+
+}				/* hysdn_tx_netget */
+
+
+/*******************************************/
+/* init function called by register device */
+/*******************************************/
+static int
+net_init(struct device *dev)
+{
+	/* setup the function table */
+	dev->open = net_open;
+	dev->stop = net_close;
+	dev->hard_start_xmit = net_send_packet;
+	dev->get_stats = net_get_stats;
+
+	/* Fill in the fields of the device structure with ethernet values. */
+	ether_setup(dev);
+
+	return (0);		/* success */
+}				/* net_init */
+
+/*****************************************************************************/
+/* hysdn_net_create creates a new net device for the given card. If a device */
+/* already exists, it will be deleted and created a new one. The return value */
+/* 0 announces success, else a negative error code will be returned.         */
+/*****************************************************************************/
+int
+hysdn_net_create(hysdn_card * card)
+{
+	struct device *dev;
+	int i;
+	if(!card) {
+		printk(KERN_WARNING "No card-pt in hysdn_net_create!\n");
+		return (-ENOMEM);
+	}
+	hysdn_net_release(card);	/* release an existing net device */
+	if ((dev = kmalloc(sizeof(struct net_local), GFP_KERNEL)) == NULL) {
+		printk(KERN_WARNING "HYSDN: unable to allocate mem\n");
+		if (card->debug_flags & LOG_NET_INIT)
+			return (-ENOMEM);
+	}
+	memset(dev, 0, sizeof(struct net_local));	/* clean the structure */
+
+
+	/* initialise necessary or informing fields */
+	dev->base_addr = card->iobase;	/* IO address */
+	dev->irq = card->irq;	/* irq */
+	dev->init = net_init;	/* the init function of the device */
+	dev->name = ((struct net_local *) dev)->dev_name;	/* device name */
+	if ((i = register_netdev(dev))) {
+		printk(KERN_WARNING "HYSDN: unable to create network device\n");
+		kfree(dev);
+		return (i);
+	}
+	dev->priv = card;	/* remember pointer to own data structure */
+	card->netif = dev;	/* setup the local pointer */
+
+	if (card->debug_flags & LOG_NET_INIT)
+		hysdn_addlog(card, "network device created");
+	return (0);		/* and return success */
+}				/* hysdn_net_create */
+
+/***************************************************************************/
+/* hysdn_net_release deletes the net device for the given card. The return */
+/* value 0 announces success, else a negative error code will be returned. */
+/***************************************************************************/
+int
+hysdn_net_release(hysdn_card * card)
+{
+	struct device *dev = card->netif;
+
+	if (!dev)
+		return (0);	/* non existing */
+
+	card->netif = NULL;	/* clear out pointer */
+	dev->stop(dev);		/* close the device */
+
+
+	unregister_netdev(dev);	/* release the device */
+	kfree(dev);		/* release the memory allocated */
+	if (card->debug_flags & LOG_NET_INIT)
+		hysdn_addlog(card, "network device deleted");
+
+	return (0);		/* always successfull */
+}				/* hysdn_net_release */
+
+/*****************************************************************************/
+/* hysdn_net_getname returns a pointer to the name of the network interface. */
+/* if the interface is not existing, a "-" is returned.                      */
+/*****************************************************************************/
+char *
+hysdn_net_getname(hysdn_card * card)
+{
+	struct device *dev = card->netif;
+
+	if (!dev)
+		return ("-");	/* non existing */
+
+	return (dev->name);
+}				/* hysdn_net_getname */
diff -urN linux-2.2.19-pre10/drivers/isdn/hysdn/hysdn_pof.h linux/drivers/isdn/hysdn/hysdn_pof.h
--- linux-2.2.19-pre10/drivers/isdn/hysdn/hysdn_pof.h	Wed Dec 31 16:00:00 1969
+++ linux/drivers/isdn/hysdn/hysdn_pof.h	Mon Dec  3 21:03:00 2001
@@ -0,0 +1,89 @@
+/* $Id: hysdn_pof.h,v 1.2 2000/11/13 22:51:47 kai Exp $
+
+ * Linux driver for HYSDN cards, definitions used for handling pof-files.
+ * written by Werner Cornelius (werner@titro.de) for Hypercope GmbH
+ *
+ * Copyright 1999  by Werner Cornelius (werner@titro.de)
+ *
+ * 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; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+/************************/
+/* POF specific defines */
+/************************/
+#define BOOT_BUF_SIZE   0x1000	/* =4096, maybe moved to other h file */
+#define CRYPT_FEEDTERM  0x8142
+#define CRYPT_STARTTERM 0x81a5
+				    /*  max. timeout time in seconds
+				     *  from end of booting to POF is ready
+				     */
+#define POF_READY_TIME_OUT_SEC  10
+
+/**********************************/
+/* defines for 1.stage boot image */
+/**********************************/
+
+/*  the POF file record containing the boot loader image
+ *  has 2 pages a 16KB:
+ *  1. page contains the high 16-bit part of the 32-bit E1 words
+ *  2. page contains the low  16-bit part of the 32-bit E1 words
+ *
+ *  In each 16KB page we assume the start of the boot loader code
+ *  in the highest 2KB part (at offset 0x3800);
+ *  the rest (0x0000..0x37FF) is assumed to contain 0 bytes.
+ */
+
+#define POF_BOOT_LOADER_PAGE_SIZE   0x4000	/* =16384U */
+#define POF_BOOT_LOADER_TOTAL_SIZE  (2U*POF_BOOT_LOADER_PAGE_SIZE)
+
+#define POF_BOOT_LOADER_CODE_SIZE   0x0800	/* =2KB =2048U */
+
+		    /* offset in boot page, where loader code may start */
+					    /* =0x3800= 14336U */
+#define POF_BOOT_LOADER_OFF_IN_PAGE (POF_BOOT_LOADER_PAGE_SIZE-POF_BOOT_LOADER_CODE_SIZE)
+
+
+/*--------------------------------------POF file record structs------------*/
+typedef struct PofFileHdr_tag {	/* Pof file header */
+/*00 */ ulong Magic __attribute__((packed));
+/*04 */ ulong N_PofRecs __attribute__((packed));
+/*08 */
+} tPofFileHdr;
+
+typedef struct PofRecHdr_tag {	/* Pof record header */
+/*00 */ word PofRecId __attribute__((packed));
+/*02 */ ulong PofRecDataLen __attribute__((packed));
+/*06 */
+} tPofRecHdr;
+
+typedef struct PofTimeStamp_tag {
+/*00 */ ulong UnixTime __attribute__((packed));
+	/*04 */ uchar DateTimeText[0x28] __attribute__((packed));
+	/* =40 */
+/*2C */
+} tPofTimeStamp;
+
+				    /* tPofFileHdr.Magic value: */
+#define TAGFILEMAGIC 0x464F501AUL
+				    /* tPofRecHdr.PofRecId values: */
+#define TAG_ABSDATA  0x1000	/* abs. data */
+#define TAG_BOOTDTA  0x1001	/* boot data */
+#define TAG_COMMENT  0x0020
+#define TAG_SYSCALL  0x0021
+#define TAG_FLOWCTRL 0x0022
+#define TAG_TIMESTMP 0x0010	/* date/time stamp of version */
+#define TAG_CABSDATA 0x1100	/* crypted abs. data */
+#define TAG_CBOOTDTA 0x1101	/* crypted boot data */
diff -urN linux-2.2.19-pre10/drivers/isdn/hysdn/hysdn_procconf.c linux/drivers/isdn/hysdn/hysdn_procconf.c
--- linux-2.2.19-pre10/drivers/isdn/hysdn/hysdn_procconf.c	Wed Dec 31 16:00:00 1969
+++ linux/drivers/isdn/hysdn/hysdn_procconf.c	Mon Dec  3 21:03:00 2001
@@ -0,0 +1,467 @@
+/* $Id: hysdn_procconf.c,v 1.8 2000/11/13 22:51:47 kai Exp $
+
+ * Linux driver for HYSDN cards, /proc/net filesystem dir and conf functions.
+ * written by Werner Cornelius (werner@titro.de) for Hypercope GmbH
+ *
+ * Copyright 1999  by Werner Cornelius (werner@titro.de)
+ *
+ * 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; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+#define __NO_VERSION__
+#include <linux/module.h>
+#include <linux/version.h>
+#include <linux/poll.h>
+#include <linux/proc_fs.h>
+#include <linux/pci.h>
+
+#include "hysdn_defs.h"
+
+static char *hysdn_procconf_revision = "$Revision: 1.8 $";
+
+#define INFO_OUT_LEN 80		/* length of info line including lf */
+
+/********************************************************/
+/* defines and data structure for conf write operations */
+/********************************************************/
+#define CONF_STATE_DETECT 0	/* waiting for detect */
+#define CONF_STATE_CONF   1	/* writing config data */
+#define CONF_STATE_POF    2	/* writing pof data */
+#define CONF_LINE_LEN    80	/* 80 chars max */
+
+struct conf_writedata {
+	hysdn_card *card;	/* card the device is connected to */
+	int buf_size;		/* actual number of bytes in the buffer */
+	int needed_size;	/* needed size when reading pof */
+	int state;		/* actual interface states from above constants */
+	uchar conf_line[CONF_LINE_LEN];		/* buffered conf line */
+	word channel;		/* active channel number */
+	uchar *pof_buffer;	/* buffer when writing pof */
+};
+
+/***********************************************************************/
+/* process_line parses one config line and transfers it to the card if */
+/* necessary.                                                          */
+/* if the return value is negative an error occured.                   */
+/***********************************************************************/
+static int
+process_line(struct conf_writedata *cnf)
+{
+	uchar *cp = cnf->conf_line;
+	int i;
+
+	if (cnf->card->debug_flags & LOG_CNF_LINE)
+		hysdn_addlog(cnf->card, "conf line: %s", cp);
+
+	if (*cp == '-') {	/* option */
+		cp++;		/* point to option char */
+
+		if (*cp++ != 'c')
+			return (0);	/* option unknown or used */
+		i = 0;		/* start value for channel */
+		while ((*cp <= '9') && (*cp >= '0'))
+			i = i * 10 + *cp++ - '0';	/* get decimal number */
+		if (i > 65535) {
+			if (cnf->card->debug_flags & LOG_CNF_MISC)
+				hysdn_addlog(cnf->card, "conf channel invalid  %d", i);
+			return (-ERR_INV_CHAN);		/* invalid channel */
+		}
+		cnf->channel = i & 0xFFFF;	/* set new channel number */
+		return (0);	/* success */
+	}			/* option */
+	if (*cp == '*') {	/* line to send */
+		if (cnf->card->debug_flags & LOG_CNF_DATA)
+			hysdn_addlog(cnf->card, "conf chan=%d %s", cnf->channel, cp);
+		return (hysdn_tx_cfgline(cnf->card, cnf->conf_line + 1,
+					 cnf->channel));	/* send the line without * */
+	}			/* line to send */
+	return (0);
+}				/* process_line */
+
+/*************************/
+/* dummy file operations */
+/*************************/
+static loff_t
+hysdn_dummy_lseek(struct file *file, loff_t offset, int orig)
+{
+	return -ESPIPE;
+}				/* hysdn_dummy_lseek */
+
+/***********************************/
+/* conf file operations and tables */
+/***********************************/
+
+/****************************************************/
+/* write conf file -> boot or send cfg line to card */
+/****************************************************/
+static ssize_t
+hysdn_conf_write(struct file *file, const char *buf, size_t count, loff_t * off)
+{
+	struct conf_writedata *cnf;
+	int i;
+	uchar ch, *cp;
+
+	if (&file->f_pos != off)	/* fs error check */
+		return (-ESPIPE);
+	if (!count)
+		return (0);	/* nothing to handle */
+
+	if (!(cnf = file->private_data))
+		return (-EFAULT);	/* should never happen */
+
+	if (cnf->state == CONF_STATE_DETECT) {	/* auto detect cnf or pof data */
+		if (copy_from_user(&ch, buf, 1))	/* get first char for detect */
+			return (-EFAULT);
+
+		if (ch == 0x1A) {
+			/* we detected a pof file */
+			if ((cnf->needed_size = pof_write_open(cnf->card, &cnf->pof_buffer)) <= 0)
+				return (cnf->needed_size);	/* an error occured -> exit */
+			cnf->buf_size = 0;	/* buffer is empty */
+			cnf->state = CONF_STATE_POF;	/* new state */
+		} else {
+			/* conf data has been detected */
+			cnf->buf_size = 0;	/* buffer is empty */
+			cnf->state = CONF_STATE_CONF;	/* requested conf data write */
+			if (cnf->card->state != CARD_STATE_RUN)
+				return (-ERR_NOT_BOOTED);
+			cnf->conf_line[CONF_LINE_LEN - 1] = 0;	/* limit string length */
+			cnf->channel = 4098;	/* default channel for output */
+		}
+	}			/* state was auto detect */
+	if (cnf->state == CONF_STATE_POF) {	/* pof write active */
+		i = cnf->needed_size - cnf->buf_size;	/* bytes still missing for write */
+		if (i <= 0)
+			return (-EINVAL);	/* size error handling pof */
+
+		if (i < count)
+			count = i;	/* limit requested number of bytes */
+		if (copy_from_user(cnf->pof_buffer + cnf->buf_size, buf, count))
+			return (-EFAULT);	/* error while copying */
+		cnf->buf_size += count;
+
+		if (cnf->needed_size == cnf->buf_size) {
+			cnf->needed_size = pof_write_buffer(cnf->card, cnf->buf_size);	/* write data */
+			if (cnf->needed_size <= 0) {
+				cnf->card->state = CARD_STATE_BOOTERR;	/* show boot error */
+				return (cnf->needed_size);	/* an error occured */
+			}
+			cnf->buf_size = 0;	/* buffer is empty again */
+		}
+	}
+	/* pof write active */
+	else {			/* conf write active */
+
+		if (cnf->card->state != CARD_STATE_RUN) {
+			if (cnf->card->debug_flags & LOG_CNF_MISC)
+				hysdn_addlog(cnf->card, "cnf write denied -> not booted");
+			return (-ERR_NOT_BOOTED);
+		}
+		i = (CONF_LINE_LEN - 1) - cnf->buf_size;	/* bytes available in buffer */
+		if (i > 0) {
+			/* copy remaining bytes into buffer */
+
+			if (count > i)
+				count = i;	/* limit transfer */
+			if (copy_from_user(cnf->conf_line + cnf->buf_size, buf, count))
+				return (-EFAULT);	/* error while copying */
+
+			i = count;	/* number of chars in buffer */
+			cp = cnf->conf_line + cnf->buf_size;
+			while (i) {
+				/* search for end of line */
+				if ((*cp < ' ') && (*cp != 9))
+					break;	/* end of line found */
+				cp++;
+				i--;
+			}	/* search for end of line */
+
+			if (i) {
+				/* delimiter found */
+				*cp++ = 0;	/* string termination */
+				count -= (i - 1);	/* subtract remaining bytes from count */
+				while ((i) && (*cp < ' ') && (*cp != 9)) {
+					i--;	/* discard next char */
+					count++;	/* mark as read */
+					cp++;	/* next char */
+				}
+				cnf->buf_size = 0;	/* buffer is empty after transfer */
+				if ((i = process_line(cnf)) < 0)	/* handle the line */
+					count = i;	/* return the error */
+			}
+			/* delimiter found */
+			else {
+				cnf->buf_size += count;		/* add chars to string */
+				if (cnf->buf_size >= CONF_LINE_LEN - 1) {
+					if (cnf->card->debug_flags & LOG_CNF_MISC)
+						hysdn_addlog(cnf->card, "cnf line too long %d chars pos %d", cnf->buf_size, count);
+					return (-ERR_CONF_LONG);
+				}
+			}	/* not delimited */
+
+		}
+		/* copy remaining bytes into buffer */
+		else {
+			if (cnf->card->debug_flags & LOG_CNF_MISC)
+				hysdn_addlog(cnf->card, "cnf line too long");
+			return (-ERR_CONF_LONG);
+		}
+	}			/* conf write active */
+
+	return (count);
+}				/* hysdn_conf_write */
+
+/*******************************************/
+/* read conf file -> output card info data */
+/*******************************************/
+static ssize_t
+hysdn_conf_read(struct file *file, char *buf, size_t count, loff_t * off)
+{
+	char *cp;
+	int i;
+
+	if (off != &file->f_pos)	/* fs error check */
+		return -ESPIPE;
+
+	if (file->f_mode & FMODE_READ) {
+		if (!(cp = file->private_data))
+			return (-EFAULT);	/* should never happen */
+		i = strlen(cp);	/* get total string length */
+		if (*off < i) {
+			/* still bytes to transfer */
+			cp += *off;	/* point to desired data offset */
+			i -= *off;	/* remaining length */
+			if (i > count)
+				i = count;	/* limit length to transfer */
+			if (copy_to_user(buf, cp, i))
+				return (-EFAULT);	/* copy error */
+			*off += i;	/* adjust offset */
+		} else
+			return (0);
+	} else
+		return (-EPERM);	/* no permission to read */
+
+	return (i);
+}				/* hysdn_conf_read */
+
+/******************/
+/* open conf file */
+/******************/
+static int
+hysdn_conf_open(struct inode *ino, struct file *filep)
+{
+	hysdn_card *card;
+	struct proc_dir_entry *pd;
+	struct conf_writedata *cnf;
+	char *cp, *tmp;
+
+	/* now search the addressed card */
+	MOD_INC_USE_COUNT;
+	card = card_root;
+	while (card) {
+		pd = card->procconf;
+		if (pd->low_ino == (ino->i_ino & 0xFFFF))
+			break;
+		card = card->next;	/* search next entry */
+	}
+	if (!card) {
+		MOD_DEC_USE_COUNT;
+		return (-ENODEV);	/* device is unknown/invalid */
+	}
+	if (card->debug_flags & (LOG_PROC_OPEN | LOG_PROC_ALL))
+		hysdn_addlog(card, "config open for uid=%d gid=%d mode=0x%x",
+			     filep->f_uid, filep->f_gid, filep->f_mode);
+
+	if ((filep->f_mode & (FMODE_READ | FMODE_WRITE)) == FMODE_WRITE) {
+		/* write only access -> write boot file or conf line */
+
+		if (!(cnf = kmalloc(sizeof(struct conf_writedata), GFP_KERNEL))) {
+			MOD_DEC_USE_COUNT;
+			return (-EFAULT);
+		}
+		cnf->card = card;
+		cnf->buf_size = 0;	/* nothing buffered */
+		cnf->state = CONF_STATE_DETECT;		/* start auto detect */
+		filep->private_data = cnf;
+
+	} else if ((filep->f_mode & (FMODE_READ | FMODE_WRITE)) == FMODE_READ) {
+		/* read access -> output card info data */
+
+		if (!(tmp = (char *) kmalloc(INFO_OUT_LEN * 2 + 2, GFP_KERNEL))) {
+			MOD_DEC_USE_COUNT;
+			return (-EFAULT);	/* out of memory */
+		}
+		filep->private_data = tmp;	/* start of string */
+
+		/* first output a headline */
+		sprintf(tmp, "id bus slot type irq iobase dp-mem     b-chans fax-chans state device");
+		cp = tmp;	/* start of string */
+		while (*cp)
+			cp++;
+		while (((cp - tmp) % (INFO_OUT_LEN + 1)) != INFO_OUT_LEN)
+			*cp++ = ' ';
+		*cp++ = '\n';
+
+		/* and now the data */
+		sprintf(cp, "%d  %3d %4d %4d %3d 0x%04x 0x%08lx %7d %9d %3d   %s",
+			card->myid,
+			card->bus,
+			PCI_SLOT(card->devfn),
+			card->brdtype,
+			card->irq,
+			card->iobase,
+			card->membase,
+			card->bchans,
+			card->faxchans,
+			card->state,
+			hysdn_net_getname(card));
+		while (*cp)
+			cp++;
+		while (((cp - tmp) % (INFO_OUT_LEN + 1)) != INFO_OUT_LEN)
+			*cp++ = ' ';
+		*cp++ = '\n';
+		*cp = 0;	/* end of string */
+	} else {		/* simultaneous read/write access forbidden ! */
+		MOD_DEC_USE_COUNT;
+		return (-EPERM);	/* no permission this time */
+	}
+	return (0);
+}				/* hysdn_conf_open */
+
+/***************************/
+/* close a config file.    */
+/***************************/
+static int
+hysdn_conf_close(struct inode *ino, struct file *filep)
+{
+	hysdn_card *card;
+	struct conf_writedata *cnf;
+	int retval = 0;
+	struct proc_dir_entry *pd;
+
+	/* search the addressed card */
+	card = card_root;
+	while (card) {
+		pd = card->procconf;
+		if (pd->low_ino == (ino->i_ino & 0xFFFF))
+			break;
+		card = card->next;	/* search next entry */
+	}
+	if (!card) {
+		return (-ENODEV);	/* device is unknown/invalid */
+	}
+	if (card->debug_flags & (LOG_PROC_OPEN | LOG_PROC_ALL))
+		hysdn_addlog(card, "config close for uid=%d gid=%d mode=0x%x",
+			     filep->f_uid, filep->f_gid, filep->f_mode);
+
+	if ((filep->f_mode & (FMODE_READ | FMODE_WRITE)) == FMODE_WRITE) {
+		/* write only access -> write boot file or conf line */
+		if (filep->private_data) {
+			cnf = filep->private_data;
+
+			if (cnf->state == CONF_STATE_POF)
+				retval = pof_write_close(cnf->card);	/* close the pof write */
+			kfree(filep->private_data);	/* free allocated memory for buffer */
+
+		}		/* handle write private data */
+	} else if ((filep->f_mode & (FMODE_READ | FMODE_WRITE)) == FMODE_READ) {
+		/* read access -> output card info data */
+
+		if (filep->private_data)
+			kfree(filep->private_data);	/* release memory */
+	}
+	MOD_DEC_USE_COUNT;
+	return (retval);
+}				/* hysdn_conf_close */
+
+/******************************************************/
+/* table for conf filesystem functions defined above. */
+/******************************************************/
+static struct file_operations conf_fops =
+{
+	llseek:         hysdn_dummy_lseek,
+	read:           hysdn_conf_read,
+	write:          hysdn_conf_write,
+	open:           hysdn_conf_open,
+	release:        hysdn_conf_close,                                       
+};
+
+static struct inode_operations conf_inode_operations;
+/*****************************/
+/* hysdn subdir in /proc/net */
+/*****************************/
+struct proc_dir_entry *hysdn_proc_entry = NULL;
+
+/*******************************************************************************/
+/* hysdn_procconf_init is called when the module is loaded and after the cards */
+/* have been detected. The needed proc dir and card config files are created.  */
+/* The log init is called at last.                                             */
+/*******************************************************************************/
+int
+hysdn_procconf_init(void)
+{
+	hysdn_card *card;
+	uchar conf_name[20];
+
+	hysdn_proc_entry = create_proc_entry(PROC_SUBDIR_NAME, S_IFDIR | S_IRUGO | S_IXUGO, proc_net);
+	if (!hysdn_proc_entry) {
+		printk(KERN_ERR "HYSDN: unable to create hysdn subdir\n");
+		return (-1);
+	}
+	card = card_root;	/* point to first card */
+	while (card) {
+
+		sprintf(conf_name, "%s%d", PROC_CONF_BASENAME, card->myid);
+		if ((card->procconf = (void *) create_proc_entry(conf_name,
+					     S_IFREG | S_IRUGO | S_IWUSR,
+					    hysdn_proc_entry)) != NULL) {
+			memset(&conf_inode_operations, 0, sizeof(struct inode_operations));
+			conf_inode_operations.default_file_ops = &conf_fops;
+
+			((struct proc_dir_entry *) card->procconf)->ops = &conf_inode_operations;
+			hysdn_proclog_init(card);	/* init the log file entry */
+		}
+		card = card->next;	/* next entry */
+	}
+
+	printk(KERN_NOTICE "HYSDN: procfs Rev. %s initialised\n", hysdn_getrev(hysdn_procconf_revision));
+	return (0);
+}				/* hysdn_procconf_init */
+
+/*************************************************************************************/
+/* hysdn_procconf_release is called when the module is unloaded and before the cards */
+/* resources are released. The module counter is assumed to be 0 !                   */
+/*************************************************************************************/
+void
+hysdn_procconf_release(void)
+{
+	hysdn_card *card;
+	uchar conf_name[20];
+
+	card = card_root;	/* start with first card */
+	while (card) {
+
+		sprintf(conf_name, "%s%d", PROC_CONF_BASENAME, card->myid);
+		if (card->procconf)
+			remove_proc_entry(conf_name, hysdn_proc_entry);
+
+		hysdn_proclog_release(card);	/* init the log file entry */
+
+		card = card->next;	/* point to next card */
+	}
+
+	remove_proc_entry(PROC_SUBDIR_NAME, proc_net);
+}				/* hysdn_procfs_release */
diff -urN linux-2.2.19-pre10/drivers/isdn/hysdn/hysdn_proclog.c linux/drivers/isdn/hysdn/hysdn_proclog.c
--- linux-2.2.19-pre10/drivers/isdn/hysdn/hysdn_proclog.c	Wed Dec 31 16:00:00 1969
+++ linux/drivers/isdn/hysdn/hysdn_proclog.c	Mon Dec  3 21:03:00 2001
@@ -0,0 +1,464 @@
+/* $Id: hysdn_proclog.c,v 1.9 2000/11/25 17:01:01 kai Exp $
+
+ * Linux driver for HYSDN cards, /proc/net filesystem log functions.
+ * written by Werner Cornelius (werner@titro.de) for Hypercope GmbH
+ *
+ * Copyright 1999  by Werner Cornelius (werner@titro.de)
+ *
+ * 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; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+#define __NO_VERSION__
+#include <linux/module.h>
+#include <linux/version.h>
+#include <linux/poll.h>
+#include <linux/proc_fs.h>
+#include <linux/pci.h>
+
+#include "hysdn_defs.h"
+
+/* the proc subdir for the interface is defined in the procconf module */
+extern struct proc_dir_entry *hysdn_proc_entry;
+
+/*************************************************/
+/* structure keeping ascii log for device output */
+/*************************************************/
+struct log_data {
+	struct log_data *next;
+	ulong usage_cnt;	/* number of files still to work */
+	void *proc_ctrl;	/* pointer to own control procdata structure */
+	char log_start[2];	/* log string start (final len aligned by size) */
+};
+
+/**********************************************/
+/* structure holding proc entrys for one card */
+/**********************************************/
+struct procdata {
+	struct proc_dir_entry *log;	/* log entry */
+	char log_name[15];	/* log filename */
+	struct log_data *log_head, *log_tail;	/* head and tail for queue */
+	int if_used;		/* open count for interface */
+	int volatile del_lock;	/* lock for delete operations */
+	uchar logtmp[LOG_MAX_LINELEN];
+	wait_queue_head_t rd_queue;
+};
+
+
+/**********************************************/
+/* log function for cards error log interface */
+/**********************************************/
+void
+hysdn_card_errlog(hysdn_card * card, tErrLogEntry * logp, int maxsize)
+{
+	char buf[ERRLOG_TEXT_SIZE + 40];
+
+	sprintf(buf, "LOG 0x%08lX 0x%08lX : %s\n", logp->ulErrType, logp->ulErrSubtype, logp->ucText);
+	put_log_buffer(card, buf);	/* output the string */
+}				/* hysdn_card_errlog */
+
+/***************************************************/
+/* Log function using format specifiers for output */
+/***************************************************/
+void
+hysdn_addlog(hysdn_card * card, char *fmt,...)
+{
+	struct procdata *pd = card->proclog;
+	char *cp;
+	va_list args;
+
+	if (!pd)
+		return;		/* log structure non existent */
+
+	cp = pd->logtmp;
+	cp += sprintf(cp, "HYSDN: card %d ", card->myid);
+
+	va_start(args, fmt);
+	cp += vsprintf(cp, fmt, args);
+	va_end(args);
+	*cp++ = '\n';
+	*cp = 0;
+
+	if (card->debug_flags & DEB_OUT_SYSLOG)
+		printk(KERN_INFO "%s", pd->logtmp);
+	else
+		put_log_buffer(card, pd->logtmp);
+
+}				/* hysdn_addlog */
+
+/********************************************/
+/* put an log buffer into the log queue.    */
+/* This buffer will be kept until all files */
+/* opened for read got the contents.        */
+/* Flushes buffers not longer in use.       */
+/********************************************/
+void
+put_log_buffer(hysdn_card * card, char *cp)
+{
+	struct log_data *ib;
+	struct procdata *pd = card->proclog;
+	int i, flags;
+
+	if (!pd)
+		return;
+	if (!cp)
+		return;
+	if (!*cp)
+		return;
+	if (pd->if_used <= 0)
+		return;		/* no open file for read */
+
+	if (!(ib = (struct log_data *) kmalloc(sizeof(struct log_data) + strlen(cp), GFP_ATOMIC)))
+		 return;	/* no memory */
+	strcpy(ib->log_start, cp);	/* set output string */
+	ib->next = NULL;
+	ib->proc_ctrl = pd;	/* point to own control structure */
+	save_flags(flags);
+	cli();
+	ib->usage_cnt = pd->if_used;
+	if (!pd->log_head)
+		pd->log_head = ib;	/* new head */
+	else
+		pd->log_tail->next = ib;	/* follows existing messages */
+	pd->log_tail = ib;	/* new tail */
+	i = pd->del_lock++;	/* get lock state */
+	restore_flags(flags);
+
+	/* delete old entrys */
+	if (!i)
+		while (pd->log_head->next) {
+			if ((pd->log_head->usage_cnt <= 0) &&
+			    (pd->log_head->next->usage_cnt <= 0)) {
+				ib = pd->log_head;
+				pd->log_head = pd->log_head->next;
+				kfree(ib);
+			} else
+				break;
+		}		/* pd->log_head->next */
+	pd->del_lock--;		/* release lock level */
+	wake_up_interruptible(&(pd->rd_queue));		/* announce new entry */
+}				/* put_log_buffer */
+
+
+/*************************/
+/* dummy file operations */
+/*************************/
+static loff_t
+hysdn_dummy_lseek(struct file *file, loff_t offset, int orig)
+{
+	return -ESPIPE;
+}				/* hysdn_dummy_lseek */
+
+/******************************/
+/* file operations and tables */
+/******************************/
+
+/****************************************/
+/* write log file -> set log level bits */
+/****************************************/
+static ssize_t
+hysdn_log_write(struct file *file, const char *buf, size_t count, loff_t * off)
+{
+	ulong u = 0;
+	int found = 0;
+	uchar *cp, valbuf[128];
+	long base = 10;
+	hysdn_card *card = (hysdn_card *) file->private_data;
+
+	if (&file->f_pos != off)	/* fs error check */
+		return (-ESPIPE);
+
+	if (count > (sizeof(valbuf) - 1))
+		count = sizeof(valbuf) - 1;	/* limit length */
+	if (copy_from_user(valbuf, buf, count))
+		return (-EFAULT);	/* copy failed */
+
+	valbuf[count] = 0;	/* terminating 0 */
+	cp = valbuf;
+	if ((count > 2) && (valbuf[0] == '0') && (valbuf[1] == 'x')) {
+		cp += 2;	/* pointer after hex modifier */
+		base = 16;
+	}
+	/* scan the input for debug flags */
+	while (*cp) {
+		if ((*cp >= '0') && (*cp <= '9')) {
+			found = 1;
+			u *= base;	/* adjust to next digit */
+			u += *cp++ - '0';
+			continue;
+		}
+		if (base != 16)
+			break;	/* end of number */
+
+		if ((*cp >= 'a') && (*cp <= 'f')) {
+			found = 1;
+			u *= base;	/* adjust to next digit */
+			u += *cp++ - 'a' + 10;
+			continue;
+		}
+		break;		/* terminated */
+	}
+
+	if (found) {
+		card->debug_flags = u;	/* remember debug flags */
+		hysdn_addlog(card, "debug set to 0x%lx", card->debug_flags);
+	}
+	return (count);
+}				/* hysdn_log_write */
+
+/******************/
+/* read log file */
+/******************/
+static ssize_t
+hysdn_log_read(struct file *file, char *buf, size_t count, loff_t * off)
+{
+	struct log_data *inf;
+	int len;
+	word ino;
+	struct procdata *pd;
+	hysdn_card *card;
+
+	if (!*((struct log_data **) file->private_data)) {
+		if (file->f_flags & O_NONBLOCK)
+			return (-EAGAIN);
+
+		/* sorry, but we need to search the card */
+		ino = file->f_dentry->d_inode->i_ino & 0xFFFF;	/* low-ino */
+		card = card_root;
+		while (card) {
+			pd = card->proclog;
+			if (pd->log->low_ino == ino)
+				break;
+			card = card->next;	/* search next entry */
+		}
+		if (card)
+			interruptible_sleep_on(&(pd->rd_queue));
+		else
+			return (-EAGAIN);
+
+	}
+	if (!(inf = *((struct log_data **) file->private_data)))
+		return (0);
+
+	inf->usage_cnt--;	/* new usage count */
+	(struct log_data **) file->private_data = &inf->next;	/* next structure */
+	if ((len = strlen(inf->log_start)) <= count) {
+		if (copy_to_user(buf, inf->log_start, len))
+			return -EFAULT;
+		file->f_pos += len;
+		return (len);
+	}
+	return (0);
+}				/* hysdn_log_read */
+
+/******************/
+/* open log file */
+/******************/
+static int
+hysdn_log_open(struct inode *ino, struct file *filep)
+{
+	hysdn_card *card;
+	struct procdata *pd;
+	ulong flags;
+
+	MOD_INC_USE_COUNT;
+	card = card_root;
+	while (card) {
+		pd = card->proclog;
+		if (pd->log->low_ino == (ino->i_ino & 0xFFFF))
+			break;
+		card = card->next;	/* search next entry */
+	}
+	if (!card) {
+		MOD_DEC_USE_COUNT;
+		return (-ENODEV);	/* device is unknown/invalid */
+	}
+	filep->private_data = card;	/* remember our own card */
+
+	if ((filep->f_mode & (FMODE_READ | FMODE_WRITE)) == FMODE_WRITE) {
+		/* write only access -> write log level only */
+	} else if ((filep->f_mode & (FMODE_READ | FMODE_WRITE)) == FMODE_READ) {
+
+		/* read access -> log/debug read */
+		save_flags(flags);
+		cli();
+		pd->if_used++;
+		if (pd->log_head)
+			(struct log_data **) filep->private_data = &(pd->log_tail->next);
+		else
+			(struct log_data **) filep->private_data = &(pd->log_head);
+		restore_flags(flags);
+	} else {		/* simultaneous read/write access forbidden ! */
+		MOD_DEC_USE_COUNT;
+		return (-EPERM);	/* no permission this time */
+	}
+	return (0);
+}				/* hysdn_log_open */
+
+/*******************************************************************************/
+/* close a cardlog file. If the file has been opened for exclusive write it is */
+/* assumed as pof data input and the pof loader is noticed about.              */
+/* Otherwise file is handled as log output. In this case the interface usage   */
+/* count is decremented and all buffers are noticed of closing. If this file   */
+/* was the last one to be closed, all buffers are freed.                       */
+/*******************************************************************************/
+static int
+hysdn_log_close(struct inode *ino, struct file *filep)
+{
+	struct log_data *inf;
+	struct procdata *pd;
+	hysdn_card *card;
+	int flags, retval = 0;
+
+
+	if ((filep->f_mode & (FMODE_READ | FMODE_WRITE)) == FMODE_WRITE) {
+		/* write only access -> write debug level written */
+		retval = 0;	/* success */
+	} else {
+		/* read access -> log/debug read, mark one further file as closed */
+
+		pd = NULL;
+		save_flags(flags);
+		cli();
+		inf = *((struct log_data **) filep->private_data);	/* get first log entry */
+		if (inf)
+			pd = (struct procdata *) inf->proc_ctrl;	/* still entries there */
+		else {
+			/* no info available -> search card */
+			card = card_root;
+			while (card) {
+				pd = card->proclog;
+				if (pd->log->low_ino == (ino->i_ino & 0xFFFF))
+					break;
+				card = card->next;	/* search next entry */
+			}
+			if (card)
+				pd = card->proclog;	/* pointer to procfs log */
+		}
+		if (pd)
+			pd->if_used--;	/* decrement interface usage count by one */
+
+		while (inf) {
+			inf->usage_cnt--;	/* decrement usage count for buffers */
+			inf = inf->next;
+		}
+		restore_flags(flags);
+
+		if (pd)
+			if (pd->if_used <= 0)	/* delete buffers if last file closed */
+				while (pd->log_head) {
+					inf = pd->log_head;
+					pd->log_head = pd->log_head->next;
+					kfree(inf);
+				}
+	}			/* read access */
+	MOD_DEC_USE_COUNT;
+
+	return (retval);
+}				/* hysdn_log_close */
+
+/*************************************************/
+/* select/poll routine to be able using select() */
+/*************************************************/
+static unsigned int
+hysdn_log_poll(struct file *file, poll_table * wait)
+{
+	unsigned int mask = 0;
+	word ino;
+	hysdn_card *card;
+	struct procdata *pd;
+
+	if ((file->f_mode & (FMODE_READ | FMODE_WRITE)) == FMODE_WRITE)
+		return (mask);	/* no polling for write supported */
+
+	/* we need to search the card */
+	ino = file->f_dentry->d_inode->i_ino & 0xFFFF;	/* low-ino */
+	card = card_root;
+	while (card) {
+		pd = card->proclog;
+		if (pd->log->low_ino == ino)
+			break;
+		card = card->next;	/* search next entry */
+	}
+	if (!card)
+		return (mask);	/* card not found */
+
+	poll_wait(file, &(pd->rd_queue), wait);
+
+	if (*((struct log_data **) file->private_data))
+		mask |= POLLIN | POLLRDNORM;
+
+	return mask;
+}				/* hysdn_log_poll */
+
+/**************************************************/
+/* table for log filesystem functions defined above. */
+/**************************************************/
+static struct file_operations log_fops =
+{
+	llseek:         hysdn_dummy_lseek,
+	read:           hysdn_log_read,
+	write:          hysdn_log_write,
+	poll:           hysdn_log_poll,
+	open:           hysdn_log_open,
+	release:        hysdn_log_close,                                        
+};
+
+struct inode_operations log_inode_operations;
+
+/***********************************************************************************/
+/* hysdn_proclog_init is called when the module is loaded after creating the cards */
+/* conf files.                                                                     */
+/***********************************************************************************/
+int
+hysdn_proclog_init(hysdn_card * card)
+{
+	struct procdata *pd;
+
+	/* create a cardlog proc entry */
+
+	if ((pd = (struct procdata *) kmalloc(sizeof(struct procdata), GFP_KERNEL)) != NULL) {
+		memset(pd, 0, sizeof(struct procdata));
+		memset(&log_inode_operations, 0, sizeof(struct inode_operations));
+		log_inode_operations.default_file_ops = &log_fops;
+		sprintf(pd->log_name, "%s%d", PROC_LOG_BASENAME, card->myid);
+		if ((pd->log = create_proc_entry(pd->log_name, S_IFREG | S_IRUGO | S_IWUSR, hysdn_proc_entry)) != NULL) {
+			pd->log->ops = &log_inode_operations;	/* set new operations table */
+		}
+
+		init_waitqueue_head(&(pd->rd_queue));
+
+		card->proclog = (void *) pd;	/* remember procfs structure */
+	}
+	return (0);
+}				/* hysdn_proclog_init */
+
+/************************************************************************************/
+/* hysdn_proclog_release is called when the module is unloaded and before the cards */
+/* conf file is released                                                            */
+/* The module counter is assumed to be 0 !                                          */
+/************************************************************************************/
+void
+hysdn_proclog_release(hysdn_card * card)
+{
+	struct procdata *pd;
+
+	if ((pd = (struct procdata *) card->proclog) != NULL) {
+		if (pd->log)
+			remove_proc_entry(pd->log_name, hysdn_proc_entry);
+		kfree(pd);	/* release memory */
+		card->proclog = NULL;
+	}
+}				/* hysdn_proclog_release */
diff -urN linux-2.2.19-pre10/drivers/isdn/hysdn/hysdn_sched.c linux/drivers/isdn/hysdn/hysdn_sched.c
--- linux-2.2.19-pre10/drivers/isdn/hysdn/hysdn_sched.c	Wed Dec 31 16:00:00 1969
+++ linux/drivers/isdn/hysdn/hysdn_sched.c	Mon Dec  3 21:03:00 2001
@@ -0,0 +1,213 @@
+/* $Id: hysdn_sched.c,v 1.5 2000/11/22 17:13:13 kai Exp $
+
+ * Linux driver for HYSDN cards, scheduler routines for handling exchange card <-> pc.
+ *
+ * written by Werner Cornelius (werner@titro.de) for Hypercope GmbH
+ *
+ * Copyright 1999  by Werner Cornelius (werner@titro.de)
+ *
+ * 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; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+#define __NO_VERSION__
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/version.h>
+#include <asm/io.h>
+#include <linux/signal.h>
+#include <linux/kernel.h>
+#include <linux/ioport.h>
+#include <linux/interrupt.h>
+
+#include "hysdn_defs.h"
+
+/*****************************************************************************/
+/* hysdn_sched_rx is called from the cards handler to announce new data is   */
+/* available from the card. The routine has to handle the data and return    */
+/* with a nonzero code if the data could be worked (or even thrown away), if */
+/* no room to buffer the data is available a zero return tells the card      */
+/* to keep the data until later.                                             */
+/*****************************************************************************/
+int
+hysdn_sched_rx(hysdn_card * card, uchar * buf, word len, word chan)
+{
+
+	switch (chan) {
+		case CHAN_NDIS_DATA:
+			hysdn_rx_netpkt(card, buf, len);	/* give packet to network handler */
+			break;
+
+		case CHAN_ERRLOG:
+			hysdn_card_errlog(card, (tErrLogEntry *) buf, len);
+			if (card->err_log_state == ERRLOG_STATE_ON)
+				card->err_log_state = ERRLOG_STATE_START;	/* start new fetch */
+			break;
+#ifdef CONFIG_HYSDN_CAPI
+         	case CHAN_CAPI:
+/* give packet to CAPI handler */
+			hycapi_rx_capipkt(card, buf, len);
+			break;
+#endif /* CONFIG_HYSDN_CAPI */
+		default:
+			printk(KERN_INFO "irq message channel %d len %d unhandled \n", chan, len);
+			break;
+
+	}			/* switch rx channel */
+
+	return (1);		/* always handled */
+}				/* hysdn_sched_rx */
+
+/*****************************************************************************/
+/* hysdn_sched_tx is called from the cards handler to announce that there is */
+/* room in the tx-buffer to the card and data may be sent if needed.         */
+/* If the routine wants to send data it must fill buf, len and chan with the */
+/* appropriate data and return a nonzero value. With a zero return no new    */
+/* data to send is assumed. maxlen specifies the buffer size available for   */
+/* sending.                                                                  */
+/*****************************************************************************/
+int
+hysdn_sched_tx(hysdn_card * card, uchar * buf, word volatile *len, word volatile *chan, word maxlen)
+{
+	struct sk_buff *skb;
+
+	if (card->net_tx_busy) {
+		card->net_tx_busy = 0;	/* reset flag */
+		hysdn_tx_netack(card);	/* acknowledge packet send */
+	}			/* a network packet has completely been transferred */
+	/* first of all async requests are handled */
+	if (card->async_busy) {
+		if (card->async_len <= maxlen) {
+			memcpy(buf, card->async_data, card->async_len);
+			*len = card->async_len;
+			*chan = card->async_channel;
+			card->async_busy = 0;	/* reset request */
+			return (1);
+		}
+		card->async_busy = 0;	/* in case of length error */
+	}			/* async request */
+	if ((card->err_log_state == ERRLOG_STATE_START) &&
+	    (maxlen >= ERRLOG_CMD_REQ_SIZE)) {
+		strcpy(buf, ERRLOG_CMD_REQ);	/* copy the command */
+		*len = ERRLOG_CMD_REQ_SIZE;	/* buffer length */
+		*chan = CHAN_ERRLOG;	/* and channel */
+		card->err_log_state = ERRLOG_STATE_ON;	/* new state is on */
+		return (1);	/* tell that data should be send */
+	}			/* error log start and able to send */
+	if ((card->err_log_state == ERRLOG_STATE_STOP) &&
+	    (maxlen >= ERRLOG_CMD_STOP_SIZE)) {
+		strcpy(buf, ERRLOG_CMD_STOP);	/* copy the command */
+		*len = ERRLOG_CMD_STOP_SIZE;	/* buffer length */
+		*chan = CHAN_ERRLOG;	/* and channel */
+		card->err_log_state = ERRLOG_STATE_OFF;		/* new state is off */
+		return (1);	/* tell that data should be send */
+	}			/* error log start and able to send */
+	/* now handle network interface packets */
+	if ((skb = hysdn_tx_netget(card)) != NULL) {
+		if (skb->len <= maxlen) {
+			memcpy(buf, skb->data, skb->len);	/* copy the packet to the buffer */
+			*len = skb->len;
+			*chan = CHAN_NDIS_DATA;
+			card->net_tx_busy = 1;	/* we are busy sending network data */
+			return (1);	/* go and send the data */
+		} else
+			hysdn_tx_netack(card);	/* aknowledge packet -> throw away */
+	}			/* send a network packet if available */
+#ifdef CONFIG_HYSDN_CAPI
+	if((skb = hycapi_tx_capiget(card)) != NULL) {
+		if (skb->len <= maxlen) {
+			memcpy(buf, skb->data, skb->len);
+			*len = skb->len;
+			*chan = CHAN_CAPI;
+			hycapi_tx_capiack(card);
+			return (1);	/* go and send the data */
+		}
+	}
+#endif /* CONFIG_HYSDN_CAPI */
+	return (0);		/* nothing to send */
+}				/* hysdn_sched_tx */
+
+
+/*****************************************************************************/
+/* send one config line to the card and return 0 if successfull, otherwise a */
+/* negative error code.                                                      */
+/* The function works with timeouts perhaps not giving the greatest speed    */
+/* sending the line, but this should be meaningless beacuse only some lines  */
+/* are to be sent and this happens very seldom.                              */
+/*****************************************************************************/
+int
+hysdn_tx_cfgline(hysdn_card * card, uchar * line, word chan)
+{
+	int cnt = 50;		/* timeout intervalls */
+	ulong flags;
+
+	if (card->debug_flags & LOG_SCHED_ASYN)
+		hysdn_addlog(card, "async tx-cfg chan=%d len=%d", chan, strlen(line) + 1);
+
+	save_flags(flags);
+	cli();
+	while (card->async_busy) {
+		sti();
+
+		if (card->debug_flags & LOG_SCHED_ASYN)
+			hysdn_addlog(card, "async tx-cfg delayed");
+
+		set_current_state(TASK_INTERRUPTIBLE);
+		schedule_timeout((20 * HZ) / 1000);	/* Timeout 20ms */
+		if (!--cnt) {
+			restore_flags(flags);
+			return (-ERR_ASYNC_TIME);	/* timed out */
+		}
+		cli();
+	}			/* wait for buffer to become free */
+
+	strcpy(card->async_data, line);
+	card->async_len = strlen(line) + 1;
+	card->async_channel = chan;
+	card->async_busy = 1;	/* request transfer */
+
+	/* now queue the task */
+	queue_task(&card->irq_queue, &tq_immediate);
+	mark_bh(IMMEDIATE_BH);
+	sti();
+
+	if (card->debug_flags & LOG_SCHED_ASYN)
+		hysdn_addlog(card, "async tx-cfg data queued");
+
+	cnt++;			/* short delay */
+	cli();
+
+	while (card->async_busy) {
+		sti();
+
+		if (card->debug_flags & LOG_SCHED_ASYN)
+			hysdn_addlog(card, "async tx-cfg waiting for tx-ready");
+
+		set_current_state(TASK_INTERRUPTIBLE);
+		schedule_timeout((20 * HZ) / 1000);	/* Timeout 20ms */
+		if (!--cnt) {
+			restore_flags(flags);
+			return (-ERR_ASYNC_TIME);	/* timed out */
+		}
+		cli();
+	}			/* wait for buffer to become free again */
+
+	restore_flags(flags);
+
+	if (card->debug_flags & LOG_SCHED_ASYN)
+		hysdn_addlog(card, "async tx-cfg data send");
+
+	return (0);		/* line send correctly */
+}				/* hysdn_tx_cfgline */
diff -urN linux-2.2.19-pre10/drivers/isdn/hysdn/ince1pc.h linux/drivers/isdn/hysdn/ince1pc.h
--- linux-2.2.19-pre10/drivers/isdn/hysdn/ince1pc.h	Wed Dec 31 16:00:00 1969
+++ linux/drivers/isdn/hysdn/ince1pc.h	Mon Dec  3 21:03:00 2001
@@ -0,0 +1,132 @@
+#ifndef __INCE1PC_H__
+#define __INCE1PC_H__
+
+/****************************************************************************
+
+    FILE:       ince1pc.h
+
+    AUTHOR:     M.Steinkopf
+
+    PURPOSE:    common definitions for both sides of the bus:
+		- conventions both spoolers must know
+		- channel numbers agreed upon
+
+*****************************************************************************/ 
+
+/*  basic scalar definitions have same meanning,
+ *  but their declaration location depends on environment
+ */ 
+
+/*--------------------------------------channel numbers---------------------*/ 
+#define CHAN_SYSTEM     0x0001      /* system channel (spooler to spooler) */
+#define CHAN_ERRLOG     0x0005      /* error logger */
+#define CHAN_CAPI       0x0064      /* CAPI interface */
+#define CHAN_NDIS_DATA  0x1001      /* NDIS data transfer */
+
+/*--------------------------------------POF ready msg-----------------------*/ 
+	    /* NOTE: after booting POF sends system ready message to PC: */ 
+#define RDY_MAGIC       0x52535953UL    /* 'SYSR' reversed */
+#define RDY_MAGIC_SIZE  4               /* size in bytes */
+
+#define MAX_N_TOK_BYTES 255
+
+#define MIN_RDY_MSG_SIZE    RDY_MAGIC_SIZE
+#define MAX_RDY_MSG_SIZE    (RDY_MAGIC_SIZE+MAX_N_TOK_BYTES)
+
+#define SYSR_TOK_END            0
+#define SYSR_TOK_B_CHAN         1   /* nr. of B-Channels;   DataLen=1; def: 2 */
+#define SYSR_TOK_FAX_CHAN       2   /* nr. of FAX Channels; DataLen=1; def: 0 */
+#define SYSR_TOK_MAC_ADDR       3   /* MAC-Address; DataLen=6; def: auto */
+#define SYSR_TOK_ESC            255 /* undefined data size yet */
+			    /* default values, if not corrected by token: */ 
+#define SYSR_TOK_B_CHAN_DEF     2   /* assume 2 B-Channels */
+#define SYSR_TOK_FAX_CHAN_DEF   1   /* assume 1 FAX Channel */
+
+/*  syntax of new SYSR token stream:
+ *  channel: CHAN_SYSTEM
+ *  msgsize: MIN_RDY_MSG_SIZE <= x <= MAX_RDY_MSG_SIZE
+ *           RDY_MAGIC_SIZE   <= x <= (RDY_MAGIC_SIZE+MAX_N_TOK_BYTES)
+ *  msg    : 0 1 2 3 {4 5 6 ..}
+ *           S Y S R  MAX_N_TOK_BYTES bytes of TokenStream
+ *
+ *  TokenStream     :=   empty
+ *                     | {NonEndTokenChunk} EndToken RotlCRC
+ *  NonEndTokenChunk:= NonEndTokenId DataLen [Data]
+ *  NonEndTokenId   := 0x01 .. 0xFE                 1 BYTE
+ *  DataLen         := 0x00 .. 0xFF                 1 BYTE
+ *  Data            := DataLen bytes
+ *  EndToken        := 0x00
+ *  RotlCRC         := special 1 byte CRC over all NonEndTokenChunk bytes
+ *                     s. RotlCRC algorithm
+ *
+ *  RotlCRC algorithm:
+ *      ucSum= 0                        1 uchar
+ *      for all NonEndTokenChunk bytes:
+ *          ROTL(ucSum,1)               rotate left by 1
+ *          ucSum += Char;              add current byte with swap around
+ *      RotlCRC= ~ucSum;                invert all bits for result
+ *
+ *  note:
+ *  - for 16-bit FIFO add padding 0 byte to achieve even token data bytes!
+ */ 
+
+/*--------------------------------------error logger------------------------*/ 
+					    /* note: pof needs final 0 ! */ 
+#define ERRLOG_CMD_REQ          "ERRLOG ON"
+#define ERRLOG_CMD_REQ_SIZE     10              /* with final 0 byte ! */
+#define ERRLOG_CMD_STOP         "ERRLOG OFF"
+#define ERRLOG_CMD_STOP_SIZE    11              /* with final 0 byte ! */
+
+#define ERRLOG_ENTRY_SIZE       64      /* sizeof(tErrLogEntry) */
+					/* remaining text size = 55 */ 
+#define ERRLOG_TEXT_SIZE    (ERRLOG_ENTRY_SIZE-2*4-1)
+
+typedef struct ErrLogEntry_tag {
+	
+/*00 */ ulong ulErrType;
+	
+/*04 */ ulong ulErrSubtype;
+	
+/*08 */ uchar ucTextSize;
+	
+	/*09 */ uchar ucText[ERRLOG_TEXT_SIZE];
+	/* ASCIIZ of len ucTextSize-1 */
+	
+/*40 */ 
+} tErrLogEntry;
+
+
+#if defined(__TURBOC__)
+#if sizeof(tErrLogEntry) != ERRLOG_ENTRY_SIZE
+#error size of tErrLogEntry != ERRLOG_ENTRY_SIZE
+#endif				/*  */
+#endif				/*  */
+
+/*--------------------------------------DPRAM boot spooler------------------*/ 
+				/*  this is the struture used between pc and
+				 *  hyperstone to exchange boot data
+				 */ 
+#define DPRAM_SPOOLER_DATA_SIZE 0x20
+typedef struct DpramBootSpooler_tag {
+	
+/*00 */ uchar Len;
+	
+/*01 */ volatile uchar RdPtr;
+	
+/*02 */ uchar WrPtr;
+	
+/*03 */ uchar Data[DPRAM_SPOOLER_DATA_SIZE];
+	
+/*23 */ 
+} tDpramBootSpooler;
+
+
+#define DPRAM_SPOOLER_MIN_SIZE  5       /* Len+RdPtr+Wrptr+2*data */
+#define DPRAM_SPOOLER_DEF_SIZE  0x23    /* current default size   */
+
+/*--------------------------------------HYCARD/ERGO DPRAM SoftUart----------*/ 
+				    /* at DPRAM offset 0x1C00: */ 
+#define SIZE_RSV_SOFT_UART  0x1B0   /* 432 bytes reserved for SoftUart */
+
+
+#endif	/* __INCE1PC_H__ */
diff -urN linux-2.2.19-pre10/drivers/isdn/icn/Makefile linux/drivers/isdn/icn/Makefile
--- linux-2.2.19-pre10/drivers/isdn/icn/Makefile	Fri Jan 16 11:18:09 1998
+++ linux/drivers/isdn/icn/Makefile	Mon Dec  3 21:03:00 2001
@@ -1,8 +1,11 @@
-ifeq ($(CONFIG_ISDN_DRV_ICN),y)
-  O_TARGET := icn_obj.o
-  O_OBJS   := icn.o
-else
-  M_OBJS   := icn.o
-endif
+# Makefile for the act2000 ISDN device driver
 
-include $(TOPDIR)/Rules.make
+# The target object and module list name.
+
+O_TARGET	:= vmlinux-obj.o
+
+# Each configuration option enables a list of files.
+
+obj-$(CONFIG_ISDN_DRV_ICN)	+= icn.o
+
+include $(TOPDIR)/drivers/isdn/Rules.make
diff -urN linux-2.2.19-pre10/drivers/isdn/icn/icn.c linux/drivers/isdn/icn/icn.c
--- linux-2.2.19-pre10/drivers/isdn/icn/icn.c	Sun Dec 10 16:49:42 2000
+++ linux/drivers/isdn/icn/icn.c	Mon Dec  3 21:03:00 2001
@@ -1,4 +1,4 @@
-/* $Id: icn.c,v 1.65 2000/11/13 22:51:48 kai Exp $
+/* $Id: icn.c,v 1.65.6.2 2000/12/17 22:45:13 kai Exp $
 
  * ISDN low-level module for the ICN active ISDN-Card.
  *
@@ -21,6 +21,7 @@
  */
 
 #include "icn.h"
+#include <linux/init.h>
 
 /*
  * Verbose bootcode- and protocol-downloading.
@@ -33,7 +34,7 @@
 #undef MAP_DEBUG
 
 static char
-*revision = "$Revision: 1.65 $";
+*revision = "$Revision: 1.65.6.2 $";
 
 static int icn_addcard(int, char *, char *);
 
@@ -1638,9 +1639,7 @@
 	return 0;
 }
 
-#ifdef MODULE
-#define icn_init init_module
-#else
+#ifndef MODULE
 void
 icn_setup(char *str, int *ints)
 {
@@ -1661,10 +1660,9 @@
 		}
 	}
 }
-#endif /* MODULES */
+#endif /* MODULE */
 
-int
-icn_init(void)
+static int __init icn_init(void)
 {
 	char *p;
 	char rev[10];
@@ -1675,9 +1673,6 @@
 	dev.mcard = NULL;
 	dev.firstload = 1;
 
-	/* No symbols to export, hide all symbols */
-	EXPORT_NO_SYMBOLS;
-
 	if ((p = strchr(revision, ':'))) {
 		strcpy(rev, p + 1);
 		p = strchr(rev, '$');
@@ -1689,9 +1684,7 @@
 	return (icn_addcard(portbase, icn_id, icn_id2));
 }
 
-#ifdef MODULE
-void
-cleanup_module(void)
+static void  icn_exit(void)
 {
 	isdn_ctrl cmd;
 	icn_card *card = cards;
@@ -1725,4 +1718,6 @@
 		release_shmem((ulong) dev.shmem, 0x4000);
 	printk(KERN_NOTICE "ICN-ISDN-driver unloaded\n");
 }
-#endif
+
+module_init(icn_init);
+module_exit(icn_exit);
diff -urN linux-2.2.19-pre10/drivers/isdn/icn/icn.h linux/drivers/isdn/icn/icn.h
--- linux-2.2.19-pre10/drivers/isdn/icn/icn.h	Sun Dec 10 16:49:42 2000
+++ linux/drivers/isdn/icn/icn.h	Mon Dec  3 21:03:00 2001
@@ -1,4 +1,4 @@
-/* $Id: icn.h,v 1.30 2000/11/13 22:51:48 kai Exp $
+/* $Id: icn.h,v 1.30.6.1 2001/02/10 14:41:23 kai Exp $
 
  * ISDN lowlevel-module for the ICN active ISDN-Card.
  *
@@ -55,7 +55,7 @@
 #include <asm/io.h>
 #include <linux/kernel.h>
 #include <linux/signal.h>
-#include <linux/malloc.h>
+#include <linux/slab.h>
 #include <linux/mm.h>
 #include <linux/mman.h>
 #include <linux/ioport.h>
diff -urN linux-2.2.19-pre10/drivers/isdn/isdn_bsdcomp.c linux/drivers/isdn/isdn_bsdcomp.c
--- linux-2.2.19-pre10/drivers/isdn/isdn_bsdcomp.c	Tue Oct 26 17:53:40 1999
+++ linux/drivers/isdn/isdn_bsdcomp.c	Mon Dec  3 21:03:00 2001
@@ -47,12 +47,8 @@
  * SUCH DAMAGE.
  */
 
-#ifndef MODULE
-#error This file must be compiled as a module.
-#endif
-
 #include <linux/module.h>
-
+#include <linux/init.h>
 #include <linux/kernel.h>
 #include <linux/sched.h>
 #include <linux/types.h>
@@ -61,7 +57,7 @@
 #include <linux/ptrace.h>
 #include <linux/ioport.h>
 #include <linux/in.h>
-#include <linux/malloc.h>
+#include <linux/slab.h>
 #include <linux/tty.h>
 #include <linux/errno.h>
 #include <linux/string.h>	/* used in new tty drivers */
@@ -919,7 +915,7 @@
  * Module support routines
  *************************************************************/
 
-int init_module(void)
+static int __init isdn_bsdcomp_init(void)
 {
 	int answer = isdn_ppp_register_compressor (&ippp_bsd_compress);
 	if (answer == 0)
@@ -927,7 +923,10 @@
 	return answer;
 }
 
-void cleanup_module(void)
+static void  isdn_bsdcomp_exit(void)
 {
 	isdn_ppp_unregister_compressor (&ippp_bsd_compress);
 }
+
+module_init(isdn_bsdcomp_init);
+module_exit(isdn_bsdcomp_exit);
diff -urN linux-2.2.19-pre10/drivers/isdn/isdn_cards.c linux/drivers/isdn/isdn_cards.c
--- linux-2.2.19-pre10/drivers/isdn/isdn_cards.c	Sun Dec 10 16:49:42 2000
+++ linux/drivers/isdn/isdn_cards.c	Wed Dec 31 16:00:00 1969
@@ -1,73 +0,0 @@
-/* $Id: isdn_cards.c,v 1.13 2000/10/28 23:03:38 kai Exp $
-
- * Linux ISDN subsystem, initialization for non-modularized drivers.
- *
- * Copyright 1994,95,96 by Fritz Elfert (fritz@isdn4linux.de)
- *
- * 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; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- */
-
-#include <linux/config.h>
-
-#ifdef CONFIG_ISDN_DRV_ICN
-extern void icn_init(void);
-#endif
-
-#ifdef CONFIG_ISDN_DRV_HISAX
-extern void HiSax_init(void);
-#endif
-
-#ifdef CONFIG_ISDN_DRV_PCBIT
-extern void pcbit_init(void);
-#endif
-
-#ifdef CONFIG_ISDN_DRV_EICON
-extern void eicon_init(void);
-#endif
-
-#ifdef CONFIG_ISDN_DRV_AVMB1
-extern void kcapi_init(void);
-extern void capi_init(void);
-extern void capidrv_init(void);
-#endif
-#if CONFIG_ISDN_DRV_ACT2000
-extern void act2000_init(void);
-#endif
-
-void
-isdn_cards_init(void)
-{
-#if CONFIG_ISDN_DRV_ICN
-	icn_init();
-#endif
-#ifdef CONFIG_ISDN_DRV_HISAX
-	HiSax_init();
-#endif
-#if CONFIG_ISDN_DRV_PCBIT
-	pcbit_init();
-#endif
-#ifdef CONFIG_ISDN_DRV_AVMB1
-	kcapi_init();
-	capi_init();
-	capidrv_init();
-#endif
-#if CONFIG_ISDN_DRV_ACT2000
-	act2000_init();
-#endif
-#if CONFIG_ISDN_DRV_EICON
-	eicon_init();
-#endif
-}
diff -urN linux-2.2.19-pre10/drivers/isdn/isdn_cards.h linux/drivers/isdn/isdn_cards.h
--- linux-2.2.19-pre10/drivers/isdn/isdn_cards.h	Sun Dec 10 16:49:42 2000
+++ linux/drivers/isdn/isdn_cards.h	Wed Dec 31 16:00:00 1969
@@ -1,23 +0,0 @@
-/* $Id: isdn_cards.h,v 1.4 2000/05/11 22:29:20 kai Exp $
-
- * Linux ISDN subsystem, initialization for non-modularized drivers.
- *
- * Copyright 1994-1999 by Fritz Elfert (fritz@isdn4linux.de)
- *
- * 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; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- */
-
-extern void isdn_cards_init(void);
diff -urN linux-2.2.19-pre10/drivers/isdn/isdn_common.c linux/drivers/isdn/isdn_common.c
--- linux-2.2.19-pre10/drivers/isdn/isdn_common.c	Mon Dec  3 21:02:16 2001
+++ linux/drivers/isdn/isdn_common.c	Mon Dec  3 21:03:00 2001
@@ -1,4 +1,4 @@
-/* $Id: isdn_common.c,v 1.114.6.3 2000/12/18 22:14:09 kai Exp $
+/* $Id: isdn_common.c,v 1.114.6.7 2001/02/10 14:41:19 kai Exp $
 
  * Linux ISDN subsystem, common used functions (linklevel).
  *
@@ -24,6 +24,7 @@
 
 #include <linux/config.h>
 #include <linux/module.h>
+#include <linux/init.h>
 #include <linux/version.h>
 #include <linux/poll.h>
 #include <linux/vmalloc.h>
@@ -40,7 +41,6 @@
 #include <linux/isdn_divertif.h>
 #endif CONFIG_ISDN_DIVERSION
 #include "isdn_v110.h"
-#include "isdn_cards.h"
 
 /* Debugflags */
 #undef ISDN_DEBUG_STATCALLB
@@ -2230,12 +2230,6 @@
  *****************************************************************************
  */
 
-extern int printk(const char *fmt,...);
-
-#ifdef MODULE
-#define isdn_init init_module
-#endif
-
 static char *
 isdn_getrev(const char *revision)
 {
@@ -2255,8 +2249,7 @@
 /*
  * Allocate and initialize all data, register modem-devices
  */
-int
-isdn_init(void)
+static int __init isdn_init(void)
 {
 	int i;
 	char tmprev[50];
@@ -2323,18 +2316,15 @@
 	printk(" loaded\n");
 #else
 	printk("\n");
-	isdn_cards_init();
 #endif
 	isdn_info_update();
 	return 0;
 }
 
-#ifdef MODULE
 /*
  * Unload module
  */
-void
-cleanup_module(void)
+static void  isdn_exit(void)
 {
 	int flags;
 	int i;
@@ -2377,4 +2367,6 @@
 		printk(KERN_NOTICE "ISDN-subsystem unloaded\n");
 	}
 }
-#endif
+
+module_init(isdn_init);
+module_exit(isdn_exit);
diff -urN linux-2.2.19-pre10/drivers/isdn/isdn_v110.c linux/drivers/isdn/isdn_v110.c
--- linux-2.2.19-pre10/drivers/isdn/isdn_v110.c	Mon Dec  3 21:02:16 2001
+++ linux/drivers/isdn/isdn_v110.c	Mon Dec  3 21:03:00 2001
@@ -1,4 +1,4 @@
-/* $Id: isdn_v110.c,v 1.5.6.1 2001/01/23 17:45:02 kai Exp $
+/* $Id: isdn_v110.c,v 1.5.6.2 2001/02/10 14:41:19 kai Exp $
 
  * Linux ISDN subsystem, V.110 related functions (linklevel).
  *
@@ -22,7 +22,7 @@
 
 #include <linux/string.h>
 #include <linux/kernel.h>
-#include <linux/malloc.h>
+#include <linux/slab.h>
 #include <linux/mm.h>
 
 #include <linux/isdn.h>
@@ -30,7 +30,7 @@
 
 #undef ISDN_V110_DEBUG
 
-char *isdn_v110_revision = "$Revision: 1.5.6.1 $";
+char *isdn_v110_revision = "$Revision: 1.5.6.2 $";
 
 #define V110_38400 255
 #define V110_19200  15
diff -urN linux-2.2.19-pre10/drivers/isdn/isdnloop/Makefile linux/drivers/isdn/isdnloop/Makefile
--- linux-2.2.19-pre10/drivers/isdn/isdnloop/Makefile	Wed Apr  1 16:21:03 1998
+++ linux/drivers/isdn/isdnloop/Makefile	Mon Dec  3 21:03:00 2001
@@ -1,11 +1,14 @@
-L_OBJS :=
-M_OBJS :=
+#
+# Makefile for the isdnloop ISDN device driver
+#
 
-ifeq ($(CONFIG_ISDN_DRV_LOOP),y)
-  L_OBJS += isdnloop.o
-else
-  M_OBJS += isdnloop.o
-endif
+# The target object and module list name.
 
-include $(TOPDIR)/Rules.make
+O_TARGET	:= vmlinux-obj.o
+
+# Each configuration option enables a list of files.
+
+obj-$(CONFIG_ISDN_DRV_LOOP)	+= isdnloop.o
+
+include $(TOPDIR)/drivers/isdn/Rules.make
 
diff -urN linux-2.2.19-pre10/drivers/isdn/isdnloop/isdnloop.c linux/drivers/isdn/isdnloop/isdnloop.c
--- linux-2.2.19-pre10/drivers/isdn/isdnloop/isdnloop.c	Sun Dec 10 16:49:42 2000
+++ linux/drivers/isdn/isdnloop/isdnloop.c	Mon Dec  3 21:03:00 2001
@@ -1,4 +1,4 @@
-/* $Id: isdnloop.c,v 1.11 2000/11/13 22:51:50 kai Exp $
+/* $Id: isdnloop.c,v 1.11.6.1 2000/12/17 16:47:18 kai Exp $
 
  * ISDN low-level module implementing a dummy loop driver.
  *
@@ -21,10 +21,12 @@
  */
 
 #include <linux/config.h>
+#include <linux/module.h>
+#include <linux/init.h>
 #include "isdnloop.h"
 
 static char
-*revision = "$Revision: 1.11 $";
+*revision = "$Revision: 1.11.6.1 $";
 
 static int isdnloop_addcard(char *);
 
@@ -1534,22 +1536,7 @@
 	return 0;
 }
 
-#ifdef MODULE
-#define isdnloop_init init_module
-#else
-void
-isdnloop_setup(char *str, int *ints)
-{
-	static char sid[20];
-
-	if (strlen(str)) {
-		strcpy(sid, str);
-		isdnloop_id = sid;
-	}
-}
-#endif
-
-int
+static int __init
 isdnloop_init(void)
 {
 	char *p;
@@ -1568,9 +1555,8 @@
 	return (isdnloop_addcard(isdnloop_id));
 }
 
-#ifdef MODULE
-void
-cleanup_module(void)
+static void 
+isdnloop_exit(void)
 {
 	isdn_ctrl cmd;
 	isdnloop_card *card = cards;
@@ -1598,4 +1584,6 @@
 	}
 	printk(KERN_NOTICE "isdnloop-ISDN-driver unloaded\n");
 }
-#endif
+
+module_init(isdnloop_init);
+module_exit(isdnloop_exit);
diff -urN linux-2.2.19-pre10/drivers/isdn/isdnloop/isdnloop.h linux/drivers/isdn/isdnloop/isdnloop.h
--- linux-2.2.19-pre10/drivers/isdn/isdnloop/isdnloop.h	Sun Dec 10 16:49:42 2000
+++ linux/drivers/isdn/isdnloop/isdnloop.h	Mon Dec  3 21:03:00 2001
@@ -1,4 +1,4 @@
-/* $Id: isdnloop.h,v 1.5 2000/11/13 22:51:50 kai Exp $
+/* $Id: isdnloop.h,v 1.5.6.1 2001/02/10 14:41:23 kai Exp $
 
  * Loopback lowlevel module for testing of linklevel.
  *
@@ -53,7 +53,7 @@
 #include <asm/io.h>
 #include <linux/kernel.h>
 #include <linux/signal.h>
-#include <linux/malloc.h>
+#include <linux/slab.h>
 #include <linux/mm.h>
 #include <linux/mman.h>
 #include <linux/ioport.h>
diff -urN linux-2.2.19-pre10/drivers/isdn/pcbit/Makefile linux/drivers/isdn/pcbit/Makefile
--- linux-2.2.19-pre10/drivers/isdn/pcbit/Makefile	Sun Apr 21 01:56:14 1996
+++ linux/drivers/isdn/pcbit/Makefile	Mon Dec  3 21:03:00 2001
@@ -1,15 +1,21 @@
-L_OBJS :=
-M_OBJS :=
-O_OBJS := module.o edss1.o drv.o layer2.o capi.o callbacks.o 
-
-O_TARGET :=
-ifeq ($(CONFIG_ISDN_DRV_PCBIT),y)
-  O_TARGET += pcbit.o
-else
-  ifeq ($(CONFIG_ISDN_DRV_PCBIT),m)
-    O_TARGET += pcbit.o
-    M_OBJS += pcbit.o
-  endif
-endif
+# Makefile for the pcbit ISDN device driver
 
-include $(TOPDIR)/Rules.make
+# The target object and module list name.
+
+O_TARGET	:= vmlinux-obj.o
+
+# Multipart objects.
+
+list-multi	:= pcbit.o
+pcbit-objs	:= module.o edss1.o drv.o layer2.o capi.o callbacks.o
+
+# Each configuration option enables a list of files.
+
+obj-$(CONFIG_ISDN_DRV_PCBIT)	+= pcbit.o
+
+include $(TOPDIR)/drivers/isdn/Rules.make
+
+# Link rules for multi-part drivers.
+
+pcbit.o: $(pcbit-objs)
+	$(LD) -r -o $@ $(pcbit-objs)
diff -urN linux-2.2.19-pre10/drivers/isdn/pcbit/callbacks.c linux/drivers/isdn/pcbit/callbacks.c
--- linux-2.2.19-pre10/drivers/isdn/pcbit/callbacks.c	Mon Aug  9 12:04:39 1999
+++ linux/drivers/isdn/pcbit/callbacks.c	Mon Dec  3 21:03:00 2001
@@ -27,7 +27,7 @@
 #include <linux/kernel.h>
 
 #include <linux/types.h>
-#include <linux/malloc.h>
+#include <linux/slab.h>
 #include <linux/mm.h>
 #include <linux/tqueue.h>
 #include <linux/skbuff.h>
diff -urN linux-2.2.19-pre10/drivers/isdn/pcbit/capi.c linux/drivers/isdn/pcbit/capi.c
--- linux-2.2.19-pre10/drivers/isdn/pcbit/capi.c	Wed May  3 17:16:40 2000
+++ linux/drivers/isdn/pcbit/capi.c	Mon Dec  3 21:03:00 2001
@@ -37,7 +37,7 @@
 #include <linux/kernel.h>
 
 #include <linux/types.h>
-#include <linux/malloc.h>
+#include <linux/slab.h>
 #include <linux/mm.h>
 
 #include <linux/tqueue.h>
diff -urN linux-2.2.19-pre10/drivers/isdn/pcbit/drv.c linux/drivers/isdn/pcbit/drv.c
--- linux-2.2.19-pre10/drivers/isdn/pcbit/drv.c	Wed May  3 17:16:40 2000
+++ linux/drivers/isdn/pcbit/drv.c	Mon Dec  3 21:03:00 2001
@@ -28,7 +28,7 @@
 #include <linux/kernel.h>
 
 #include <linux/types.h>
-#include <linux/malloc.h>
+#include <linux/slab.h>
 #include <linux/mm.h>
 #include <linux/interrupt.h>
 #include <linux/string.h>
@@ -86,6 +86,7 @@
 
 	dev_pcbit[board] = dev;
 	memset(dev, 0, sizeof(struct pcbit_dev));
+	init_waitqueue_head(&dev->set_running_wq);
 
 	if (mem_base >= 0xA0000 && mem_base <= 0xFFFFF ) {
 		dev->ph_mem = mem_base;
@@ -118,8 +119,6 @@
 	memset(dev->b2, 0, sizeof(struct pcbit_chan));
 	dev->b2->id = 1;
 
-
-	dev->qdelivery.next = NULL;
 	dev->qdelivery.sync = 0;
 	dev->qdelivery.routine = pcbit_deliver;
 	dev->qdelivery.data = dev;
diff -urN linux-2.2.19-pre10/drivers/isdn/pcbit/edss1.c linux/drivers/isdn/pcbit/edss1.c
--- linux-2.2.19-pre10/drivers/isdn/pcbit/edss1.c	Sat Aug 31 10:01:58 1996
+++ linux/drivers/isdn/pcbit/edss1.c	Mon Dec  3 21:03:00 2001
@@ -26,7 +26,7 @@
 #include <linux/kernel.h>
 
 #include <linux/types.h>
-#include <linux/malloc.h>
+#include <linux/slab.h>
 #include <linux/mm.h>
 #include <linux/tqueue.h>
 #include <linux/skbuff.h>
diff -urN linux-2.2.19-pre10/drivers/isdn/pcbit/layer2.c linux/drivers/isdn/pcbit/layer2.c
--- linux-2.2.19-pre10/drivers/isdn/pcbit/layer2.c	Wed May  3 17:16:40 2000
+++ linux/drivers/isdn/pcbit/layer2.c	Mon Dec  3 21:03:00 2001
@@ -40,7 +40,7 @@
 #include <linux/string.h>
 #include <linux/kernel.h>
 #include <linux/types.h>
-#include <linux/malloc.h>
+#include <linux/slab.h>
 #include <linux/interrupt.h>
 #include <linux/tqueue.h>
 #include <linux/mm.h>
diff -urN linux-2.2.19-pre10/drivers/isdn/pcbit/module.c linux/drivers/isdn/pcbit/module.c
--- linux-2.2.19-pre10/drivers/isdn/pcbit/module.c	Wed May  3 17:16:40 2000
+++ linux/drivers/isdn/pcbit/module.c	Mon Dec  3 21:03:00 2001
@@ -12,7 +12,7 @@
  */
 
 #include <linux/module.h>
-
+#include <linux/init.h>
 #include <linux/sched.h>
 #include <linux/string.h>
 #include <linux/kernel.h>
@@ -26,21 +26,12 @@
 static int irq[MAX_PCBIT_CARDS] = {0, };
 
 static int num_boards;
-struct pcbit_dev * dev_pcbit[MAX_PCBIT_CARDS] = {0, 0, 0, 0};
-
-int init_module(void);
-void cleanup_module(void);
+struct pcbit_dev * dev_pcbit[MAX_PCBIT_CARDS] = {0, };
 
 extern void pcbit_terminate(int board);
 extern int pcbit_init_dev(int board, int mem_base, int irq);
 
-#ifdef MODULE
-MODULE_PARM(mem, "1-" __MODULE_STRING(MAX_PCBIT_CARDS) "i");
-MODULE_PARM(irq, "1-" __MODULE_STRING(MAX_PCBIT_CARDS) "i");
-#define pcbit_init init_module
-#endif
-
-int pcbit_init(void)
+static int __init pcbit_init(void)
 {
 	int board;
 
@@ -83,15 +74,10 @@
 		else
 			return -EIO;
 	}
-
-	/* No symbols to export, hide all symbols */
-	EXPORT_NO_SYMBOLS;
-
 	return 0;
 }
 
-#ifdef MODULE
-void cleanup_module(void)
+static void  pcbit_exit(void)
 {
 	int board;
 
@@ -101,7 +87,7 @@
 	       "PCBIT-D module unloaded\n");
 }
 
-#else
+#ifndef MODULE
 void pcbit_setup(char *str, int *ints)
 {
 	int i, j, argc;
@@ -126,5 +112,9 @@
 }
 #endif
 
+MODULE_PARM(mem, "1-" __MODULE_STRING(MAX_PCBIT_CARDS) "i");
+MODULE_PARM(irq, "1-" __MODULE_STRING(MAX_PCBIT_CARDS) "i");
 
+module_init(pcbit_init);
+module_exit(pcbit_exit);
 
diff -urN linux-2.2.19-pre10/drivers/isdn/pcbit/pcbit.h linux/drivers/isdn/pcbit/pcbit.h
--- linux-2.2.19-pre10/drivers/isdn/pcbit/pcbit.h	Tue Jan  4 10:12:17 2000
+++ linux/drivers/isdn/pcbit/pcbit.h	Mon Dec  3 21:03:00 2001
@@ -69,7 +69,7 @@
 	struct frame_buf *write_queue;
 
 	/* Protocol start */
-	struct wait_queue *set_running_wq;
+	wait_queue_head_t set_running_wq;
 	struct timer_list set_running_timer;
 
 	struct timer_list error_recover_timer;
diff -urN linux-2.2.19-pre10/drivers/isdn/sc/Makefile linux/drivers/isdn/sc/Makefile
--- linux-2.2.19-pre10/drivers/isdn/sc/Makefile	Thu Jun 26 12:33:39 1997
+++ linux/drivers/isdn/sc/Makefile	Mon Dec  3 21:03:00 2001
@@ -1,44 +1,22 @@
-#
-#  $Id: Makefile,v 1.1 1997/03/22 02:01:22 fritz Exp $
-#  Copyright (C) 1996  SpellCaster Telecommunications Inc.
-#
-#  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 of the License, 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; if not, write to the Free Software
-#  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-#
-#  For more information, please contact gpl-info@spellcast.com or write:
-#
-#     SpellCaster Telecommunications Inc.
-#     5621 Finch Avenue East, Unit #3
-#     Scarborough, Ontario  Canada
-#     M1B 2T9
-#     +1 (416) 297-8565
-#     +1 (416) 297-6433 Facsimile
-#
-
-L_OBJS :=
-M_OBJS :=
-O_OBJS := shmem.o init.o debug.o packet.o command.o event.o \
-	ioctl.o interrupt.o message.o timer.o
-
-O_TARGET :=
-ifeq ($(CONFIG_ISDN_DRV_SC),y)
-	O_TARGET += sc.o
-else
-  ifeq ($(CONFIG_ISDN_DRV_SC),m)
-    O_TARGET += sc.o
-    M_OBJS += sc.o
-  endif
-endif
+# Makefile for the sc ISDN device driver
 
-include $(TOPDIR)/Rules.make
+# The target object and module list name.
+
+O_TARGET	:= vmlinux-obj.o
+
+# Multipart objects.
+
+list-multi	:= sc.o
+sc-objs		:= shmem.o init.o debug.o packet.o command.o event.o \
+		   ioctl.o interrupt.o message.o timer.o	
+
+# Each configuration option enables a list of files.
+
+obj-$(CONFIG_ISDN_DRV_SC)	+= sc.o
+
+include $(TOPDIR)/drivers/isdn/Rules.make
+
+# Link rules for multi-part drivers.
+
+sc.o: $(sc-objs)
+	$(LD) -r -o $@ $(sc-objs)
diff -urN linux-2.2.19-pre10/drivers/isdn/sc/includes.h linux/drivers/isdn/sc/includes.h
--- linux-2.2.19-pre10/drivers/isdn/sc/includes.h	Sun Jan 25 10:05:46 1998
+++ linux/drivers/isdn/sc/includes.h	Mon Dec  3 21:03:00 2001
@@ -5,7 +5,7 @@
 #include <asm/io.h>
 #include <linux/delay.h>
 #include <linux/kernel.h>
-#include <linux/malloc.h>
+#include <linux/slab.h>
 #include <linux/mm.h>
 #include <linux/ioport.h>
 #include <linux/timer.h>
diff -urN linux-2.2.19-pre10/drivers/isdn/sc/init.c linux/drivers/isdn/sc/init.c
--- linux-2.2.19-pre10/drivers/isdn/sc/init.c	Mon Dec  3 21:02:16 2001
+++ linux/drivers/isdn/sc/init.c	Mon Dec  3 21:03:00 2001
@@ -1,3 +1,5 @@
+#include <linux/module.h>
+#include <linux/init.h>
 #include "includes.h"
 #include "hardware.h"
 #include "card.h"
@@ -37,23 +39,12 @@
 	return 0;
 }
 
-#ifdef MODULE
 MODULE_PARM(io, "1-4i");
 MODULE_PARM(irq, "1-4i");
 MODULE_PARM(ram, "1-4i");
 MODULE_PARM(do_reset, "i");
-#define init_sc init_module
-#else
-/*
-Initialization code for non-module version to be included
 
-void sc_setup(char *str, int *ints)
-{
-}
-*/
-#endif
-
-int init_sc(void)
+static int __init sc_init(void)
 {
 	int b = -1;
 	int i, j;
@@ -410,8 +401,7 @@
 	return status;
 }
 
-#ifdef MODULE
-void cleanup_module(void)
+static void  sc_exit(void)
 {
 	int i, j;
 
@@ -463,7 +453,6 @@
 	}
 	pr_info("SpellCaster ISA ISDN Adapter Driver Unloaded.\n");
 }
-#endif
 
 int identify_board(unsigned long rambase, unsigned int iobase) 
 {
@@ -579,3 +568,6 @@
 		
 	return -1;
 }
+
+module_init(sc_init);
+module_exit(sc_exit);
diff -urN linux-2.2.19-pre10/drivers/net/Space.c linux/drivers/net/Space.c
--- linux-2.2.19-pre10/drivers/net/Space.c	Mon Dec  3 21:02:17 2001
+++ linux/drivers/net/Space.c	Mon Dec  3 21:03:00 2001
@@ -127,6 +127,7 @@
 extern int rcpci_probe(struct device *);
 extern int dmfe_probe(struct device *);
 extern int sktr_probe(struct device *dev);
+extern int starfire_probe(struct device *dev);
 
 /* Gigabit Ethernet adapters */
 extern int yellowfin_probe(struct device *dev);
@@ -278,9 +279,12 @@
 #ifdef CONFIG_VIA_RHINE
 	{via_rhine_probe, 0},
 #endif
-#ifdef CONFI_NET_DM9102
+#ifdef CONFIG_NET_DM9102
 	{dmfe_probe, 0},
-#endif	
+#endif
+#ifdef CONFIG_ADAPTEC_STARFIRE
+	{starfire_probe, 0},
+#endif
 	{NULL, 0},
 };
 
diff -urN linux-2.2.19-pre10/drivers/net/starfire.c linux/drivers/net/starfire.c
--- linux-2.2.19-pre10/drivers/net/starfire.c	Mon Dec  3 21:02:17 2001
+++ linux/drivers/net/starfire.c	Mon Dec  3 21:03:00 2001
@@ -20,7 +20,7 @@
 	-----------------------------------------------------------
 
 	Linux kernel-specific changes:
-	
+
 	LK1.1.1 (jgarzik):
 	- Use PCI driver interface
 	- Fix MOD_xxx races
@@ -31,7 +31,7 @@
 
 	LK1.1.3 (Andrew Morton)
 	- Timer cleanups
-	
+
 	LK1.1.4 (jgarzik):
 	- Merge Becker version 1.03
 
@@ -41,6 +41,17 @@
 
 	LK1.2.2 (Ion Badulescu)
 	- Backported to 2.2.x
+
+	LK1.2.3 (Ion Badulescu)
+	- Fix the flaky mdio interface
+	- More compat clean-ups
+
+	LK1.2.4 (Ion Badulescu)
+	- More 2.2.x initialization fixes
+
+TODO:
+	- implement tx_timeout() properly
+	- support ethtool
 */
 
 /* These identify the driver base version and may not be removed. */
@@ -50,7 +61,7 @@
 " Updates and info at http://www.scyld.com/network/starfire.html\n";
 
 static const char version3[] =
-" (unofficial 2.2.x kernel port, version 1.2.2, February 07, 2001)\n";
+" (unofficial 2.2.x kernel port, version 1.2.4, February 11, 2001)\n";
 
 /* The user-configurable values.
    These may be modified when a driver module is loaded.*/
@@ -66,8 +77,8 @@
  * for this driver to really use the firmware. Note that Rx/Tx
  * hardware TCP checksumming is not possible without the firmware.
  *
- * I'm currently talking to Adaptec about this redistribution issue.
- * Stay tuned...
+ * I'm currently [Feb 2001] talking to Adaptec about this redistribution
+ * issue. Stay tuned...
  */
 #undef HAS_FIRMWARE
 /*
@@ -75,10 +86,6 @@
  * of length 1. If and when this is fixed, the #define below can be removed.
  */
 #define HAS_BROKEN_FIRMWARE
-/*
- * Define this if using the driver with the zero-copy patch
- */
-#undef ZEROCOPY
 
 /* Used for tuning interrupt latency vs. overhead. */
 static int interrupt_mitigation = 0x0;
@@ -87,12 +94,27 @@
 static int max_interrupt_work = 20;
 static int mtu = 0;
 /* Maximum number of multicast addresses to filter (vs. rx-all-multicast).
-   The Starfire has a 512 element hash table based on the Ethernet CRC.  */
+   The Starfire has a 512 element hash table based on the Ethernet CRC. */
 static int multicast_filter_limit = 32;
 
-/* Set the copy breakpoint for the copy-only-tiny-frames scheme.
-   Setting to > 1518 effectively disables this feature. */
+#define PKT_BUF_SZ	1536		/* Size of each temporary Rx buffer.*/
+/*
+ * Set the copy breakpoint for the copy-only-tiny-frames scheme.
+ * Setting to > 1518 effectively disables this feature.
+ *
+ * NOTE:
+ * The ia64 doesn't allow for unaligned loads even of integers being
+ * misaligned on a 2 byte boundary. Thus always force copying of
+ * packets as the starfire doesn't allow for misaligned DMAs ;-(
+ * 23/10/2000 - Jes
+ *
+ * Neither does the Alpha. -Ion
+ */
+#if defined(__ia64__) || defined(__alpha__)
+static int rx_copybreak = PKT_BUF_SZ;
+#else
 static int rx_copybreak = 0;
+#endif
 
 /* Used to pass the media type, etc.
    Both 'options[]' and 'full_duplex[]' exist for driver interoperability.
@@ -116,29 +138,9 @@
 
 /* Operational parameters that usually are not changed. */
 /* Time in jiffies before concluding the transmitter is hung. */
-#define TX_TIMEOUT  (2*HZ)
-
-#define PKT_BUF_SZ		1536			/* Size of each temporary Rx buffer.*/
-
-/*
- * The ia64 doesn't allow for unaligned loads even of integers being
- * misaligned on a 2 byte boundary. Thus always force copying of
- * packets as the starfire doesn't allow for misaligned DMAs ;-(
- * 23/10/2000 - Jes
- *
- * Neither does the Alpha. -Ion
- */
-#if defined(__ia64__) || defined(__alpha__)
-#define PKT_SHOULD_COPY(pkt_len)       1
-#else
-#define PKT_SHOULD_COPY(pkt_len)       (pkt_len < rx_copybreak)
-#endif
+#define TX_TIMEOUT	(2*HZ)
 
-#ifdef ZEROCOPY
-#define skb_first_frag_len(skb)	skb_headlen(skb)
-#else  /* not ZEROCOPY */
 #define skb_first_frag_len(skb)	(skb->len)
-#endif /* not ZEROCOPY */
 
 #if !defined(__OPTIMIZE__)
 #warning  You must compile this file with the correct options!
@@ -146,6 +148,7 @@
 #error You must compile this driver with "-O".
 #endif
 
+#include <linux/version.h>
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/string.h>
@@ -159,58 +162,159 @@
 #include <linux/etherdevice.h>
 #include <linux/skbuff.h>
 #include <linux/init.h>
+#include <linux/delay.h>
 #include <asm/processor.h>		/* Processor type for cache alignment. */
 #include <asm/bitops.h>
 #include <asm/io.h>
 
-#include <linux/version.h>
+#ifdef HAS_FIRMWARE
+#include "starfire_firmware.h"
+#endif /* HAS_FIRMWARE */
+
+MODULE_AUTHOR("Donald Becker <becker@scyld.com>");
+MODULE_DESCRIPTION("Adaptec Starfire Ethernet driver");
+MODULE_PARM(max_interrupt_work, "i");
+MODULE_PARM(mtu, "i");
+MODULE_PARM(debug, "i");
+MODULE_PARM(rx_copybreak, "i");
+MODULE_PARM(interrupt_mitigation, "i");
+MODULE_PARM(options, "1-" __MODULE_STRING(MAX_UNITS) "i");
+MODULE_PARM(full_duplex, "1-" __MODULE_STRING(MAX_UNITS) "i");
+
+/*
+				Theory of Operation
+
+I. Board Compatibility
+
+This driver is for the Adaptec 6915 "Starfire" 64 bit PCI Ethernet adapter.
+
+II. Board-specific settings
+
+III. Driver operation
+
+IIIa. Ring buffers
+
+The Starfire hardware uses multiple fixed-size descriptor queues/rings.  The
+ring sizes are set fixed by the hardware, but may optionally be wrapped
+earlier by the END bit in the descriptor.
+This driver uses that hardware queue size for the Rx ring, where a large
+number of entries has no ill effect beyond increases the potential backlog.
+The Tx ring is wrapped with the END bit, since a large hardware Tx queue
+disables the queue layer priority ordering and we have no mechanism to
+utilize the hardware two-level priority queue.  When modifying the
+RX/TX_RING_SIZE pay close attention to page sizes and the ring-empty warning
+levels.
+
+IIIb/c. Transmit/Receive Structure
+
+See the Adaptec manual for the many possible structures, and options for
+each structure.  There are far too many to document here.
+
+For transmit this driver uses type 0/1 transmit descriptors (depending
+on the presence of the zerocopy patches), and relies on automatic
+minimum-length padding.  It does not use the completion queue
+consumer index, but instead checks for non-zero status entries.
+
+For receive this driver uses type 0 receive descriptors.  The driver
+allocates full frame size skbuffs for the Rx ring buffers, so all frames
+should fit in a single descriptor.  The driver does not use the completion
+queue consumer index, but instead checks for non-zero status entries.
+
+When an incoming frame is less than RX_COPYBREAK bytes long, a fresh skbuff
+is allocated and the frame is copied to the new skbuff.  When the incoming
+frame is larger, the skbuff is passed directly up the protocol stack.
+Buffers consumed this way are replaced by newly allocated skbuffs in a later
+phase of receive.
+
+A notable aspect of operation is that unaligned buffers are not permitted by
+the Starfire hardware.  The IP header at offset 14 in an ethernet frame thus
+isn't longword aligned, which may cause problems on some machine
+e.g. Alphas and IA64. For these architectures, the driver is forced to copy
+the frame into a new skbuff unconditionally. Copied frames are put into the
+skbuff at an offset of "+2", thus 16-byte aligning the IP header.
+
+IIId. Synchronization
+
+The driver runs as two independent, single-threaded flows of control.  One
+is the send-packet routine, which enforces single-threaded use by the
+dev->tbusy flag.  The other thread is the interrupt handler, which is single
+threaded by the hardware and interrupt handling software.
+
+The send packet thread has partial control over the Tx ring and 'dev->tbusy'
+flag.  It sets the tbusy flag whenever it's queuing a Tx packet. If the next
+queue slot is empty, it clears the tbusy flag when finished otherwise it sets
+the 'lp->tx_full' flag.
+
+The interrupt handler has exclusive control over the Rx ring and records stats
+from the Tx ring.  After reaping the stats, it marks the Tx queue entry as
+empty by incrementing the dirty_tx mark. Iff the 'lp->tx_full' flag is set, it
+clears both the tx_full and tbusy flags.
+
+IV. Notes
+
+IVb. References
+
+The Adaptec Starfire manuals, available only from Adaptec.
+http://www.scyld.com/expert/100mbps.html
+http://www.scyld.com/expert/NWay.html
+
+IVc. Errata
+
+*/
+
+
+
+/* 2.2.x compatibility code */
 #if LINUX_VERSION_CODE < 0x20300
 #include <linux/kcomp.h>
 
 static LIST_HEAD(pci_drivers);
 
 struct pci_driver_mapping {
-        struct pci_dev *dev;
-        struct pci_driver *drv;
-        void *driver_data;
+	struct pci_dev *dev;
+	struct pci_driver *drv;
+	void *driver_data;
 };
 
 struct pci_device_id {
-        unsigned int vendor, device;
-        unsigned int subvendor, subdevice;
-        unsigned int class, class_mask;
-        unsigned long driver_data;
+	unsigned int vendor, device;
+	unsigned int subvendor, subdevice;
+	unsigned int class, class_mask;
+	unsigned long driver_data;
 };
 
 struct pci_driver {
-        struct list_head node;
-        struct pci_dev *dev;
-        char *name;
-        const struct pci_device_id *id_table;   /* NULL if wants all devices */
-        int (*probe)(struct pci_dev *dev, const struct pci_device_id *id);      /* New device inserted */
-        void (*remove)(struct pci_dev *dev);    /* Device removed (NULL if not a hot-plug capable driver) */
-        void (*suspend)(struct pci_dev *dev);   /* Device suspended */
-        void (*resume)(struct pci_dev *dev);    /* Device woken up */
+	struct list_head node;
+	struct pci_dev *dev;
+	char *name;
+	const struct pci_device_id *id_table;	/* NULL if wants all devices */
+	int (*probe)(struct pci_dev *dev, const struct pci_device_id *id);		/* New device inserted */
+	void (*remove)(struct pci_dev *dev);	/* Device removed (NULL if not a hot-plug capable driver) */
+	void (*suspend)(struct pci_dev *dev);	/* Device suspended */
+	void (*resume)(struct pci_dev *dev);	/* Device woken up */
 };
 
 #define PCI_MAX_MAPPINGS 16
 static struct pci_driver_mapping drvmap [PCI_MAX_MAPPINGS] = { { NULL, } , };
 
-#define __devinit
-#define __devinitdata
+#define __devinit			__init
+#define __devinitdata			__initdata
 #define __devexit
 #define MODULE_DEVICE_TABLE(foo,bar)
+#define SET_MODULE_OWNER(dev)
+#define COMPAT_MOD_INC_USE_COUNT	MOD_INC_USE_COUNT
+#define COMPAT_MOD_DEC_USE_COUNT	MOD_DEC_USE_COUNT
 #define PCI_ANY_ID (~0)
-#define IORESOURCE_MEM          2
-#define PCI_DMA_FROMDEVICE 0
-#define PCI_DMA_TODEVICE 0
+#define IORESOURCE_MEM			2
+#define PCI_DMA_FROMDEVICE		0
+#define PCI_DMA_TODEVICE		0
 
 #define request_mem_region(addr, size, name)	((void *)1)
 #define release_mem_region(addr, size)
 #define del_timer_sync(timer)	del_timer(timer)
 
 static inline void *pci_alloc_consistent(struct pci_dev *hwdev, size_t size,
-										 dma_addr_t *dma_handle)
+					 dma_addr_t *dma_handle)
 {
 	void *virt_ptr;
 
@@ -222,7 +326,7 @@
 #define pci_map_single(cookie, address, size, dir)	virt_to_bus(address)
 #define pci_unmap_single(cookie, address, size, dir)
 #define pci_dma_sync_single(cookie, address, size, dir)
-#undef  pci_resource_flags
+#undef	pci_resource_flags
 #define pci_resource_flags(dev, i) \
   ((dev->base_address[i] & IORESOURCE_IO) ? IORESOURCE_IO : IORESOURCE_MEM)
 
@@ -282,19 +386,22 @@
 		id = NULL;
 
 	found = 0;
-	for (i = 0; i < PCI_MAX_MAPPINGS && !found; i++)
+	for (i = 0; i < PCI_MAX_MAPPINGS; i++)
 		if (!drvmap[i].dev) {
 			drvmap[i].dev = dev;
 			drvmap[i].drv = drv;
 			found = 1;
+			break;
 		}
 
-	if (drv->probe(dev, id) >= 0) {
-		if(found)
-			return 1;
-	} else {
-		drvmap[i - 1].dev = NULL;
-	}
+	if (!found)
+		return 0;
+
+	if (drv->probe(dev, id) >= 0)
+		return 1;
+
+	/* clean up */
+	drvmap[i].dev = NULL;
 	return 0;
 }
 
@@ -326,13 +433,15 @@
 	list_del(&drv->node);
 	for (dev = pci_devices; dev; dev = dev->next) {
 		found = 0;
-		for (i = 0; i < PCI_MAX_MAPPINGS && !found; i++)
-			if (drvmap[i].dev == dev)
+		for (i = 0; i < PCI_MAX_MAPPINGS; i++)
+			if (drvmap[i].dev == dev) {
 				found = 1;
+				break;
+			}
 		if (found) {
 			if (drv->remove)
 				drv->remove(dev);
-			drvmap[i - 1].dev = NULL;
+			drvmap[i].dev = NULL;
 		}
 	}
 #endif
@@ -348,116 +457,46 @@
 
 static inline int pci_module_init(struct pci_driver *drv)
 {
-	int rc = pci_register_driver (drv);
-
-	if (rc > 0)
+	if (pci_register_driver(drv))
 		return 0;
-
-	/* if we get here, we need to clean up pci driver instance
-	 * and return some sort of error */
-	pci_unregister_driver (drv);
-
 	return -ENODEV;
 }
 
-#endif /* LINUX_VERSION_CODE < 0x20300 */
-
-#ifdef HAS_FIRMWARE
-#include "starfire_firmware.h"
-#endif /* HAS_FIRMWARE */
+static struct pci_driver starfire_driver;
 
-MODULE_AUTHOR("Donald Becker <becker@scyld.com>");
-MODULE_DESCRIPTION("Adaptec Starfire Ethernet driver");
-MODULE_PARM(max_interrupt_work, "i");
-MODULE_PARM(mtu, "i");
-MODULE_PARM(debug, "i");
-MODULE_PARM(rx_copybreak, "i");
-MODULE_PARM(interrupt_mitigation, "i");
-MODULE_PARM(options, "1-" __MODULE_STRING(MAX_UNITS) "i");
-MODULE_PARM(full_duplex, "1-" __MODULE_STRING(MAX_UNITS) "i");
-
-/*
-				Theory of Operation
-
-I. Board Compatibility
-
-This driver is for the Adaptec 6915 "Starfire" 64 bit PCI Ethernet adapter.
-
-II. Board-specific settings
-
-III. Driver operation
-
-IIIa. Ring buffers
-
-The Starfire hardware uses multiple fixed-size descriptor queues/rings.  The
-ring sizes are set fixed by the hardware, but may optionally be wrapped
-earlier by the END bit in the descriptor.
-This driver uses that hardware queue size for the Rx ring, where a large
-number of entries has no ill effect beyond increases the potential backlog.
-The Tx ring is wrapped with the END bit, since a large hardware Tx queue
-disables the queue layer priority ordering and we have no mechanism to
-utilize the hardware two-level priority queue.  When modifying the
-RX/TX_RING_SIZE pay close attention to page sizes and the ring-empty warning
-levels.
-
-IIIb/c. Transmit/Receive Structure
-
-See the Adaptec manual for the many possible structures, and options for
-each structure.  There are far too many to document here.
-
-For transmit this driver uses type 0/1 transmit descriptors (depending
-on the presence of the zerocopy patches), and relies on automatic
-minimum-length padding.  It does not use the completion queue
-consumer index, but instead checks for non-zero status entries.
-
-For receive this driver uses type 0 receive descriptors.  The driver
-allocates full frame size skbuffs for the Rx ring buffers, so all frames
-should fit in a single descriptor.  The driver does not use the completion
-queue consumer index, but instead checks for non-zero status entries.
-
-When an incoming frame is less than RX_COPYBREAK bytes long, a fresh skbuff
-is allocated and the frame is copied to the new skbuff.  When the incoming
-frame is larger, the skbuff is passed directly up the protocol stack.
-Buffers consumed this way are replaced by newly allocated skbuffs in a
-later phase of receive.
-
-A notable aspect of operation is that unaligned buffers are not permitted by
-the Starfire hardware.  The IP header at offset 14 in an ethernet frame thus
-isn't longword aligned, which may cause problems on some machine
-e.g. Alphas and IA64. For these architectures, the driver is forced to copy
-the frame into a new skbuff unconditionally. Copied frames are put into the
-skbuff at an offset of "+2", thus 16-byte aligning the IP header.
-
-IIId. Synchronization
+int __init starfire_probe(struct net_device *dev)
+{
+	static int __initdata probed = 0;
 
-The driver runs as two independent, single-threaded flows of control.  One
-is the send-packet routine, which enforces single-threaded use by the
-dev->tbusy flag.  The other thread is the interrupt handler, which is single
-threaded by the hardware and interrupt handling software.
+	if (probed)
+		return -ENODEV;
+	probed++;
 
-The send packet thread has partial control over the Tx ring and 'dev->tbusy'
-flag.  It sets the tbusy flag whenever it's queuing a Tx packet. If the next
-queue slot is empty, it clears the tbusy flag when finished otherwise it sets
-the 'lp->tx_full' flag.
+	return pci_module_init(&starfire_driver);
+}
 
-The interrupt handler has exclusive control over the Rx ring and records stats
-from the Tx ring.  After reaping the stats, it marks the Tx queue entry as
-empty by incrementing the dirty_tx mark. Iff the 'lp->tx_full' flag is set, it
-clears both the tx_full and tbusy flags.
+#define init_tx_timer(dev, func, timeout)
+#define kick_tx_timer(dev, func, timeout) \
+	if (netif_queue_stopped(dev)) { \
+		/* If this happens network layer tells us we're broken. */ \
+		if (jiffies - dev->trans_start > timeout) \
+			func(dev); \
+	}
 
-IV. Notes
+#else  /* LINUX_VERSION_CODE > 0x20300 */
 
-IVb. References
+#define COMPAT_MOD_INC_USE_COUNT
+#define COMPAT_MOD_DEC_USE_COUNT
 
-The Adaptec Starfire manuals, available only from Adaptec.
-http://www.scyld.com/expert/100mbps.html
-http://www.scyld.com/expert/NWay.html
+#define init_tx_timer(dev, func, timeout) \
+	dev->tx_timeout = func; \
+	dev->watchdog_timeo = timeout;
+#define kick_tx_timer(dev, func, timeout)
 
-IVc. Errata
 
-*/
+#endif /* LINUX_VERSION_CODE > 0x20300 */
+/* end of compatibility code */
 
-
 
 enum chip_capability_flags {CanHaveMII=1, };
 #define PCI_IOTYPE (PCI_USES_MASTER | PCI_USES_MEM | PCI_ADDR0)
@@ -574,7 +613,7 @@
 
 /* The Rx and Tx buffer descriptors. */
 struct starfire_rx_desc {
-	u32 rxaddr;					/* Optionally 64 bits. */
+	u32 rxaddr;			/* Optionally 64 bits. */
 };
 enum rx_desc_bits {
 	RxDescValid=1, RxDescEndRing=2,
@@ -587,14 +626,14 @@
 #define csum_rx_status
 #endif /* HAS_FIRMWARE */
 struct rx_done_desc {
-	u32 status;					/* Low 16 bits is length. */
+	u32 status;			/* Low 16 bits is length. */
 #ifdef csum_rx_status
-	u32 status2;				/* Low 16 bits is csum */
+	u32 status2;			/* Low 16 bits is csum */
 #endif /* csum_rx_status */
 #ifdef full_rx_status
 	u32 status2;
 	u16 vlanid;
-	u16 csum; 			/* partial checksum */
+	u16 csum;			/* partial checksum */
 	u32 timestamp;
 #endif /* full_rx_status */
 };
@@ -602,41 +641,24 @@
 	RxOK=0x20000000, RxFIFOErr=0x10000000, RxBufQ2=0x08000000,
 };
 
-#ifdef ZEROCOPY
-/* Type 0 Tx descriptor. */
-/* If more fragments are needed, don't forget to change the
-   descriptor spacing as well! */
-struct starfire_tx_desc {
-	u32 status;
-	u32 nbufs;
-	u32 first_addr;
-	u16 first_len;
-	u16 total_len;
-	struct {
-		u32 addr;
-		u32 len;
-	} frag[6];
-};
-#else  /* not ZEROCOPY */
 /* Type 1 Tx descriptor. */
 struct starfire_tx_desc {
-	u32 status;					/* Upper bits are status, lower 16 length. */
+	u32 status;			/* Upper bits are status, lower 16 length. */
 	u32 first_addr;
 };
-#endif /* not ZEROCOPY */
 enum tx_desc_bits {
 	TxDescID=0xB0000000,
 	TxCRCEn=0x01000000, TxDescIntr=0x08000000,
 	TxRingWrap=0x04000000, TxCalTCP=0x02000000,
 };
 struct tx_done_report {
-	u32 status;					/* timestamp, index. */
+	u32 status;			/* timestamp, index. */
 #if 0
-	u32 intrstatus;				/* interrupt status */
+	u32 intrstatus;			/* interrupt status */
 #endif
 };
 
-#define PRIV_ALIGN	15 	/* Required alignment mask */
+#define PRIV_ALIGN	15	/* Required alignment mask */
 struct rx_ring_info {
 	struct sk_buff *skb;
 	dma_addr_t mapping;
@@ -644,9 +666,6 @@
 struct tx_ring_info {
 	struct sk_buff *skb;
 	dma_addr_t first_mapping;
-#ifdef ZEROCOPY
-	dma_addr_t frag_mapping[6];
-#endif /* ZEROCOPY */
 };
 
 struct netdev_private {
@@ -670,45 +689,45 @@
 	struct timer_list timer;	/* Media monitoring timer. */
 	struct pci_dev *pci_dev;
 	/* Frequently used values: keep some adjacent for cache effect. */
-	unsigned int cur_rx, dirty_rx;		/* Producer/consumer ring indices */
+	unsigned int cur_rx, dirty_rx;	/* Producer/consumer ring indices */
 	unsigned int cur_tx, dirty_tx;
-	unsigned int rx_buf_sz;				/* Based on MTU+slack. */
-	unsigned int tx_full:1;				/* The Tx queue is full. */
+	unsigned int rx_buf_sz;		/* Based on MTU+slack. */
+	unsigned int tx_full:1;		/* The Tx queue is full. */
 	/* These values are keep track of the transceiver/media in use. */
-	unsigned int full_duplex:1,			/* Full-duplex operation requested. */
-		medialock:1,					/* Xcvr set to fixed speed/duplex. */
+	unsigned int full_duplex:1,	/* Full-duplex operation requested. */
+		medialock:1,		/* Xcvr set to fixed speed/duplex. */
 		rx_flowctrl:1,
-		tx_flowctrl:1;					/* Use 802.3x flow control. */
-	unsigned int default_port:4;		/* Last dev->if_port value. */
+		tx_flowctrl:1;		/* Use 802.3x flow control. */
+	unsigned int default_port:4;	/* Last dev->if_port value. */
 	u32 tx_mode;
 	u8 tx_threshold;
 	/* MII transceiver section. */
-	int mii_cnt;						/* MII device addresses. */
-	u16 advertising;					/* NWay media advertisement */
-	unsigned char phys[2];				/* MII device addresses. */
-};
-
-static int  mdio_read(struct net_device *dev, int phy_id, int location);
-static void mdio_write(struct net_device *dev, int phy_id, int location, int value);
-static int  netdev_open(struct net_device *dev);
-static void check_duplex(struct net_device *dev, int startup);
-static void netdev_timer(unsigned long data);
-static void tx_timeout(struct net_device *dev);
-static void init_ring(struct net_device *dev);
-static int  start_tx(struct sk_buff *skb, struct net_device *dev);
-static void intr_handler(int irq, void *dev_instance, struct pt_regs *regs);
-static void netdev_error(struct net_device *dev, int intr_status);
-static int  netdev_rx(struct net_device *dev);
-static void netdev_error(struct net_device *dev, int intr_status);
-static void set_rx_mode(struct net_device *dev);
+	int mii_cnt;			/* MII device addresses. */
+	u16 advertising;		/* NWay media advertisement */
+	unsigned char phys[2];		/* MII device addresses. */
+};
+
+static int	mdio_read(struct net_device *dev, int phy_id, int location);
+static void	mdio_write(struct net_device *dev, int phy_id, int location, int value);
+static int	netdev_open(struct net_device *dev);
+static void	check_duplex(struct net_device *dev, int startup);
+static void	netdev_timer(unsigned long data);
+static void	tx_timeout(struct net_device *dev);
+static void	init_ring(struct net_device *dev);
+static int	start_tx(struct sk_buff *skb, struct net_device *dev);
+static void	intr_handler(int irq, void *dev_instance, struct pt_regs *regs);
+static void	netdev_error(struct net_device *dev, int intr_status);
+static int	netdev_rx(struct net_device *dev);
+static void	netdev_error(struct net_device *dev, int intr_status);
+static void	set_rx_mode(struct net_device *dev);
 static struct net_device_stats *get_stats(struct net_device *dev);
-static int mii_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
-static int  netdev_close(struct net_device *dev);
+static int	mii_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
+static int	netdev_close(struct net_device *dev);
 
 
 
-static int __devinit starfire_init_one (struct pci_dev *pdev,
-					const struct pci_device_id *ent)
+static int __devinit starfire_init_one(struct pci_dev *pdev,
+				       const struct pci_device_id *ent)
 {
 	struct netdev_private *np;
 	int i, irq, option, chip_idx = ent->driver_data;
@@ -717,13 +736,14 @@
 	static int printed_version = 0;
 	long ioaddr;
 	int drv_flags, io_size;
+	int boguscnt;
 
 	card_idx++;
 	option = card_idx < MAX_UNITS ? options[card_idx] : 0;
 
 	if (!printed_version++)
 		printk(KERN_INFO "%s" KERN_INFO "%s" KERN_INFO "%s",
-		       version1, version2, version3);
+			   version1, version2, version3);
 
 	if (pci_enable_device (pdev))
 		return -EIO;
@@ -734,21 +754,22 @@
 		printk (KERN_ERR "starfire %d: no PCI MEM resources, aborting\n", card_idx);
 		return -ENODEV;
 	}
-	
+
 	dev = init_etherdev(NULL, sizeof(*np));
 	if (!dev) {
 		printk (KERN_ERR "starfire %d: cannot alloc etherdev, aborting\n", card_idx);
 		return -ENOMEM;
 	}
-	
-	irq = pdev->irq; 
+	SET_MODULE_OWNER(dev);
+
+	irq = pdev->irq;
 
 	if (request_mem_region (ioaddr, io_size, dev->name) == NULL) {
 		printk (KERN_ERR "starfire %d: resource 0x%x @ 0x%lx busy, aborting\n",
 			card_idx, io_size, ioaddr);
 		goto err_out_free_netdev;
 	}
-	
+
 	ioaddr = (long) ioremap (ioaddr, io_size);
 	if (!ioaddr) {
 		printk (KERN_ERR "starfire %d: cannot remap 0x%x @ 0x%lx, aborting\n",
@@ -757,34 +778,42 @@
 	}
 
 	pci_set_master (pdev);
-	
+
 	printk(KERN_INFO "%s: %s at 0x%lx, ",
 		   dev->name, netdrv_tbl[chip_idx].name, ioaddr);
 
-#ifdef ZEROCOPY
-	/* Starfire can do SG and TCP/UDP checksumming */
-	dev->features |= NETIF_F_SG;
-#ifdef HAS_FIRMWARE
-	dev->features |= NETIF_F_IP_CSUM;
-#endif /* HAS_FIRMWARE */
-#endif /* ZEROCOPY */
-
 	/* Serial EEPROM reads are hidden by the hardware. */
 	for (i = 0; i < 6; i++)
 		dev->dev_addr[i] = readb(ioaddr + EEPROMCtrl + 20-i);
 	for (i = 0; i < 5; i++)
-			printk("%2.2x:", dev->dev_addr[i]);
+		printk("%2.2x:", dev->dev_addr[i]);
 	printk("%2.2x, IRQ %d.\n", dev->dev_addr[i], irq);
 
 #if ! defined(final_version) /* Dump the EEPROM contents during development. */
 	if (debug > 4)
 		for (i = 0; i < 0x20; i++)
-			printk("%2.2x%s", (unsigned int)readb(ioaddr + EEPROMCtrl + i),
-				   i % 16 != 15 ? " " : "\n");
+			printk("%2.2x%s",
+			       (unsigned int)readb(ioaddr + EEPROMCtrl + i),
+			       i % 16 != 15 ? " " : "\n");
 #endif
 
+	/* Issue soft reset */
+	writel(0x8000, ioaddr + TxMode);
+	udelay(1000);
+	writel(0, ioaddr + TxMode);
+
 	/* Reset the chip to erase previous misconfiguration. */
 	writel(1, ioaddr + PCIDeviceConfig);
+	boguscnt = 1000;
+	while (--boguscnt > 0) {
+		udelay(10);
+		if ((readl(ioaddr + PCIDeviceConfig) & 1) == 0)
+			break;
+	}
+	if (boguscnt == 0)
+		printk("%s: chipset reset never completed!\n", dev->name);
+	/* wait a little longer */
+	udelay(1000);
 
 	dev->base_addr = ioaddr;
 	dev->irq = irq;
@@ -806,7 +835,7 @@
 		if (np->default_port)
 			np->medialock = 1;
 	}
-	if (card_idx < MAX_UNITS  &&  full_duplex[card_idx] > 0)
+	if (card_idx < MAX_UNITS && full_duplex[card_idx] > 0)
 		np->full_duplex = 1;
 
 	if (np->full_duplex)
@@ -815,6 +844,7 @@
 	/* The chip-specific entries in the device structure. */
 	dev->open = &netdev_open;
 	dev->hard_start_xmit = &start_tx;
+	init_tx_timer(dev, tx_timeout, TX_TIMEOUT);
 	dev->stop = &netdev_close;
 	dev->get_stats = &get_stats;
 	dev->set_multicast_list = &set_rx_mode;
@@ -825,14 +855,27 @@
 
 	if (drv_flags & CanHaveMII) {
 		int phy, phy_idx = 0;
+		int mii_status;
 		for (phy = 0; phy < 32 && phy_idx < 4; phy++) {
-			int mii_status = mdio_read(dev, phy, 1);
-			if (mii_status != 0xffff  &&  mii_status != 0x0000) {
+			mdio_write(dev, phy, 0, 0x8000);
+			udelay(500);
+			boguscnt = 1000;
+			while (--boguscnt > 0)
+				if ((mdio_read(dev, phy, 0) & 0x8000) == 0)
+					break;
+			if (boguscnt == 0) {
+				printk("%s: PHY reset never completed!\n", dev->name);
+				continue;
+			}
+			mii_status = mdio_read(dev, phy, 1);
+			if (mii_status != 0x0000) {
 				np->phys[phy_idx++] = phy;
 				np->advertising = mdio_read(dev, phy, 4);
 				printk(KERN_INFO "%s: MII PHY found at address %d, status "
 					   "0x%4.4x advertising %4.4x.\n",
 					   dev->name, phy, mii_status, np->advertising);
+				/* there can be only one PHY on-board */
+				break;
 			}
 		}
 		np->mii_cnt = phy_idx;
@@ -858,7 +901,11 @@
 	/* ??? Should we add a busy-wait here? */
 	do
 		result = readl(mdio_addr);
-	while ((result & 0xC0000000) != 0x80000000 && --boguscnt >= 0);
+	while ((result & 0xC0000000) != 0x80000000 && --boguscnt > 0);
+	if (boguscnt == 0)
+		return 0;
+	if ((result & 0xffff) == 0xffff)
+		return 0;
 	return result & 0xffff;
 }
 
@@ -879,11 +926,11 @@
 
 	/* Do we ever need to reset the chip??? */
 
-	MOD_INC_USE_COUNT;
+	COMPAT_MOD_INC_USE_COUNT;
 
 	retval = request_irq(dev->irq, &intr_handler, SA_SHIRQ, dev->name, dev);
 	if (retval) {
-		MOD_DEC_USE_COUNT;
+		COMPAT_MOD_DEC_USE_COUNT;
 		return retval;
 	}
 
@@ -892,7 +939,7 @@
 	writel(1, ioaddr + PCIDeviceConfig);
 	if (debug > 1)
 		printk(KERN_DEBUG "%s: netdev_open() irq %d.\n",
-			   dev->name, dev->irq);
+		       dev->name, dev->irq);
 	/* Allocate the various queues, failing gracefully. */
 	if (np->tx_done_q == 0)
 		np->tx_done_q = pci_alloc_consistent(np->pci_dev, PAGE_SIZE, &np->tx_done_q_dma);
@@ -902,47 +949,38 @@
 		np->tx_ring = pci_alloc_consistent(np->pci_dev, PAGE_SIZE, &np->tx_ring_dma);
 	if (np->rx_ring == 0)
 		np->rx_ring = pci_alloc_consistent(np->pci_dev, PAGE_SIZE, &np->rx_ring_dma);
-	if (np->tx_done_q == 0  ||  np->rx_done_q == 0
-		|| np->rx_ring == 0 ||  np->tx_ring == 0) {
+	if (np->tx_done_q == 0 || np->rx_done_q == 0
+		|| np->rx_ring == 0 || np->tx_ring == 0) {
 		if (np->tx_done_q)
 			pci_free_consistent(np->pci_dev, PAGE_SIZE,
-								np->tx_done_q, np->tx_done_q_dma);
+					    np->tx_done_q, np->tx_done_q_dma);
 		if (np->rx_done_q)
 			pci_free_consistent(np->pci_dev, sizeof(struct rx_done_desc) * DONE_Q_SIZE,
-								np->rx_done_q, np->rx_done_q_dma);
+					    np->rx_done_q, np->rx_done_q_dma);
 		if (np->tx_ring)
 			pci_free_consistent(np->pci_dev, PAGE_SIZE,
-								np->tx_ring, np->tx_ring_dma);
+					    np->tx_ring, np->tx_ring_dma);
 		if (np->rx_ring)
 			pci_free_consistent(np->pci_dev, PAGE_SIZE,
-								np->rx_ring, np->rx_ring_dma);
-		MOD_DEC_USE_COUNT;
+					    np->rx_ring, np->rx_ring_dma);
+		COMPAT_MOD_DEC_USE_COUNT;
 		return -ENOMEM;
 	}
 
 	init_ring(dev);
 	/* Set the size of the Rx buffers. */
 	writel((np->rx_buf_sz << RxBufferLenShift) |
-		   (0 << RxMinDescrThreshShift) |
-		   RxPrefetchMode | RxVariableQ |
-		   RxDescSpace4,
-		   ioaddr + RxDescQCtrl);
+	       (0 << RxMinDescrThreshShift) |
+	       RxPrefetchMode | RxVariableQ |
+	       RxDescSpace4,
+	       ioaddr + RxDescQCtrl);
 
-#ifdef ZEROCOPY
-	/* Set Tx descriptor to type 0 and spacing to 64 bytes. */
-	writel((2 << TxHiPriFIFOThreshShift) |
-	       (0 << TxPadLenShift) |
-	       (4 << TxDMABurstSizeShift) |
-	       TxDescSpace64 | TxDescType0,
-	       ioaddr + TxDescCtrl);
-#else  /* not ZEROCOPY */
 	/* Set Tx descriptor to type 1 and padding to 0 bytes. */
 	writel((2 << TxHiPriFIFOThreshShift) |
 	       (0 << TxPadLenShift) |
 	       (4 << TxDMABurstSizeShift) |
 	       TxDescSpaceUnlim | TxDescType1,
 	       ioaddr + TxDescCtrl);
-#endif /* not ZEROCOPY */
 
 #if defined(ADDR_64BITS) && defined(__alpha__)
 	/* XXX We really need a 64-bit PCI dma interfaces too... -DaveM */
@@ -959,25 +997,25 @@
 	writel(np->tx_done_q_dma, ioaddr + TxCompletionAddr);
 #ifdef full_rx_status
 	writel(np->rx_done_q_dma |
-		   RxComplType3 |
-		   (0 << RxComplThreshShift),
-		   ioaddr + RxCompletionAddr);
+	       RxComplType3 |
+	       (0 << RxComplThreshShift),
+	       ioaddr + RxCompletionAddr);
 #else  /* not full_rx_status */
 #ifdef csum_rx_status
 	writel(np->rx_done_q_dma |
-		   RxComplType2 |
-		   (0 << RxComplThreshShift),
-		   ioaddr + RxCompletionAddr);
+	       RxComplType2 |
+	       (0 << RxComplThreshShift),
+	       ioaddr + RxCompletionAddr);
 #else  /* not csum_rx_status */
 	writel(np->rx_done_q_dma |
-		   RxComplType0 |
-		   (0 << RxComplThreshShift),
-		   ioaddr + RxCompletionAddr);
+	       RxComplType0 |
+	       (0 << RxComplThreshShift),
+	       ioaddr + RxCompletionAddr);
 #endif /* not csum_rx_status */
 #endif /* not full_rx_status */
 
 	if (debug > 1)
-		printk(KERN_DEBUG "%s:  Filling in the station address.\n", dev->name);
+		printk(KERN_DEBUG "%s: Filling in the station address.\n", dev->name);
 
 	/* Fill both the unused Tx SA register and the Rx perfect filter. */
 	for (i = 0; i < 6; i++)
@@ -1003,7 +1041,7 @@
 	netif_start_queue(dev);
 
 	if (debug > 1)
-		printk(KERN_DEBUG "%s:  Setting the Rx and Tx modes.\n", dev->name);
+		printk(KERN_DEBUG "%s: Setting the Rx and Tx modes.\n", dev->name);
 	set_rx_mode(dev);
 
 	np->advertising = mdio_read(dev, np->phys[0], 4);
@@ -1016,7 +1054,7 @@
 	       IntrRxGFPDead | IntrNoTxCsum | IntrTxBadID,
 	       ioaddr + IntrEnable);
 	writel(0x00800000 | readl(ioaddr + PCIDeviceConfig),
-		   ioaddr + PCIDeviceConfig);
+	       ioaddr + PCIDeviceConfig);
 
 #ifdef HAS_FIRMWARE
 	/* Load Rx/Tx firmware into the frame processors */
@@ -1033,7 +1071,7 @@
 
 	if (debug > 2)
 		printk(KERN_DEBUG "%s: Done netdev_open().\n",
-			   dev->name);
+		       dev->name);
 
 	/* Set the timer to check for link beat. */
 	init_timer(&np->timer);
@@ -1066,8 +1104,8 @@
 			np->full_duplex = duplex;
 			if (debug > 1)
 				printk(KERN_INFO "%s: Setting %s-duplex based on MII #%d"
-					   " negotiated capability %4.4x.\n", dev->name,
-					   duplex ? "full" : "half", np->phys[0], negotiated);
+				       " negotiated capability %4.4x.\n", dev->name,
+				       duplex ? "full" : "half", np->phys[0], negotiated);
 		}
 	}
 	if (new_tx_mode != np->tx_mode) {
@@ -1086,7 +1124,7 @@
 
 	if (debug > 3) {
 		printk(KERN_DEBUG "%s: Media selection timer tick, status %8.8x.\n",
-			   dev->name, (int)readl(ioaddr + IntrStatus));
+		       dev->name, (int)readl(ioaddr + IntrStatus));
 	}
 	check_duplex(dev, 0);
 #if ! defined(final_version)
@@ -1096,7 +1134,7 @@
 		/* Bogus hardware IRQ: Fake an interrupt handler call. */
 		if (new_status & 1) {
 			printk(KERN_ERR "%s: Interrupt blocked, status %8.8x/%8.8x.\n",
-				   dev->name, new_status, (int)readl(ioaddr + IntrStatus));
+			       dev->name, new_status, (int)readl(ioaddr + IntrStatus));
 			intr_handler(dev->irq, dev, 0);
 		}
 	}
@@ -1112,7 +1150,7 @@
 	long ioaddr = dev->base_addr;
 
 	printk(KERN_WARNING "%s: Transmit timed out, status %8.8x,"
-		   " resetting...\n", dev->name, (int)readl(ioaddr + IntrStatus));
+	       " resetting...\n", dev->name, (int)readl(ioaddr + IntrStatus));
 
 #ifndef __alpha__
 	{
@@ -1183,13 +1221,6 @@
 	for (i = 0; i < TX_RING_SIZE; i++) {
 		np->tx_info[i].skb = NULL;
 		np->tx_info[i].first_mapping = 0;
-#ifdef ZEROCOPY
-		{
-			int j;
-			for (j = 0; j < 6; j++)
-				np->tx_info[i].frag_mapping[j] = 0;
-		}
-#endif /* ZEROCOPY */
 		np->tx_ring[i].status = 0;
 	}
 	return;
@@ -1199,15 +1230,8 @@
 {
 	struct netdev_private *np = dev->priv;
 	unsigned int entry;
-#ifdef ZEROCOPY
-	int i;
-#endif
 
-	if (netif_queue_stopped(dev)) {
-		/* If this happens network layer tells us we're broken. */
-		if (jiffies - dev->trans_start > TX_TIMEOUT)
-			tx_timeout(dev);
-	}
+	kick_tx_timer(dev, tx_timeout, TX_TIMEOUT);
 
 	/* Caution: the write order is important here, set the field
 	   with the "ownership" bits last. */
@@ -1215,80 +1239,22 @@
 	/* Calculate the next Tx descriptor entry. */
 	entry = np->cur_tx % TX_RING_SIZE;
 
-#if defined(ZEROCOPY) && defined(HAS_FIRMWARE) && defined(HAS_BROKEN_FIRMWARE)
-	{
-		int has_bad_length = 0;
-
-		if (skb_first_frag_len(skb) == 1)
-			has_bad_length = 1;
-		else {
-			for (i = 0; i < skb_shinfo(skb)->nr_frags; i++)
-				if (skb_shinfo(skb)->frags[i].size == 1) {
-					has_bad_length = 1;
-					break;
-				}
-		}
-
-		if (has_bad_length)
-			skb_checksum_help(skb);
-	}
-#endif /* ZEROCOPY && HAS_FIRMWARE && HAS_BROKEN_FIRMWARE */
-
 	np->tx_info[entry].skb = skb;
 	np->tx_info[entry].first_mapping =
 		pci_map_single(np->pci_dev, skb->data, skb_first_frag_len(skb), PCI_DMA_TODEVICE);
 
 	np->tx_ring[entry].first_addr = cpu_to_le32(np->tx_info[entry].first_mapping);
-#ifdef ZEROCOPY
-	np->tx_ring[entry].first_len = cpu_to_le32(skb_first_frag_len(skb));
-	np->tx_ring[entry].total_len = cpu_to_le32(skb->len);
-	/* Add  "| TxDescIntr" to generate Tx-done interrupts. */
-	np->tx_ring[entry].status = cpu_to_le32(TxDescID | TxCRCEn);
-	np->tx_ring[entry].nbufs = cpu_to_le32(skb_shinfo(skb)->nr_frags + 1);
-#else  /* not ZEROCOPY */
-	/* Add  "| TxDescIntr" to generate Tx-done interrupts. */
+	/* Add "| TxDescIntr" to generate Tx-done interrupts. */
 	np->tx_ring[entry].status = cpu_to_le32(skb->len | TxDescID | TxCRCEn | 1 << 16);
-#endif /* not ZEROCOPY */
 
 	if (entry >= TX_RING_SIZE-1)		 /* Wrap ring */
 		np->tx_ring[entry].status |= cpu_to_le32(TxRingWrap | TxDescIntr);
 
-	/* not ifdef'ed, but shouldn't happen without ZEROCOPY */
-	if (skb->ip_summed == CHECKSUM_HW)
-		np->tx_ring[entry].status |= cpu_to_le32(TxCalTCP);
-
 	if (debug > 5) {
-#ifdef ZEROCOPY
-		printk(KERN_DEBUG "%s: Tx #%d slot %d status %8.8x nbufs %d len %4.4x/%4.4x.\n",
-			   dev->name, np->cur_tx, entry,
-			   le32_to_cpu(np->tx_ring[entry].status),
-			   le32_to_cpu(np->tx_ring[entry].nbufs),
-			   le32_to_cpu(np->tx_ring[entry].first_len),
-			   le32_to_cpu(np->tx_ring[entry].total_len));
-#else  /* not ZEROCOPY */
 		printk(KERN_DEBUG "%s: Tx #%d slot %d status %8.8x.\n",
-			   dev->name, np->cur_tx, entry,
-			   le32_to_cpu(np->tx_ring[entry].status));
-#endif /* not ZEROCOPY */
-	}
-
-#ifdef ZEROCOPY
-	for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) {
-		skb_frag_t *this_frag = &skb_shinfo(skb)->frags[i];
-
-		/* we already have the proper value in entry */
-		np->tx_info[entry].frag_mapping[i] =
-			pci_map_single(np->pci_dev, page_address(this_frag->page) + this_frag->page_offset, this_frag->size, PCI_DMA_TODEVICE);
-
-		np->tx_ring[entry].frag[i].addr = cpu_to_le32(np->tx_info[entry].frag_mapping[i]);
-		np->tx_ring[entry].frag[i].len = cpu_to_le32(this_frag->size);
-		if (debug > 5) {
-			printk(KERN_DEBUG "%s: Tx #%d frag %d len %4.4x.\n",
-				   dev->name, np->cur_tx, i,
-				   le32_to_cpu(np->tx_ring[entry].frag[i].len));
-		}
+		       dev->name, np->cur_tx, entry,
+		       le32_to_cpu(np->tx_ring[entry].status));
 	}
-#endif /* ZEROCOPY */
 
 	np->cur_tx++;
 
@@ -1322,11 +1288,12 @@
 	struct netdev_private *np;
 	long ioaddr;
 	int boguscnt = max_interrupt_work;
+	int consumer;
+	int tx_status;
 
 #ifndef final_version			/* Can never occur. */
 	if (dev == NULL) {
-		printk (KERN_ERR "Netdev interrupt handler(): IRQ %d for unknown "
-				"device.\n", irq);
+		printk (KERN_ERR "Netdev interrupt handler(): IRQ %d for unknown device.\n", irq);
 		return;
 	}
 #endif
@@ -1339,7 +1306,7 @@
 
 		if (debug > 4)
 			printk(KERN_DEBUG "%s: Interrupt status %4.4x.\n",
-				   dev->name, intr_status);
+			       dev->name, intr_status);
 
 		if (intr_status == 0)
 			break;
@@ -1350,63 +1317,48 @@
 		/* Scavenge the skbuff list based on the Tx-done queue.
 		   There are redundant checks here that may be cleaned up
 		   after the driver has proven to be reliable. */
-		{
-			int consumer = readl(ioaddr + TxConsumerIdx);
-			int tx_status;
-			if (debug > 4)
-				printk(KERN_DEBUG "%s: Tx Consumer index is %d.\n",
-					   dev->name, consumer);
+		consumer = readl(ioaddr + TxConsumerIdx);
+		if (debug > 4)
+			printk(KERN_DEBUG "%s: Tx Consumer index is %d.\n",
+			       dev->name, consumer);
 #if 0
-			if (np->tx_done >= 250  || np->tx_done == 0)
-				printk(KERN_DEBUG "%s: Tx completion entry %d is %8.8x, "
-					   "%d is %8.8x.\n", dev->name,
-					   np->tx_done, le32_to_cpu(np->tx_done_q[np->tx_done].status),
-					   (np->tx_done+1) & (DONE_Q_SIZE-1),
-					   le32_to_cpu(np->tx_done_q[(np->tx_done+1)&(DONE_Q_SIZE-1)].status));
+		if (np->tx_done >= 250 || np->tx_done == 0)
+			printk(KERN_DEBUG "%s: Tx completion entry %d is %8.8x, %d is %8.8x.\n",
+			       dev->name, np->tx_done,
+			       le32_to_cpu(np->tx_done_q[np->tx_done].status),
+			       (np->tx_done+1) & (DONE_Q_SIZE-1),
+			       le32_to_cpu(np->tx_done_q[(np->tx_done+1)&(DONE_Q_SIZE-1)].status));
 #endif
-			while ((tx_status = le32_to_cpu(np->tx_done_q[np->tx_done].status))
-				   != 0) {
-				if (debug > 4)
-					printk(KERN_DEBUG "%s: Tx completion entry %d is %8.8x.\n",
-						   dev->name, np->tx_done, tx_status);
-				if ((tx_status & 0xe0000000) == 0xa0000000) {
-					np->stats.tx_packets++;
-				} else if ((tx_status & 0xe0000000) == 0x80000000) {
-					struct sk_buff *skb;
-#ifdef ZEROCOPY
-					int i;
-#endif /* ZEROCOPY */
-					u16 entry = tx_status; 		/* Implicit truncate */
-					entry /= sizeof(struct starfire_tx_desc);
-
-					skb = np->tx_info[entry].skb;
-					np->tx_info[entry].skb = NULL;
-					pci_unmap_single(np->pci_dev,
-									 np->tx_info[entry].first_mapping,
-									 skb_first_frag_len(skb),
-									 PCI_DMA_TODEVICE);
-					np->tx_info[entry].first_mapping = 0;
-
-#ifdef ZEROCOPY
-					for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) {
-						pci_unmap_single(np->pci_dev,
-										 np->tx_info[entry].frag_mapping[i],
-										 skb_shinfo(skb)->frags[i].size,
-										 PCI_DMA_TODEVICE);
-						np->tx_info[entry].frag_mapping[i] = 0;
-					}
-#endif /* ZEROCOPY */
 
-					/* Scavenge the descriptor. */
-					dev_kfree_skb_irq(skb);
+		while ((tx_status = le32_to_cpu(np->tx_done_q[np->tx_done].status)) != 0) {
+			if (debug > 4)
+				printk(KERN_DEBUG "%s: Tx completion entry %d is %8.8x.\n",
+				       dev->name, np->tx_done, tx_status);
+			if ((tx_status & 0xe0000000) == 0xa0000000) {
+				np->stats.tx_packets++;
+			} else if ((tx_status & 0xe0000000) == 0x80000000) {
+				struct sk_buff *skb;
+				u16 entry = tx_status;		/* Implicit truncate */
+				entry /= sizeof(struct starfire_tx_desc);
+
+				skb = np->tx_info[entry].skb;
+				np->tx_info[entry].skb = NULL;
+				pci_unmap_single(np->pci_dev,
+						 np->tx_info[entry].first_mapping,
+						 skb_first_frag_len(skb),
+						 PCI_DMA_TODEVICE);
+				np->tx_info[entry].first_mapping = 0;
 
-					np->dirty_tx++;
-				}
-				np->tx_done_q[np->tx_done].status = 0;
-				np->tx_done = (np->tx_done+1) & (DONE_Q_SIZE-1);
+				/* Scavenge the descriptor. */
+				dev_kfree_skb_irq(skb);
+
+				np->dirty_tx++;
 			}
-			writew(np->tx_done, ioaddr + CompletionQConsumerIdx + 2);
+			np->tx_done_q[np->tx_done].status = 0;
+			np->tx_done = (np->tx_done+1) & (DONE_Q_SIZE-1);
 		}
+		writew(np->tx_done, ioaddr + CompletionQConsumerIdx + 2);
+
 		if (np->tx_full && np->cur_tx - np->dirty_tx < TX_RING_SIZE - 4) {
 			/* The ring is no longer full, wake the queue. */
 			np->tx_full = 0;
@@ -1419,23 +1371,23 @@
 
 		if (--boguscnt < 0) {
 			printk(KERN_WARNING "%s: Too much work at interrupt, "
-				   "status=0x%4.4x.\n",
-				   dev->name, intr_status);
+			       "status=0x%4.4x.\n",
+			       dev->name, intr_status);
 			break;
 		}
 	} while (1);
 
 	if (debug > 4)
 		printk(KERN_DEBUG "%s: exiting interrupt, status=%#4.4x.\n",
-			   dev->name, (int)readl(ioaddr + IntrStatus));
+		       dev->name, (int)readl(ioaddr + IntrStatus));
 
 #ifndef final_version
 	/* Code that should never be run!  Remove after testing.. */
 	{
 		static int stopit = 10;
-		if (!netif_running(dev)  &&  --stopit < 0) {
+		if (!netif_running(dev) && --stopit < 0) {
 			printk(KERN_ERR "%s: Emergency stop, looping startup interrupt.\n",
-				   dev->name);
+			       dev->name);
 			free_irq(irq, dev);
 		}
 	}
@@ -1452,98 +1404,99 @@
 
 	if (np->rx_done_q == 0) {
 		printk(KERN_ERR "%s:  rx_done_q is NULL!  rx_done is %d. %p.\n",
-			   dev->name, np->rx_done, np->tx_done_q);
+		       dev->name, np->rx_done, np->tx_done_q);
 		return 0;
 	}
 
 	/* If EOP is set on the next entry, it's a new packet. Send it up. */
 	while ((desc_status = le32_to_cpu(np->rx_done_q[np->rx_done].status)) != 0) {
+		struct sk_buff *skb;
+		u16 pkt_len;
+		int entry;
+
 		if (debug > 4)
-			printk(KERN_DEBUG "  netdev_rx() status of %d was %8.8x.\n",
-				   np->rx_done, desc_status);
+			printk(KERN_DEBUG "  netdev_rx() status of %d was %8.8x.\n", np->rx_done, desc_status);
 		if (--boguscnt < 0)
 			break;
 		if ( ! (desc_status & RxOK)) {
 			/* There was a error. */
 			if (debug > 2)
-				printk(KERN_DEBUG "  netdev_rx() Rx error was %8.8x.\n",
-					   desc_status);
+				printk(KERN_DEBUG "  netdev_rx() Rx error was %8.8x.\n", desc_status);
 			np->stats.rx_errors++;
 			if (desc_status & RxFIFOErr)
 				np->stats.rx_fifo_errors++;
-		} else {
-			struct sk_buff *skb;
-			u16 pkt_len = desc_status;			/* Implicitly Truncate */
-			int entry = (desc_status >> 16) & 0x7ff;
+			goto next_rx;
+		}
+
+		pkt_len = desc_status;	/* Implicitly Truncate */
+		entry = (desc_status >> 16) & 0x7ff;
 
 #ifndef final_version
-			if (debug > 4)
-				printk(KERN_DEBUG "  netdev_rx() normal Rx pkt length %d"
-					   ", bogus_cnt %d.\n",
-					   pkt_len, boguscnt);
+		if (debug > 4)
+			printk(KERN_DEBUG "  netdev_rx() normal Rx pkt length %d, bogus_cnt %d.\n", pkt_len, boguscnt);
 #endif
-			/* Check if the packet is long enough to accept without copying
-			   to a minimally-sized skbuff. */
-			if (PKT_SHOULD_COPY(pkt_len)
-				&& (skb = dev_alloc_skb(pkt_len + 2)) != NULL) {
-				skb->dev = dev;
-				skb_reserve(skb, 2);	/* 16 byte align the IP header */
-				pci_dma_sync_single(np->pci_dev,
-						    np->rx_info[entry].mapping,
-						    pkt_len, PCI_DMA_FROMDEVICE);
+		/* Check if the packet is long enough to accept without copying
+		   to a minimally-sized skbuff. */
+		if (pkt_len < rx_copybreak
+		    && (skb = dev_alloc_skb(pkt_len + 2)) != NULL) {
+			skb->dev = dev;
+			skb_reserve(skb, 2);	/* 16 byte align the IP header */
+			pci_dma_sync_single(np->pci_dev,
+					    np->rx_info[entry].mapping,
+					    pkt_len, PCI_DMA_FROMDEVICE);
 #if HAS_IP_COPYSUM			/* Call copy + cksum if available. */
-				eth_copy_and_sum(skb, np->rx_info[entry].skb->tail, pkt_len, 0);
-				skb_put(skb, pkt_len);
+			eth_copy_and_sum(skb, np->rx_info[entry].skb->tail, pkt_len, 0);
+			skb_put(skb, pkt_len);
 #else
-				memcpy(skb_put(skb, pkt_len), np->rx_info[entry].skb->tail,
-					   pkt_len);
+			memcpy(skb_put(skb, pkt_len), np->rx_info[entry].skb->tail, pkt_len);
 #endif
-			} else {
-				char *temp;
+		} else {
+			char *temp;
 
-				pci_unmap_single(np->pci_dev, np->rx_info[entry].mapping, np->rx_buf_sz, PCI_DMA_FROMDEVICE);
-				skb = np->rx_info[entry].skb;
-				temp = skb_put(skb, pkt_len);
-				np->rx_info[entry].skb = NULL;
-				np->rx_info[entry].mapping = 0;
-			}
-#ifndef final_version				/* Remove after testing. */
-			/* You will want this info for the initial debug. */
-			if (debug > 5)
-				printk(KERN_DEBUG "  Rx data %2.2x:%2.2x:%2.2x:%2.2x:%2.2x:"
-					   "%2.2x %2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x %2.2x%2.2x "
-					   "%d.%d.%d.%d.\n",
-					   skb->data[0], skb->data[1], skb->data[2], skb->data[3],
-					   skb->data[4], skb->data[5], skb->data[6], skb->data[7],
-					   skb->data[8], skb->data[9], skb->data[10],
-					   skb->data[11], skb->data[12], skb->data[13],
-					   skb->data[14], skb->data[15], skb->data[16],
-					   skb->data[17]);
+			pci_unmap_single(np->pci_dev, np->rx_info[entry].mapping, np->rx_buf_sz, PCI_DMA_FROMDEVICE);
+			skb = np->rx_info[entry].skb;
+			temp = skb_put(skb, pkt_len);
+			np->rx_info[entry].skb = NULL;
+			np->rx_info[entry].mapping = 0;
+		}
+#ifndef final_version			/* Remove after testing. */
+		/* You will want this info for the initial debug. */
+		if (debug > 5)
+			printk(KERN_DEBUG "  Rx data %2.2x:%2.2x:%2.2x:%2.2x:%2.2x:"
+			       "%2.2x %2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x %2.2x%2.2x "
+			       "%d.%d.%d.%d.\n",
+			       skb->data[0], skb->data[1], skb->data[2], skb->data[3],
+			       skb->data[4], skb->data[5], skb->data[6], skb->data[7],
+			       skb->data[8], skb->data[9], skb->data[10],
+			       skb->data[11], skb->data[12], skb->data[13],
+			       skb->data[14], skb->data[15], skb->data[16],
+			       skb->data[17]);
 #endif
-			skb->protocol = eth_type_trans(skb, dev);
+		skb->protocol = eth_type_trans(skb, dev);
 #if defined(full_rx_status) || defined(csum_rx_status)
-			if (le32_to_cpu(np->rx_done_q[np->rx_done].status2) & 0x01000000) {
-				skb->ip_summed = CHECKSUM_UNNECESSARY;
-			}
-			/*
-			 * This feature doesn't seem to be working, at least
-			 * with the two firmware versions I have. If the GFP sees
-			 * a fragment, it either ignores it completely, or reports
-			 * "bad checksum" on it.
-			 *
-			 * Maybe I missed something -- corrections are welcome.
-			 * Until then, the printk stays. :-) -Ion
-			 */
-			else if (le32_to_cpu(np->rx_done_q[np->rx_done].status2) & 0x00400000) {
-				skb->ip_summed = CHECKSUM_HW;
-				skb->csum = le32_to_cpu(np->rx_done_q[np->rx_done].status2) & 0xffff;
-				printk(KERN_DEBUG "%s: checksum_hw, status2 = %x\n", dev->name, np->rx_done_q[np->rx_done].status2);
-			}
-#endif
-			netif_rx(skb);
-			dev->last_rx = jiffies;
-			np->stats.rx_packets++;
+		if (le32_to_cpu(np->rx_done_q[np->rx_done].status2) & 0x01000000) {
+			skb->ip_summed = CHECKSUM_UNNECESSARY;
 		}
+		/*
+		 * This feature doesn't seem to be working, at least
+		 * with the two firmware versions I have. If the GFP sees
+		 * a fragment, it either ignores it completely, or reports
+		 * "bad checksum" on it.
+		 *
+		 * Maybe I missed something -- corrections are welcome.
+		 * Until then, the printk stays. :-) -Ion
+		 */
+		else if (le32_to_cpu(np->rx_done_q[np->rx_done].status2) & 0x00400000) {
+			skb->ip_summed = CHECKSUM_HW;
+			skb->csum = le32_to_cpu(np->rx_done_q[np->rx_done].status2) & 0xffff;
+			printk(KERN_DEBUG "%s: checksum_hw, status2 = %x\n", dev->name, np->rx_done_q[np->rx_done].status2);
+		}
+#endif
+		netif_rx(skb);
+		dev->last_rx = jiffies;
+		np->stats.rx_packets++;
+
+next_rx:
 		np->cur_rx++;
 		np->rx_done_q[np->rx_done].status = 0;
 		np->rx_done = (np->rx_done + 1) & (DONE_Q_SIZE-1);
@@ -1558,10 +1511,10 @@
 			skb = dev_alloc_skb(np->rx_buf_sz);
 			np->rx_info[entry].skb = skb;
 			if (skb == NULL)
-				break;			/* Better luck next round. */
+				break;	/* Better luck next round. */
 			np->rx_info[entry].mapping =
 				pci_map_single(np->pci_dev, skb->tail, np->rx_buf_sz, PCI_DMA_FROMDEVICE);
-			skb->dev = dev;			/* Mark as being used by this device. */
+			skb->dev = dev;	/* Mark as being used by this device. */
 			np->rx_ring[entry].rxaddr =
 				cpu_to_le32(np->rx_info[entry].mapping | RxDescValid);
 		}
@@ -1572,10 +1525,10 @@
 	}
 
 	if (debug > 5
-		|| memcmp(np->pad0, np->pad0 + 1, sizeof(np->pad0) -1))
+	    || memcmp(np->pad0, np->pad0 + 1, sizeof(np->pad0) -1))
 		printk(KERN_DEBUG "  exiting netdev_rx() status of %d was %8.8x %d.\n",
-			   np->rx_done, desc_status,
-			   memcmp(np->pad0, np->pad0 + 1, sizeof(np->pad0) -1));
+		       np->rx_done, desc_status,
+		       memcmp(np->pad0, np->pad0 + 1, sizeof(np->pad0) -1));
 
 	/* Restart Rx engine if stopped. */
 	return 0;
@@ -1587,9 +1540,9 @@
 
 	if (intr_status & IntrLinkChange) {
 		printk(KERN_NOTICE "%s: Link changed: Autonegotiation advertising"
-			   " %4.4x  partner %4.4x.\n", dev->name,
-			   mdio_read(dev, np->phys[0], 4),
-			   mdio_read(dev, np->phys[0], 5));
+		       " %4.4x, partner %4.4x.\n", dev->name,
+		       mdio_read(dev, np->phys[0], 4),
+		       mdio_read(dev, np->phys[0], 5));
 		check_duplex(dev, 0);
 	}
 	if (intr_status & IntrStatsMax) {
@@ -1598,10 +1551,9 @@
 	/* Came close to underrunning the Tx FIFO, increase threshold. */
 	if (intr_status & IntrTxDataLow)
 		writel(++np->tx_threshold, dev->base_addr + TxThreshold);
-	if ((intr_status &
-		 ~(IntrAbnormalSummary|IntrLinkChange|IntrStatsMax|IntrTxDataLow|1)) && debug)
+	if ((intr_status & ~(IntrAbnormalSummary|IntrLinkChange|IntrStatsMax|IntrTxDataLow|1)) && debug)
 		printk(KERN_ERR "%s: Something Wicked happened! %4.4x.\n",
-			   dev->name, intr_status);
+		       dev->name, intr_status);
 	/* Hmmmmm, it's not clear how to recover from DMA faults. */
 	if (intr_status & IntrDMAErr)
 		np->stats.tx_fifo_errors++;
@@ -1619,12 +1571,13 @@
 	np->stats.tx_aborted_errors =
 		readl(ioaddr + 0x57024) + readl(ioaddr + 0x57028);
 	np->stats.tx_window_errors = readl(ioaddr + 0x57018);
-	np->stats.collisions = readl(ioaddr + 0x57004) + readl(ioaddr + 0x57008);
+	np->stats.collisions =
+		readl(ioaddr + 0x57004) + readl(ioaddr + 0x57008);
 
 	/* The chip only need report frame silently dropped. */
-	np->stats.rx_dropped	   += readw(ioaddr + RxDMAStatus);
+	np->stats.rx_dropped += readw(ioaddr + RxDMAStatus);
 	writew(0, ioaddr + RxDMAStatus);
-	np->stats.rx_crc_errors	   = readl(ioaddr + 0x5703C);
+	np->stats.rx_crc_errors = readl(ioaddr + 0x5703C);
 	np->stats.rx_frame_errors = readl(ioaddr + 0x57040);
 	np->stats.rx_length_errors = readl(ioaddr + 0x57058);
 	np->stats.rx_missed_errors = readl(ioaddr + 0x5707C);
@@ -1665,19 +1618,19 @@
 	struct dev_mc_list *mclist;
 	int i;
 
-	if (dev->flags & IFF_PROMISC) {			/* Set promiscuous. */
+	if (dev->flags & IFF_PROMISC) {	/* Set promiscuous. */
 		/* Unconditionally log net taps. */
 		printk(KERN_NOTICE "%s: Promiscuous mode enabled.\n", dev->name);
 		rx_mode = AcceptBroadcast|AcceptAllMulticast|AcceptAll|AcceptMyPhys;
 	} else if ((dev->mc_count > multicast_filter_limit)
-			   ||  (dev->flags & IFF_ALLMULTI)) {
+		   || (dev->flags & IFF_ALLMULTI)) {
 		/* Too many to match, or accept all multicasts. */
 		rx_mode = AcceptBroadcast|AcceptAllMulticast|AcceptMyPhys;
 	} else if (dev->mc_count <= 15) {
 		/* Use the 16 element perfect filter. */
 		long filter_addr = ioaddr + 0x56000 + 1*16;
-		for (i = 1, mclist = dev->mc_list; mclist  &&  i <= dev->mc_count;
-			 i++, mclist = mclist->next) {
+		for (i = 1, mclist = dev->mc_list; mclist && i <= dev->mc_count;
+		     i++, mclist = mclist->next) {
 			u16 *eaddrs = (u16 *)mclist->dmi_addr;
 			writew(cpu_to_be16(eaddrs[2]), filter_addr); filter_addr += 4;
 			writew(cpu_to_be16(eaddrs[1]), filter_addr); filter_addr += 4;
@@ -1696,7 +1649,7 @@
 
 		memset(mc_filter, 0, sizeof(mc_filter));
 		for (i = 0, mclist = dev->mc_list; mclist && i < dev->mc_count;
-			 i++, mclist = mclist->next) {
+		     i++, mclist = mclist->next) {
 			set_bit(ether_crc_le(ETH_ALEN, mclist->dmi_addr) >> 23, mc_filter);
 		}
 		/* Clear the perfect filter list. */
@@ -1778,15 +1731,15 @@
 			   np->tx_ring_dma);
 		for (i = 0; i < 8 /* TX_RING_SIZE is huge! */; i++)
 			printk(KERN_DEBUG " #%d desc. %8.8x %8.8x -> %8.8x.\n",
-				   i, le32_to_cpu(np->tx_ring[i].status),
-				   le32_to_cpu(np->tx_ring[i].first_addr),
-				   le32_to_cpu(np->tx_done_q[i].status));
+			       i, le32_to_cpu(np->tx_ring[i].status),
+			       le32_to_cpu(np->tx_ring[i].first_addr),
+			       le32_to_cpu(np->tx_done_q[i].status));
 		printk(KERN_DEBUG "  Rx ring at %8.8x -> %p:\n",
-			   np->rx_ring_dma, np->rx_done_q);
+		       np->rx_ring_dma, np->rx_done_q);
 		if (np->rx_done_q)
 			for (i = 0; i < 8 /* RX_RING_SIZE */; i++) {
 				printk(KERN_DEBUG " #%d desc. %8.8x -> %8.8x\n",
-					   i, le32_to_cpu(np->rx_ring[i].rxaddr), le32_to_cpu(np->rx_done_q[i].status));
+				       i, le32_to_cpu(np->rx_ring[i].rxaddr), le32_to_cpu(np->rx_done_q[i].status));
 		}
 	}
 #endif /* __i386__ debugging only */
@@ -1805,31 +1758,17 @@
 	}
 	for (i = 0; i < TX_RING_SIZE; i++) {
 		struct sk_buff *skb = np->tx_info[i].skb;
-#ifdef ZEROCOPY
-		int j;
-#endif /* ZEROCOPY */
-		if (skb != NULL) {
-			pci_unmap_single(np->pci_dev,
-					 np->tx_info[i].first_mapping,
-					 skb_first_frag_len(skb), PCI_DMA_TODEVICE);
-			np->tx_info[i].first_mapping = 0;
-			dev_kfree_skb(skb);
-			np->tx_info[i].skb = NULL;
-#ifdef ZEROCOPY
-			for (j = 0; j < 6; j++)
-				if (np->tx_info[i].frag_mapping[j]) {
-					pci_unmap_single(np->pci_dev,
-									 np->tx_info[i].frag_mapping[j],
-									 skb_shinfo(skb)->frags[j].size,
-									 PCI_DMA_TODEVICE);
-					np->tx_info[i].frag_mapping[j] = 0;
-				} else
-					break;
-#endif /* ZEROCOPY */
-		}
+		if (skb == NULL)
+			continue;
+		pci_unmap_single(np->pci_dev,
+				 np->tx_info[i].first_mapping,
+				 skb_first_frag_len(skb), PCI_DMA_TODEVICE);
+		np->tx_info[i].first_mapping = 0;
+		dev_kfree_skb(skb);
+		np->tx_info[i].skb = NULL;
 	}
 
-	MOD_DEC_USE_COUNT;
+	COMPAT_MOD_DEC_USE_COUNT;
 
 	return 0;
 }
@@ -1839,7 +1778,7 @@
 {
 	struct net_device *dev = pci_get_drvdata(pdev);
 	struct netdev_private *np;
-	
+
 	if (!dev)
 		BUG();
 
@@ -1849,7 +1788,7 @@
 	iounmap((char *)dev->base_addr);
 
 	release_mem_region(pci_resource_start (pdev, 0),
-					   pci_resource_len (pdev, 0));
+			   pci_resource_len (pdev, 0));
 
 	if (np->tx_done_q)
 		pci_free_consistent(np->pci_dev, PAGE_SIZE,
@@ -1896,8 +1835,7 @@
  * Local variables:
  *  compile-command: "gcc -DMODULE -Wall -Wstrict-prototypes -O6 -c starfire.c"
  *  simple-compile-command: "gcc -DMODULE -O6 -c starfire.c"
- *  c-indent-level: 4
- *  c-basic-offset: 4
- *  tab-width: 4
+ *  c-basic-offset: 8
+ *  tab-width: 8
  * End:
  */
diff -urN linux-2.2.19-pre10/include/linux/hysdn_if.h linux/include/linux/hysdn_if.h
--- linux-2.2.19-pre10/include/linux/hysdn_if.h	Wed Dec 31 16:00:00 1969
+++ linux/include/linux/hysdn_if.h	Mon Dec  3 21:03:02 2001
@@ -0,0 +1,49 @@
+/* $Id: hysdn_if.h,v 1.1 2000/02/10 19:47:50 werner Exp $
+
+ * Linux driver for HYSDN cards, ioctl definitions shared by hynetmgr and driver.
+ * written by Werner Cornelius (werner@titro.de) for Hypercope GmbH
+ *
+ * Copyright 1999  by Werner Cornelius (werner@titro.de)
+ *
+ * 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; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * $Log: hysdn_if.h,v $
+ * Revision 1.1  2000/02/10 19:47:50  werner
+ *
+ * Initial release
+ *
+ *
+ */
+
+/****************/
+/* error values */
+/****************/
+#define ERR_NONE             0 /* no error occured */
+#define ERR_ALREADY_BOOT  1000 /* we are already booting */
+#define EPOF_BAD_MAGIC    1001 /* bad magic in POF header */
+#define ERR_BOARD_DPRAM   1002 /* board DPRAM failed */
+#define EPOF_INTERNAL     1003 /* internal POF handler error */
+#define EPOF_BAD_IMG_SIZE 1004 /* POF boot image size invalid */
+#define ERR_BOOTIMG_FAIL  1005 /* 1. stage boot image did not start */
+#define ERR_BOOTSEQ_FAIL  1006 /* 2. stage boot seq handshake timeout */
+#define ERR_POF_TIMEOUT   1007 /* timeout waiting for card pof ready */
+#define ERR_NOT_BOOTED    1008 /* operation only allowed when booted */
+#define ERR_CONF_LONG     1009 /* conf line is to long */ 
+#define ERR_INV_CHAN      1010 /* invalid channel number */ 
+#define ERR_ASYNC_TIME    1011 /* timeout sending async data */ 
+
+
+
+
diff -urN linux-2.2.19-pre10/include/linux/isdn.h linux/include/linux/isdn.h
--- linux-2.2.19-pre10/include/linux/isdn.h	Mon Dec  3 21:02:18 2001
+++ linux/include/linux/isdn.h	Mon Dec  3 21:03:02 2001
@@ -1,4 +1,4 @@
-/* $Id: isdn.h,v 1.111 2000/11/25 17:01:02 kai Exp $
+/* $Id: isdn.h,v 1.111.6.3 2001/02/10 14:44:10 kai Exp $
 
  * Main header for the Linux ISDN subsystem (linklevel).
  *
@@ -538,8 +538,7 @@
   atemu                 emu;             /* AT-emulator data               */
   struct termios	normal_termios;  /* For saving termios structs     */
   struct termios	callout_termios;
-  struct wait_queue	*open_wait;
-  struct wait_queue	*close_wait;
+  wait_queue_head_t	open_wait, close_wait;
   struct semaphore      write_sem;
 } modem_info;
 
diff -urN linux-2.2.19-pre10/include/linux/isdn_compat.h linux/include/linux/isdn_compat.h
--- linux-2.2.19-pre10/include/linux/isdn_compat.h	Wed Dec 31 16:00:00 1969
+++ linux/include/linux/isdn_compat.h	Mon Dec  3 21:03:02 2001
@@ -0,0 +1,48 @@
+/* Compatibility for various Linux kernel versions */
+
+#ifndef _LINUX_ISDN_COMPAT_H
+#define _LINUX_ISDN_COMPAT_H
+
+#ifdef __KERNEL__
+
+
+#include <linux/pci.h>
+#ifdef __powerpc__
+static inline int pci_enable_device(struct pci_dev *dev)
+{
+	u16 cmd;
+	pci_read_config_word(dev, PCI_COMMAND, &cmd);
+	cmd |= PCI_COMMAND_MEMORY | PCI_COMMAND_IO | PCI_COMMAND_SERR;
+	cmd &= ~PCI_COMMAND_FAST_BACK;
+	pci_write_config_word(dev, PCI_COMMAND, cmd);
+	return(0);
+}
+#else
+static inline int pci_enable_device(struct pci_dev *dev)
+{
+	return 0;
+}
+#endif /* __powerpc__ */
+
+#define PCI_ANY_ID (~0)
+
+/* as this is included multiple times, we make it inline */
+
+static inline struct pci_dev * pci_find_subsys(unsigned int vendor, unsigned int device,
+					unsigned int ss_vendor, unsigned int ss_device,
+					struct pci_dev *from)
+{
+	unsigned short subsystem_vendor, subsystem_device;
+
+	while ((from = pci_find_device(vendor, device, from))) {
+		pci_read_config_word(from, PCI_SUBSYSTEM_VENDOR_ID, &subsystem_vendor);
+		pci_read_config_word(from, PCI_SUBSYSTEM_ID, &subsystem_device);
+		if ((ss_vendor == PCI_ANY_ID || subsystem_vendor == ss_vendor) &&
+		    (ss_device == PCI_ANY_ID || subsystem_device == ss_device))
+			return from;
+	}
+	return NULL;
+}
+
+#endif /* __KERNEL__ */
+#endif /* _LINUX_ISDN_COMPAT_H */
diff -urN linux-2.2.19-pre10/include/linux/isdn_ppp.h linux/include/linux/isdn_ppp.h
--- linux-2.2.19-pre10/include/linux/isdn_ppp.h	Mon Dec  3 21:02:18 2001
+++ linux/include/linux/isdn_ppp.h	Mon Dec  3 21:03:02 2001
@@ -201,7 +201,7 @@
   struct ippp_buf_queue rq[NUM_RCV_BUFFS]; /* packet queue for isdn_ppp_read() */
   struct ippp_buf_queue *first;  /* pointer to (current) first packet */
   struct ippp_buf_queue *last;   /* pointer to (current) last used packet in queue */
-  struct wait_queue *wq;
+  wait_queue_head_t wq;
   struct task_struct *tk;
   unsigned int mpppcfg;
   unsigned int pppcfg;
diff -urN linux-2.2.19-pre10/include/linux/isdnif.h linux/include/linux/isdnif.h
--- linux-2.2.19-pre10/include/linux/isdnif.h	Mon Dec  3 21:02:18 2001
+++ linux/include/linux/isdnif.h	Mon Dec  3 21:03:02 2001
@@ -53,6 +53,7 @@
 #define ISDN_PROTO_L2_V11038 9   /* V.110 bitrate adaption 38400 Baud */
 #define ISDN_PROTO_L2_MODEM  10  /* Analog Modem on Board */
 #define ISDN_PROTO_L2_FAX    11  /* Fax Group 2/3         */
+#define ISDN_PROTO_L2_HDLC_56K 12   /* HDLC 56k                          */
 #define ISDN_PROTO_L2_MAX    15  /* Max. 16 Protocols                 */
 
 /*
@@ -253,6 +254,7 @@
 #define ISDN_FEATURE_L2_V11038  (0x0001 << ISDN_PROTO_L2_V11038)
 #define ISDN_FEATURE_L2_MODEM   (0x0001 << ISDN_PROTO_L2_MODEM)
 #define ISDN_FEATURE_L2_FAX	(0x0001 << ISDN_PROTO_L2_FAX)
+#define ISDN_FEATURE_L2_HDLC_56K (0x0001 << ISDN_PROTO_L2_HDLC_56K)
 
 #define ISDN_FEATURE_L2_MASK    (0x0FFFF) /* Max. 16 protocols */
 #define ISDN_FEATURE_L2_SHIFT   (0)
diff -urN linux-2.2.19-pre10/ipc/shm.c linux/ipc/shm.c
--- linux-2.2.19-pre10/ipc/shm.c	Mon Dec  3 21:02:19 2001
+++ linux/ipc/shm.c	Mon Dec  3 21:03:03 2001
@@ -337,6 +337,8 @@
 		if (current->euid == shp->u.shm_perm.uid ||
 		    current->euid == shp->u.shm_perm.cuid || 
 		    capable(CAP_SYS_ADMIN)) {
+			/* Do not find it any more */
+			shp->u.shm_perm.key = IPC_PRIVATE;
 			shp->u.shm_perm.mode |= SHM_DEST;
 			if (shp->u.shm_nattch <= 0)
 				killseg (id);
diff -urN linux-2.2.19-pre10/net/core/sock.c linux/net/core/sock.c
--- linux-2.2.19-pre10/net/core/sock.c	Sun Dec 10 16:49:44 2000
+++ linux/net/core/sock.c	Mon Dec  3 21:03:03 2001
@@ -79,6 +79,7 @@
  *		Jay Schulist	:	Added SO_ATTACH_FILTER and SO_DETACH_FILTER.
  *		Andi Kleen	:	Add sock_kmalloc()/sock_kfree_s()
  *		Andi Kleen	:	Fix write_space callback
+ *		Chris Evans	:	Security fixes - signedness again
  *
  * To Fix:
  *
@@ -376,7 +377,7 @@
 		struct timeval tm;
 	} v;
 	
-	int lv=sizeof(int),len;
+	unsigned int lv=sizeof(int),len;
   	
   	if(get_user(len,optlen))
   		return -EFAULT;
