]> git.neil.brown.name Git - history.git/commitdiff
Linux 2.2.19pre11 2.2.19pre11
authorAlan Cox <alan@lxorguk.ukuu.org.uk>
Fri, 23 Nov 2007 20:23:18 +0000 (15:23 -0500)
committerAlan Cox <alan@lxorguk.ukuu.org.uk>
Fri, 23 Nov 2007 20:23:18 +0000 (15:23 -0500)
o Corrected version of ipc/shm.c fix (Christoph Rohland)
o Update/cleanup starfire (Ion Badulescu)
o Update isdn makefiles (Kai Germaschewski)
o Eicon driver updates/new driver (Armin Schindler)
| code
o Hysdn driver (Werner Cornelius)
o Hisax updates (Kai Germaschewski)

96 files changed:
Documentation/isdn/README.diversion
Documentation/isdn/README.hysdn [new file with mode: 0644]
Makefile
aic7xxx-5.1.32.patch [deleted file]
drivers/isdn/Config.in
drivers/isdn/Makefile
drivers/isdn/Rules.make [new file with mode: 0644]
drivers/isdn/act2000/Makefile
drivers/isdn/act2000/act2000.h
drivers/isdn/act2000/module.c
drivers/isdn/avmb1/Makefile
drivers/isdn/avmb1/avm_cs.c [deleted file]
drivers/isdn/avmb1/b1.c
drivers/isdn/avmb1/b1dma.c
drivers/isdn/avmb1/b1isa.c
drivers/isdn/avmb1/b1pci.c
drivers/isdn/avmb1/b1pcmcia.c
drivers/isdn/avmb1/c4.c
drivers/isdn/avmb1/capi.c
drivers/isdn/avmb1/capidev.h
drivers/isdn/avmb1/capidrv.c
drivers/isdn/avmb1/capifs.c
drivers/isdn/avmb1/capiutil.c
drivers/isdn/avmb1/kcapi.c
drivers/isdn/avmb1/t1isa.c
drivers/isdn/avmb1/t1pci.c
drivers/isdn/divert/Makefile
drivers/isdn/divert/divert_init.c
drivers/isdn/divert/divert_procfs.c
drivers/isdn/eicon/Makefile
drivers/isdn/hisax/Makefile
drivers/isdn/hisax/avm_pci.c
drivers/isdn/hisax/bkm_a4t.c
drivers/isdn/hisax/bkm_a8.c
drivers/isdn/hisax/callc.c
drivers/isdn/hisax/config.c
drivers/isdn/hisax/diva.c
drivers/isdn/hisax/elsa.c
drivers/isdn/hisax/gazel.c
drivers/isdn/hisax/hfc_pci.c
drivers/isdn/hisax/hisax.h
drivers/isdn/hisax/isdnl3.c
drivers/isdn/hisax/l3ni1.c
drivers/isdn/hisax/netjet.c
drivers/isdn/hisax/niccy.c
drivers/isdn/hisax/nj_s.c
drivers/isdn/hisax/nj_u.c
drivers/isdn/hisax/sedlbauer.c
drivers/isdn/hisax/sportster.c
drivers/isdn/hisax/tei.c
drivers/isdn/hisax/telespci.c
drivers/isdn/hisax/w6692.c
drivers/isdn/hysdn/Makefile [new file with mode: 0644]
drivers/isdn/hysdn/boardergo.c [new file with mode: 0644]
drivers/isdn/hysdn/boardergo.h [new file with mode: 0644]
drivers/isdn/hysdn/hycapi.c [new file with mode: 0644]
drivers/isdn/hysdn/hysdn_boot.c [new file with mode: 0644]
drivers/isdn/hysdn/hysdn_defs.h [new file with mode: 0644]
drivers/isdn/hysdn/hysdn_init.c [new file with mode: 0644]
drivers/isdn/hysdn/hysdn_net.c [new file with mode: 0644]
drivers/isdn/hysdn/hysdn_pof.h [new file with mode: 0644]
drivers/isdn/hysdn/hysdn_procconf.c [new file with mode: 0644]
drivers/isdn/hysdn/hysdn_proclog.c [new file with mode: 0644]
drivers/isdn/hysdn/hysdn_sched.c [new file with mode: 0644]
drivers/isdn/hysdn/ince1pc.h [new file with mode: 0644]
drivers/isdn/icn/Makefile
drivers/isdn/icn/icn.c
drivers/isdn/icn/icn.h
drivers/isdn/isdn_bsdcomp.c
drivers/isdn/isdn_cards.c [deleted file]
drivers/isdn/isdn_cards.h [deleted file]
drivers/isdn/isdn_common.c
drivers/isdn/isdn_v110.c
drivers/isdn/isdnloop/Makefile
drivers/isdn/isdnloop/isdnloop.c
drivers/isdn/isdnloop/isdnloop.h
drivers/isdn/pcbit/Makefile
drivers/isdn/pcbit/callbacks.c
drivers/isdn/pcbit/capi.c
drivers/isdn/pcbit/drv.c
drivers/isdn/pcbit/edss1.c
drivers/isdn/pcbit/layer2.c
drivers/isdn/pcbit/module.c
drivers/isdn/pcbit/pcbit.h
drivers/isdn/sc/Makefile
drivers/isdn/sc/includes.h
drivers/isdn/sc/init.c
drivers/net/Space.c
drivers/net/starfire.c
include/linux/hysdn_if.h [new file with mode: 0644]
include/linux/isdn.h
include/linux/isdn_compat.h [new file with mode: 0644]
include/linux/isdn_ppp.h
include/linux/isdnif.h
ipc/shm.c
net/core/sock.c

index 98909b1bf7e4977c758f5eeb459371141816d644..bddcd5fb86ff6e1bc436d5473f0edb689b4543e6 100644 (file)
@@ -6,7 +6,7 @@ document. The diversion services may be used with all cards supported by
 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 --git a/Documentation/isdn/README.hysdn b/Documentation/isdn/README.hysdn
new file mode 100644 (file)
index 0000000..94e9f90
--- /dev/null
@@ -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).
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
index d5dbbf6a54610409490d201a9cad281ff56954a3..bb75f54df543df9ff9da670f2d61686734abfc9e 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -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 --git a/aic7xxx-5.1.32.patch b/aic7xxx-5.1.32.patch
deleted file mode 100644 (file)
index f68d002..0000000
+++ /dev/null
@@ -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 },
--
--};
index 7b8111881a66be51d2dc5642c574f126332aadcf..b97184a7b5fd2a6bed0d0c23359cd26e0a205571 100644 (file)
@@ -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 @@ fi
 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 @@ if [ "$CONFIG_ISDN_DRV_HISAX" != "n" ]; then
    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 @@ if [ "$CONFIG_ISDN_DRV_HISAX" != "n" ]; then
 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
index 2414eddd2ebc1557bbe1ff4c9c2b0c7d40cd0c68..d2663a87d35a4414cef3e663280a7e6ef4823d0b 100644 (file)
-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
-
-include $(TOPDIR)/Rules.make
+# Makefile for the kernel ISDN subsystem and device drivers.
 
+# 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 --git a/drivers/isdn/Rules.make b/drivers/isdn/Rules.make
new file mode 100644 (file)
index 0000000..a70f49d
--- /dev/null
@@ -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
index 31312e8f6df195f1cf0acccb1467a6208e3e5503..5964208eb1bf422b1b4998783dba4bf42b9bbee1 100644 (file)
@@ -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
-
-include $(TOPDIR)/Rules.make
+# Makefile for the act2000 ISDN device driver
+
+# 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)
index 432f433cb3966ade6c8f36d25c5c41e14ef1bfdf..95c3737e69fdf38efda53a6b10852afe9f62d930 100644 (file)
@@ -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 @@ typedef struct act2000_fwid {
 #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>
index c602d945f27e0d3e220396ba94f7c5e79f30f02a..5d634f991e5c7001432697c4810fee96f946f4c1 100644 (file)
@@ -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 @@ act2000_addcard(int bus, int port, int irq, char *id)
 
 #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 @@ act2000_init(void)
         return 0;
 }
 
-#ifdef MODULE
-void
-cleanup_module(void)
+static void  act2000_exit(void)
 {
         act2000_card *card = cards;
         act2000_card *last;
@@ -858,34 +852,5 @@ cleanup_module(void)
         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);
index 74eba296bb7db8ee23272d80a44828bd9d3af2a6..285059036a2f56fcccf56b1b526477c9f8642a8d 100644 (file)
-#
-# $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
-#
-#
+# Makefile for the AVM ISDN device drivers and CAPI subsystem.
 
-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)
+# The target object and module list name.
 
-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
+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 --git a/drivers/isdn/avmb1/avm_cs.c b/drivers/isdn/avmb1/avm_cs.c
deleted file mode 100644 (file)
index b803e88..0000000
+++ /dev/null
@@ -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);
-    }
-}
index cdd1c436d63556d65285ebd543c0fa3db309fb79..5cb5f07b93a31af4f1b2d68f647fa1425c230af4 100644 (file)
@@ -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
  *
 #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(b1_handle_interrupt);
 
 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 @@ int b1_init(void)
        return 0;
 }
 
-#ifdef MODULE
-void cleanup_module(void)
+static void  b1_exit(void)
 {
 }
-#endif
+
+module_init(b1_init);
+module_exit(b1_exit);
index f1c30a5d6668f226b596de60286535ef8907aa6c..db4f47b7970e9d611979555c04bf0ced747fa0dc 100644 (file)
@@ -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
  *
 #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_release_appl);
 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 @@ int b1dma_init(void)
        return 0;
 }
 
-#ifdef MODULE
-void cleanup_module(void)
+void b1dma_exit(void)
 {
 }
-#endif
+
+module_init(b1dma_init);
+module_exit(b1dma_exit);
index 5515ef63adc464886cb4b1b3e67bc3cc5c723ac7..784bf307edda8c5fc594ad444f0a23b57c6b2130 100644 (file)
@@ -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 ...
 #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 @@ static struct capi_driver b1isa_driver = {
     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 @@ int b1isa_init(void)
        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);
index cae8fe28dfe507ba7d26473eb7d0936663aad9d7..babbccf5ffb1b54fc136c536b567f57edd328d40 100644 (file)
@@ -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
  *
 #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 @@ static struct capi_driver b1pciv4_driver = {
 
 #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 @@ static int add_card(struct pci_dev *dev)
                        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 @@ static int add_card(struct pci_dev *dev)
                        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 @@ static int add_card(struct pci_dev *dev)
        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 @@ int b1pci_init(void)
        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 @@ int b1pci_init(void)
 #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);
index 18a325a5efd9edbaec3e48014bbca6d012d2649e..f64f4dc3256cc58b7c1396dd8d76b3f982109df6 100644 (file)
@@ -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 @@ EXPORT_SYMBOL(b1pcmcia_delcard);
 
 /* ------------------------------------------------------------- */
 
-#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 @@ int b1pcmcia_init(void)
        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);
index db8788876cf8a2d3f0670268ed28631694573db5..98e7f281b5da377bafc39f6e6f8b05d8d39c844d 100644 (file)
@@ -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 @@ static struct capi_driver c4_driver = {
     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 @@ int c4_init(void)
                        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 @@ int c4_init(void)
                        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 @@ int c4_init(void)
 #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);
index f3bff38dbbab4534369bd45bd0ddc07330c6b207..f3724615df1106210573754a05b53f2576db56e3 100644 (file)
@@ -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
  *
  *
  */
 
+#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
 #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 @@ struct capiminor {
 
        /* 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 @@ struct capidev {
        unsigned        userflags;
 
        struct sk_buff_head recvqueue;
-       struct wait_queue *recvwait;
+       wait_queue_head_t recvwait;
 
        /* Statistic */
        unsigned long   nrecvctlpkt;
@@ -400,7 +406,8 @@ void capiminor_del_all_ack(struct capiminor *mp)
 {
        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 @@ struct capiminor *capiminor_alloc(__u16 applid, __u32 ncci)
        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 @@ static struct capincci *capincci_alloc(struct capidev *cdev, __u32 ncci)
 #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 @@ static void capincci_free(struct capidev *cdev, __u32 ncci)
                        *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 @@ static struct capidev *capidev_alloc(struct file *file)
        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 @@ capi_release(struct inode *inode, struct file *file)
 {
        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 @@ capi_release(struct inode *inode, struct file *file)
 #ifdef _DEBUG_REFCOUNT
        printk(KERN_DEBUG "capi_release %d\n", GET_USE_COUNT(&__this_module));
 #endif
+       unlock_kernel();
        return 0;
 }
 
@@ -1447,11 +1459,13 @@ capinc_raw_release(struct inode *inode, struct file *file)
        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 @@ int capinc_tty_open(struct tty_struct * tty, struct file * file)
                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 @@ static struct procfsentries {
    { "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_init(void)
     }
 }
 
-static void proc_exit(void)
+static void  proc_exit(void)
 {
     int nelem = sizeof(procfsentries)/sizeof(procfsentries[0]);
     int i;
@@ -1999,18 +2015,14 @@ static void lower_callback(unsigned int cmd, __u32 contr, void *data)
        }
 }
 
-#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 @@ int capi_init(void)
        return 0;
 }
 
-#ifdef MODULE
-void cleanup_module(void)
+static void  capi_exit(void)
 {
 #ifdef CONFIG_ISDN_CAPI_MIDDLEWARE
 #endif
@@ -2086,4 +2097,5 @@ void cleanup_module(void)
        printk(KERN_NOTICE "capi: Rev%s: unloaded\n", rev);
 }
 
-#endif
+module_init(capi_init);
+module_exit(capi_exit);
index 7d18213d10aab961f39942adca1cec883b755d97..7221784858dc29e49d1de6070aaf7b19ec541acc 100644 (file)
@@ -61,7 +61,7 @@ struct capidev {
        unsigned int    minor;
 
        struct sk_buff_head recv_queue;
-       struct wait_queue *recv_wait;
+       wait_queue_head_t recv_wait;
 
        /* Statistic */
        unsigned long   nrecvctlpkt;
index c0ab5e312eb9ed5bae2cab6fe84ae73c7e3573b8..d789e767ea53cc89e7b5927c46daf88006f9bd86 100644 (file)
@@ -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.
 #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/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 @@ static struct procfsentries {
    { "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_init(void)
     }
 }
 
-static void proc_exit(void)
+static void  proc_exit(void)
 {
     int nelem = sizeof(procfsentries)/sizeof(procfsentries[0]);
     int i;
@@ -2479,11 +2483,7 @@ static struct capi_interface_user cuser = {
        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 @@ int capidrv_init(void)
        return 0;
 }
 
-#ifdef MODULE
-void cleanup_module(void)
+static void  capidrv_exit(void)
 {
        char rev[10];
        char *p;
@@ -2566,4 +2565,5 @@ void cleanup_module(void)
        printk(KERN_NOTICE "capidrv: Rev%s: unloaded\n", rev);
 }
 
-#endif
+module_init(capidrv_init);
+module_exit(capidrv_exit);
index 21be6c19d29bef71754ffbc3937706872c6cff87..8072e66ba3646d180fd35995839499b9fa1879e9 100644 (file)
@@ -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
  *
 #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 @@ void capifs_free_ncci(char type, unsigned int num)
        }
 }
 
-int __init capifs_init(void)
+static int __init capifs_init(void)
 {
        char rev[10];
        char *p;
@@ -581,7 +614,7 @@ int __init capifs_init(void)
        return 0;
 }
 
-void capifs_exit(void)
+static void  capifs_exit(void)
 {
        unregister_filesystem(&capifs_fs_type);
 }
@@ -589,16 +622,5 @@ void capifs_exit(void)
 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);
index 62160445c4c12b6b4625b7218a4693ecbed1d5f6..0d237e4680c28bae169e923452634a520df58f95 100644 (file)
@@ -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_cmsg2str);
 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);
index 9d3e94a3de407938d04521b20d56c794ceee5b70..424e82e01059269ae63e767b211bbf16e50639f9 100644 (file)
@@ -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.
  *
 #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 @@ static int old_capi_manufacturer(unsigned int cmd, void *data)
 
                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 @@ static int old_capi_manufacturer(unsigned int cmd, void *data)
 
                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 @@ static int old_capi_manufacturer(unsigned int cmd, void *data)
 
                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(detach_capi_interface);
 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 @@ int kcapi_init(void)
         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 @@ void cleanup_module(void)
         proc_capi_exit();
        printk(KERN_NOTICE "CAPI-driver Rev%s: unloaded\n", rev);
 }
-#endif
+
+module_init(kcapi_init);
+module_exit(kcapi_exit);
index fc7423d486102c660632bbafdc305f989696f25d..5b70cb4529a7abf57bd6cd7e9628aea1f1f676dd 100644 (file)
@@ -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 @@ static struct capi_driver t1isa_driver = {
     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 @@ int t1isa_init(void)
        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);
index ac0c6665644668beba930227f31cbacd29642259..4de3e05d32d3ad5bcbc11045c02130edab1ea24b 100644 (file)
@@ -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().
  *
 #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 @@ static struct capi_driver t1pci_driver = {
     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 @@ int t1pci_init(void)
                        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 @@ int t1pci_init(void)
                        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 @@ int t1pci_init(void)
 #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);
index 109c900d8ac52c2877ce1ba5795e1dafa620c7aa..8f2927bd4af568f37efecd3e8df197a43852da5b 100644 (file)
@@ -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
-
-include $(TOPDIR)/Rules.make
+#
+# Makefile for the dss1_divert ISDN module
+#
+
+# 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)
 
 
 
index 012df24ee7222fc6f20c9a87721cc0a6de077b41..8320d8d34058b39840c7a4b6af3aa7bac21aa0cc 100644 (file)
@@ -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 @@ isdn_divert_if divert_if =
 /* 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 @@ int init_module(void)
 #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 @@ void cleanup_module(void)
   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);
 
index 65738a2f4d6ec62ffc65763330576be0992b56da..0da6516d4c409074568579754e4fb54eb772cdc9 100644 (file)
@@ -32,6 +32,7 @@
 #include <linux/fs.h>
 #endif
 #include <linux/isdnif.h>
+#include <linux/isdn_compat.h>
 #include "isdn_divert.h"
 
 /*********************************/
index 306aac0e826554dfeb7de0df2e1b83646a8fc94a..41ea25adf251a9ff12f25384af292fd9f0628428 100644 (file)
@@ -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)
index 071e3b1caa1d5667e5e4d36fab1369bd17cf5468..fd257919b4d341d2dc31087cb865ff15602ea3f6 100644 (file)
-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
-
-CERT = $(shell md5sum -c md5sums.asc >> /dev/null;echo $$?)
-
-cert.o:        $(MD5FILES) md5sums.asc
-       $(CC) $(CFLAGS) $(EXTRA_CFLAGS) -D CERTIFICATION=$(CERT) -c -o cert.o cert.c
+# Makefile for the hisax ISDN device driver
+
+# The target object and module list name.
+
+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)
index 4f107052d9637e27d41c4bbe07fa99d6d6416de3..d0282411b207a444b25eb3488b3e76400c064e7c 100644 (file)
@@ -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
 #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
index b9cb063c4f8a0212ccfe81ba145a2f45f14a10a9..dedfd07a70359987b9b3ba6dd6623261da99929e 100644 (file)
@@ -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
 #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
index 9d13c31cca8ef156957ae8e68e5cf21b34da1fc0..75cc5f06a715b02f74c8a03397a94552982fdaa3 100644 (file)
@@ -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[] =
 {
index f632f47d53fcefe37c611a7bc8f917bf9eef325f..ced19e429a28da77c52d71e28406dc832a0238fa 100644 (file)
@@ -878,6 +878,7 @@ release_b_st(struct Channel *chanp)
                                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 @@ init_b_st(struct Channel *chanp, int incoming)
                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 @@ init_b_st(struct Channel *chanp, int incoming)
                        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):
index 21ddd9182865888debc8baa964afaacea4f85804..750a455318d84e45d3de70510ed462a1d7626e3b 100644 (file)
@@ -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 @@ HiSax_mod_inc_use_count(void)
        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 @@ checkcard(int cardnr, char *id, int *busy_flag)
                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 @@ HiSax_reportcard(int cardnr, int sel)
 #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 @@ HiSax_init(void))
 #endif
 #endif
        nrcards = 0;
-       HiSaxVersion();
 #ifdef MODULE
        if (id)                 /* If id= string used */
                HiSax_id = id;
@@ -1463,7 +1460,6 @@ HiSax_init(void))
        }
        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 @@ HiSax_init(void))
        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 @@ HiSax_init(void))
        }
 }
 
-#ifdef MODULE
-void
-cleanup_module(void)
+static void  HiSax_exit(void)
 {
        int cardnr = nrcards -1;
        long flags;
@@ -1516,17 +1503,14 @@ cleanup_module(void)
        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 @@ int elsa_init_pcmcia(void *pcm_iob, int pcm_irq, int *busy_flag, int prot)
                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 @@ int elsa_init_pcmcia(void *pcm_iob, int pcm_irq, int *busy_flag, int prot)
        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 hfc_init_pcmcia(void *pcm_iob, int pcm_irq, int *busy_flag, int prot)
        int nzproto = 0;
 
        nrcards = 0;
-       HiSaxVersion();
        /* Initialize all structs, even though we only accept
           two pcmcia cards
           */
@@ -1604,11 +1580,6 @@ int hfc_init_pcmcia(void *pcm_iob, int pcm_irq, int *busy_flag, int prot)
        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 sedl_init_pcmcia(void *pcm_iob, int pcm_irq, int *busy_flag, int prot)
        int nzproto = 0;
 
        nrcards = 0;
-       HiSaxVersion();
        /* Initialize all structs, even though we only accept
           two pcmcia cards
           */
@@ -1653,11 +1623,6 @@ int sedl_init_pcmcia(void *pcm_iob, int pcm_irq, int *busy_flag, int prot)
        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 avm_a1_init_pcmcia(void *pcm_iob, int pcm_irq, int *busy_flag, int prot)
        int nzproto = 0;
 
        nrcards = 0;
-       HiSaxVersion();
        /* Initialize all structs, even though we only accept
           two pcmcia cards
           */
@@ -1702,11 +1666,6 @@ int avm_a1_init_pcmcia(void *pcm_iob, int pcm_irq, int *busy_flag, int prot)
        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 @@ int avm_a1_init_pcmcia(void *pcm_iob, int pcm_irq, int *busy_flag, int prot)
 }
 #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 @@ int hisax_init_pcmcia(void *pcm_iob, int *busy_flag, struct IsdnCard *card)
        nrcards++;
        return (ret);
 }
+
+
+module_init(HiSax_init);
+module_exit(HiSax_exit);
index deb981074a3c7c1474bfe387d14435b6dfa9976b..fd6960646b6d4690523bb62e7e244e86b762c5d3 100644 (file)
@@ -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
  *
 #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)
index a9ef249433e00069309ebce6f54832f5726926c5..aad897565f1b42f2cf37bddca536c431af99efc7 100644 (file)
@@ -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
  *
 #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", 
index e64dc28d9ea0babcbf466c6976e0d6a00feffd7e..877b2c71fc248707161d5d6bcad79bacda6c9a02 100644 (file)
@@ -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
  *
 #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
index c673fd881b32391271b82b2da3ed030ce25b3a76..65df8159b07ed63e02ac6680b37ad4f8630cbe81 100644 (file)
@@ -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
  *
 #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 @@ static struct pci_dev *dev_hfcpci __initdata = NULL;
 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 @@ int __init setup_hfcpci(struct IsdnCard *card)
 #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,
@@ -1687,39 +1683,6 @@ int __init setup_hfcpci(struct IsdnCard *card)
                        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");
                        return (0);
index 0cb4bd66675264c88ec28909bcd79fa36d56bd04..52e8421e4cd8361790ffdb76ad5975165125ddec 100644 (file)
@@ -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 @@ struct amd7930_hw {
 #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 @@ char *HiSax_getrev(const char *revision);
 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__ */
index 63636d3d1f48a3305eb53ec65c1769aeb2056189..d305077d86dafdde45cace18cde4a58357e5a846 100644 (file)
@@ -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 @@ release_l3_process(struct l3_process *p)
                                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");
@@ -482,6 +485,18 @@ lc_start_delay(struct FsmInst *fi, int event, void *arg)
        FsmAddTimer(&st->l3.l3m_timer, DREL_TIMER_VALUE, EV_TIMEOUT, NULL, 50);
 }
 
+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)
 {
@@ -530,7 +545,7 @@ static struct FsmNode L3FnList[] __initdata =
        {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 @@ l3_msg(struct PStack *st, int pr, void *arg)
                        } 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;
index 714cad9157ce4dfff2d46ace8ddb9ce5cd82bb25..4440f44e7bd71822f3da795fe661e88c1caad7e7 100644 (file)
@@ -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
@@ -446,6 +446,27 @@ l3ni1_message(struct l3_process *pc, u_char mt)
        l3_msg(pc->st, DL_DATA | REQUEST, skb);
 }
 
+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)
 {
@@ -1179,9 +1200,9 @@ l3ni1_setup_req(struct l3_process *pc, u_char pr,
        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 @@ l3ni1_setup_req(struct l3_process *pc, u_char pr,
                        *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 @@ l3ni1_setup_rsp(struct l3_process *pc, u_char pr,
            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 @@ l3ni1_global_restart(struct l3_process *pc, u_char pr, void *arg)
                        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;
index 2904bb3851dcb1d1425b80af8fac8cb2ea002716..1ca81cdb9340e6014221718b7a7e4a4c1090d6e5 100644 (file)
@@ -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
  *
 #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 @@ mode_tiger(struct BCState *bcs, int mode, int bc)
                        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 @@ mode_tiger(struct BCState *bcs, int mode, int bc)
                                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 @@ static void printframe(struct IsdnCardState *cs, u_char *buf, int count, char *s
        }
 }
 
+// macro for 64k
+
 #define MAKE_RAW_BYTE for (j=0; j<8; j++) { \
                        bitcnt++;\
                        s_val >>= 1;\
@@ -236,6 +239,7 @@ static void printframe(struct IsdnCardState *cs, u_char *buf, int count, char *s
                }
 
 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 @@ static int make_raw_data(struct BCState *bcs) {
        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 @@ static void read_raw(struct BCState *bcs, u_int *buf, int cnt){
        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 @@ void read_tiger(struct IsdnCardState *cs) {
                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 @@ void netjet_fill_dma(struct BCState *bcs)
                        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 @@ void write_tiger(struct IsdnCardState *cs) {
                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;
 }
index 6924c3325c722d42604af72fd7b3da4e2ec527da..c80afd716d2a7b8785ea650cbef475fddef32b49 100644 (file)
@@ -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)
 #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)
index bc640a6c503f32b4f5f02c268128ab22b50cedf9..f844e8ae154297d38a37bd1eeb8f47630fbe68d6 100644 (file)
@@ -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 @@ netjet_s_interrupt(int intno, void *dev_id, struct pt_regs *regs)
        }
        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 @@ reset_netjet_s(struct IsdnCardState *cs)
        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 @@ setup_netjet_s(struct IsdnCard *card)
        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 @@ setup_netjet_s(struct IsdnCard *card)
        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 @@ setup_netjet_s(struct IsdnCard *card)
                        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");
index 67c18a35cc1a2602505691395f26c9106e8bf3db..9977477f825cc20d6d8e5b7864094cbc607bdca1 100644 (file)
@@ -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 @@ netjet_u_interrupt(int intno, void *dev_id, struct pt_regs *regs)
        }
        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 @@ reset_netjet_u(struct IsdnCardState *cs)
        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 @@ setup_netjet_u(struct IsdnCard *card)
        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 @@ setup_netjet_u(struct IsdnCard *card)
                       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;
index 791405f2709072374c710cc125ce89dc33ea9720..013f83c2e50966534d6c9640a71b5f623d97e303 100644 (file)
@@ -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),
 #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 @@ Sedl_card_msg(struct IsdnCardState *cs, int mt, void *arg)
        return(0);
 }
 
-static         struct pci_dev *dev_sedl  = NULL;
+static struct pci_dev *dev_sedl  = NULL;
 
 int 
 setup_sedlbauer(struct IsdnCard *card)
index 2e4e10ff35fdd900c04cfb32e029732a4941930c..b72ff032c6bd46acc86fbbbe4b6905b4f5070dfd 100644 (file)
@@ -208,8 +208,8 @@ get_io_range(struct IsdnCardState *cs)
        }
 }
 
-__initfunc(int
-setup_sportster(struct IsdnCard *card))
+int __init
+setup_sportster(struct IsdnCard *card)
 {
        struct IsdnCardState *cs = card->cs;
        char tmp[64];
index a85e54bb67b1dee99448a3909a0033044ceb8d38..41a7446b75211e326c80a904c3b2ed25cd5723f2 100644 (file)
@@ -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 $";
index dda87c51e9d6a603fde844d3284c59628e309219..deca1d2d5a9ca0a131e933eae0b0e191f6576d69 100644 (file)
@@ -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
  *
 #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 @@ TelesPCI_card_msg(struct IsdnCardState *cs, int mt, void *arg)
        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)
index 6a0012b37315378c22cdad4d43f5b023ecfd146c..3586d75d4675292d9933874e29852634a52fb4b1 100644 (file)
@@ -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 @@ static const PCI_ENTRY id_list[] =
 
 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 @@ w6692_card_msg(struct IsdnCardState *cs, int mt, void *arg)
        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 --git a/drivers/isdn/hysdn/Makefile b/drivers/isdn/hysdn/Makefile
new file mode 100644 (file)
index 0000000..a3ab66f
--- /dev/null
@@ -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 --git a/drivers/isdn/hysdn/boardergo.c b/drivers/isdn/hysdn/boardergo.c
new file mode 100644 (file)
index 0000000..92e96ec
--- /dev/null
@@ -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 --git a/drivers/isdn/hysdn/boardergo.h b/drivers/isdn/hysdn/boardergo.h
new file mode 100644 (file)
index 0000000..ea3c744
--- /dev/null
@@ -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 --git a/drivers/isdn/hysdn/hycapi.c b/drivers/isdn/hysdn/hycapi.c
new file mode 100644 (file)
index 0000000..ddc0082
--- /dev/null
@@ -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 --git a/drivers/isdn/hysdn/hysdn_boot.c b/drivers/isdn/hysdn/hysdn_boot.c
new file mode 100644 (file)
index 0000000..abab312
--- /dev/null
@@ -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 --git a/drivers/isdn/hysdn/hysdn_defs.h b/drivers/isdn/hysdn/hysdn_defs.h
new file mode 100644 (file)
index 0000000..1b37955
--- /dev/null
@@ -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 --git a/drivers/isdn/hysdn/hysdn_init.c b/drivers/isdn/hysdn/hysdn_init.c
new file mode 100644 (file)
index 0000000..25790f7
--- /dev/null
@@ -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 --git a/drivers/isdn/hysdn/hysdn_net.c b/drivers/isdn/hysdn/hysdn_net.c
new file mode 100644 (file)
index 0000000..dc9c7af
--- /dev/null
@@ -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 --git a/drivers/isdn/hysdn/hysdn_pof.h b/drivers/isdn/hysdn/hysdn_pof.h
new file mode 100644 (file)
index 0000000..524b7a0
--- /dev/null
@@ -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 --git a/drivers/isdn/hysdn/hysdn_procconf.c b/drivers/isdn/hysdn/hysdn_procconf.c
new file mode 100644 (file)
index 0000000..6fb29ff
--- /dev/null
@@ -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 --git a/drivers/isdn/hysdn/hysdn_proclog.c b/drivers/isdn/hysdn/hysdn_proclog.c
new file mode 100644 (file)
index 0000000..f8187ea
--- /dev/null
@@ -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 --git a/drivers/isdn/hysdn/hysdn_sched.c b/drivers/isdn/hysdn/hysdn_sched.c
new file mode 100644 (file)
index 0000000..276f44d
--- /dev/null
@@ -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 --git a/drivers/isdn/hysdn/ince1pc.h b/drivers/isdn/hysdn/ince1pc.h
new file mode 100644 (file)
index 0000000..9f9d310
--- /dev/null
@@ -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__ */
index 17c533ee8157c0354c61a0bebf0eb269c0610dcf..51915f11c9d3703f456e2a0c274c2d63ef0e1990 100644 (file)
@@ -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
-
-include $(TOPDIR)/Rules.make
+# Makefile for the act2000 ISDN device driver
+
+# 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
index 3212a6a8abeb20e541726533729cb597c0e55413..d7e8d8bad47ee74c6f7a5175179704b643ec8342 100644 (file)
@@ -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 @@ icn_addcard(int port, char *id1, char *id2)
        return 0;
 }
 
-#ifdef MODULE
-#define icn_init init_module
-#else
+#ifndef MODULE
 void
 icn_setup(char *str, int *ints)
 {
@@ -1661,10 +1660,9 @@ icn_setup(char *str, int *ints)
                }
        }
 }
-#endif /* MODULES */
+#endif /* MODULE */
 
-int
-icn_init(void)
+static int __init icn_init(void)
 {
        char *p;
        char rev[10];
@@ -1675,9 +1673,6 @@ icn_init(void)
        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 @@ icn_init(void)
        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 @@ cleanup_module(void)
                release_shmem((ulong) dev.shmem, 0x4000);
        printk(KERN_NOTICE "ICN-ISDN-driver unloaded\n");
 }
-#endif
+
+module_init(icn_init);
+module_exit(icn_exit);
index b49887c2aadf5ba403c872c48c4dc7ec767725e3..7cea7c2ed311582a3d7c7ee4e9c0d790fe55d13d 100644 (file)
@@ -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 @@ typedef struct icn_cdef {
 #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>
index e5cc0ea30be552fed8e594948a1899410b0797f4..d328754ab0f559b84c467fc40fab15b1eed412a2 100644 (file)
  * 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 @@ static struct isdn_ppp_compressor ippp_bsd_compress = {
  * 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 @@ int init_module(void)
        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 --git a/drivers/isdn/isdn_cards.c b/drivers/isdn/isdn_cards.c
deleted file mode 100644 (file)
index 1441328..0000000
+++ /dev/null
@@ -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 --git a/drivers/isdn/isdn_cards.h b/drivers/isdn/isdn_cards.h
deleted file mode 100644 (file)
index 6122ac8..0000000
+++ /dev/null
@@ -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);
index 08e4bf0cc9fde71d569848b84a4875e5ce52ce12..b73b6a34cc111c2ea41dffd259fb581a28e7843f 100644 (file)
@@ -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 @@ register_isdn(isdn_if * i)
  *****************************************************************************
  */
 
-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 @@ isdn_getrev(const char *revision)
 /*
  * 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 @@ isdn_init(void)
        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 @@ cleanup_module(void)
                printk(KERN_NOTICE "ISDN-subsystem unloaded\n");
        }
 }
-#endif
+
+module_init(isdn_init);
+module_exit(isdn_exit);
index 4272b69b2ef9e4e208f2d98c41c1dd5633900960..079918a16fc0c98fd85ae2e5039c9d949683f9dc 100644 (file)
@@ -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
index 588d80760f300fbe6104f2b806c817d2876b2d00..cb66f9af049f0f421e56bbc751c7741fdf086127 100644 (file)
@@ -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
 
index f91723bbe0785c8a598422436b98adc316b028be..5f1b6295b618688f5ae62b3e0f6424476f06ccdb 100644 (file)
@@ -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.
  *
  */
 
 #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 @@ isdnloop_addcard(char *id1)
        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 @@ isdnloop_init(void)
        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 @@ cleanup_module(void)
        }
        printk(KERN_NOTICE "isdnloop-ISDN-driver unloaded\n");
 }
-#endif
+
+module_init(isdnloop_init);
+module_exit(isdnloop_exit);
index e0ddaaf36a37529d9f822c7dc6620c3cce14bb61..fe8a501104fff16b1e567c7d7334bf8ff5cb0f3a 100644 (file)
@@ -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 @@ typedef struct isdnloop_sdef {
 #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>
index 50a67269ea7498e761df6cfec94623efff04a3b1..bbdaa55f087a77b303485729f8b2470f0d3bb19b 100644 (file)
@@ -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
-
-include $(TOPDIR)/Rules.make
+# Makefile for the pcbit ISDN device driver
+
+# 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)
index afa22b7401a67270d9565d8370829b2436fbbb20..ed2ba29d9814f601ed19c55be1e57c99e87931c1 100644 (file)
@@ -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>
index 1a32c0825429e62fcd382d03d1c94d9256dafe7b..57b23498fe540f25b4706b41d6b1974bc6443acb 100644 (file)
@@ -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>
index 92b1e398af25d25b998a1151410603285d5a0870..2c978622bdac080e2dd1f1ecc7b47cd9aaf774d0 100644 (file)
@@ -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 @@ int pcbit_init_dev(int board, int mem_base, int irq)
 
        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 @@ int pcbit_init_dev(int board, int mem_base, int irq)
        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;
index 1b76b346203815880d45d035771b552a5085d626..991f430e66d80070bd9a249c5f6d35c525633c51 100644 (file)
@@ -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>
index 98daf755849df24c3eb7f8a27c1e8f9bc76206bc..e80b12fafc21d8a61aed6da2cbe01d061b445892 100644 (file)
@@ -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>
index 55dfd75ac88a0c2dd76097974b172b9f5ecacb01..11f54d0d3ad35e875f32a3c8140dc54e1f95ca3d 100644 (file)
@@ -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 mem[MAX_PCBIT_CARDS] = {0, };
 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 @@ int pcbit_init(void)
                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 @@ void cleanup_module(void)
               "PCBIT-D module unloaded\n");
 }
 
-#else
+#ifndef MODULE
 void pcbit_setup(char *str, int *ints)
 {
        int i, j, argc;
@@ -126,5 +112,9 @@ void pcbit_setup(char *str, int *ints)
 }
 #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);
 
index 92a561d29981c0e58e10f1916eecabd03c387d7a..99aab08ccfee903e979f791b64c07331a267df7c 100644 (file)
@@ -69,7 +69,7 @@ struct pcbit_dev {
        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;
index ff87210b87d19b9ef1f4830ae5bf8297bed93283..c27bf6c27f7455678f17e63716c3f8e3d6886a62 100644 (file)
@@ -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
-
-include $(TOPDIR)/Rules.make
+# Makefile for the sc ISDN device driver
+
+# 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)
index 951f06f258f81f1d191eeab1cb207de49917e9b0..840dfc0976fdd1370a02cdb28ab64e3e9e4edbeb 100644 (file)
@@ -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>
index e379ae44255d5192ccb78deed94975a03dff23a0..fbe7891793b79b62514647a645887d38ffe65cec 100644 (file)
@@ -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 @@ int irq_supported(int irq_x)
        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 @@ int init_sc(void)
        return status;
 }
 
-#ifdef MODULE
-void cleanup_module(void)
+static void  sc_exit(void)
 {
        int i, j;
 
@@ -463,7 +453,6 @@ void cleanup_module(void)
        }
        pr_info("SpellCaster ISA ISDN Adapter Driver Unloaded.\n");
 }
-#endif
 
 int identify_board(unsigned long rambase, unsigned int iobase) 
 {
@@ -579,3 +568,6 @@ int identify_board(unsigned long rambase, unsigned int iobase)
                
        return -1;
 }
+
+module_init(sc_init);
+module_exit(sc_exit);
index 5faa19d58fabbee73fadbfb8f08e8c395402889f..85449e338307239a9eebebc72ef0747712a10d73 100644 (file)
@@ -127,6 +127,7 @@ extern int lance_probe(struct device *dev);
 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 @@ struct devprobe pci_probes[] __initdata = {
 #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},
 };
 
index b0b0a0e3c702d5f43aa77aac253008967d7de409..a776433e2c45053e863748c5fd4ab16730fd297e 100644 (file)
@@ -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
 
 
        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 @@ static const char version2[] =
 " 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 @@ static const char version3[] =
  * 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 @@ static const char version3[] =
  * 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 debug = 1;                       /* 1 normal messages, 0 quiet .. 7 verbose. */
 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 @@ static int full_duplex[MAX_UNITS] = {-1, -1, -1, -1, -1, -1, -1, -1};
 
 /* Operational parameters that usually are not changed. */
 /* Time in jiffies before concluding the transmitter is hung. */
-#define TX_TIMEOUT  (2*HZ)
+#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
-
-#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 @@ static int full_duplex[MAX_UNITS] = {-1, -1, -1, -1, -1, -1, -1, -1};
 #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 @@ static int full_duplex[MAX_UNITS] = {-1, -1, -1, -1, -1, -1, -1, -1};
 #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
+
+*/
+
+\f
+
+/* 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 @@ static inline void *pci_alloc_consistent(struct pci_dev *hwdev, size_t size,
 #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 @@ pci_announce_device(struct pci_driver *drv, struct pci_dev *dev)
                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 @@ pci_unregister_driver(struct pci_driver *drv)
        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 @@ void *compat_request_region (unsigned long start, unsigned long n, const char *n
 
 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 */
-
-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.
+static struct pci_driver starfire_driver;
 
-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 */
 
-\f
 
 enum chip_capability_flags {CanHaveMII=1, };
 #define PCI_IOTYPE (PCI_USES_MASTER | PCI_USES_MEM | PCI_ADDR0)
@@ -574,7 +613,7 @@ enum rx_compl_bits {
 
 /* 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 @@ enum rx_desc_bits {
 #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 @@ enum rx_done_bits {
        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 rx_ring_info {
 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 netdev_private {
        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. */
+       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 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);
 
 \f
 
-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 __devinit starfire_init_one (struct pci_dev *pdev,
        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 @@ static int __devinit starfire_init_one (struct pci_dev *pdev,
                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 @@ static int __devinit starfire_init_one (struct pci_dev *pdev,
        }
 
        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 @@ static int __devinit starfire_init_one (struct pci_dev *pdev,
                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 @@ static int __devinit starfire_init_one (struct pci_dev *pdev,
        /* 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 @@ static int __devinit starfire_init_one (struct pci_dev *pdev,
 
        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 @@ static int mdio_read(struct net_device *dev, int phy_id, int location)
        /* ??? 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 @@ static int netdev_open(struct net_device *dev)
 
        /* 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 @@ static int netdev_open(struct net_device *dev)
        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 @@ static int netdev_open(struct net_device *dev)
                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 @@ static int netdev_open(struct net_device *dev)
        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 @@ static int netdev_open(struct net_device *dev)
        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 @@ static int netdev_open(struct net_device *dev)
               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 @@ static int netdev_open(struct net_device *dev)
 
        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 @@ static void check_duplex(struct net_device *dev, int startup)
                        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 @@ static void netdev_timer(unsigned long data)
 
        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 @@ static void netdev_timer(unsigned long data)
                /* 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 @@ static void tx_timeout(struct net_device *dev)
        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 @@ static void init_ring(struct net_device *dev)
        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 @@ static int start_tx(struct sk_buff *skb, struct net_device *dev)
 {
        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 @@ static int start_tx(struct sk_buff *skb, struct net_device *dev)
        /* 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 @@ static void intr_handler(int irq, void *dev_instance, struct pt_regs *rgs)
        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 @@ static void intr_handler(int irq, void *dev_instance, struct pt_regs *rgs)
 
                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 @@ static void intr_handler(int irq, void *dev_instance, struct pt_regs *rgs)
                /* 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);
-
-                                       np->dirty_tx++;
-                               }
-                               np->tx_done_q[np->tx_done].status = 0;
-                               np->tx_done = (np->tx_done+1) & (DONE_Q_SIZE-1);
+
+               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;
+
+                               /* 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 @@ static void intr_handler(int irq, void *dev_instance, struct pt_regs *rgs)
 
                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 @@ static int netdev_rx(struct net_device *dev)
 
        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;
-
-                               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]);
+               } 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]);
 #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 @@ static int netdev_rx(struct net_device *dev)
                        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 @@ static int netdev_rx(struct net_device *dev)
        }
 
        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 @@ static void netdev_error(struct net_device *dev, int intr_status)
 
        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 @@ static void netdev_error(struct net_device *dev, int intr_status)
        /* 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 @@ static struct net_device_stats *get_stats(struct net_device *dev)
        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 @@ static void set_rx_mode(struct net_device *dev)
        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 @@ static void set_rx_mode(struct net_device *dev)
 
                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 @@ static int netdev_close(struct net_device *dev)
                           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 @@ static int netdev_close(struct net_device *dev)
        }
        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 @@ static void __devexit starfire_remove_one (struct pci_dev *pdev)
 {
        struct net_device *dev = pci_get_drvdata(pdev);
        struct netdev_private *np;
-       
+
        if (!dev)
                BUG();
 
@@ -1849,7 +1788,7 @@ static void __devexit starfire_remove_one (struct pci_dev *pdev)
        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 @@ module_exit(starfire_cleanup);
  * 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 --git a/include/linux/hysdn_if.h b/include/linux/hysdn_if.h
new file mode 100644 (file)
index 0000000..68cc720
--- /dev/null
@@ -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 */ 
+
+
+
+
index 41190a2a2e00bfbf1e2bc4e4da292e2f3e326255..b9bf7dd3d2eb5b552c402382c9407ca9c821b3b7 100644 (file)
@@ -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 @@ typedef struct modem_info {
   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 --git a/include/linux/isdn_compat.h b/include/linux/isdn_compat.h
new file mode 100644 (file)
index 0000000..90917b4
--- /dev/null
@@ -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 */
index 988c9402d7a2853f8f3c40aea961cc012cf9995d..e2d9b1de101f8e51941ac75fc933b728a793f218 100644 (file)
@@ -201,7 +201,7 @@ struct ippp_struct {
   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;
index 7ce2fb214aa90f7401a6ea35ec3c1a7dd2a78cc3..1d5d4f85b7dd9ac041b2d8116e4188cd26b1835e 100644 (file)
@@ -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 @@ typedef struct
 #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)
index 4a33fa8fe85060781de7070a5f22bd75a6be7e3a..ca25f68e223e741496f8c983712348007465cd6a 100644 (file)
--- a/ipc/shm.c
+++ b/ipc/shm.c
@@ -337,6 +337,8 @@ asmlinkage int sys_shmctl (int shmid, int cmd, struct shmid_ds *buf)
                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);
index 0fe23ed6f6e69780cc372bf080466f7ba1e331ad..70324492115415484f8a8faec8d19810121bb6b7 100644 (file)
@@ -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 @@ int sock_getsockopt(struct socket *sock, int level, int optname,
                struct timeval tm;
        } v;
        
-       int lv=sizeof(int),len;
+       unsigned int lv=sizeof(int),len;
        
        if(get_user(len,optlen))
                return -EFAULT;