--- a/Documentation/isdn/CREDITS
+++ b/Documentation/isdn/CREDITS
@@ -37,7 +37,7 @@ Michael Knigge (knick@cove.han.de)
 Andreas Kool (akool@Kool.f.EUnet.de)
   For contribution of the isdnlog/isdnrep-tool
 
-Pedro Roque Marques (pedro_m@yahoo.com)
+Pedro Roque Marques (roque@di.fc.ul.pt)
   For lot of new ideas and the pcbit driver.
 
 Eberhard Moenkeberg (emoenke@gwdg.de)
--- a/Documentation/isdn/HiSax.cert
+++ b/Documentation/isdn/HiSax.cert
@@ -68,6 +68,8 @@ drivers/isdn/hisax/cert.c
 drivers/isdn/hisax/elsa.c
 drivers/isdn/hisax/diva.c
 drivers/isdn/hisax/hfc_pci.c
+drivers/isdn/hisax/hfc_usbr.c
+drivers/isdn/hisax/hfc_usb.c
 
 Please send any changes, bugfixes and patches to me rather than implementing
 them directly into the HiSax sources.
--- a/Documentation/isdn/INTERFACE
+++ b/Documentation/isdn/INTERFACE
@@ -1,4 +1,4 @@
-$Id: INTERFACE,v 1.1.4.1 2001/11/20 14:19:33 kai Exp $
+$Id: INTERFACE,v 1.17 2002/01/31 13:26:35 keil Exp $
 
 Description of the Interface between Linklevel and Hardwarelevel
   of isdn4linux:
@@ -399,7 +399,7 @@ Description of the Interface between Lin
                     protocol-Id is one of the constants ISDN_PROTO_L3...
       parm.fax    = Pointer to T30_s fax struct. (fax usage only)
 
-  ISDN_CMD_GETL2: (currently unused)
+  ISDN_CMD_GETL3: (currently unused)
 
     With this command, the HL-driver is told to return the current
     setting of the Layer-3-protocol.
@@ -781,3 +781,22 @@ Description of the Interface between Lin
       arg         = channel-number, locally to the driver. (starting with 0)
       parm        = unused.
 
+  ISDN_STAT_ALERT:
+
+    With this call, the HL-driver signals the receive of an ALERTING message to the LL.
+
+    Parameter:
+      driver      = driver-Id
+      command     = ISDN_STAT_ALERT
+      arg         = channel-number, locally to the driver. (starting with 0)
+
+  ISDN_STAT_PROCEED:
+
+    With this call, the HL-driver signals the receive of an CALL PROCEEDING message
+    to the LL.
+
+    Parameter:
+      driver      = driver-Id
+      command     = ISDN_STAT_PROCEED
+      arg         = channel-number, locally to the driver. (starting with 0)
+
--- a/Documentation/isdn/INTERFACE.fax
+++ b/Documentation/isdn/INTERFACE.fax
@@ -1,4 +1,4 @@
-$Id: INTERFACE.fax,v 1.1.4.1 2001/11/20 14:19:33 kai Exp $
+$Id: INTERFACE.fax,v 1.2 2000/08/06 09:22:50 armin Exp $
 
 
 Description of the fax-subinterface between linklevel and hardwarelevel of 
--- a/Documentation/isdn/README
+++ b/Documentation/isdn/README
@@ -278,6 +278,12 @@ README for the ISDN-subsystem
                                       1 = Add CPN to FCON message on
                             Bit 2:    0 = Add CDN to RING/FCON message off
                                       1 = Add CDN to RING/FCON message on
+                            Bit 3:    0 = Do not signal RINGING
+                                      1 = Signal RINGING if ALERT was received
+                            Bit 4:    0 = Do not signal PROCEEDING
+                                      1 = Signal PROCEEDING if CALL PROCEEDING
+                                          was received
+
 
   Last but not least a (at the moment fairly primitive) device to request
   the line-status (/dev/isdninfo) is made available.
--- a/Documentation/isdn/README.HiSax
+++ b/Documentation/isdn/README.HiSax
@@ -41,10 +41,9 @@ ELSA Quickstep 3000 (same settings as QS
 ELSA Quickstep 3000PCI
 ELSA PCMCIA
 ITK ix1-micro Rev.2
-Eicon Diva 2.0 ISA and PCI (S0 and U interface, no PRO version)
-Eicon Diva 2.01 ISA and PCI
-Eicon Diva 2.02 PCI
-Eicon Diva Piccola
+Eicon.Diehl Diva 2.0 ISA and PCI (S0 and U interface, no PRO version)
+Eicon.Diehl Diva 2.01 ISA and PCI
+Eicon.Diehl Diva Piccola
 ASUSCOM NETWORK INC. ISDNLink 128K PC adapter (order code I-IN100-ST-D)
 Dynalink IS64PH (OEM version of ASUSCOM NETWORK INC. ISDNLink 128K adapter)
 PCBIT-DP (OEM version of ASUSCOM NETWORK INC. ISDNLink)
@@ -53,7 +52,6 @@ Sedlbauer Speed Card (Speed Win, Teledat
 Sedlbauer Speed Star/Speed Star2 (PCMCIA)
 Sedlbauer ISDN-Controller PC/104
 USR Sportster internal TA (compatible Stollmann tina-pp V3)
-USR internal TA PCI
 ith Kommunikationstechnik GmbH MIC 16 ISA card
 Traverse Technologie NETjet PCI S0 card and NETspider U card
 Ovislink ISDN sc100-p card (NETjet driver)
@@ -68,14 +66,14 @@ Gazel ISDN cards
 HFC-PCI based cards
 Winbond W6692 based cards
 HFC-S+, HFC-SP/PCMCIA cards
-formula-n enternow
-Gerdes Power ISDN
+HFC-USB ISDN TAs
 
 Note: PCF, PCF-Pro: up to now, only the ISDN part is supported
       PCC-8: not tested yet
       Eicon.Diehl Diva U interface not tested
 
 If you know other passive cards with the Siemens chipset, please let me know.
+To use the PNP cards you need the isapnptools.
 You can combine any card, if there is no conflict between the resources
 (io, mem, irq).
 
@@ -91,15 +89,8 @@ There is also some config needed before 
 modules. It is included in the normal "make [menu]config" target at the
 kernel. Don't forget it, especially to select the right D-channel protocol.
 
-Please note: In older versions of the HiSax driver, all PnP cards
-needed to be configured with isapnp and worked only with the HiSax
-driver used as a module.
-
-In the current version, HiSax will automatically use the in-kernel
-ISAPnP support, provided you selected it during kernel configuration
-(CONFIG_ISAPNP), if you don't give the io=, irq= command line parameters.
-
-The affected card types are: 4,7,12,14,19,27-30
+Please note: All PnP cards need to be configured with isapnp and will work
+only with the HiSax driver used as a module.
 
 a) when built as a module
 -------------------------
@@ -200,8 +191,6 @@ Card types:
    37	HFC 2BDS0 S+, SP         irq,io 
    38	NETspider U PCI card     none
    39	HFC 2BDS0 SP/PCMCIA      irq,io (set with cardmgr)
-   40   hotplug interface
-   41   Formula-n enter:now PCI  none
 
 At the moment IRQ sharing is only possible with PCI cards. Please make sure
 that your IRQ is free and enabled for ISA use.
@@ -227,13 +216,6 @@ Examples for module loading
                    (IO 1 (BASE 0x0180))
    modprobe hisax type=4 protocol=2 irq=10 io0=0x580 io1=0x180
 
-   In the current version of HiSax, you can instead simply use
-
-   modprobe hisax type=4 protocol=2
-
-   if you configured your kernel for ISAPnP. Don't run isapnp in
-   this case!
-
 6. Teles 16.3, Euro ISDN, I/O base 280 hex, IRQ 12 and
    Teles 16.0, 1TR6, IRQ 5, Memory d0000 hex
    modprobe hisax type=3,1 protocol=2,1 io=0x280 mem=0,0xd0000
@@ -314,9 +296,7 @@ type
    36	W6692 based PCI cards   none
    37	HFC 2BDS0 S+,SP/PCMCIA  ONLY WORKS AS A MODULE !
    38	NETspider U PCI card    none
-   39	HFC 2BDS0 SP/PCMCIA     ONLY WORKS AS A MODULE !
-   40   hotplug interface	ONLY WORKS AS A MODULE !
-   41   Formula-n enter:now PCI none
+
 
 Running the driver
 ------------------
--- a/Documentation/isdn/README.act2000
+++ b/Documentation/isdn/README.act2000
@@ -1,4 +1,4 @@
-$Id: README.act2000,v 1.1.4.1 2001/11/20 14:19:33 kai Exp $
+$Id: README.act2000,v 1.3 2000/08/06 09:22:51 armin Exp $
 
 This document describes the ACT2000 driver for the
 IBM Active 2000 ISDN card.
--- a/Documentation/isdn/README.audio
+++ b/Documentation/isdn/README.audio
@@ -1,4 +1,4 @@
-$Id: README.audio,v 1.1.4.1 2001/11/20 14:19:33 kai Exp $
+$Id: README.audio,v 1.8 1999/07/11 17:17:29 armin Exp $
 
 ISDN subsystem for Linux.
   Description of audio mode.
--- a/Documentation/isdn/README.eicon
+++ b/Documentation/isdn/README.eicon
@@ -1,4 +1,4 @@
-$Id: README.eicon,v 1.1.4.1 2001/11/20 14:19:33 kai Exp $
+$Id: README.eicon,v 1.10 2000/08/13 12:19:15 armin Exp $
 
 (c) 1999,2000 Armin Schindler (mac@melware.de)
 (c) 1999,2000 Cytronics & Melware (info@melware.de)
--- a/Documentation/isdn/README.hysdn
+++ b/Documentation/isdn/README.hysdn
@@ -1,4 +1,4 @@
-$Id: README.hysdn,v 1.1.4.1 2001/11/20 14:19:33 kai Exp $
+$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
--- a/Documentation/isdn/README.icn
+++ b/Documentation/isdn/README.icn
@@ -1,4 +1,4 @@
-$Id: README.icn,v 1.1.4.1 2001/11/20 14:19:33 kai Exp $
+$Id: README.icn,v 1.7 2000/08/06 09:22:51 armin Exp $
 
 You can get the ICN-ISDN-card from:
 
--- a/Documentation/isdn/README.pcbit
+++ b/Documentation/isdn/README.pcbit
@@ -37,4 +37,4 @@ mailing list (isdn4linux@listserv.isdn4l
 regards,
   Pedro.
 		
-<pedro_m@yahoo.com>
+<roque@di.fc.ul.pt>
--- /dev/null
+++ b/Documentation/isdn/abcext_kernel.help
@@ -0,0 +1,166 @@
+ 
+ISDN-ABC-DW Extension
+CONFIG_ISDN_WITH_ABC
+   These are many brand new Options and Features for the
+   ISDN SUBSYSTEM. Including Logical Device bindings,
+   Compression and other good stuff for Optimizing your
+   ISDN System.
+
+   To Use this Extensions you MUST HAVE THE NEWEST
+   ISDN4K-UTILS. You must have Version 3.1-Beta6 or
+   higher. Elsewhere you can not configure this Extensions.
+
+   WARNING ! THIS STUF IS NOT PRODUCTION RELEASE THE
+   FUNCTION ARE UNDER DEVELOPMENT. This ist BETA-CODE.
+   You can use it at you Own Risk.
+
+   For more Information on these Extensions take a look at
+   "linux/Documentation/isdn/dw-abc-extension-howto.txt or
+   Online at the Web "http://www.mediatronix.de/i4l/index.html"
+
+   Please Report Bugs to "mario@mediatronix.de" or
+   "delefw@isdn4linux.de"
+
+D-Channel-Callback with Channel in use check
+CONFIG_ISDN_WITH_ABC_CALLB
+   When a Interface is declared as an Callback Interface,
+   the Interface is checking that the other Side is not
+   Calling on the same time before the Interface is Dialing.
+
+   See "linux/Documentation/isdn/dw-abc-extension-howto.txt" 
+   for more Information
+
+   In most case answer with "Yes" when you have Callback devices,
+   otherwise leave it "No"
+
+Outgoing-EAZ-Support
+CONFIG_ISDN_WITH_ABC_OUTGOING_EAZ
+   Enables the Feature to Define an other EAZ or MSN for
+   Outgoing calls on an Interface.
+
+   See "linux/Documentation/isdn/dw-abc-extension-howto.txt" 
+   for more Information
+
+Least Cost Router Support
+CONFIG_ISDN_WITH_ABC_LCR_SUPPORT
+   This is the final Kernel Code for configuring an Least
+   Cost Router Softwarebased. The other Job is to do the
+   action in ISDNLOG. You need the ISDNLOG to use this 
+   function. Currently the ISDNLOG have not the Support for
+   this Option.
+   So in most situations let the Option off.
+
+TCP keepalive detect and response
+CONFIG_ISDN_WITH_ABC_IPV4_TCP_KEEPALIVE
+   This Option works only with the TCP/IP V4. It enables
+   the Function that ISDN Devices are Answering TCP_KEEPALIVE Pakets
+   localy. So that TCP KEEPALIVE Pakets not longer takes the Line
+   open.
+
+Drop frames Sourceadresse is not Interfaceadress
+CONFIG_ISDN_WITH_ABC_IPV4_DYNADDR
+   This Option works only with the TCP/IP V4. It will allow only
+   the Transmitt of Pakets where the Sourceadresse is the Interface
+   adress. It is usefull when you have Lines with Dynamic IP.
+
+   See "linux/Documentation/isdn/dw-abc-extension-howto.txt" 
+   for more Information
+
+Receive do not reset the Hanguptimer
+CONFIG_ISDN_WITH_ABC_RCV_NO_HUPTIMER
+   When you activate this option than the reiceive of pakets do
+   not reset the Hanguptimer. It is very usefull because if the
+   Paket vor your Network your Network generate an Response and
+   the Transmit is reseting the HUPTIMER. But when the Paket is
+   Rejected at your firewall your network generate no Response
+   and no Sendtraffic is generated. So in this case there is no 
+   need to Reset the Huptimer because you have only received Data.
+   With that option only Transmitted Data/Pakets will reset the
+   HUPTIMER.
+
+Support of (device-channel) and Binding Groups
+CONFIG_ISDN_WITH_ABC_ICALL_BIND
+   This Option enables the Feature to Bind logical ISDN Interfaces
+   to an prefered ISDN Card or ISDN Card plus Channel. So you have
+   the Chance to keep Channels exclusively for one (or more) 
+   Connection. Very usefull when you have more channels and Use 
+   Calling Line Identification, because you can organize that your
+   call is going out over the Line with the right EAZ for the CLI.
+
+Skip channel if used external (Dial Only)
+CONFIG_ISDN_WITH_ABC_CH_EXTINUSE
+   When you have more than One ISDN Card in your System and you
+   will Dialout with an Interface you can become the Situation
+   that an External Device such a Telephone or Fax is Using the
+   B-Channels. Normaly ISDN4Linux does not detect this Situation
+   and dial everytime of the "External Busy" line out. With this
+   Option Enabled the I4L will detect that he can not dialout on
+   This Card and dial over the next Card out.
+
+   See "linux/Documentation/isdn/dw-abc-extension-howto.txt" 
+   for more Information
+
+Interface autodisable if Config error
+CONFIG_ISDN_WITH_ABC_CONN_ERROR
+   This Option will detect an Device which generate Telephone
+   Cost but does not Function correctly because there are
+   Configerrors on one of the Site. In this Situation the
+   Interface will be marked as Unsuably for some time to do
+   not call every time this Site.
+
+   See "linux/Documentation/isdn/dw-abc-extension-howto.txt" 
+   for more Information
+
+UDP-Info-Support
+CONFIG_ISDN_WITH_ABC_UDP_CHECK
+   This is the Mainoption to Enable or Disable the UDP
+   Info Support. An Option to Controll ISDN-Interfaces
+   Remotely. For this very Complex thing take a look at
+
+   "linux/Documentation/isdn/dw-abc-extension-howto.txt" 
+   for more Information.
+
+UDP Hangup Support
+CONFIG_ISDN_WITH_ABC_UDP_CHECK_HANGUP
+
+   Sorry no more Information!
+
+   See "linux/Documentation/isdn/dw-abc-extension-howto.txt" 
+   for more Information
+   
+UDP Dial Support
+CONFIG_ISDN_WITH_ABC_UDP_CHECK_DIAL
+
+   Sorry no more Information!
+
+   See "linux/Documentation/isdn/dw-abc-extension-howto.txt" 
+   for more Information
+   
+Limit on the line frames to two
+CONFIG_ISDN_WITH_ABC_FRAME_LIMIT
+
+   This Option enables support for sending only 2 Pakets on
+   the Fly to the ISDN Driver. It is very usefull when you
+   will use the new RAW-IP Compression. Because of sending
+   Only 2 Pakets on the Fly makes the risk of overflowing
+   the ISDN Driver very smaller.
+
+   See "linux/Documentation/isdn/dw-abc-extension-howto.txt" 
+   for more Information
+
+Compression with RAWIP and X75I
+CONFIG_ISDN_WITH_ABC_RAWIPCOMPRESS
+
+   With this Option you have the ability to make Datacompression
+   on RAW-IP Lines. It is function on HDLC and X75I Connection,
+   but the Prefered L2-Protocol for Compression is X75I because
+   the HDLC Protocol have no Errorcorrection.
+
+   To Use this Option YOU MUST HAVE ENABLED THE OPTION:
+   Support synchronous PPP
+   and must load after loading the main isdndrivers the
+   Modul "isdn_bsdcomp".
+
+   See "linux/Documentation/isdn/dw-abc-extension-howto.txt" 
+   for more Information
+
--- a/drivers/isdn/Config.in
+++ b/drivers/isdn/Config.in
@@ -4,11 +4,9 @@
 
 # only included if CONFIG_ISDN != n
 
-define_bool CONFIG_ISDN_BOOL y
 if [ "$CONFIG_INET" != "n" ]; then
    bool '  Support synchronous PPP' CONFIG_ISDN_PPP
    if [ "$CONFIG_ISDN_PPP" != "n" ]; then
-      dep_bool     '    PPP filtering for ISDN' CONFIG_IPPP_FILTER $CONFIG_FILTER
       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
@@ -23,6 +21,30 @@ if [ "$CONFIG_X25" != "n" ]; then
 fi
 
 mainmenu_option next_comment
+comment 'ISDN abc-dw-extension'
+bool 'Enable isdn-abc-dw-extension' CONFIG_ISDN_WITH_ABC
+if [ "$CONFIG_ISDN_WITH_ABC" != "n" ]; then
+	bool '  Use D-Channel-Callback with Channel in use check' CONFIG_ISDN_WITH_ABC_CALLB
+	bool '  Enable Outgoing-EAZ-Support' CONFIG_ISDN_WITH_ABC_OUTGOING_EAZ
+	bool '  Enable LCR-Support (need isdnlog)' CONFIG_ISDN_WITH_ABC_LCR_SUPPORT
+	bool '  RX dont reset hanguptimeout' CONFIG_ISDN_WITH_ABC_RCV_NO_HUPTIMER
+	if [ "$CONFIG_EXPERIMENTAL" != "n" ]; then
+		bool '  Enable UDP-Info-Support' CONFIG_ISDN_WITH_ABC_UDP_CHECK
+		if [ "$CONFIG_ISDN_WITH_ABC_UDP_CHECK" != "n" ]; then
+			bool '    Enable Hangup-Support with UDP-INFO' CONFIG_ISDN_WITH_ABC_UDP_CHECK_HANGUP
+			bool '    Enable Dial-Support with UDP-INFO' CONFIG_ISDN_WITH_ABC_UDP_CHECK_DIAL
+		fi
+	fi
+
+	bool '  Skip channel if used external (dial only)' CONFIG_ISDN_WITH_ABC_CH_EXTINUSE
+	bool '  Support interface-auto-disable if config-error' CONFIG_ISDN_WITH_ABC_CONN_ERROR
+	if [ "$CONFIG_ISDN_PPP" != "n" ]; then
+		bool '  Enable Compression with rawip and x75i' CONFIG_ISDN_WITH_ABC_RAWIPCOMPRESS
+	fi
+fi
+endmenu
+
+mainmenu_option next_comment
 comment 'ISDN feature submodules'
    dep_tristate 'isdnloop support' CONFIG_ISDN_DRV_LOOP $CONFIG_ISDN
    dep_tristate 'Support isdn diversion services' CONFIG_ISDN_DIVERSION $CONFIG_ISDN
@@ -34,7 +56,6 @@ mainmenu_option next_comment
 comment 'Passive ISDN cards'
 dep_tristate 'HiSax SiemensChipSet driver support' CONFIG_ISDN_DRV_HISAX $CONFIG_ISDN
 if [ "$CONFIG_ISDN_DRV_HISAX" != "n" ]; then
-   define_bool CONFIG_ISDN_HISAX y
    comment '  D-channel protocol features'
    bool '  HiSax Support for EURO/DSS1' CONFIG_HISAX_EURO
    if [ "$CONFIG_HISAX_EURO" != "n" ]; then
@@ -45,31 +66,28 @@ if [ "$CONFIG_ISDN_DRV_HISAX" != "n" ]; 
    fi
    bool '  HiSax Support for german 1TR6' CONFIG_HISAX_1TR6
    bool '  HiSax Support for US NI1' CONFIG_HISAX_NI1
-   int  '  Maximum number of cards supported by HiSax' CONFIG_HISAX_MAX_CARDS 8
    comment '  HiSax supported cards'
-   if [ "$CONFIG_ISA" != "n" ]; then
-      bool '  Teles 16.0/8.0' CONFIG_HISAX_16_0
-      bool '  Teles 16.3 or PNP or PCMCIA' CONFIG_HISAX_16_3
-      bool '  AVM A1 (Fritz)' CONFIG_HISAX_AVM_A1
-      bool '  ITK ix1-micro Revision 2' CONFIG_HISAX_IX1MICROR2
-      bool '  ASUSCOM ISA cards' CONFIG_HISAX_ASUSCOM
-      bool '  TELEINT cards' CONFIG_HISAX_TELEINT
-      bool '  HFC-S based cards' CONFIG_HISAX_HFCS
-      bool '  USR Sportster internal TA' CONFIG_HISAX_SPORTSTER
-      bool '  MIC card' CONFIG_HISAX_MIC
-      bool '  Siemens I-Surf card' CONFIG_HISAX_ISURF
-      bool '  HST Saphir card' CONFIG_HISAX_HSTSAPHIR
-   fi
+   bool '  Teles 16.0/8.0' CONFIG_HISAX_16_0
+   bool '  Teles 16.3 or PNP or PCMCIA' CONFIG_HISAX_16_3
    bool '  Teles PCI' CONFIG_HISAX_TELESPCI 
    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
+   bool '  ASUSCOM ISA cards' CONFIG_HISAX_ASUSCOM
+   bool '  TELEINT cards' CONFIG_HISAX_TELEINT
+   bool '  HFC-S based cards' CONFIG_HISAX_HFCS
    bool '  Sedlbauer cards' CONFIG_HISAX_SEDLBAUER
+   bool '  USR Sportster internal TA' CONFIG_HISAX_SPORTSTER
+   bool '  MIC card' CONFIG_HISAX_MIC
    bool '  NETjet card' CONFIG_HISAX_NETJET
    bool '  NETspider U card' CONFIG_HISAX_NETJET_U
    bool '  Niccy PnP/PCI card' CONFIG_HISAX_NICCY
+   bool '  Siemens I-Surf card' CONFIG_HISAX_ISURF
+   bool '  HST Saphir card' CONFIG_HISAX_HSTSAPHIR
    bool '  Telekom A4T card' CONFIG_HISAX_BKM_A4T
    bool '  Scitel Quadro card' CONFIG_HISAX_SCT_QUADRO
    bool '  Gazel cards' CONFIG_HISAX_GAZEL
@@ -78,20 +96,27 @@ if [ "$CONFIG_ISDN_DRV_HISAX" != "n" ]; 
    bool '  HFC-S+, HFC-SP, HFC-PCMCIA cards' CONFIG_HISAX_HFC_SX
    if [ "$CONFIG_EXPERIMENTAL" != "n" ]; then
 #      bool '  TESTEMULATOR (EXPERIMENTAL)' CONFIG_HISAX_TESTEMU
-      bool '  Formula-n enter:now PCI card' CONFIG_HISAX_ENTERNOW_PCI
       if [ "$ARCH" = "sparc" -o "$ARCH" = "sparc64" ]; then
 	 bool '  Am7930' CONFIG_HISAX_AMD7930
       fi
    fi
    bool '  HiSax debugging' CONFIG_HISAX_DEBUG
 
-   dep_tristate 'Sedlbauer PCMCIA cards'                              CONFIG_HISAX_SEDLBAUER_CS  $CONFIG_ISDN_DRV_HISAX $CONFIG_PCMCIA
-   dep_tristate 'ELSA PCMCIA MicroLink cards'                         CONFIG_HISAX_ELSA_CS       $CONFIG_ISDN_DRV_HISAX $CONFIG_PCMCIA
-   dep_tristate 'AVM A1 PCMCIA cards'                                 CONFIG_HISAX_AVM_A1_CS     $CONFIG_ISDN_DRV_HISAX $CONFIG_PCMCIA $CONFIG_HISAX_AVM_A1_PCMCIA
-   dep_tristate 'ST5481 USB ISDN modem (EXPERIMENTAL)'                CONFIG_HISAX_ST5481        $CONFIG_ISDN_DRV_HISAX    $CONFIG_EXPERIMENTAL
-   dep_tristate 'AVM Fritz!Card PCI/PCIv2/PnP support (EXPERIMENTAL)' CONFIG_HISAX_FRITZ_PCIPNP  $CONFIG_ISDN_DRV_HISAX                $CONFIG_EXPERIMENTAL
-   dep_tristate 'Auerswald devices ISDN support'                      CONFIG_USB_AUERISDN        $CONFIG_ISDN_DRV_HISAX
+   dep_tristate 'Sedlbauer PCMCIA cards' CONFIG_HISAX_SEDLBAUER_CS $CONFIG_PCMCIA
+   dep_tristate 'ELSA PCMCIA MicroLink cards' CONFIG_HISAX_ELSA_CS $CONFIG_PCMCIA
+   dep_tristate 'Colognechip HFC-USB support' CONFIG_HISAX_HFC_USB_CS $CONFIG_HISAX $CONFIG_USB
+   dep_tristate 'ST5481 USB ISDN modem (EXPERIMENTAL)' CONFIG_HISAX_ST5481 $CONFIG_HISAX $CONFIG_USB $CONFIG_EXPERIMENTAL
+   dep_tristate 'Fritz!PCIv2 support (EXPERIMENTAL)' CONFIG_HISAX_FRITZ_PCIPNP $CONFIG_HISAX $CONFIG_EXPERIMENTAL
 
+   if [ "$CONFIG_HISAX_SEDLBAUER_CS" != "n" ]; then
+      define_bool CONFIG_HISAX_SEDLBAUER y
+   fi
+   if [ "$CONFIG_HISAX_ELSA_CS" != "n" ]; then
+      define_bool CONFIG_HISAX_ELSA y
+   fi
+   if [ "$CONFIG_HISAX_HFC_USB_CS" != "n" ]; then
+      define_bool CONFIG_HISAX_HFC_USB y
+   fi
 fi
 endmenu
 
--- a/drivers/isdn/Makefile
+++ b/drivers/isdn/Makefile
@@ -2,7 +2,7 @@
 
 # The target object and module list name.
 
-O_TARGET	:= vmlinux-obj.o
+O_TARGET	:= isdn.a
 
 # Objects that export symbols.
 
@@ -32,9 +32,9 @@ obj-$(CONFIG_ISDN_PPP_BSDCOMP)		+= isdn_
 
 # Object files in subdirectories
 
-mod-subdirs				:= avmb1 eicon hisax
+mod-subdirs				:= avmb1 eicon
 subdir-$(CONFIG_ISDN_DIVERSION)		+= divert
-subdir-$(CONFIG_ISDN_HISAX)		+= hisax
+subdir-$(CONFIG_ISDN_DRV_HISAX)		+= hisax
 subdir-$(CONFIG_ISDN_DRV_ICN)		+= icn
 subdir-$(CONFIG_ISDN_DRV_PCBIT)		+= pcbit
 subdir-$(CONFIG_ISDN_DRV_SC)		+= sc
--- a/drivers/isdn/act2000/act2000.h
+++ b/drivers/isdn/act2000/act2000.h
@@ -1,4 +1,4 @@
-/* $Id: act2000.h,v 1.1.4.1 2001/11/20 14:19:34 kai Exp $
+/* $Id$
  *
  * ISDN lowlevel-module for the IBM ISDN-S0 Active 2000.
  *
@@ -178,19 +178,19 @@ typedef struct act2000_card {
         char regname[35];                /* Name used for request_region     */
 } act2000_card;
 
-static inline void act2000_schedule_tx(act2000_card *card)
+extern __inline__ void act2000_schedule_tx(act2000_card *card)
 {
         queue_task(&card->snd_tq, &tq_immediate);
         mark_bh(IMMEDIATE_BH);
 }
 
-static inline void act2000_schedule_rx(act2000_card *card)
+extern __inline__ void act2000_schedule_rx(act2000_card *card)
 {
         queue_task(&card->rcv_tq, &tq_immediate);
         mark_bh(IMMEDIATE_BH);
 }
 
-static inline void act2000_schedule_poll(act2000_card *card)
+extern __inline__ void act2000_schedule_poll(act2000_card *card)
 {
         queue_task(&card->poll_tq, &tq_immediate);
         mark_bh(IMMEDIATE_BH);
--- a/drivers/isdn/act2000/act2000_isa.c
+++ b/drivers/isdn/act2000/act2000_isa.c
@@ -1,4 +1,4 @@
-/* $Id: act2000_isa.c,v 1.1.4.1 2001/11/20 14:19:34 kai Exp $
+/* $Id$
  *
  * ISDN lowlevel-module for the IBM ISDN-S0 Active 2000 (ISA-Version).
  *
@@ -178,8 +178,7 @@ act2000_isa_config_port(act2000_card * c
                 card->flags &= ~ACT2000_FLAGS_PVALID;
         }
         if (!check_region(portbase, ISA_REGION)) {
-                if (request_region(portbase, ACT2000_PORTLEN, card->regname) == NULL)
-			return -EIO;
+                request_region(portbase, ACT2000_PORTLEN, card->regname);
                 card->port = portbase;
                 card->flags |= ACT2000_FLAGS_PVALID;
                 return 0;
@@ -341,6 +340,9 @@ act2000_isa_send(act2000_card * card)
 		while (skb->len) {
 			if (act2000_isa_writeb(card, *(skb->data))) {
 				/* Fifo is full, but more data to send */
+#if 0
+				printk(KERN_DEBUG "act2000_isa_send: %d bytes\n", l);
+#endif
 				test_and_clear_bit(ACT2000_LOCK_TX, (void *) &card->ilock);
 				/* Schedule myself */
 				act2000_schedule_tx(card);
@@ -363,6 +365,9 @@ act2000_isa_send(act2000_card * card)
 		} else
 			dev_kfree_skb(skb);
 		card->sbuf = NULL;
+#if 0
+		printk(KERN_DEBUG "act2000_isa_send: %d bytes\n", l);
+#endif
 	}
 }
 
--- a/drivers/isdn/act2000/act2000_isa.h
+++ b/drivers/isdn/act2000/act2000_isa.h
@@ -1,4 +1,4 @@
-/* $Id: act2000_isa.h,v 1.1.4.1 2001/11/20 14:19:34 kai Exp $
+/* $Id$
  *
  * ISDN lowlevel-module for the IBM ISDN-S0 Active 2000 (ISA-Version).
  *
--- a/drivers/isdn/act2000/capi.c
+++ b/drivers/isdn/act2000/capi.c
@@ -1,4 +1,4 @@
-/* $Id: capi.c,v 1.1.4.1 2001/11/20 14:19:34 kai Exp $
+/* $Id$
  *
  * ISDN lowlevel-module for the IBM ISDN-S0 Active 2000.
  * CAPI encoder/decoder
@@ -76,6 +76,10 @@ static actcapi_msgdsc valid_msg[] = {
 	{{ 0x84, 0x03}, "DISCONNECT_B3_RESP"},
 	{{ 0x86, 0x03}, "DATA_B3_RESP"},
 	{{ 0xff, 0x03}, "MANUFACTURER_RESP"},
+#if 0
+/* CAPI 2.0 */
+	{{ 0x05, 0x80}, "LISTEN_REQ (CAPI 2.0)"},
+#endif
 #endif
 	{{ 0x00, 0x00}, NULL},
 };
--- a/drivers/isdn/act2000/capi.h
+++ b/drivers/isdn/act2000/capi.h
@@ -1,4 +1,4 @@
-/* $Id: capi.h,v 1.1.4.1 2001/11/20 14:19:34 kai Exp $
+/* $Id$
  *
  * ISDN lowlevel-module for the IBM ISDN-S0 Active 2000.
  *
@@ -294,6 +294,19 @@ typedef struct actcapi_msg {
 			__u16 plci;
 			__u16 info;
 		} select_b3_protocol_conf;
+#if 0
+		struct listen_req {
+			__u32 controller;
+			__u32 infomask;  
+			__u32 cipmask;
+			__u32 cipmask2;
+			__u16 dummy; /* 2 Length-bytes of 2 Structs MUST always be 0!!! */
+		} listen_req;
+		struct listen_conf {
+			__u32  controller;
+			__u16 info;
+		} listen_conf;
+#else
 		struct listen_req {
 			__u8  controller;
 			__u32 infomask __attribute__ ((packed));  
@@ -304,6 +317,7 @@ typedef struct actcapi_msg {
 			__u8  controller;
 			__u16 info __attribute__ ((packed));
 		} listen_conf;
+#endif
 		struct data_b3_req {
 			__u16 fakencci;
 			__u16 datalen;
@@ -330,7 +344,7 @@ typedef struct actcapi_msg {
 	} msg;
 } actcapi_msg;
 
-static inline unsigned short
+extern __inline__ unsigned short
 actcapi_nextsmsg(act2000_card *card)
 {
 	unsigned long flags;
--- a/drivers/isdn/act2000/module.c
+++ b/drivers/isdn/act2000/module.c
@@ -1,4 +1,4 @@
-/* $Id: module.c,v 1.1.4.1 2001/11/20 14:19:34 kai Exp $
+/* $Id$
  *
  * ISDN lowlevel-module for the IBM ISDN-S0 Active 2000.
  *
@@ -630,6 +630,10 @@ act2000_alloccard(int bus, int port, int
         card->interface.features =
 		ISDN_FEATURE_L2_X75I |
 		ISDN_FEATURE_L2_HDLC |
+#if 0
+/* Not yet! New Firmware is on the way ... */
+		ISDN_FEATURE_L2_TRANS |
+#endif
 		ISDN_FEATURE_L3_TRANS |
 		ISDN_FEATURE_P_UNKNOWN;
         card->interface.hl_hdrlen = 20;
@@ -843,6 +847,39 @@ static void __exit act2000_exit(void)
         }
         printk(KERN_INFO "%s unloaded\n", DRIVERNAME);
 }
+#if 0
+#ifndef MODULE
+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
+#endif
 
 module_init(act2000_init);
 module_exit(act2000_exit);
--- a/drivers/isdn/avmb1/avm_cs.c
+++ b/drivers/isdn/avmb1/avm_cs.c
@@ -1,4 +1,4 @@
-/* $Id: avm_cs.c,v 1.1.4.1 2001/11/20 14:19:34 kai Exp $
+/* $Id: avm_cs.c,v 1.6 2001/09/24 13:22:44 kai Exp $
  *
  * A PCMCIA client driver for AVM B1/M1/M2
  *
--- a/drivers/isdn/avmb1/avmcard.h
+++ b/drivers/isdn/avmb1/avmcard.h
@@ -1,4 +1,4 @@
-/* $Id: avmcard.h,v 1.1.4.1 2001/11/20 14:19:34 kai Exp $
+/* $Id: avmcard.h,v 1.12 2001/09/24 13:22:44 kai Exp $
  *
  * Copyright 1999 by Carsten Paeth <calle@calle.de>
  *
--- a/drivers/isdn/avmb1/b1.c
+++ b/drivers/isdn/avmb1/b1.c
@@ -1,4 +1,4 @@
-/* $Id: b1.c,v 1.1.4.1 2001/11/20 14:19:34 kai Exp $
+/* $Id: b1.c,v 1.26 2001/09/24 13:22:44 kai Exp $
  * 
  * Common module for AVM B1 cards.
  * 
@@ -20,6 +20,7 @@
 #include <linux/kernelcapi.h>
 #include <asm/io.h>
 #include <linux/init.h>
+#include <linux/isdn_compat.h>
 #include <asm/uaccess.h>
 #include <linux/netdevice.h>
 #include "capilli.h"
@@ -27,7 +28,7 @@
 #include "capicmd.h"
 #include "capiutil.h"
 
-static char *revision = "$Revision: 1.1.4.1 $";
+static char *revision = "$Revision: 1.26 $";
 
 /* ------------------------------------------------------------- */
 
--- a/drivers/isdn/avmb1/b1dma.c
+++ b/drivers/isdn/avmb1/b1dma.c
@@ -1,4 +1,4 @@
-/* $Id: b1dma.c,v 1.1.4.1 2001/11/20 14:19:34 kai Exp $
+/* $Id: b1dma.c,v 1.18 2001/09/24 13:22:44 kai Exp $
  * 
  * Common module for AVM B1 cards that support dma with AMCC
  * 
@@ -21,6 +21,7 @@
 #include <linux/kernelcapi.h>
 #include <asm/io.h>
 #include <linux/init.h>
+#include <linux/isdn_compat.h>
 #include <asm/uaccess.h>
 #include <linux/netdevice.h>
 #include "capilli.h"
@@ -28,7 +29,11 @@
 #include "capicmd.h"
 #include "capiutil.h"
 
-static char *revision = "$Revision: 1.1.4.1 $";
+#if BITS_PER_LONG != 32
+#error FIXME: driver requires 32-bit platform
+#endif
+
+static char *revision = "$Revision: 1.18 $";
 
 /* ------------------------------------------------------------- */
 
@@ -851,7 +856,7 @@ int b1dmactl_read_proc(char *page, char 
 	__u8 flag;
 	int len = 0;
 	char *s;
-	u_long txaddr, txlen, rxaddr, rxlen, csr;
+	__u32 txaddr, txlen, rxaddr, rxlen, csr;
 
 	len += sprintf(page+len, "%-16s %s\n", "name", card->name);
 	len += sprintf(page+len, "%-16s 0x%x\n", "io", card->port);
@@ -907,12 +912,12 @@ int b1dmactl_read_proc(char *page, char 
 	save_flags(flags);
 	cli();
 
-	txaddr = (u_long)phys_to_virt(b1dmainmeml(card->mbase+0x2c));
-	txaddr -= (u_long)card->dma->sendbuf;
+	txaddr = (__u32)phys_to_virt(b1dmainmeml(card->mbase+0x2c));
+	txaddr -= (__u32)card->dma->sendbuf;
 	txlen  = b1dmainmeml(card->mbase+0x30);
 
-	rxaddr = (u_long)phys_to_virt(b1dmainmeml(card->mbase+0x24));
-	rxaddr -= (u_long)card->dma->recvbuf;
+	rxaddr = (__u32)phys_to_virt(b1dmainmeml(card->mbase+0x24));
+	rxaddr -= (__u32)card->dma->recvbuf;
 	rxlen  = b1dmainmeml(card->mbase+0x28);
 
 	csr  = b1dmainmeml(card->mbase+AMCC_INTCSR);
--- a/drivers/isdn/avmb1/b1isa.c
+++ b/drivers/isdn/avmb1/b1isa.c
@@ -1,4 +1,4 @@
-/* $Id: b1isa.c,v 1.1.4.1 2001/11/20 14:19:34 kai Exp $
+/* $Id: b1isa.c,v 1.14 2001/09/24 13:22:44 kai Exp $
  * 
  * Module for AVM B1 ISA-card.
  * 
@@ -19,12 +19,13 @@
 #include <linux/capi.h>
 #include <linux/init.h>
 #include <asm/io.h>
+#include <linux/isdn_compat.h>
 #include "capicmd.h"
 #include "capiutil.h"
 #include "capilli.h"
 #include "avmcard.h"
 
-static char *revision = "$Revision: 1.1.4.1 $";
+static char *revision = "$Revision: 1.14 $";
 
 /* ------------------------------------------------------------- */
 
--- a/drivers/isdn/avmb1/b1pci.c
+++ b/drivers/isdn/avmb1/b1pci.c
@@ -1,4 +1,4 @@
-/* $Id: b1pci.c,v 1.1.4.1 2001/11/20 14:19:34 kai Exp $
+/* $Id: b1pci.c,v 1.40 2001/09/24 13:22:44 kai Exp $
  * 
  * Module for AVM B1 PCI-card.
  * 
@@ -21,21 +21,24 @@
 #include <linux/capi.h>
 #include <asm/io.h>
 #include <linux/init.h>
+#include <linux/isdn_compat.h>
 #include "capicmd.h"
 #include "capiutil.h"
 #include "capilli.h"
 #include "avmcard.h"
 
-static char *revision = "$Revision: 1.1.4.1 $";
+static char *revision = "$Revision: 1.40 $";
 
 /* ------------------------------------------------------------- */
 
+#ifndef COMPAT_HAS_2_2_PCI
 static struct pci_device_id b1pci_pci_tbl[] __initdata = {
 	{ PCI_VENDOR_ID_AVM, PCI_DEVICE_ID_AVM_B1, PCI_ANY_ID, PCI_ANY_ID },
 	{ }				/* Terminating entry */
 };
 
 MODULE_DEVICE_TABLE(pci, b1pci_pci_tbl);
+#endif
 MODULE_DESCRIPTION("CAPI4Linux: Driver for AVM B1 PCI card");
 MODULE_AUTHOR("Carsten Paeth");
 MODULE_LICENSE("GPL");
@@ -416,14 +419,14 @@ static int add_card(struct pci_dev *dev)
 	}
 	param.irq = dev->irq;
 
-	if (pci_resource_start(dev, 2)) { /* B1 PCI V4 */
+	if (pci_resource_start_io(dev, 2)) { /* B1 PCI V4 */
 #ifdef CONFIG_ISDN_DRV_AVMB1_B1PCIV4
 		driver = &b1pciv4_driver;
 
 		pci_set_master(dev);
 #endif
-		param.membase = pci_resource_start(dev, 0);
-		param.port = pci_resource_start(dev, 2);
+		param.membase = pci_resource_start_mem(dev, 0);
+		param.port = pci_resource_start_io(dev, 2);
 
 		printk(KERN_INFO
 		"%s: PCI BIOS reports AVM-B1 V4 at i/o %#x, irq %d, mem %#x\n",
@@ -440,7 +443,7 @@ static int add_card(struct pci_dev *dev)
 		}
 	} else {
 		param.membase = 0;
-		param.port = pci_resource_start(dev, 1);
+		param.port = pci_resource_start_io(dev, 1);
 
 		printk(KERN_INFO
 		"%s: PCI BIOS reports AVM-B1 at i/o %#x, irq %d\n",
--- a/drivers/isdn/avmb1/b1pcmcia.c
+++ b/drivers/isdn/avmb1/b1pcmcia.c
@@ -1,4 +1,4 @@
-/* $Id: b1pcmcia.c,v 1.1.4.1 2001/11/20 14:19:34 kai Exp $
+/* $Id: b1pcmcia.c,v 1.17 2001/09/24 13:22:44 kai Exp $
  * 
  * Module for AVM B1/M1/M2 PCMCIA-card.
  * 
@@ -25,7 +25,7 @@
 #include "capilli.h"
 #include "avmcard.h"
 
-static char *revision = "$Revision: 1.1.4.1 $";
+static char *revision = "$Revision: 1.17 $";
 
 /* ------------------------------------------------------------- */
 
--- a/drivers/isdn/avmb1/c4.c
+++ b/drivers/isdn/avmb1/c4.c
@@ -1,4 +1,4 @@
-/* $Id: c4.c,v 1.1.4.1 2001/11/20 14:19:34 kai Exp $
+/* $Id: c4.c,v 1.38 2001/09/24 13:22:44 kai Exp $
  * 
  * Module for AVM C4 & C2 card.
  * 
@@ -18,6 +18,7 @@
 #include <linux/interrupt.h>
 #include <linux/ioport.h>
 #include <linux/pci.h>
+#include <linux/isdn_compat.h>
 #include <linux/capi.h>
 #include <linux/kernelcapi.h>
 #include <linux/init.h>
@@ -30,7 +31,7 @@
 #include "capilli.h"
 #include "avmcard.h"
 
-static char *revision = "$Revision: 1.1.4.1 $";
+static char *revision = "$Revision: 1.38 $";
 
 #undef CONFIG_C4_DEBUG
 #undef CONFIG_C4_POLLDEBUG
@@ -39,6 +40,7 @@ static char *revision = "$Revision: 1.1.
 
 static int suppress_pollack;
 
+#ifndef COMPAT_HAS_2_2_PCI
 static struct pci_device_id c4_pci_tbl[] __initdata = {
 	{ PCI_VENDOR_ID_DEC,PCI_DEVICE_ID_DEC_21285, PCI_VENDOR_ID_AVM, PCI_DEVICE_ID_AVM_C4 },
 	{ PCI_VENDOR_ID_DEC,PCI_DEVICE_ID_DEC_21285, PCI_VENDOR_ID_AVM, PCI_DEVICE_ID_AVM_C2 },
@@ -46,6 +48,7 @@ static struct pci_device_id c4_pci_tbl[]
 };
 
 MODULE_DEVICE_TABLE(pci, c4_pci_tbl);
+#endif
 MODULE_DESCRIPTION("CAPI4Linux: Driver for AVM C2/C4 cards");
 MODULE_AUTHOR("Carsten Paeth");
 MODULE_LICENSE("GPL");
@@ -1332,9 +1335,9 @@ static int __init search_cards(struct ca
 		}
 		pci_set_master(dev);
 
-		param.port = pci_resource_start(dev, 1);
+		param.port = pci_resource_start_io(dev, 1);
 		param.irq = dev->irq;
-		param.membase = pci_resource_start(dev, 0);
+		param.membase = pci_resource_start_mem(dev, 0);
   
 		printk(KERN_INFO
 			"%s: PCI BIOS reports AVM-C%d at i/o %#x, irq %d, mem %#x\n",
--- a/drivers/isdn/avmb1/capi.c
+++ b/drivers/isdn/avmb1/capi.c
@@ -1,4 +1,4 @@
-/* $Id: capi.c,v 1.1.4.2 2001/12/09 18:45:13 kai Exp $
+/* $Id: capi.c,v 1.59 2001/11/07 22:35:48 kai Exp $
  *
  * CAPI 2.0 Interface for Linux
  *
@@ -23,6 +23,7 @@
 #include <linux/smp_lock.h>
 #include <linux/timer.h>
 #include <linux/wait.h>
+#include <linux/isdn_compat.h>
 #ifdef CONFIG_ISDN_CAPI_MIDDLEWARE
 #include <linux/tty.h>
 #ifdef CONFIG_PPP
@@ -30,6 +31,9 @@
 #include <linux/ppp_defs.h>
 #include <linux/if_ppp.h>
 #undef CAPI_PPP_ON_RAW_DEVICE
+#ifdef CAPI_PPP_ON_RAW_DEVICE
+#include <linux/ppp_channel.h>
+#endif /* CAPI_PPP_ON_RAW_DEVICE */
 #endif /* CONFIG_PPP */
 #endif /* CONFIG_ISDN_CAPI_MIDDLEWARE */
 #include <linux/skbuff.h>
@@ -38,14 +42,16 @@
 #include <linux/capi.h>
 #include <linux/kernelcapi.h>
 #include <linux/init.h>
+#ifdef HAVE_DEVFS_FS
 #include <linux/devfs_fs_kernel.h>
+#endif /* HAVE_DEVFS_FS */
 #include "capiutil.h"
 #include "capicmd.h"
 #if defined(CONFIG_ISDN_CAPI_CAPIFS) || defined(CONFIG_ISDN_CAPI_CAPIFS_MODULE)
 #include "capifs.h"
 #endif
 
-static char *revision = "$Revision: 1.1.4.2 $";
+static char *revision = "$Revision: 1.59 $";
 
 MODULE_DESCRIPTION("CAPI4Linux: Userspace /dev/capi20 interface");
 MODULE_AUTHOR("Carsten Paeth");
@@ -87,10 +93,10 @@ struct capiminor {
 	struct capincci  *nccip;
 	unsigned int      minor;
 
-	u16  		 applid;
-	u32		 ncci;
-	u16		 datahandle;
-	u16		 msgid;
+	__u16		 applid;
+	__u32		 ncci;
+	__u16		 datahandle;
+	__u16		 msgid;
 
 	struct file      *file;
 	struct tty_struct *tty;
@@ -112,16 +118,22 @@ struct capiminor {
 	/* transmit path */
 	struct datahandle_queue {
 		    struct datahandle_queue *next;
-		    u16                      datahandle;
+		    __u16                    datahandle;
 	} *ackqueue;
 	int nack;
 
+#ifdef CAPI_PPP_ON_RAW_DEVICE
+	/* interface to generic ppp layer */
+	struct ppp_channel	chan;
+	int			chan_connected;
+	int			chan_index;
+#endif
 };
 #endif /* CONFIG_ISDN_CAPI_MIDDLEWARE */
 
 struct capincci {
 	struct capincci *next;
-	u32		 ncci;
+	__u32		 ncci;
 	struct capidev	*cdev;
 #ifdef CONFIG_ISDN_CAPI_MIDDLEWARE
 	struct capiminor *minorp;
@@ -131,8 +143,8 @@ struct capincci {
 struct capidev {
 	struct capidev *next;
 	struct file    *file;
-	u16		applid;
-	u16		errcode;
+	__u16		applid;
+	__u16		errcode;
 	unsigned int    minor;
 	unsigned        userflags;
 
@@ -156,22 +168,28 @@ static struct capidev *capidev_openlist 
 static struct capiminor *minors = 0;
 #endif /* CONFIG_ISDN_CAPI_MIDDLEWARE */
 
+#ifdef COMPAT_HAS_kmem_cache
 static kmem_cache_t *capidev_cachep = 0;
 static kmem_cache_t *capincci_cachep = 0;
 #ifdef CONFIG_ISDN_CAPI_MIDDLEWARE
 static kmem_cache_t *capiminor_cachep = 0;
 static kmem_cache_t *capidh_cachep = 0;
 #endif /* CONFIG_ISDN_CAPI_MIDDLEWARE */
+#endif
 
 #ifdef CONFIG_ISDN_CAPI_MIDDLEWARE
 /* -------- datahandles --------------------------------------------- */
 
-static int capincci_add_ack(struct capiminor *mp, u16 datahandle)
+int capincci_add_ack(struct capiminor *mp, __u16 datahandle)
 {
 	struct datahandle_queue *n, **pp;
 
 	n = (struct datahandle_queue *)
+#ifdef COMPAT_HAS_kmem_cache
 	kmem_cache_alloc(capidh_cachep, GFP_ATOMIC);
+#else
+	kmalloc(sizeof(struct datahandle_queue), GFP_ATOMIC);
+#endif
 	if (!n) {
 	   printk(KERN_ERR "capi: alloc datahandle failed\n");
 	   return -1;
@@ -184,7 +202,7 @@ static int capincci_add_ack(struct capim
 	return 0;
 }
 
-static int capiminor_del_ack(struct capiminor *mp, u16 datahandle)
+int capiminor_del_ack(struct capiminor *mp, __u16 datahandle)
 {
 	struct datahandle_queue **pp, *p;
 
@@ -192,7 +210,11 @@ static int capiminor_del_ack(struct capi
  		if ((*pp)->datahandle == datahandle) {
 			p = *pp;
 			*pp = (*pp)->next;
+#ifdef COMPAT_HAS_kmem_cache
 			kmem_cache_free(capidh_cachep, p);
+#else
+		        kfree(p);
+#endif
 			mp->nack--;
 			return 0;
 		}
@@ -200,7 +222,7 @@ static int capiminor_del_ack(struct capi
 	return -1;
 }
 
-static void capiminor_del_all_ack(struct capiminor *mp)
+void capiminor_del_all_ack(struct capiminor *mp)
 {
 	struct datahandle_queue **pp, *p;
 
@@ -208,7 +230,11 @@ static void capiminor_del_all_ack(struct
 	while (*pp) {
 		p = *pp;
 		*pp = (*pp)->next;
+#ifdef COMPAT_HAS_kmem_cache
 		kmem_cache_free(capidh_cachep, p);
+#else
+		kfree(p);
+#endif
 		mp->nack--;
 	}
 }
@@ -216,13 +242,17 @@ static void capiminor_del_all_ack(struct
 
 /* -------- struct capiminor ---------------------------------------- */
 
-static struct capiminor *capiminor_alloc(u16 applid, u32 ncci)
+struct capiminor *capiminor_alloc(__u16 applid, __u32 ncci)
 {
 	struct capiminor *mp, **pp;
         unsigned int minor = 0;
 
 	MOD_INC_USE_COUNT;
+#ifdef COMPAT_HAS_kmem_cache
 	mp = (struct capiminor *)kmem_cache_alloc(capiminor_cachep, GFP_ATOMIC);
+#else
+	mp = (struct capiminor *)kmalloc(sizeof(struct capiminor), GFP_ATOMIC);
+#endif
 	if (!mp) {
 		MOD_DEC_USE_COUNT;
 		printk(KERN_ERR "capi: can't alloc capiminor\n");
@@ -257,7 +287,7 @@ static struct capiminor *capiminor_alloc
 	return mp;
 }
 
-static void capiminor_free(struct capiminor *mp)
+void capiminor_free(struct capiminor *mp)
 {
 	struct capiminor **pp;
 
@@ -271,7 +301,11 @@ static void capiminor_free(struct capimi
 			skb_queue_purge(&mp->inqueue);
 			skb_queue_purge(&mp->outqueue);
 			capiminor_del_all_ack(mp);
+#ifdef COMPAT_HAS_kmem_cache
 			kmem_cache_free(capiminor_cachep, mp);
+#else
+			kfree(mp);
+#endif
 			MOD_DEC_USE_COUNT;
 #ifdef _DEBUG_REFCOUNT
 			printk(KERN_DEBUG "capiminor_free %d\n", GET_USE_COUNT(THIS_MODULE));
@@ -283,7 +317,7 @@ static void capiminor_free(struct capimi
 	}
 }
 
-static struct capiminor *capiminor_find(unsigned int minor)
+struct capiminor *capiminor_find(unsigned int minor)
 {
 	struct capiminor *p;
 	for (p = minors; p && p->minor != minor; p = p->next)
@@ -294,7 +328,7 @@ static struct capiminor *capiminor_find(
 
 /* -------- struct capincci ----------------------------------------- */
 
-static struct capincci *capincci_alloc(struct capidev *cdev, u32 ncci)
+static struct capincci *capincci_alloc(struct capidev *cdev, __u32 ncci)
 {
 	struct capincci *np, **pp;
 #ifdef CONFIG_ISDN_CAPI_MIDDLEWARE
@@ -302,7 +336,11 @@ static struct capincci *capincci_alloc(s
 	kdev_t kdev;
 #endif /* CONFIG_ISDN_CAPI_MIDDLEWARE */
 
+#ifdef COMPAT_HAS_kmem_cache
 	np = (struct capincci *)kmem_cache_alloc(capincci_cachep, GFP_ATOMIC);
+#else
+	np = (struct capincci *)kmalloc(sizeof(struct capincci), GFP_ATOMIC);
+#endif
 	if (!np)
 		return 0;
 	memset(np, 0, sizeof(struct capincci));
@@ -331,7 +369,7 @@ static struct capincci *capincci_alloc(s
         return np;
 }
 
-static void capincci_free(struct capidev *cdev, u32 ncci)
+static void capincci_free(struct capidev *cdev, __u32 ncci)
 {
 	struct capincci *np, **pp;
 #ifdef CONFIG_ISDN_CAPI_MIDDLEWARE
@@ -367,7 +405,11 @@ static void capincci_free(struct capidev
 				}
 			}
 #endif /* CONFIG_ISDN_CAPI_MIDDLEWARE */
+#ifdef COMPAT_HAS_kmem_cache
 			kmem_cache_free(capincci_cachep, np);
+#else
+			kfree(np);
+#endif
 			if (*pp == 0) return;
 		} else {
 			pp = &(*pp)->next;
@@ -375,7 +417,7 @@ static void capincci_free(struct capidev
 	}
 }
 
-static struct capincci *capincci_find(struct capidev *cdev, u32 ncci)
+struct capincci *capincci_find(struct capidev *cdev, __u32 ncci)
 {
 	struct capincci *p;
 
@@ -393,7 +435,11 @@ static struct capidev *capidev_alloc(str
 	struct capidev *cdev;
 	struct capidev **pp;
 
+#ifdef COMPAT_HAS_kmem_cache
 	cdev = (struct capidev *)kmem_cache_alloc(capidev_cachep, GFP_KERNEL);
+#else
+	cdev = (struct capidev *)kmalloc(sizeof(struct capidev), GFP_KERNEL);
+#endif
 	if (!cdev)
 		return 0;
 	memset(cdev, 0, sizeof(struct capidev));
@@ -423,10 +469,14 @@ static void capidev_free(struct capidev 
 	if (*pp)
 		*pp = cdev->next;
 
+#ifdef COMPAT_HAS_kmem_cache
 	kmem_cache_free(capidev_cachep, cdev);
+#else
+	kfree(cdev);
+#endif
 }
 
-static struct capidev *capidev_find(u16 applid)
+static struct capidev *capidev_find(__u16 applid)
 {
 	struct capidev *p;
 	for (p=capidev_openlist; p; p = p->next) {
@@ -439,13 +489,13 @@ static struct capidev *capidev_find(u16 
 #ifdef CONFIG_ISDN_CAPI_MIDDLEWARE
 /* -------- handle data queue --------------------------------------- */
 
-static struct sk_buff *
+struct sk_buff *
 gen_data_b3_resp_for(struct capiminor *mp, struct sk_buff *skb)
 {
 	struct sk_buff *nskb;
 	nskb = alloc_skb(CAPI_DATA_B3_RESP_LEN, GFP_ATOMIC);
 	if (nskb) {
-		u16 datahandle = CAPIMSG_U16(skb->data,CAPIMSG_BASELEN+4+4+2);
+		__u16 datahandle = CAPIMSG_U16(skb->data,CAPIMSG_BASELEN+4+4+2);
 		unsigned char *s = skb_put(nskb, CAPI_DATA_B3_RESP_LEN);
 		capimsg_setu16(s, 0, CAPI_DATA_B3_RESP_LEN);
 		capimsg_setu16(s, 2, mp->applid);
@@ -458,11 +508,11 @@ gen_data_b3_resp_for(struct capiminor *m
 	return nskb;
 }
 
-static int handle_recv_skb(struct capiminor *mp, struct sk_buff *skb)
+int handle_recv_skb(struct capiminor *mp, struct sk_buff *skb)
 {
 	struct sk_buff *nskb;
 	unsigned int datalen;
-	u16 errcode, datahandle;
+	__u16 errcode, datahandle;
 
 	datalen = skb->len - CAPIMSG_LEN(skb->data);
 	if (mp->tty) {
@@ -504,6 +554,28 @@ static int handle_recv_skb(struct capimi
 		kfree_skb(skb);
 		return 0;
 
+#ifdef CAPI_PPP_ON_RAW_DEVICE
+	} else if (mp->chan_connected) {
+		if ((nskb = gen_data_b3_resp_for(mp, skb)) == 0) {
+			printk(KERN_ERR "capi: gen_data_b3_resp failed\n");
+			return -1;
+		}
+		datahandle = CAPIMSG_U16(skb->data,CAPIMSG_BASELEN+4);
+		errcode = (*capifuncs->capi_put_message)(mp->applid, nskb);
+		if (errcode != CAPI_NOERROR) {
+			printk(KERN_ERR "capi: send DATA_B3_RESP failed=%x\n",
+					errcode);
+			kfree_skb(nskb);
+			return -1;
+		}
+		(void)skb_pull(skb, CAPIMSG_LEN(skb->data));
+#ifdef _DEBUG_DATAFLOW
+		printk(KERN_DEBUG "capi: DATA_B3_RESP %u len=%d => ppp\n",
+					datahandle, skb->len);
+#endif
+		ppp_input(&mp->chan, skb);
+		return 0;
+#endif
 	} else if (mp->file) {
 		if (skb_queue_len(&mp->recvqueue) > CAPINC_MAX_RECVQUEUE) {
 #if defined(_DEBUG_DATAFLOW) || defined(_DEBUG_TTYFUNCS)
@@ -538,7 +610,7 @@ static int handle_recv_skb(struct capimi
 	return -1;
 }
 
-static void handle_minor_recv(struct capiminor *mp)
+void handle_minor_recv(struct capiminor *mp)
 {
 	struct sk_buff *skb;
 	while ((skb = skb_dequeue(&mp->inqueue)) != 0) {
@@ -552,13 +624,13 @@ static void handle_minor_recv(struct cap
 	}
 }
 
-static int handle_minor_send(struct capiminor *mp)
+int handle_minor_send(struct capiminor *mp)
 {
 	struct sk_buff *skb;
-	u16 len;
+	__u16 len;
 	int count = 0;
-	u16 errcode;
-	u16 datahandle;
+	__u16 errcode;
+	__u16 datahandle;
 
 	if (mp->tty && mp->ttyoutstop) {
 #if defined(_DEBUG_DATAFLOW) || defined(_DEBUG_TTYFUNCS)
@@ -569,7 +641,7 @@ static int handle_minor_send(struct capi
 
 	while ((skb = skb_dequeue(&mp->outqueue)) != 0) {
 		datahandle = mp->datahandle;
-		len = (u16)skb->len;
+		len = (__u16)skb->len;
 		skb_push(skb, CAPI_DATA_B3_REQ_LEN);
 		memset(skb->data, 0, CAPI_DATA_B3_REQ_LEN);
 		capimsg_setu16(skb->data, 0, CAPI_DATA_B3_REQ_LEN);
@@ -578,7 +650,7 @@ static int handle_minor_send(struct capi
 		capimsg_setu8 (skb->data, 5, CAPI_REQ);
 		capimsg_setu16(skb->data, 6, mp->msgid++);
 		capimsg_setu32(skb->data, 8, mp->ncci);	/* NCCI */
-		capimsg_setu32(skb->data, 12, (u32) skb->data); /* Data32 */
+		capimsg_setu32(skb->data, 12, (__u32) skb->data); /* Data32 */
 		capimsg_setu16(skb->data, 16, len);	/* Data length */
 		capimsg_setu16(skb->data, 18, datahandle);
 		capimsg_setu16(skb->data, 20, 0);	/* Flags */
@@ -620,16 +692,16 @@ static int handle_minor_send(struct capi
 #endif /* CONFIG_ISDN_CAPI_MIDDLEWARE */
 /* -------- function called by lower level -------------------------- */
 
-static void capi_signal(u16 applid, void *param)
+static void capi_signal(__u16 applid, void *param)
 {
 	struct capidev *cdev = (struct capidev *)param;
 #ifdef CONFIG_ISDN_CAPI_MIDDLEWARE
 	struct capiminor *mp;
-	u16 datahandle;
+	__u16 datahandle;
 #endif /* CONFIG_ISDN_CAPI_MIDDLEWARE */
 	struct capincci *np;
 	struct sk_buff *skb = 0;
-	u32 ncci;
+	__u32 ncci;
 
 	(void) (*capifuncs->capi_get_message) (applid, &skb);
 	if (!skb) {
@@ -683,6 +755,12 @@ static void capi_signal(u16 applid, void
 #endif
 		kfree_skb(skb);
 		(void)capiminor_del_ack(mp, datahandle);
+#ifdef CAPI_PPP_ON_RAW_DEVICE
+		if (mp->chan_connected) {
+			ppp_output_wakeup(&mp->chan);
+			return;
+		}
+#endif
 		if (mp->tty) {
 			if (mp->tty->ldisc.write_wakeup)
 				mp->tty->ldisc.write_wakeup(mp->tty);
@@ -758,7 +836,7 @@ capi_write(struct file *file, const char
 	struct capidev *cdev = (struct capidev *)file->private_data;
 	struct sk_buff *skb;
 	int retval;
-	u16 mlen;
+	__u16 mlen;
 
         if (ppos != &file->f_pos)
 		return -ESPIPE;
@@ -998,7 +1076,7 @@ capi_ioctl(struct inode *inode, struct f
 						sizeof(ncci));
 			if (retval)
 				return -EFAULT;
-			nccip = capincci_find(cdev, (u32) ncci);
+			nccip = capincci_find(cdev, (__u32) ncci);
 			if (!nccip)
 				return 0;
 #ifdef CONFIG_ISDN_CAPI_MIDDLEWARE
@@ -1023,7 +1101,7 @@ capi_ioctl(struct inode *inode, struct f
 						sizeof(ncci));
 			if (retval)
 				return -EFAULT;
-			nccip = capincci_find(cdev, (u32) ncci);
+			nccip = capincci_find(cdev, (__u32) ncci);
 			if (!nccip || (mp = nccip->minorp) == 0)
 				return -ESRCH;
 			return mp->minor;
@@ -1070,7 +1148,9 @@ capi_release(struct inode *inode, struct
 
 static struct file_operations capi_fops =
 {
+#ifdef COMPAT_HAS_FILEOP_OWNER
 	owner:		THIS_MODULE,
+#endif
 	llseek:		no_llseek,
 	read:		capi_read,
 	write:		capi_write,
@@ -1233,6 +1313,45 @@ capinc_raw_ioctl(struct inode *inode, st
 		return -EINVAL;
 
 	switch (cmd) {
+#ifdef CAPI_PPP_ON_RAW_DEVICE
+	case PPPIOCATTACH:
+		{
+			int retval, val;
+			if (get_user(val, (int *) arg))
+				break;
+			if (mp->chan_connected)
+				return -EALREADY;
+			mp->chan.private = mp;
+#if 1
+			return -EINVAL;
+#else
+			mp->chan.ops = &ppp_ops;
+#endif
+
+			retval = ppp_register_channel(&mp->chan, val);
+			if (retval)
+				return retval;
+			mp->chan_connected = 1;
+			mp->chan_index = val;
+		}
+		return 0;
+	case PPPIOCDETACH:
+		{
+			if (!mp->chan_connected)
+				return -ENXIO;
+			ppp_unregister_channel(&mp->chan);
+			mp->chan_connected = 0;
+		}
+		return 0;
+	case PPPIOCGUNIT:
+		{
+			if (!mp->chan_connected)
+				return -ENXIO;
+			if (put_user(mp->chan_index, (int *) arg))
+				return -EFAULT;
+		}
+		return 0;
+#endif
 	}
 	return -EINVAL;
 }
@@ -1260,7 +1379,9 @@ capinc_raw_release(struct inode *inode, 
 
 static struct file_operations capinc_raw_fops =
 {
+#ifdef COMPAT_HAS_FILEOP_OWNER
 	owner:		THIS_MODULE,
+#endif
 	llseek:		no_llseek,
 	read:		capinc_raw_read,
 	write:		capinc_raw_write,
@@ -1272,7 +1393,7 @@ static struct file_operations capinc_raw
 
 /* -------- tty_operations for capincci ----------------------------- */
 
-static int capinc_tty_open(struct tty_struct * tty, struct file * file)
+int capinc_tty_open(struct tty_struct * tty, struct file * file)
 {
 	struct capiminor *mp;
 
@@ -1300,7 +1421,7 @@ static int capinc_tty_open(struct tty_st
 	return 0;
 }
 
-static void capinc_tty_close(struct tty_struct * tty, struct file * file)
+void capinc_tty_close(struct tty_struct * tty, struct file * file)
 {
 	struct capiminor *mp;
 
@@ -1325,8 +1446,8 @@ static void capinc_tty_close(struct tty_
 #endif
 }
 
-static int capinc_tty_write(struct tty_struct * tty, int from_user,
-			    const unsigned char *buf, int count)
+int capinc_tty_write(struct tty_struct * tty, int from_user,
+		      const unsigned char *buf, int count)
 {
 	struct capiminor *mp = (struct capiminor *)tty->driver_data;
 	struct sk_buff *skb;
@@ -1377,7 +1498,7 @@ static int capinc_tty_write(struct tty_s
 	return count;
 }
 
-static void capinc_tty_put_char(struct tty_struct *tty, unsigned char ch)
+void capinc_tty_put_char(struct tty_struct *tty, unsigned char ch)
 {
 	struct capiminor *mp = (struct capiminor *)tty->driver_data;
 	struct sk_buff *skb;
@@ -1414,7 +1535,7 @@ static void capinc_tty_put_char(struct t
 	}
 }
 
-static void capinc_tty_flush_chars(struct tty_struct *tty)
+void capinc_tty_flush_chars(struct tty_struct *tty)
 {
 	struct capiminor *mp = (struct capiminor *)tty->driver_data;
 	struct sk_buff *skb;
@@ -1440,7 +1561,7 @@ static void capinc_tty_flush_chars(struc
 	(void)handle_minor_recv(mp);
 }
 
-static int capinc_tty_write_room(struct tty_struct *tty)
+int capinc_tty_write_room(struct tty_struct *tty)
 {
 	struct capiminor *mp = (struct capiminor *)tty->driver_data;
 	int room;
@@ -1458,7 +1579,7 @@ static int capinc_tty_write_room(struct 
 	return room;
 }
 
-static int capinc_tty_chars_in_buffer(struct tty_struct *tty)
+int capinc_tty_chars_in_buffer(struct tty_struct *tty)
 {
 	struct capiminor *mp = (struct capiminor *)tty->driver_data;
 	if (!mp || !mp->nccip) {
@@ -1476,7 +1597,7 @@ static int capinc_tty_chars_in_buffer(st
 	return mp->outbytes;
 }
 
-static int capinc_tty_ioctl(struct tty_struct *tty, struct file * file,
+int capinc_tty_ioctl(struct tty_struct *tty, struct file * file,
 		    unsigned int cmd, unsigned long arg)
 {
 	int error = 0;
@@ -1488,14 +1609,14 @@ static int capinc_tty_ioctl(struct tty_s
 	return error;
 }
 
-static void capinc_tty_set_termios(struct tty_struct *tty, struct termios * old)
+void capinc_tty_set_termios(struct tty_struct *tty, struct termios * old)
 {
 #ifdef _DEBUG_TTYFUNCS
 	printk(KERN_DEBUG "capinc_tty_set_termios\n");
 #endif
 }
 
-static void capinc_tty_throttle(struct tty_struct * tty)
+void capinc_tty_throttle(struct tty_struct * tty)
 {
 	struct capiminor *mp = (struct capiminor *)tty->driver_data;
 #ifdef _DEBUG_TTYFUNCS
@@ -1505,7 +1626,7 @@ static void capinc_tty_throttle(struct t
 		mp->ttyinstop = 1;
 }
 
-static void capinc_tty_unthrottle(struct tty_struct * tty)
+void capinc_tty_unthrottle(struct tty_struct * tty)
 {
 	struct capiminor *mp = (struct capiminor *)tty->driver_data;
 #ifdef _DEBUG_TTYFUNCS
@@ -1517,7 +1638,7 @@ static void capinc_tty_unthrottle(struct
 	}
 }
 
-static void capinc_tty_stop(struct tty_struct *tty)
+void capinc_tty_stop(struct tty_struct *tty)
 {
 	struct capiminor *mp = (struct capiminor *)tty->driver_data;
 #ifdef _DEBUG_TTYFUNCS
@@ -1528,7 +1649,7 @@ static void capinc_tty_stop(struct tty_s
 	}
 }
 
-static void capinc_tty_start(struct tty_struct *tty)
+void capinc_tty_start(struct tty_struct *tty)
 {
 	struct capiminor *mp = (struct capiminor *)tty->driver_data;
 #ifdef _DEBUG_TTYFUNCS
@@ -1540,43 +1661,49 @@ static void capinc_tty_start(struct tty_
 	}
 }
 
-static void capinc_tty_hangup(struct tty_struct *tty)
+void capinc_tty_hangup(struct tty_struct *tty)
 {
 #ifdef _DEBUG_TTYFUNCS
 	printk(KERN_DEBUG "capinc_tty_hangup\n");
 #endif
 }
 
-static void capinc_tty_break_ctl(struct tty_struct *tty, int state)
+void capinc_tty_break_ctl(struct tty_struct *tty, int state)
 {
 #ifdef _DEBUG_TTYFUNCS
 	printk(KERN_DEBUG "capinc_tty_break_ctl(%d)\n", state);
 #endif
 }
 
-static void capinc_tty_flush_buffer(struct tty_struct *tty)
+void capinc_tty_flush_buffer(struct tty_struct *tty)
 {
 #ifdef _DEBUG_TTYFUNCS
 	printk(KERN_DEBUG "capinc_tty_flush_buffer\n");
 #endif
 }
 
-static void capinc_tty_set_ldisc(struct tty_struct *tty)
+void capinc_tty_set_ldisc(struct tty_struct *tty)
 {
 #ifdef _DEBUG_TTYFUNCS
 	printk(KERN_DEBUG "capinc_tty_set_ldisc\n");
 #endif
 }
 
-static void capinc_tty_send_xchar(struct tty_struct *tty, char ch)
+void capinc_tty_send_xchar(struct tty_struct *tty, char ch)
 {
 #ifdef _DEBUG_TTYFUNCS
 	printk(KERN_DEBUG "capinc_tty_send_xchar(%d)\n", ch);
 #endif
 }
 
-static int capinc_tty_read_proc(char *page, char **start, off_t off,
-				int count, int *eof, void *data)
+int capinc_tty_read_proc(char *page, char **start, off_t off,
+			  int count, int *eof, void *data)
+{
+	return 0;
+}
+
+int capinc_write_proc(struct file *file, const char *buffer,
+			  unsigned long count, void *data)
 {
 	return 0;
 }
@@ -1588,7 +1715,7 @@ static struct tty_struct *capinc_tty_tab
 static struct termios *capinc_tty_termios[CAPINC_NR_PORTS];
 static struct termios *capinc_tty_termios_locked[CAPINC_NR_PORTS];
 
-static int capinc_tty_init(void)
+int capinc_tty_init(void)
 {
 	struct tty_driver *drv = &capinc_tty_driver;
 
@@ -1646,7 +1773,7 @@ static int capinc_tty_init(void)
 	return 0;
 }
 
-static void capinc_tty_exit(void)
+void capinc_tty_exit(void)
 {
 	struct tty_driver *drv = &capinc_tty_driver;
 	int retval;
@@ -1771,8 +1898,9 @@ static void __exit proc_exit(void)
 
 /* -------- init function and module interface ---------------------- */
 
+#ifdef COMPAT_HAS_kmem_cache
 
-static void alloc_exit(void)
+static void __exit alloc_exit(void)
 {
 	if (capidev_cachep) {
 		(void)kmem_cache_destroy(capidev_cachep);
@@ -1837,8 +1965,9 @@ static int __init alloc_init(void)
 #endif /* CONFIG_ISDN_CAPI_MIDDLEWARE */
 	return 0;
 }
+#endif
 
-static void lower_callback(unsigned int cmd, u32 contr, void *data)
+static void lower_callback(unsigned int cmd, __u32 contr, void *data)
 {
 	struct capi_ncciinfo *np;
 	struct capidev *cdev;
@@ -1900,15 +2029,19 @@ static int __init capi_init(void)
 		MOD_DEC_USE_COUNT;
 		return -EIO;
 	}
+#ifdef HAVE_DEVFS_FS
         devfs_register_series (NULL, "capi/r%u", CAPINC_NR_PORTS,
 			      DEVFS_FL_DEFAULT,
                               capi_rawmajor, 0,
                               S_IFCHR | S_IRUSR | S_IWUSR,
                               &capinc_raw_fops, NULL);
+#endif
 #endif /* CONFIG_ISDN_CAPI_MIDDLEWARE */
+#ifdef HAVE_DEVFS_FS
 	devfs_register (NULL, "isdn/capi20", DEVFS_FL_DEFAULT,
 			capi_major, 0, S_IFCHR | S_IRUSR | S_IWUSR,
 			&capi_fops, NULL);
+#endif
 	printk(KERN_NOTICE "capi20: started up with major %d\n", capi_major);
 
 	if ((capifuncs = attach_capi_interface(&cuser)) == 0) {
@@ -1918,9 +2051,11 @@ static int __init capi_init(void)
 #ifdef CONFIG_ISDN_CAPI_MIDDLEWARE
 		devfs_unregister_chrdev(capi_rawmajor, "capi/r%d");
 #endif /* CONFIG_ISDN_CAPI_MIDDLEWARE */
+#ifdef HAVE_DEVFS_FS
 		devfs_unregister(devfs_find_handle(NULL, "capi20",
 						   capi_major, 0,
 						   DEVFS_SPECIAL_CHR, 0));
+#endif
 		return -EIO;
 	}
 
@@ -1934,8 +2069,10 @@ static int __init capi_init(void)
 	}
 #endif /* CONFIG_ISDN_CAPI_MIDDLEWARE */
 
+#ifdef COMPAT_HAS_kmem_cache
 	if (alloc_init() < 0) {
 #ifdef CONFIG_ISDN_CAPI_MIDDLEWARE
+#ifdef HAVE_DEVFS_FS
 		unsigned int j;
 		devfs_unregister_chrdev(capi_rawmajor, "capi/r%d");
 		for (j = 0; j < CAPINC_NR_PORTS; j++) {
@@ -1943,16 +2080,20 @@ static int __init capi_init(void)
 			sprintf(devname, "capi/r%u", j);
 			devfs_unregister(devfs_find_handle(NULL, devname, capi_rawmajor, j, DEVFS_SPECIAL_CHR, 0));
 		}
+#endif
 		capinc_tty_exit();
 #endif /* CONFIG_ISDN_CAPI_MIDDLEWARE */
 		(void) detach_capi_interface(&cuser);
 		devfs_unregister_chrdev(capi_major, "capi20");
+#ifdef HAVE_DEVFS_FS
 		devfs_unregister(devfs_find_handle(NULL, "capi20",
 						   capi_major, 0,
 						   DEVFS_SPECIAL_CHR, 0));
+#endif
 		MOD_DEC_USE_COUNT;
 		return -ENOMEM;
 	}
+#endif /* COMPAT_HAS_kmem_cache */
 
 	(void)proc_init();
 
@@ -1975,23 +2116,31 @@ static int __init capi_init(void)
 static void __exit capi_exit(void)
 {
 #ifdef CONFIG_ISDN_CAPI_MIDDLEWARE
+#ifdef HAVE_DEVFS_FS
 	unsigned int j;
 #endif
+#endif
+#ifdef COMPAT_HAS_kmem_cache
 	alloc_exit();
+#endif
 	(void)proc_exit();
 
 	devfs_unregister_chrdev(capi_major, "capi20");
+#ifdef HAVE_DEVFS_FS
 	devfs_unregister(devfs_find_handle(NULL, "isdn/capi20", capi_major, 0, DEVFS_SPECIAL_CHR, 0));
+#endif
 
 #ifdef CONFIG_ISDN_CAPI_MIDDLEWARE
 	capinc_tty_exit();
 	devfs_unregister_chrdev(capi_rawmajor, "capi/r%d");
+#ifdef HAVE_DEVFS_FS
 	for (j = 0; j < CAPINC_NR_PORTS; j++) {
 		char devname[32];
 		sprintf(devname, "capi/r%u", j);
 		devfs_unregister(devfs_find_handle(NULL, devname, capi_rawmajor, j, DEVFS_SPECIAL_CHR, 0));
 	}
 #endif
+#endif
 	(void) detach_capi_interface(&cuser);
 	printk(KERN_NOTICE "capi: Rev %s: unloaded\n", rev);
 }
--- a/drivers/isdn/avmb1/capicmd.h
+++ b/drivers/isdn/avmb1/capicmd.h
@@ -1,4 +1,4 @@
-/* $Id: capicmd.h,v 1.1.4.1 2001/11/20 14:19:34 kai Exp $
+/* $Id: capicmd.h,v 1.4 2001/09/24 13:22:44 kai Exp $
  * 
  * CAPI 2.0 Interface for Linux
  * 
--- a/drivers/isdn/avmb1/capidev.h
+++ b/drivers/isdn/avmb1/capidev.h
@@ -1,4 +1,4 @@
-/* $Id: capidev.h,v 1.1.4.1 2001/11/20 14:19:34 kai Exp $
+/* $Id: capidev.h,v 1.8 2001/09/24 13:22:44 kai Exp $
  *
  * CAPI 2.0 Interface for Linux
  *
--- a/drivers/isdn/avmb1/capidrv.c
+++ b/drivers/isdn/avmb1/capidrv.c
@@ -1,4 +1,4 @@
-/* $Id: capidrv.c,v 1.1.4.1 2001/11/20 14:19:34 kai Exp $
+/* $Id: capidrv.c,v 1.45 2001/09/24 13:22:44 kai Exp $
  *
  * ISDN4Linux Driver, using capi20 interface (kernelcapi)
  *
@@ -35,7 +35,7 @@
 #include "capicmd.h"
 #include "capidrv.h"
 
-static char *revision = "$Revision: 1.1.4.1 $";
+static char *revision = "$Revision: 1.45 $";
 static int debugmode = 0;
 
 MODULE_DESCRIPTION("CAPI4Linux: Interface to ISDN4Linux");
@@ -105,7 +105,6 @@ struct capidrv_contr {
 				int oldstate;
 				/* */
 				__u16 datahandle;
-                                spinlock_t lock;
 				struct ncci_datahandle_queue {
 				    struct ncci_datahandle_queue *next;
 				    __u16                         datahandle;
@@ -423,7 +422,6 @@ static inline capidrv_ncci *new_ncci(cap
 	nccip->plcip = plcip;
 	nccip->chan = plcip->chan;
 	nccip->datahandle = 0;
-        nccip->lock = SPIN_LOCK_UNLOCKED;
 
 	nccip->next = plcip->ncci_list;
 	plcip->ncci_list = nccip;
@@ -480,7 +478,6 @@ static int capidrv_add_ack(struct capidr
 		           __u16 datahandle, int len)
 {
 	struct ncci_datahandle_queue *n, **pp;
-	unsigned long flags;
 
 	n = (struct ncci_datahandle_queue *)
 		kmalloc(sizeof(struct ncci_datahandle_queue), GFP_ATOMIC);
@@ -491,31 +488,25 @@ static int capidrv_add_ack(struct capidr
 	n->next = 0;
 	n->datahandle = datahandle;
 	n->len = len;
-	spin_lock_irqsave(&nccip->lock, flags);
 	for (pp = &nccip->ackqueue; *pp; pp = &(*pp)->next) ;
 	*pp = n;
-	spin_unlock_irqrestore(&nccip->lock, flags);
 	return 0;
 }
 
 static int capidrv_del_ack(struct capidrv_ncci *nccip, __u16 datahandle)
 {
 	struct ncci_datahandle_queue **pp, *p;
-	unsigned long flags;
 	int len;
 
-	spin_lock_irqsave(&nccip->lock, flags);
 	for (pp = &nccip->ackqueue; *pp; pp = &(*pp)->next) {
  		if ((*pp)->datahandle == datahandle) {
 			p = *pp;
 			len = p->len;
 			*pp = (*pp)->next;
-	                spin_unlock_irqrestore(&nccip->lock, flags);
 		        kfree(p);
 			return len;
 		}
 	}
-        spin_unlock_irqrestore(&nccip->lock, flags);
 	return -1;
 }
 
@@ -523,25 +514,13 @@ static int capidrv_del_ack(struct capidr
 
 static void send_message(capidrv_contr * card, _cmsg * cmsg)
 {
-	struct sk_buff	*skb;
-	size_t		len;
-	u16		err;
-
+	struct sk_buff *skb;
+	size_t len;
 	capi_cmsg2message(cmsg, cmsg->buf);
 	len = CAPIMSG_LEN(cmsg->buf);
 	skb = alloc_skb(len, GFP_ATOMIC);
-	if(!skb) {
-		printk(KERN_ERR "no skb len(%d) memory\n", len);
-		return;
-	}
 	memcpy(skb_put(skb, len), cmsg->buf, len);
-	err = (*capifuncs->capi_put_message) (global.appid, skb);
-	if (err) {
-		printk(KERN_WARNING "%s: capi_put_message error: %04x\n",
-			__FUNCTION__, err);
-		kfree_skb(skb);
-		return;
-	}
+	(*capifuncs->capi_put_message) (global.appid, skb);
 	global.nsentctlpkt++;
 }
 
@@ -1932,8 +1911,10 @@ static int if_sendbuf(int id, int channe
 		        (void)capidrv_del_ack(nccip, datahandle);
 			return 0;
 		}
+#if 1
 		printk(KERN_DEBUG "capidrv-%d: only %d bytes headroom, need %d\n",
 		       card->contrnr, skb_headroom(skb), msglen);
+#endif
 		memcpy(skb_push(nskb, msglen), sendcmsg.buf, msglen);
 		errcode = (*capifuncs->capi_put_message) (global.appid, nskb);
 		if (errcode == CAPI_NOERROR) {
@@ -2035,6 +2016,52 @@ static void enable_dchannel_trace(capidr
 	send_message(card, &cmdcmsg);
 }
 
+#if 0
+static void disable_dchannel_trace(capidrv_contr *card)
+{
+        __u8 manufacturer[CAPI_MANUFACTURER_LEN];
+        capi_version version;
+	__u16 contr = card->contrnr;
+	__u16 errcode;
+	__u16 avmversion[3];
+
+        errcode = (*capifuncs->capi_get_manufacturer)(contr, manufacturer);
+        if (errcode != CAPI_NOERROR) {
+	   printk(KERN_ERR "%s: can't get manufacturer (0x%x)\n",
+			card->name, errcode);
+	   return;
+	}
+	if (strstr(manufacturer, "AVM") == 0) {
+	   printk(KERN_ERR "%s: not from AVM, no d-channel trace possible (%s)\n",
+			card->name, manufacturer);
+	   return;
+	}
+        errcode = (*capifuncs->capi_get_version)(contr, &version);
+        if (errcode != CAPI_NOERROR) {
+	   printk(KERN_ERR "%s: can't get version (0x%x)\n",
+			card->name, errcode);
+	   return;
+	}
+	avmversion[0] = (version.majormanuversion >> 4) & 0x0f;
+	avmversion[1] = (version.majormanuversion << 4) & 0xf0;
+	avmversion[1] |= (version.minormanuversion >> 4) & 0x0f;
+	avmversion[2] |= version.minormanuversion & 0x0f;
+
+        if (avmversion[0] > 3 || (avmversion[0] == 3 && avmversion[1] > 5)) {
+		printk(KERN_INFO "%s: D2 trace disabled\n", card->name);
+	} else {
+		printk(KERN_INFO "%s: D3 trace disabled\n", card->name);
+	}
+	capi_fill_MANUFACTURER_REQ(&cmdcmsg, global.appid,
+				   card->msgid++,
+				   contr,
+				   0x214D5641,  /* ManuID */
+				   0,           /* Class */
+				   1,           /* Function */
+				   (_cstruct)"\004\000\000\000\000");
+	send_message(card, &cmdcmsg);
+}
+#endif
 
 static void send_listen(capidrv_contr *card)
 {
@@ -2200,10 +2227,10 @@ static int capidrv_delcontr(__u16 contr)
 			free_ncci(card, card->bchans[card->nbchan-1].nccip);
 		if (card->bchans[card->nbchan-1].plcip)
 			free_plci(card, card->bchans[card->nbchan-1].plcip);
+		if (card->plci_list)
+			printk(KERN_ERR "capidrv: bug in free_plci()\n");
 		card->nbchan--;
 	}
-	if (card->plci_list)
-		printk(KERN_ERR "capidrv: bug in free_plci()\n");
 	kfree(card->bchans);
 	card->bchans = 0;
 
--- a/drivers/isdn/avmb1/capidrv.h
+++ b/drivers/isdn/avmb1/capidrv.h
@@ -1,4 +1,4 @@
-/* $Id: capidrv.h,v 1.1.4.1 2001/11/20 14:19:34 kai Exp $
+/* $Id: capidrv.h,v 1.4 2001/09/24 13:22:44 kai Exp $
  *
  * ISDN4Linux Driver, using capi20 interface (kernelcapi)
  *
--- a/drivers/isdn/avmb1/capifs.c
+++ b/drivers/isdn/avmb1/capifs.c
@@ -1,4 +1,4 @@
-/* $Id: capifs.c,v 1.1.4.1 2001/11/20 14:19:34 kai Exp $
+/* $Id: capifs.c,v 1.22 2001/09/24 13:22:44 kai Exp $
  * 
  * Copyright 2000 by Carsten Paeth <calle@calle.de>
  *
@@ -25,6 +25,7 @@
 #include <linux/major.h>
 #include <linux/slab.h>
 #include <linux/ctype.h>
+#include <linux/isdn_compat.h>
 #include <asm/bitops.h>
 #include <asm/uaccess.h>
 
@@ -32,7 +33,7 @@ MODULE_DESCRIPTION("CAPI4Linux: /dev/cap
 MODULE_AUTHOR("Carsten Paeth");
 MODULE_LICENSE("GPL");
 
-static char *revision = "$Revision: 1.1.4.1 $";
+static char *revision = "$Revision: 1.22 $";
 
 struct capifs_ncci {
 	struct inode *inode;
@@ -69,14 +70,21 @@ static inline struct capifs_sb_info *SBI
 static int capifs_root_readdir(struct file *,void *,filldir_t);
 static struct dentry *capifs_root_lookup(struct inode *,struct dentry *);
 static int capifs_revalidate(struct dentry *, int);
+#ifdef COMPAT_VFS_2_4
 static struct inode *capifs_new_inode(struct super_block *sb);
+#endif
 
 static struct file_operations capifs_root_operations = {
+#ifdef COMPAT_VFS_2_4
 	read:		generic_read_dir,
+#endif
 	readdir:	capifs_root_readdir,
 };
 
 struct inode_operations capifs_root_inode_operations = {
+#ifndef COMPAT_VFS_2_4
+	default_file_ops: &capifs_root_operations, /* file operations */
+#endif
 	lookup: capifs_root_lookup,
 };
 
@@ -101,12 +109,20 @@ static int capifs_root_readdir(struct fi
 	switch(nr)
 	{
 	case 0:
+#ifdef COMPAT_VFS_2_4
 		if (filldir(dirent, ".", 1, nr, inode->i_ino, DT_DIR) < 0)
+#else
+		if (filldir(dirent, ".", 1, nr, inode->i_ino) < 0)
+#endif
 			return 0;
 		filp->f_pos = ++nr;
 		/* fall through */
 	case 1:
+#ifdef COMPAT_VFS_2_4
 		if (filldir(dirent, "..", 2, nr, inode->i_ino, DT_DIR) < 0)
+#else
+		if (filldir(dirent, "..", 2, nr, inode->i_ino) < 0)
+#endif
 			return 0;
 		filp->f_pos = ++nr;
 		/* fall through */
@@ -118,7 +134,11 @@ static int capifs_root_readdir(struct fi
 				char *p = numbuf;
 				if (np->type) *p++ = np->type;
 				sprintf(p, "%u", np->num);
+#ifdef COMPAT_VFS_2_4
 				if ( filldir(dirent, numbuf, strlen(numbuf), nr, nr, DT_UNKNOWN) < 0 )
+#else
+				if ( filldir(dirent, numbuf, strlen(numbuf), nr, nr) < 0 )
+#endif
 					return 0;
 			}
 			filp->f_pos = ++nr;
@@ -180,7 +200,7 @@ static struct dentry *capifs_root_lookup
 
 	dentry->d_inode = np->inode;
 	if ( dentry->d_inode )
-		atomic_inc(&dentry->d_inode->i_count);
+		i_count_inc(dentry->d_inode->i_count);
 	
 	d_add(dentry, dentry->d_inode);
 
@@ -199,9 +219,9 @@ static void capifs_put_super(struct supe
 
 	for ( i = 0 ; i < sbi->max_ncci ; i++ ) {
 		if ( (inode = sbi->nccis[i].inode) ) {
-			if (atomic_read(&inode->i_count) != 1 )
+			if (i_count_read(inode->i_count) != 1 )
 				printk("capifs_put_super: badness: entry %d count %d\n",
-				       i, (unsigned)atomic_read(&inode->i_count));
+				       i, (unsigned)i_count_read(inode->i_count));
 			inode->i_nlink--;
 			iput(inode);
 		}
@@ -213,11 +233,24 @@ static void capifs_put_super(struct supe
 
 	kfree(sbi->nccis);
 	kfree(sbi);
+#ifndef COMPAT_VFS_2_4
+	MOD_DEC_USE_COUNT;
+#endif
 }
 
+#ifdef COMPAT_VFS_2_4
 static int capifs_statfs(struct super_block *sb, struct statfs *buf);
+#else
+static int capifs_statfs(struct super_block *sb, struct statfs *buf, int bufsiz);
+static void capifs_write_inode(struct inode *inode) { };
+static void capifs_read_inode(struct inode *inode);
+#endif
 
 static struct super_operations capifs_sops = {
+#ifndef COMPAT_VFS_2_4
+	read_inode:	capifs_read_inode,
+	write_inode:	capifs_write_inode,
+#endif
 	put_super:	capifs_put_super,
 	statfs:		capifs_statfs,
 };
@@ -288,6 +321,10 @@ struct super_block *capifs_read_super(st
 	struct dentry * root;
 	struct capifs_sb_info *sbi;
 
+#ifndef COMPAT_VFS_2_4
+	MOD_INC_USE_COUNT;
+	lock_super(s);
+#endif
 	/* Super block already completed? */
 	if (s->s_root)
 		goto out;
@@ -322,6 +359,7 @@ struct super_block *capifs_read_super(st
 	/*
 	 * Get the root inode and dentry, but defer checking for errors.
 	 */
+#ifdef COMPAT_VFS_2_4
 	root_inode = capifs_new_inode(s);
 	if (root_inode) {
 		root_inode->i_ino = 1;
@@ -331,6 +369,10 @@ struct super_block *capifs_read_super(st
 		root_inode->i_nlink = 2;
 	} 
 	root = d_alloc_root(root_inode);
+#else
+	root_inode = iget(s, 1); /* inode 1 == root directory */
+	root = d_alloc_root(root_inode, NULL);
+#endif
 
 	/*
 	 * Check whether somebody else completed the super block.
@@ -370,11 +412,34 @@ struct super_block *capifs_read_super(st
 	mounts = s;
 
 out:	/* Success ... somebody else completed the super block for us. */ 
+#ifndef COMPAT_VFS_2_4
+	unlock_super(s);
+#endif
 	return s;
 fail:
+#ifndef COMPAT_VFS_2_4
+	unlock_super(s);
+	MOD_DEC_USE_COUNT;
+#endif
 	return NULL;
 }
 
+#ifndef COMPAT_VFS_2_4
+static int capifs_statfs(struct super_block *sb, struct statfs *buf, int bufsiz)
+{
+	struct statfs tmp;
+
+	tmp.f_type = CAPIFS_SUPER_MAGIC;
+	tmp.f_bsize = 1024;
+	tmp.f_blocks = 0;
+	tmp.f_bfree = 0;
+	tmp.f_bavail = 0;
+	tmp.f_files = 0;
+	tmp.f_ffree = 0;
+	tmp.f_namelen = NAME_MAX;
+	return copy_to_user(buf, &tmp, bufsiz) ? -EFAULT : 0;
+}
+#else
 static int capifs_statfs(struct super_block *sb, struct statfs *buf)
 {
 	buf->f_type = CAPIFS_SUPER_MAGIC;
@@ -387,7 +452,9 @@ static int capifs_statfs(struct super_bl
 	buf->f_namelen = NAME_MAX;
 	return 0;
 }
+#endif
 
+#ifdef COMPAT_VFS_2_4
 static struct inode *capifs_new_inode(struct super_block *sb)
 {
 	struct inode *inode = new_inode(sb);
@@ -399,8 +466,51 @@ static struct inode *capifs_new_inode(st
 	}
 	return inode;
 }
+#else
+static void capifs_read_inode(struct inode *inode)
+{
+	ino_t ino = inode->i_ino;
+	struct capifs_sb_info *sbi = SBI(inode->i_sb);
+
+	inode->i_mode = 0;
+	inode->i_nlink = 0;
+	inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME;
+	inode->i_blocks = 0;
+	inode->i_blksize = 1024;
+	inode->i_uid = inode->i_gid = 0;
+
+	if ( ino == 1 ) {
+		inode->i_mode = S_IFDIR | S_IRUGO | S_IXUGO | S_IWUSR;
+		inode->i_op = &capifs_root_inode_operations;
+		inode->i_nlink = 2;
+		return;
+	} 
 
+	ino -= 2;
+	if ( ino >= sbi->max_ncci )
+		return;		/* Bogus */
+	
+#ifdef COMPAT_VFS_2_4
+	init_special_inode(inode, S_IFCHR, 0);
+#else
+	inode->i_mode = S_IFCHR;
+	inode->i_op = &chrdev_inode_operations;
+#endif
+
+	return;
+}
+#endif
+
+#ifndef COMPAT_VFS_2_4
+static struct file_system_type capifs_fs_type = {
+	"capifs",
+	0,
+	capifs_read_super,
+	NULL
+};
+#else
 static DECLARE_FSTYPE(capifs_fs_type, "capifs", capifs_read_super, 0);
+#endif
 
 void capifs_new_ncci(char type, unsigned int num, kdev_t device)
 {
@@ -421,16 +531,26 @@ void capifs_new_ncci(char type, unsigned
 				break;
 			}
 		}
+#ifdef COMPAT_VFS_2_4
 		if ( ino >= sbi->max_ncci )
 			continue;
 
 		if ((np->inode = capifs_new_inode(sb)) != NULL) {
+#else
+		if ((np->inode = iget(sb, ino+2)) != NULL) {
+#endif
 			struct inode *inode = np->inode;
 			inode->i_uid = sbi->setuid ? sbi->uid : current->fsuid;
 			inode->i_gid = sbi->setgid ? sbi->gid : current->fsgid;
+#ifdef COMPAT_VFS_2_4
 			inode->i_nlink = 1;
 			inode->i_ino = ino + 2;
 			init_special_inode(inode, sbi->mode|S_IFCHR, np->kdev);
+#else
+			inode->i_mode = sbi->mode | S_IFCHR;
+			inode->i_rdev = np->kdev;
+			inode->i_nlink++;
+#endif
 		}
 	}
 }
--- a/drivers/isdn/avmb1/capifs.h
+++ b/drivers/isdn/avmb1/capifs.h
@@ -1,4 +1,4 @@
-/* $Id: capifs.h,v 1.1.4.1 2001/11/20 14:19:34 kai Exp $
+/* $Id: capifs.h,v 1.4 2001/09/24 13:22:44 kai Exp $
  * 
  * Copyright 2000 by Carsten Paeth <calle@calle.de>
  *
--- a/drivers/isdn/avmb1/capilli.h
+++ b/drivers/isdn/avmb1/capilli.h
@@ -1,4 +1,4 @@
-/* $Id: capilli.h,v 1.1.4.1 2001/11/20 14:19:34 kai Exp $
+/* $Id: capilli.h,v 1.5 2001/09/24 13:22:44 kai Exp $
  * 
  * Kernel CAPI 2.0 Driver Interface for Linux
  * 
--- a/drivers/isdn/avmb1/capiutil.c
+++ b/drivers/isdn/avmb1/capiutil.c
@@ -1,4 +1,4 @@
-/* $Id: capiutil.c,v 1.1.4.1 2001/11/20 14:19:34 kai Exp $
+/* $Id: capiutil.c,v 1.16 2001/09/24 13:22:44 kai Exp $
  *
  * CAPI 2.0 convert capi message to capi message struct
  *
@@ -19,6 +19,7 @@
 #include <linux/init.h>
 #include <asm/segment.h>
 #include <linux/config.h>
+#include <linux/isdn_compat.h>
 #include "capiutil.h"
 
 MODULE_DESCRIPTION("CAPI4Linux: CAPI message conversion support");
--- a/drivers/isdn/avmb1/capiutil.h
+++ b/drivers/isdn/avmb1/capiutil.h
@@ -1,4 +1,4 @@
-/* $Id: capiutil.h,v 1.1.4.1 2001/11/20 14:19:34 kai Exp $
+/* $Id: capiutil.h,v 1.7 2001/09/24 13:22:44 kai Exp $
  *
  * CAPI 2.0 defines & types
  *
--- a/drivers/isdn/avmb1/kcapi.c
+++ b/drivers/isdn/avmb1/kcapi.c
@@ -1,4 +1,4 @@
-/* $Id: kcapi.c,v 1.1.4.1 2001/11/20 14:19:34 kai Exp $
+/* $Id: kcapi.c,v 1.28 2001/09/24 13:22:44 kai Exp $
  * 
  * Kernel CAPI 2.0 Module
  * 
@@ -21,6 +21,7 @@
 #include <linux/proc_fs.h>
 #include <linux/skbuff.h>
 #include <linux/tqueue.h>
+#include <linux/isdn_compat.h>
 #include <linux/capi.h>
 #include <linux/kernelcapi.h>
 #include <linux/locks.h>
@@ -33,7 +34,7 @@
 #include <linux/b1lli.h>
 #endif
 
-static char *revision = "$Revision: 1.1.4.1 $";
+static char *revision = "$Revision: 1.28 $";
 
 /* ------------------------------------------------------------- */
 
@@ -64,7 +65,6 @@ struct capi_ncci {
 	__u32 ncci;
 	__u32 winsize;
 	int   nmsg;
-        spinlock_t lock;
 	struct msgidqueue *msgidqueue;
 	struct msgidqueue *msgidlast;
 	struct msgidqueue *msgidfree;
@@ -104,14 +104,14 @@ static char capi_manufakturer[64] = "AVM
 #define APPL(a)		   (&applications[(a)-1])
 #define	VALID_APPLID(a)	   ((a) && (a) <= CAPI_MAXAPPL && APPL(a)->applid == a)
 #define APPL_IS_FREE(a)    (APPL(a)->applid == 0)
-#define APPL_MARK_FREE(a)  do{ APPL(a)->applid=0; MOD_DEC_USE_COUNT; }while(0)
-#define APPL_MARK_USED(a)  do{ APPL(a)->applid=(a); MOD_INC_USE_COUNT; }while(0)
+#define APPL_MARK_FREE(a)  do{ APPL(a)->applid=0; MOD_DEC_USE_COUNT; }while(0);
+#define APPL_MARK_USED(a)  do{ APPL(a)->applid=(a); MOD_INC_USE_COUNT; }while(0);
 
 #define NCCI2CTRL(ncci)    (((ncci) >> 24) & 0x7f)
 
 #define VALID_CARD(c)	   ((c) > 0 && (c) <= CAPI_MAXCONTR)
 #define CARD(c)		   (&cards[(c)-1])
-#define CARDNR(cp)	   ((((cp)-cards)+1) & 0xff)
+#define CARDNR(cp)	   (((cp)-cards)+1)
 
 static struct capi_appl applications[CAPI_MAXAPPL];
 static struct capi_ctr cards[CAPI_MAXCONTR];
@@ -535,9 +535,13 @@ static int notify_push(unsigned int cmd,
 	 * of devices. Devices can only removed in
 	 * user process, not in bh.
 	 */
+#ifdef COMPAT_HAS_SCHEDULE_TASK
 	MOD_INC_USE_COUNT;
 	if (schedule_task(&tq_state_notify) == 0)
 		MOD_DEC_USE_COUNT;
+#else
+	queue_task(&tq_state_notify, &tq_scheduler);
+#endif
 	return 0;
 }
 
@@ -546,13 +550,7 @@ static int notify_push(unsigned int cmd,
 static void notify_up(__u32 contr)
 {
 	struct capi_interface_user *p;
-	__u16 appl;
 
-	for (appl = 1; appl <= CAPI_MAXAPPL; appl++) {
-		if (!VALID_APPLID(appl)) continue;
-		if (APPL(appl)->releasing) continue;
-		CARD(contr)->driver->register_appl(CARD(contr), appl, &APPL(appl)->rparam);
-	}
         printk(KERN_NOTICE "kcapi: notify up contr %d\n", contr);
 	spin_lock(&capi_users_lock);
 	for (p = capi_users; p; p = p->next) {
@@ -639,7 +637,9 @@ static void notify_handler(void *dummy)
 		kfree(np);
 		MOD_DEC_USE_COUNT;
 	}
+#ifdef COMPAT_HAS_SCHEDULE_TASK
 	MOD_DEC_USE_COUNT;
+#endif
 }
 	
 /* -------- NCCI Handling ------------------------------------- */
@@ -647,7 +647,6 @@ static void notify_handler(void *dummy)
 static inline void mq_init(struct capi_ncci * np)
 {
 	int i;
-        np->lock = SPIN_LOCK_UNLOCKED;
 	np->msgidqueue = 0;
 	np->msgidlast = 0;
 	np->nmsg = 0;
@@ -662,11 +661,8 @@ static inline void mq_init(struct capi_n
 static inline int mq_enqueue(struct capi_ncci * np, __u16 msgid)
 {
 	struct msgidqueue *mq;
-	spin_lock_bh(&np->lock);
-	if ((mq = np->msgidfree) == 0) {
-	        spin_unlock_bh(&np->lock);
+	if ((mq = np->msgidfree) == 0)
 		return 0;
-	}
 	np->msgidfree = mq->next;
 	mq->msgid = msgid;
 	mq->next = 0;
@@ -676,14 +672,12 @@ static inline int mq_enqueue(struct capi
 	if (!np->msgidqueue)
 		np->msgidqueue = mq;
 	np->nmsg++;
-	spin_unlock_bh(&np->lock);
 	return 1;
 }
 
 static inline int mq_dequeue(struct capi_ncci * np, __u16 msgid)
 {
 	struct msgidqueue **pp;
-	spin_lock_bh(&np->lock);
 	for (pp = &np->msgidqueue; *pp; pp = &(*pp)->next) {
 		if ((*pp)->msgid == msgid) {
 			struct msgidqueue *mq = *pp;
@@ -693,11 +687,9 @@ static inline int mq_dequeue(struct capi
 			mq->next = np->msgidfree;
 			np->msgidfree = mq;
 			np->nmsg--;
-	                spin_unlock_bh(&np->lock);
 			return 1;
 		}
 	}
-	spin_unlock_bh(&np->lock);
 	return 0;
 }
 
@@ -720,16 +712,12 @@ static void controllercb_appl_released(s
 			nextpp = &(*pp)->next;
 		}
 	}
-	if (APPL(appl)->releasing) { /* only release if the application was marked for release */
-		printk(KERN_DEBUG "kcapi: appl %d releasing(%d)\n", appl, APPL(appl)->releasing);
-		APPL(appl)->releasing--;
-		if (APPL(appl)->releasing <= 0) {
-			APPL(appl)->signal = 0;
-			APPL_MARK_FREE(appl);
-			printk(KERN_INFO "kcapi: appl %d down\n", appl);
-		}
-	} else
-		printk(KERN_WARNING "kcapi: appl %d card%d released without request\n", appl, card->cnr);
+	APPL(appl)->releasing--;
+	if (APPL(appl)->releasing <= 0) {
+		APPL(appl)->signal = 0;
+		APPL_MARK_FREE(appl);
+		printk(KERN_INFO "kcapi: appl %d down\n", appl);
+	}
 }
 /*
  * ncci management
@@ -882,7 +870,16 @@ error:
 
 static void controllercb_ready(struct capi_ctr * card)
 {
+	__u16 appl;
+
 	card->cardstate = CARD_RUNNING;
+
+	for (appl = 1; appl <= CAPI_MAXAPPL; appl++) {
+		if (!VALID_APPLID(appl)) continue;
+		if (APPL(appl)->releasing) continue;
+		card->driver->register_appl(card, appl, &APPL(appl)->rparam);
+	}
+
         printk(KERN_NOTICE "kcapi: card %d \"%s\" ready.\n",
 		CARDNR(card), card->name);
 
--- a/drivers/isdn/avmb1/t1isa.c
+++ b/drivers/isdn/avmb1/t1isa.c
@@ -1,4 +1,4 @@
-/* $Id: t1isa.c,v 1.1.4.1 2001/11/20 14:19:34 kai Exp $
+/* $Id: t1isa.c,v 1.22 2001/09/24 13:22:44 kai Exp $
  * 
  * Module for AVM T1 HEMA-card.
  * 
@@ -19,13 +19,14 @@
 #include <linux/capi.h>
 #include <linux/kernelcapi.h>
 #include <linux/init.h>
+#include <linux/isdn_compat.h>
 #include <asm/io.h>
 #include "capicmd.h"
 #include "capiutil.h"
 #include "capilli.h"
 #include "avmcard.h"
 
-static char *revision = "$Revision: 1.1.4.1 $";
+static char *revision = "$Revision: 1.22 $";
 
 /* ------------------------------------------------------------- */
 
--- a/drivers/isdn/avmb1/t1pci.c
+++ b/drivers/isdn/avmb1/t1pci.c
@@ -1,4 +1,4 @@
-/* $Id: t1pci.c,v 1.1.4.1 2001/11/20 14:19:34 kai Exp $
+/* $Id: t1pci.c,v 1.25 2001/09/24 13:22:44 kai Exp $
  * 
  * Module for AVM T1 PCI-card.
  * 
@@ -18,6 +18,7 @@
 #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>
@@ -26,19 +27,21 @@
 #include "capilli.h"
 #include "avmcard.h"
 
-static char *revision = "$Revision: 1.1.4.1 $";
+static char *revision = "$Revision: 1.25 $";
 
 #undef CONFIG_T1PCI_DEBUG
 #undef CONFIG_T1PCI_POLLDEBUG
 
 /* ------------------------------------------------------------- */
 
+#ifndef COMPAT_HAS_2_2_PCI
 static struct pci_device_id t1pci_pci_tbl[] __initdata = {
 	{ PCI_VENDOR_ID_AVM, PCI_DEVICE_ID_AVM_T1, PCI_ANY_ID, PCI_ANY_ID },
 	{ }				/* Terminating entry */
 };
 
 MODULE_DEVICE_TABLE(pci, t1pci_pci_tbl);
+#endif
 MODULE_DESCRIPTION("CAPI4Linux: Driver for AVM T1 PCI card");
 MODULE_AUTHOR("Carsten Paeth");
 MODULE_LICENSE("GPL");
@@ -264,9 +267,9 @@ static int __init t1pci_init(void)
 		}
 		pci_set_master(dev);
 
-		param.port = pci_resource_start(dev, 1);
+		param.port = pci_resource_start_io(dev, 1);
  		param.irq = dev->irq;
-		param.membase = pci_resource_start(dev, 0);
+		param.membase = pci_resource_start_mem(dev, 0);
 
 		printk(KERN_INFO
 			"%s: PCI BIOS reports AVM-T1-PCI at i/o %#x, irq %d, mem %#x\n",
--- a/drivers/isdn/divert/divert_procfs.c
+++ b/drivers/isdn/divert/divert_procfs.c
@@ -1,4 +1,4 @@
-/* $Id: divert_procfs.c,v 1.1.4.1 2001/11/20 14:19:35 kai Exp $
+/* $Id$
  *
  * Filesystem handling for the diversion supplementary services.
  *
@@ -14,13 +14,16 @@
 #include <linux/module.h>
 #include <linux/version.h>
 #include <linux/poll.h>
+#ifndef COMPAT_USE_MODCOUNT_LOCK
 #include <linux/smp_lock.h>
+#endif
 #ifdef CONFIG_PROC_FS
 #include <linux/proc_fs.h>
 #else
 #include <linux/fs.h>
 #endif
 #include <linux/isdnif.h>
+#include <linux/isdn_compat.h>
 #include "isdn_divert.h"
 
 /*********************************/
@@ -80,7 +83,6 @@ static ssize_t
 isdn_divert_read(struct file *file, char *buf, size_t count, loff_t * off)
 {
 	struct divert_info *inf;
-	loff_t pos = *off;
 	int len;
 
 	if (!*((struct divert_info **) file->private_data)) {
@@ -92,11 +94,11 @@ isdn_divert_read(struct file *file, char
 		return (0);
 
 	inf->usage_cnt--;	/* new usage count */
-	file->private_data = &inf->next;	/* next structure */
+	(struct divert_info **) file->private_data = &inf->next;	/* next structure */
 	if ((len = strlen(inf->info_start)) <= count) {
 		if (copy_to_user(buf, inf->info_start, len))
 			return -EFAULT;
-		*off = pos + len;
+		file->f_pos += len;
 		return (len);
 	}
 	return (0);
@@ -136,17 +138,23 @@ isdn_divert_open(struct inode *ino, stru
 {
 	unsigned long flags;
 
+#ifdef COMPAT_USE_MODCOUNT_LOCK
+	MOD_INC_USE_COUNT;
+#else
 	lock_kernel();
+#endif
 	save_flags(flags);
 	cli();
 	if_used++;
 	if (divert_info_head)
-		filep->private_data = &(divert_info_tail->next);
+		(struct divert_info **) filep->private_data = &(divert_info_tail->next);
 	else
-		filep->private_data = &divert_info_head;
+		(struct divert_info **) filep->private_data = &divert_info_head;
 	restore_flags(flags);
 	/*  start_divert(); */
+#ifndef COMPAT_USE_MODCOUNT_LOCK
 	unlock_kernel();
+#endif
 	return (0);
 }				/* isdn_divert_open */
 
@@ -159,7 +167,9 @@ isdn_divert_close(struct inode *ino, str
 	struct divert_info *inf;
 	unsigned long flags;
 
+#ifndef COMPAT_USE_MODCOUNT_LOCK
 	lock_kernel();
+#endif
 	save_flags(flags);
 	cli();
 	if_used--;
@@ -175,7 +185,11 @@ isdn_divert_close(struct inode *ino, str
 			divert_info_head = divert_info_head->next;
 			kfree(inf);
 		}
+#ifdef COMPAT_USE_MODCOUNT_LOCK
+	MOD_DEC_USE_COUNT;
+#else
 	unlock_kernel();
+#endif
 	return (0);
 }				/* isdn_divert_close */
 
@@ -276,6 +290,9 @@ static struct file_operations isdn_fops 
 	open:           isdn_divert_open,
 	release:        isdn_divert_close,                                      
 };
+#ifdef COMPAT_NO_SOFTNET
+struct inode_operations divert_file_inode_operations;
+#endif
 
 /****************************/
 /* isdn subdir in /proc/net */
@@ -302,8 +319,16 @@ divert_dev_init(void)
 		remove_proc_entry("isdn", proc_net);
 		return (-1);
 	}
+#ifdef COMPAT_NO_SOFTNET
+	memset(&divert_file_inode_operations, 0, sizeof(struct inode_operations));
+	divert_file_inode_operations.default_file_ops = &isdn_fops;
+	isdn_divert_entry->ops = &divert_file_inode_operations;
+#else
 	isdn_divert_entry->proc_fops = &isdn_fops; 
+#ifdef COMPAT_HAS_FILEOP_OWNER
 	isdn_divert_entry->owner = THIS_MODULE; 
+#endif
+#endif  /* COMPAT_NO_SOFTNET */
 #endif	/* CONFIG_PROC_FS */
 
 	return (0);
--- a/drivers/isdn/divert/isdn_divert.c
+++ b/drivers/isdn/divert/isdn_divert.c
@@ -1,4 +1,4 @@
-/* $Id: isdn_divert.c,v 1.1.4.1 2001/11/20 14:19:35 kai Exp $
+/* $Id$
  *
  * DSS1 main diversion supplementary handling for i4l.
  *
@@ -84,6 +84,9 @@ static void deflect_timer_expire(ulong a
        restore_flags(flags); 
        break;
 
+     case NETWORK_DIAL:
+       divert_if.dial_net_name(cs->deflect_dest);  
+
      case DEFLECT_AUTODEL:
      default:
        save_flags(flags);
@@ -452,6 +455,7 @@ int isdn_divert_icall(isdn_ctrl *ic)
          case DEFLECT_PROCEED:
          case DEFLECT_REPORT:
          case DEFLECT_REJECT:
+         case NETWORK_DIAL:
            if (dv->rule.action == DEFLECT_PROCEED)
 	    if ((!if_used) || ((!extern_wait_max) && (!dv->rule.waittime))) 
               return(0); /* no external deflection needed */  
@@ -495,6 +499,11 @@ int isdn_divert_icall(isdn_ctrl *ic)
            else
              { cs->deflect_dest[0] = '\0';
 	       retval = 4; /* only proceed */
+	       if (cs->akt_state == NETWORK_DIAL) {
+		 strcpy(cs->deflect_dest,dv->rule.to_nr);
+		 cs->timer.expires = jiffies + 10;
+		 retval = 0;
+	       }
              }  
            sprintf(cs->info,"%d 0x%lx %s %s %s %s 0x%x 0x%x %d %d %s\n",
                    cs->akt_state,
@@ -739,6 +748,18 @@ int prot_stat_callback(isdn_ctrl *ic)
                       } 
 
 
+#if 0
+  sprintf(st, "0x%lx 0x%lx",ic->arg, ic->parm.dss1_io.ll_id);
+  p = st + strlen(st);
+  p1 = ic->parm.dss1_io.data;
+  i = ic->parm.dss1_io.datalen;
+  while ((i > 0) && (p - st < 530))
+   { p += sprintf(p," %02x",(*p1++) & 0xFF);
+     i--;
+   }
+  sprintf(p, "\n");
+  put_info_buffer(st);
+#endif
                    break;
  
 		   default:
--- a/drivers/isdn/divert/isdn_divert.h
+++ b/drivers/isdn/divert/isdn_divert.h
@@ -1,4 +1,4 @@
-/* $Id: isdn_divert.h,v 1.1.4.1 2001/11/20 14:19:35 kai Exp $
+/* $Id$
  *
  * Header for the diversion supplementary ioctl interface.
  *
@@ -36,9 +36,10 @@
 #define DEFLECT_PROCEED   2  /* deflect when externally triggered */
 #define DEFLECT_ALERT     3  /* alert and deflect after delay */ 
 #define DEFLECT_REJECT    4  /* reject immediately */
-#define DIVERT_ACTIVATE   5  /* diversion activate */
-#define DIVERT_DEACTIVATE 6  /* diversion deactivate */
-#define DIVERT_REPORT     7  /* interrogation result */ 
+#define NETWORK_DIAL      5  /* dial a network interface */
+#define DIVERT_ACTIVATE   16 /* diversion activate */
+#define DIVERT_DEACTIVATE 17 /* diversion deactivate */
+#define DIVERT_REPORT     18 /* interrogation result */ 
 #define DEFLECT_AUTODEL 255  /* only for internal use */ 
 
 #define DEFLECT_ALL_IDS   0xFFFFFFFF /* all drivers selected */
@@ -60,6 +61,7 @@ typedef struct
                        2 = report call, send proceed, wait max waittime secs
                        3 = report call, alert and deflect after waittime 
                        4 = report call, reject immediately  
+                       5 = dial net interface specified in to_nr  
                        actions 1-2 only take place if interface is opened 
 		    */
    u_char waittime; /* maximum wait time for proceeding */ 
--- a/drivers/isdn/eicon/Divas_mod.c
+++ b/drivers/isdn/eicon/Divas_mod.c
@@ -20,6 +20,7 @@
 #include "adapter.h"
 #include "uxio.h"
 
+#include <linux/isdn_compat.h>
 
 MODULE_DESCRIPTION("ISDN4Linux: Driver for Eicon Diva Server cards");
 MODULE_AUTHOR("Armin Schindler");
--- a/drivers/isdn/eicon/common.c
+++ b/drivers/isdn/eicon/common.c
@@ -808,9 +808,7 @@ void	DivasDoDpc(void *pData)
 	
 	while(i--)
 	{
-            if (card->state == DIA_RUNNING)
-		DivaDoCardDpc(card);
-            card++;
+		DivaDoCardDpc(card++);
 	}
 }
 
--- a/drivers/isdn/eicon/eicon.h
+++ b/drivers/isdn/eicon/eicon.h
@@ -1,4 +1,4 @@
-/* $Id: eicon.h,v 1.1.4.1 2001/11/20 14:19:35 kai Exp $
+/* $Id: eicon.h,v 1.26 2001/09/24 13:22:47 kai Exp $
  *
  * ISDN low-level module for Eicon active ISDN-Cards.
  *
@@ -347,19 +347,19 @@ typedef struct eicon_card {
 extern char *eicon_ctype_name[];
 
 
-static inline void eicon_schedule_tx(eicon_card *card)
+extern __inline__ void eicon_schedule_tx(eicon_card *card)
 {
         queue_task(&card->snd_tq, &tq_immediate);
         mark_bh(IMMEDIATE_BH);
 }
 
-static inline void eicon_schedule_rx(eicon_card *card)
+extern __inline__ void eicon_schedule_rx(eicon_card *card)
 {
         queue_task(&card->rcv_tq, &tq_immediate);
         mark_bh(IMMEDIATE_BH);
 }
 
-static inline void eicon_schedule_ack(eicon_card *card)
+extern __inline__ void eicon_schedule_ack(eicon_card *card)
 {
         queue_task(&card->ack_tq, &tq_immediate);
         mark_bh(IMMEDIATE_BH);
--- a/drivers/isdn/eicon/eicon_dsp.h
+++ b/drivers/isdn/eicon/eicon_dsp.h
@@ -1,4 +1,4 @@
-/* $Id: eicon_dsp.h,v 1.1.4.1 2001/11/20 14:19:35 kai Exp $
+/* $Id: eicon_dsp.h,v 1.8 2001/09/24 13:22:47 kai Exp $
  *
  * ISDN lowlevel-module for Eicon active cards.
  * DSP definitions
--- a/drivers/isdn/eicon/eicon_idi.c
+++ b/drivers/isdn/eicon/eicon_idi.c
@@ -1,4 +1,4 @@
-/* $Id: eicon_idi.c,v 1.1.4.1 2001/11/20 14:19:35 kai Exp $
+/* $Id: eicon_idi.c,v 1.45 2001/11/07 22:35:48 kai Exp $
  *
  * ISDN lowlevel-module for Eicon active cards.
  * IDI interface 
@@ -25,7 +25,7 @@
 
 #undef EICON_FULL_SERVICE_OKTETT
 
-char *eicon_idi_revision = "$Revision: 1.1.4.1 $";
+char *eicon_idi_revision = "$Revision: 1.45 $";
 
 eicon_manifbuf *manbuf;
 
@@ -1583,6 +1583,37 @@ idi_faxdata_rcv(eicon_card *ccard, eicon
 		return;
 	}
 
+#if 0 
+	eicon_sff_dochead *doc = (eicon_sff_dochead *)skb->data;
+	eicon_sff_pagehead *page = (eicon_sff_pagehead *)skb->data + sizeof(eicon_sff_dochead);
+
+	printk(KERN_DEBUG"SFF: doc %d / page %d (skb : %d)\n", 
+		sizeof(eicon_sff_dochead), 
+		sizeof(eicon_sff_pagehead), skb->len);
+
+	if (skb->len >= sizeof(eicon_sff_dochead)) {
+		printk(KERN_DEBUG"SFF: id = 0x%x\n", doc->id);
+		printk(KERN_DEBUG"SFF: version = 0x%x\n", doc->version);
+		printk(KERN_DEBUG"SFF: reserved1 = 0x%x\n", doc->reserved1);
+		printk(KERN_DEBUG"SFF: userinfo = 0x%x\n", doc->userinfo);
+		printk(KERN_DEBUG"SFF: pagecount = 0x%x\n", doc->pagecount);
+		printk(KERN_DEBUG"SFF: off1pagehead = 0x%x\n", doc->off1pagehead);
+		printk(KERN_DEBUG"SFF: offnpagehead = 0x%x\n", doc->offnpagehead);
+		printk(KERN_DEBUG"SFF: offdocend = 0x%x\n", doc->offdocend);
+	}
+	if (skb->len >= (sizeof(eicon_sff_dochead) + sizeof(eicon_sff_pagehead))) {
+		printk(KERN_DEBUG"SFFp: id = 0x%x\n", page->pageheadid);
+		printk(KERN_DEBUG"SFFp: len = 0x%x\n", page->pageheadlen);
+		printk(KERN_DEBUG"SFFp: resvert = 0x%x\n", page->resvert);
+		printk(KERN_DEBUG"SFFp: reshoriz = 0x%x\n", page->reshoriz);
+		printk(KERN_DEBUG"SFFp: coding = 0x%x\n", page->coding);
+		printk(KERN_DEBUG"SFFp: reserved2 = 0x%x\n", page->reserved2);
+		printk(KERN_DEBUG"SFFp: linelength = 0x%x\n", page->linelength);
+		printk(KERN_DEBUG"SFFp: pagelength = 0x%x\n", page->pagelength);
+		printk(KERN_DEBUG"SFFp: offprevpage = 0x%x\n", page->offprevpage);
+		printk(KERN_DEBUG"SFFp: offnextpage = 0x%x\n", page->offnextpage);
+	}
+#endif
 
 	
 	if (chan->fax->direction == ISDN_TTY_FAX_CONN_IN) {
@@ -2054,8 +2085,7 @@ idi_faxdata_send(eicon_card *ccard, eico
 				OutBuf.Len++;
 			} else {
 				*OutBuf.Next++ = 0;
-				*(__u16 *) OutBuf.Next = (__u16) LineBuf.Len;
-				OutBuf.Next += sizeof(__u16);
+				*((__u16 *) OutBuf.Next)++ = (__u16) LineBuf.Len;
 				OutBuf.Len += 3;
 			}
 			memcpy(OutBuf.Next, LineBuf.Data, LineBuf.Len);
@@ -2385,6 +2415,12 @@ idi_handle_ind(eicon_card *ccard, struct
 				} else {
 					if (chan->e.B2Id)
 						idi_do_req(ccard, chan, REMOVE, 1);
+#if 0
+					if (chan->e.D3Id) {
+						idi_do_req(ccard, chan, REMOVE, 0);
+						idi_do_req(ccard, chan, ASSIGN, 0);
+					}
+#endif
 					chan->statectrl &= ~WAITING_FOR_HANGUP;
 					chan->statectrl &= ~IN_HOLD;
 					if (chan->statectrl & HAVE_CONN_REQ) {
--- a/drivers/isdn/eicon/eicon_idi.h
+++ b/drivers/isdn/eicon/eicon_idi.h
@@ -1,4 +1,4 @@
-/* $Id: eicon_idi.h,v 1.1.4.1 2001/11/20 14:19:35 kai Exp $
+/* $Id: eicon_idi.h,v 1.12 2001/09/24 13:22:47 kai Exp $
  *
  * ISDN lowlevel-module for the Eicon active cards.
  * IDI-Interface
--- a/drivers/isdn/eicon/eicon_io.c
+++ b/drivers/isdn/eicon/eicon_io.c
@@ -1,4 +1,4 @@
-/* $Id: eicon_io.c,v 1.1.4.1 2001/11/20 14:19:35 kai Exp $
+/* $Id: eicon_io.c,v 1.15 2001/09/24 13:22:47 kai Exp $
  *
  * ISDN low-level module for Eicon active ISDN-Cards.
  * Code for communicating with hardware.
--- a/drivers/isdn/eicon/eicon_isa.c
+++ b/drivers/isdn/eicon/eicon_isa.c
@@ -1,4 +1,4 @@
-/* $Id: eicon_isa.c,v 1.1.4.1 2001/11/20 14:19:35 kai Exp $
+/* $Id: eicon_isa.c,v 1.18 2001/11/07 22:35:48 kai Exp $
  *
  * ISDN low-level module for Eicon active ISDN-Cards.
  * Hardware-specific code for old ISA cards.
@@ -20,7 +20,7 @@
 #define release_shmem release_region
 #define request_shmem request_region
 
-char *eicon_isa_revision = "$Revision: 1.1.4.1 $";
+char *eicon_isa_revision = "$Revision: 1.18 $";
 
 #undef EICON_MCA_DEBUG
 
@@ -38,8 +38,12 @@ static int eicon_isa_valid_irq[] = {
 static void
 eicon_isa_release_shmem(eicon_isa_card *card) {
 	if (card->mvalid) {
+#ifdef COMPAT_HAS_ISA_IOREMAP
 		iounmap(card->shmem);
 		release_mem_region(card->physmem, card->ramsize);
+#else
+		release_shmem((unsigned long)card->shmem, card->ramsize);
+#endif
 	}
 	card->mvalid = 0;
 }
@@ -94,12 +98,20 @@ eicon_isa_find_card(int Mem, int Irq, ch
 			 Mem, Id);
 		return -1;
 	}
+#ifdef COMPAT_HAS_ISA_IOREMAP
 	if (check_mem_region(Mem, RAMSIZE)) {
+#else
+	if (check_shmem(Mem, RAMSIZE)) {
+#endif
 		printk(KERN_WARNING "eicon_isa_boot: memory at 0x%x already in use.\n", Mem);
 		return -1;
 	}
 
+#ifdef COMPAT_HAS_ISA_IOREMAP
 	amem = (unsigned long) ioremap(Mem, RAMSIZE);
+#else
+	amem = (unsigned long) Mem;
+#endif
         writew(0x55aa, amem + 0x402);
         if (readw(amem + 0x402) != 0x55aa) primary = 0;
 	writew(0, amem + 0x402);
@@ -109,12 +121,16 @@ eicon_isa_find_card(int Mem, int Irq, ch
 	if (primary) {
 		printk(KERN_INFO "Eicon: assuming pri card at 0x%x\n", Mem);
 		writeb(0, amem + 0x3ffe);
+#ifdef COMPAT_HAS_ISA_IOREMAP
 		iounmap((unsigned char *)amem);
+#endif
 		return EICON_CTYPE_ISAPRI;
 	} else {
 		printk(KERN_INFO "Eicon: assuming bri card at 0x%x\n", Mem);
 		writeb(0, amem + 0x400);
+#ifdef COMPAT_HAS_ISA_IOREMAP
 		iounmap((unsigned char *)amem);
+#endif
 		return EICON_CTYPE_ISABRI;
 	}
 	return -1;
@@ -151,6 +167,7 @@ eicon_isa_bootload(eicon_isa_card *card,
 	else
 		card->ramsize  = RAMSIZE;
 
+#ifdef COMPAT_HAS_ISA_IOREMAP
 	if (check_mem_region(card->physmem, card->ramsize)) {
 		printk(KERN_WARNING "eicon_isa_boot: memory at 0x%lx already in use.\n",
 			card->physmem);
@@ -159,6 +176,16 @@ eicon_isa_bootload(eicon_isa_card *card,
 	}
 	request_mem_region(card->physmem, card->ramsize, "Eicon ISA ISDN");
 	card->shmem = (eicon_isa_shmem *) ioremap(card->physmem, card->ramsize);
+#else
+	/* Register shmem */
+	if (check_shmem((unsigned long)card->shmem, card->ramsize)) {
+		printk(KERN_WARNING "eicon_isa_boot: memory at 0x%lx already in use.\n",
+			(unsigned long)card->shmem);
+		kfree(code);
+		return -EBUSY;
+	}
+	request_shmem((unsigned long)card->shmem, card->ramsize, "Eicon ISA ISDN");
+#endif
 #ifdef EICON_MCA_DEBUG
 	printk(KERN_INFO "eicon_isa_boot: card->ramsize = %d.\n", card->ramsize);
 #endif
--- a/drivers/isdn/eicon/eicon_isa.h
+++ b/drivers/isdn/eicon/eicon_isa.h
@@ -1,4 +1,4 @@
-/* $Id: eicon_isa.h,v 1.1.4.1 2001/11/20 14:19:35 kai Exp $
+/* $Id: eicon_isa.h,v 1.11 2001/09/24 13:22:47 kai Exp $
  *
  * ISDN low-level module for Eicon active ISDN-Cards.
  *
--- a/drivers/isdn/eicon/eicon_mod.c
+++ b/drivers/isdn/eicon/eicon_mod.c
@@ -1,4 +1,4 @@
-/* $Id: eicon_mod.c,v 1.1.4.1 2001/11/20 14:19:35 kai Exp $
+/* $Id: eicon_mod.c,v 1.44 2001/11/20 09:48:25 armin Exp $
  *
  * ISDN lowlevel-module for Eicon active cards.
  * 
@@ -44,7 +44,7 @@
 static eicon_card *cards = (eicon_card *) NULL;   /* glob. var , contains
                                                      start of card-list   */
 
-static char *eicon_revision = "$Revision: 1.1.4.1 $";
+static char *eicon_revision = "$Revision: 1.44 $";
 
 extern char *eicon_pci_revision;
 extern char *eicon_isa_revision;
@@ -639,6 +639,18 @@ if_command(isdn_ctrl * c)
 static int
 if_writecmd(const u_char * buf, int len, int user, int id, int channel)
 {
+#if 0
+	/* Not yet used */
+        eicon_card *card = eicon_findcard(id);
+
+        if (card) {
+                if (!card->flags & EICON_FLAGS_RUNNING)
+                        return (len);
+                return (len);
+        }
+        printk(KERN_ERR
+               "eicon: if_writecmd called with invalid driverId!\n");
+#endif
         return (len);
 }
 
@@ -665,11 +677,8 @@ if_readstatus(u_char * buf, int len, int
 			else
 				cnt = skb->len;
 
-			if (user) {
-				spin_unlock_irqrestore(&eicon_lock, flags);
+			if (user)
 				copy_to_user(p, skb->data, cnt);
-				spin_lock_irqsave(&eicon_lock, flags);
-			}
 			else
 				memcpy(p, skb->data, cnt);
 
@@ -1459,6 +1468,7 @@ eicon_exit(void)
 
 #ifndef MODULE
 
+#ifdef COMPAT_HAS_NEW_SETUP
 static int __init
 eicon_setup(char *line)
 {
@@ -1467,6 +1477,12 @@ eicon_setup(char *line)
 	char *str;
 
 	str = get_options(line, 4, ints);
+#else
+void
+eicon_setup(char *str, int *ints)
+{
+        int i, argc;
+#endif
 
         argc = ints[0];
         i = 1;
@@ -1494,9 +1510,13 @@ eicon_setup(char *line)
 #else
 	printk(KERN_INFO "Eicon ISDN active driver setup\n");
 #endif
+#ifdef COMPAT_HAS_NEW_SETUP
 	return(1);
 }
 __setup("eicon=", eicon_setup);
+#else
+}
+#endif
 
 #endif /* MODULE */
 
--- a/drivers/isdn/eicon/eicon_pci.c
+++ b/drivers/isdn/eicon/eicon_pci.c
@@ -1,4 +1,4 @@
-/* $Id: eicon_pci.c,v 1.1.4.1 2001/11/20 14:19:35 kai Exp $
+/* $Id: eicon_pci.c,v 1.18 2001/09/24 13:22:47 kai Exp $
  *
  * ISDN low-level module for Eicon active ISDN-Cards.
  * Hardware-specific code for PCI cards.
@@ -24,7 +24,7 @@
 #include "adapter.h"
 #include "uxio.h"
 
-char *eicon_pci_revision = "$Revision: 1.1.4.1 $";
+char *eicon_pci_revision = "$Revision: 1.18 $";
 
 #if CONFIG_PCI	         /* intire stuff is only for PCI */
 #ifdef CONFIG_ISDN_DRV_EICON_PCI
--- a/drivers/isdn/eicon/eicon_pci.h
+++ b/drivers/isdn/eicon/eicon_pci.h
@@ -1,4 +1,4 @@
-/* $Id: eicon_pci.h,v 1.1.4.1 2001/11/20 14:19:35 kai Exp $
+/* $Id: eicon_pci.h,v 1.7 2001/09/24 13:22:47 kai Exp $
  *
  * ISDN low-level module for Eicon active ISDN-Cards (PCI part).
  *
--- a/drivers/isdn/eicon/fourbri.c
+++ b/drivers/isdn/eicon/fourbri.c
@@ -337,8 +337,7 @@ static int diva_server_4bri_load(card_t 
 static int diva_server_4bri_start(card_t *card, byte *channels)
 {
 	byte *ctl;
-	byte *shared;
-	int i;
+	byte *shared, i;
 	int adapter_num;
 
 	DPRINTF(("divas: start Diva Server 4BRI"));
--- a/drivers/isdn/eicon/kprintf.c
+++ b/drivers/isdn/eicon/kprintf.c
@@ -18,6 +18,468 @@
 #include "divalog.h"
 #include "uxio.h"
 
+/*
+ * Implementation of printf and sprintf for kernel
+ */
+
+#define MAX_BUFF    (80)        /* limit size of temporary buffers */
+
+#define WRITE_CHAR(BUFFER, SIZE, C) \
+  if (--(SIZE) < 0) { (BUFFER)--; *(BUFFER) = '\0'; return; } *(BUFFER)++ = (C)
+
+
+/*
+ * convert a number to decimal ASCII
+ */
+
+static
+void    do_decimal( char            *temp,
+                    int             temp_len,
+                    unsigned int    value,
+                    char            *s)
+
+{
+    int     i;
+
+    temp[0] = '\0';
+
+    for (i = 1; i < temp_len; i++)
+    {
+        temp[i] = (char) ((value % 10) + (int) '0');
+        value /= 10;
+    }
+
+    for (i = (temp_len - 1); temp[i] == '0'; i--)
+    {
+        ;
+    }
+
+    if (i == 0)
+    {
+        i++;
+    }
+
+    while (i >= 0)
+    {
+        *s++ = temp[i--];
+    }
+
+    return;
+}
+
+/*
+ * convert a number to octal ASCII
+ */
+
+static
+void    do_octal(   char            *temp,
+                    unsigned int    value,
+                    char            *s)
+
+{
+    int     i;
+
+    temp[0] = '\0';
+
+    for (i = 1; i <= 11; i++)
+    {
+        temp[i] = (char) ((value & 07) + (int) '0');
+        value >>= 3;
+    }
+    temp[11] &= '3';
+
+    for (i = 11; temp[i] == '0'; i--)
+    {
+        ;
+    }
+
+    if (i == 0)
+    {
+        i++;
+    }
+
+    while (i >= 0)
+    {
+        *s++ = temp[i--];
+    }
+
+    return;
+}
+
+/*
+ * convert a number to hex ASCII
+ */
+
+static
+void    do_hex( char            *temp,
+                unsigned int    value,
+                char            *s)
+
+{
+    int     i;
+    static
+    char    *dec_to_hex = "0123456789abcdef";
+
+    temp[0] = '\0';
+
+    for (i = 1; i <= 8; i++)
+    {
+        temp[i] = dec_to_hex[value & 0x0f];
+        value >>= 4;
+    }
+
+    for (i = 8; temp[i] == '0'; i--)
+    {
+        ;
+    }
+
+    if (i == 0)
+    {
+        i++;
+    }
+
+    while (i >= 0)
+    {
+        *s++ = temp[i--];
+    }
+
+    return;
+}
+
+/*
+ * convert a buffer to ASCII HEX
+ */
+
+static
+void    do_buffer(  char    *buffer,
+                    int     length,
+                    char    *s)
+
+{
+    static
+    char    hex_char [] = "0123456789abcdef";
+    char    *b = buffer;
+    int     hex_byte;
+    int     nybble;
+
+    length = (length >= ((MAX_BUFF / 3) + 1)) ? (MAX_BUFF / 3) : length;
+
+    while (length)
+    {
+        hex_byte = (int) *b++;
+        nybble = (hex_byte >> 4) & 0xf;
+        *s++ = hex_char[nybble];
+        nybble = hex_byte & 0xf;
+        *s++ = hex_char[nybble];
+        *s++ = ' ';
+        length--;
+    }
+    *s = '\0';
+
+    return;
+}
+
+/*
+ * Body of sprintf function: behaves just like standard sprintf, except we
+ * have an extra argument (buffer size) which we use to ensure we don't
+ * overflow
+ */
+
+void    Divas_vsprintf(   char    *buffer,
+                    int     size,
+                    char    *fmt,
+                    va_list argptr)
+
+{
+    char        c;          /* single character buffer */
+    int         i;          /* handy scratch counter */
+    int         f;          /* format character (after %) */
+    char        *str;       /* pointer into string */
+    char        temp[20];   /* temp buffer used in printing numbers */
+    char        string[MAX_BUFF]; /* output from number conversion */
+    int         length;     /* length of string "str" */
+    char        fill;       /* fill character ' ' or '0' */
+    boolean_t   leftjust;   /* TRUE if left justified, else right justified */
+    int         fmax, fmin; /* field specifiers % MIN . MAX s */
+    int         leading;    /* number of leading/trailing fill characters */
+    char        sign;       /* set to '-' for negative decimals */
+    int         number;     /* numeric argument */
+
+    char        *buff_ptr;  /* pointer to user's buffer of hex data */
+    int         buff_len;   /* length of hex data */
+
+    /* make sure we have somthing to write into */
+
+    if ((!buffer) || (size <= 0))
+    {
+        return;
+    }
+
+    while (TRUE)
+    {
+        /* echo characters until end or '%' encountered */
+
+        while ((c = *fmt++) != '%')
+        {
+            if (!c)
+            {
+                *buffer = '\0';
+                return;
+            }
+            WRITE_CHAR(buffer, size, c);
+        }
+
+        /* echo %% as % */
+
+        if (*fmt == '%')
+        {
+            WRITE_CHAR(buffer, size, *fmt);
+            continue;
+        }
+
+        /* %- turns on left-justify */
+
+        if ((leftjust = (boolean_t) ((*fmt == '-') ? TRUE : FALSE)))
+        {
+            fmt++;
+        }
+
+        /* %0 turns on zero filling */
+
+        if (*fmt == '0')
+        {
+            fill = '0';
+        }
+        else
+        {
+            fill = ' ';
+        }
+
+        /* minium field width specifier for %d, u, x, c, s */
+
+        fmin = 0;
+
+        if (*fmt == '*')
+        {
+            fmin = va_arg(argptr, int);
+            fmt++;
+        }
+        else
+        {
+            while ('0' <= *fmt && *fmt <= '9')
+            {
+                fmin = (fmin * 10) + (*fmt++ - '0');
+            }
+        }
+
+        /* maximum string width specifier for %s */
+
+        fmax = 0;
+
+        if (*fmt == '.')
+        {
+            if (*(++fmt) == '*')
+            {
+                fmax = va_arg(argptr, int);
+                fmt++;
+            }
+            else
+            {
+                while ('0' <= *fmt && *fmt <= '9')
+                {
+                    fmax = (fmax * 10) + (*fmt++ - '0');
+                }
+            }
+        }
+
+        /* skip over 'l' option (ints are assumed same size as longs) */
+
+        if (*fmt == 'l')
+        {
+            fmt++;
+        }
+
+        /* get the format chacater */
+
+        if (!(f = *fmt++))
+        {
+            WRITE_CHAR(buffer, size, '%');
+            *buffer = '\0';
+            return;
+        }
+
+        sign = '\0';        /* sign == '-' for negative decimal */
+
+        str = string;
+
+        switch (f)
+        {
+        case 'c' :
+            string[0] = (char) va_arg(argptr, int);
+            string[1] = '\0';
+            fmax = 0;
+            fill = ' ';
+            break;
+
+        case 's' :
+            str = va_arg(argptr, char *);
+            fill = ' ';
+            break;
+
+        case 'D' :
+        case 'd' :
+            number = va_arg(argptr, int);
+            if (number < 0)
+            {
+                sign = '-';
+                number = -number;
+            }
+            do_decimal(temp, DIM(temp), (unsigned int) number, str);
+            fmax = 0;
+            break;
+
+        case 'U' :
+        case 'u' :
+            number = va_arg(argptr, int);
+            do_decimal(temp, DIM(temp), (unsigned int) number, str);
+            fmax = 0;
+            break;
+
+        case 'O' :
+        case 'o' :
+            number = va_arg(argptr, int);
+            do_octal(temp, (unsigned int) number, str);
+            fmax = 0;
+            break;
+
+        case 'X' :
+        case 'x' :
+            number = va_arg(argptr, int);
+            do_hex(temp, (unsigned int) number, str);
+            fmax = 0;
+            break;
+
+        case 'H' :
+        case 'h' :
+            buff_ptr = va_arg(argptr, char *);
+            buff_len = va_arg(argptr, int);
+            do_buffer(buff_ptr, buff_len, str);
+            fmax = 0;
+            break;
+
+        default :
+            WRITE_CHAR(buffer, size, ((char) f));
+            break;
+        }
+
+        /* get the length of the string */
+
+        length = 0;
+        while (str[length])
+        {
+            length++;
+        }
+
+        /* make sure we have fmax and fmin values that are O.K. */
+
+        if (fmin > DIM(string) || fmin < 0)
+        {
+            fmin = 0;
+        }
+
+        if (fmax > DIM(string) || fmax < 0)
+        {
+            fmax = 0;
+        }
+
+        /* figure out how many leading characters thare are */
+
+        leading = 0;
+
+        if (fmax || fmin)
+        {
+            if (fmax)
+            {
+                if (length > fmax)
+                {
+                    length = fmax;
+                }
+            }
+
+            if (fmin)
+            {
+                leading = fmin - length;
+            }
+
+            if (sign == '-')
+            {
+                leading--;
+            }
+        }
+
+        /* output sign now, if fill is numeric */
+
+        if (sign == '-' && fill == '0')
+        {
+            WRITE_CHAR(buffer, size, '-');
+        }
+
+        /* if right justified, output fill characters */
+
+        if (!leftjust)
+        {
+            for (i = 0; i < leading; i++)
+            {
+                WRITE_CHAR(buffer, size, fill);
+            }
+        }
+
+        /* output sign now, if fill is spaces */
+
+        if (sign == '-' && fill == ' ')
+        {
+            WRITE_CHAR(buffer, size, '-');
+        }
+
+        /* now the actual value */
+
+        for (i = 0; i < length; i++)
+        {
+            WRITE_CHAR(buffer, size, str[i]);
+        }
+
+        /* if left justified, fill out with the fill character */
+
+        if (leftjust)
+        {
+            for (i = 0; i < leading; i++)
+            {
+                WRITE_CHAR(buffer, size, fill);
+            }
+        }
+    }
+}
+
+/*
+ * sprintf for kernel
+ *
+ * call our vsprintf assuming user has a big buffer....
+ */
+
+void    DivasSprintf(char *buffer, char *fmt, ...)
+
+{
+    va_list     argptr;         /* pointer to additional args */
+
+    va_start(argptr, fmt);
+
+    Divas_vsprintf(buffer, 1024, fmt, argptr);
+
+    va_end(argptr);
+
+    return;
+}
+
 void    DivasPrintf(char  *fmt, ...)
 
 {
@@ -40,7 +502,7 @@ void    DivasPrintf(char  *fmt, ...)
 
     /* call vsprintf to format the user's information */
 
-    vsnprintf(log.buffer, DIM(log.buffer), fmt, argptr);
+    Divas_vsprintf(log.buffer, DIM(log.buffer), fmt, argptr);
 
     va_end(argptr);
 
--- a/drivers/isdn/eicon/lincfg.c
+++ b/drivers/isdn/eicon/lincfg.c
@@ -26,6 +26,9 @@
 #include "uxio.h"
 
 #include <linux/pci.h>
+#ifndef COMPAT_HAS_2_2_PCI
+#include <linux/pci_ids.h>
+#endif
 #include <linux/kernel.h>
 #include <linux/ioport.h>
 
--- a/drivers/isdn/eicon/linchr.c
+++ b/drivers/isdn/eicon/linchr.c
@@ -154,17 +154,17 @@ ssize_t do_read(struct file *pFile, char
 	klog_t *pHeadItem;
 
 	if (BufferSize < sizeof(klog_t))
+	{
+		printk(KERN_WARNING "Divas: Divalog buffer specifed a size that is too small (%d - %d required)\n",
+			BufferSize, sizeof(klog_t));
 		return -EIO;
+	}
 
 	pHeadItem = (klog_t *) DivasLogFifoRead();
 
 	if (pHeadItem)
 	{
-		if(copy_to_user(pClientLogBuffer, pHeadItem, sizeof(klog_t)))
-		{
-			kfree(pHeadItem);
-			return -EFAULT;
-		}
+		memcpy(pClientLogBuffer, pHeadItem, sizeof(klog_t));
 		kfree(pHeadItem);
 		return sizeof(klog_t);
 	}
--- a/drivers/isdn/eicon/linio.c
+++ b/drivers/isdn/eicon/linio.c
@@ -15,6 +15,7 @@
 #include <linux/slab.h>
 #include <linux/pci.h>
 #include <linux/delay.h>
+#include <linux/isdn_compat.h>
 #undef N_DATA
 
 #include "uxio.h"
--- a/drivers/isdn/hisax/Makefile
+++ b/drivers/isdn/hisax/Makefile
@@ -4,20 +4,17 @@
 
 O_TARGET	  := vmlinux-obj.o
 
-# Define maximum number of cards
-
-EXTRA_CFLAGS      += -DHISAX_MAX_CARDS=$(CONFIG_HISAX_MAX_CARDS)
-
 # Objects that export symbols.
 
-export-objs	  := config.o hisax_isac.o isdnhdlc.o
+export-objs	  := config.o fsm.o hisax_isac.o
 
 # Multipart objects.
 
 list-multi	  := hisax.o hisax_st5481.o
 hisax-objs	  := config.o isdnl1.o tei.o isdnl2.o isdnl3.o \
 		     lmgr.o q931.o callc.o fsm.o cert.o
-hisax_st5481-objs := st5481_init.o st5481_usb.o st5481_d.o st5481_b.o
+hisax_st5481-objs := st5481_init.o st5481_usb.o st5481_d.o st5481_b.o \
+		     st5481_hdlc.o
 
 # Optional parts of multipart objects.
 hisax-objs-$(CONFIG_HISAX_EURO) += l3dss1.o
@@ -33,7 +30,7 @@ hisax-objs-$(CONFIG_HISAX_AVM_A1_PCMCIA)
 hisax-objs-$(CONFIG_HISAX_FRITZPCI) += avm_pci.o isac.o arcofi.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 ipacx.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
@@ -44,6 +41,7 @@ hisax-objs-$(CONFIG_HISAX_NETJET_U) += n
 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_HFC_USB) += hfc_usbr.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
@@ -51,7 +49,6 @@ hisax-objs-$(CONFIG_HISAX_BKM_A4T) += bk
 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_ENTERNOW_PCI) += enternow_pci.o amd7930_fn.o
 #hisax-objs-$(CONFIG_HISAX_TESTEMU) += testemu.o
 
 hisax-objs += $(sort $(hisax-objs-y))
@@ -61,10 +58,9 @@ hisax-objs += $(sort $(hisax-objs-y))
 obj-$(CONFIG_ISDN_DRV_HISAX)		+= hisax.o
 obj-$(CONFIG_HISAX_SEDLBAUER_CS)	+= sedlbauer_cs.o
 obj-$(CONFIG_HISAX_ELSA_CS)		+= elsa_cs.o
-obj-$(CONFIG_HISAX_AVM_A1_CS)		+= avma1_cs.o
-obj-$(CONFIG_HISAX_ST5481)		+= hisax_st5481.o isdnhdlc.o
-obj-$(CONFIG_HISAX_FRITZ_PCIPNP)        += hisax_isac.o hisax_fcpcipnp.o
-obj-$(CONFIG_USB_AUERISDN)	        += isdnhdlc.o
+obj-$(CONFIG_HISAX_HFC_USB_CS)		+= hfc_usb.o
+obj-$(CONFIG_HISAX_ST5481)		+= hisax_st5481.o
+obj-$(CONFIG_HISAX_FRITZ_PCIPNP)        += hisax_fcpcipnp.o hisax_isac.o
 
 CERT := $(shell md5sum -c md5sums.asc >> /dev/null;echo $$?)
 CFLAGS_cert.o := -DCERTIFICATION=$(CERT)
--- /dev/null
+++ b/drivers/isdn/hisax/amd7930.c
@@ -0,0 +1,755 @@
+/* $Id: amd7930.c,v 1.8 2001/09/24 13:22:55 kai Exp $
+ *
+ * HiSax ISDN driver - chip specific routines for AMD 7930
+ *
+ * Author       Brent Baccala
+ * Copyright    by Brent Baccala <baccala@FreeSoft.org>
+ *
+ * This software may be used and distributed according to the terms
+ * of the GNU General Public License, incorporated herein by reference.
+ *
+ *    - Existing ISDN HiSax driver provides all the smarts
+ *    - it compiles, runs, talks to an isolated phone switch, connects
+ *      to a Cisco, pings go through
+ *    - AMD 7930 support only (no DBRI yet)
+ *    - no US NI-1 support (may not work on US phone system - untested)
+ *    - periodic packet loss, apparently due to lost interrupts
+ *    - ISDN sometimes freezes, requiring reboot before it will work again
+ *
+ * The code is unreliable enough to be consider alpha
+ *
+ * This file is (c) under GNU General Public License
+ *
+ * Advanced Micro Devices' Am79C30A is an ISDN/audio chip used in the
+ * SparcStation 1+.  The chip provides microphone and speaker interfaces
+ * which provide mono-channel audio at 8K samples per second via either
+ * 8-bit A-law or 8-bit mu-law encoding.  Also, the chip features an
+ * ISDN BRI Line Interface Unit (LIU), I.430 S/T physical interface,
+ * which performs basic D channel LAPD processing and provides raw
+ * B channel data.  The digital audio channel, the two ISDN B channels,
+ * and two 64 Kbps channels to the microprocessor are all interconnected
+ * via a multiplexer.
+ *
+ * This driver interfaces to the Linux HiSax ISDN driver, which performs
+ * all high-level Q.921 and Q.931 ISDN functions.  The file is not
+ * itself a hardware driver; rather it uses functions exported by
+ * the AMD7930 driver in the sparcaudio subsystem (drivers/sbus/audio),
+ * allowing the chip to be simultaneously used for both audio and ISDN data.
+ * The hardware driver does _no_ buffering, but provides several callbacks
+ * which are called during interrupt service and should therefore run quickly.
+ *
+ * D channel transmission is performed by passing the hardware driver the
+ * address and size of an skb's data area, then waiting for a callback
+ * to signal successful transmission of the packet.  A task is then
+ * queued to notify the HiSax driver that another packet may be transmitted.
+ *
+ * D channel reception is quite simple, mainly because of:
+ *   1) the slow speed of the D channel - 16 kbps, and
+ *   2) the presence of an 8- or 32-byte (depending on chip version) FIFO
+ *      to buffer the D channel data on the chip
+ * Worst case scenario of back-to-back packets with the 8 byte buffer
+ * at 16 kbps yields an service time of 4 ms - long enough to preclude
+ * the need for fancy buffering.  We queue a background task that copies
+ * data out of the receive buffer into an skb, and the hardware driver
+ * simply does nothing until we're done with the receive buffer and
+ * reset it for a new packet.
+ *
+ * B channel processing is more complex, because of:
+ *   1) the faster speed - 64 kbps,
+ *   2) the lack of any on-chip buffering (it interrupts for every byte), and
+ *   3) the lack of any chip support for HDLC encapsulation
+ *
+ * The HiSax driver can put each B channel into one of three modes -
+ * L1_MODE_NULL (channel disabled), L1_MODE_TRANS (transparent data relay),
+ * and L1_MODE_HDLC (HDLC encapsulation by low-level driver).
+ * L1_MODE_HDLC is the most common, used for almost all "pure" digital
+ * data sessions.  L1_MODE_TRANS is used for ISDN audio.
+ *
+ * HDLC B channel transmission is performed via a large buffer into
+ * which the skb is copied while performing HDLC bit-stuffing.  A CRC
+ * is computed and attached to the end of the buffer, which is then
+ * passed to the low-level routines for raw transmission.  Once
+ * transmission is complete, the hardware driver is set to enter HDLC
+ * idle by successive transmission of mark (all 1) bytes, waiting for
+ * the ISDN driver to prepare another packet for transmission and
+ * deliver it.
+ *
+ * HDLC B channel reception is performed via an X-byte ring buffer
+ * divided into N sections of X/N bytes each.  Defaults: X=256 bytes, N=4.
+ * As the hardware driver notifies us that each section is full, we
+ * hand it the next section and schedule a background task to peruse
+ * the received section, bit-by-bit, with an HDLC decoder.  As
+ * packets are detected, they are copied into a large buffer while
+ * decoding HDLC bit-stuffing.  The ending CRC is verified, and if
+ * it is correct, we alloc a new skb of the correct length (which we
+ * now know), copy the packet into it, and hand it to the upper layers.
+ * Optimization: for large packets, we hand the buffer (which also
+ * happens to be an skb) directly to the upper layer after an skb_trim,
+ * and alloc a new large buffer for future packets, thus avoiding a copy.
+ * Then we return to HDLC processing; state is saved between calls.
+ * 
+ */
+
+#define __NO_VERSION__
+#include "hisax.h"
+#include "../../sbus/audio/amd7930.h"
+#include "isac.h"
+#include "isdnl1.h"
+#include "rawhdlc.h"
+#include <linux/interrupt.h>
+
+static const char *amd7930_revision = "$Revision: 1.8 $";
+
+#define RCV_BUFSIZE	1024	/* Size of raw receive buffer in bytes */
+#define RCV_BUFBLKS	4	/* Number of blocks to divide buffer into
+				 * (must divide RCV_BUFSIZE) */
+
+static void Bchan_fill_fifo(struct BCState *, struct sk_buff *);
+
+static void
+Bchan_xmt_bh(struct BCState *bcs)
+{
+	struct sk_buff *skb;
+
+	if (bcs->hw.amd7930.tx_skb != NULL) {
+		dev_kfree_skb(bcs->hw.amd7930.tx_skb);
+		bcs->hw.amd7930.tx_skb = NULL;
+	}
+
+	if ((skb = skb_dequeue(&bcs->squeue))) {
+		Bchan_fill_fifo(bcs, skb);
+	} else {
+		clear_bit(BC_FLG_BUSY, &bcs->Flag);
+		bcs->event |= 1 << B_XMTBUFREADY;
+		queue_task(&bcs->tqueue, &tq_immediate);
+		mark_bh(IMMEDIATE_BH);
+	}
+}
+
+static void
+Bchan_xmit_callback(struct BCState *bcs)
+{
+	queue_task(&bcs->hw.amd7930.tq_xmt, &tq_immediate);
+	mark_bh(IMMEDIATE_BH);
+}
+
+/* B channel transmission: two modes (three, if you count L1_MODE_NULL)
+ *
+ * L1_MODE_HDLC - We need to do HDLC encapsulation before transmiting
+ * the packet (i.e. make_raw_hdlc_data).  Since this can be a
+ * time-consuming operation, our completion callback just schedules
+ * a bottom half to do encapsulation for the next packet.  In between,
+ * the link will just idle
+ *
+ * L1_MODE_TRANS - Data goes through, well, transparent.  No HDLC encap,
+ * and we can't just let the link idle, so the "bottom half" actually
+ * gets called during the top half (it's our callback routine in this case),
+ * but it's a lot faster now since we don't call make_raw_hdlc_data
+ */
+
+static void
+Bchan_fill_fifo(struct BCState *bcs, struct sk_buff *skb)
+{
+	struct IsdnCardState *cs = bcs->cs;
+	int len;
+
+	if ((cs->debug & L1_DEB_HSCX) || (cs->debug & L1_DEB_HSCX_FIFO)) {
+		char tmp[1024];
+		char *t = tmp;
+
+		t += sprintf(t, "amd7930_fill_fifo %c cnt %d",
+			     bcs->channel ? 'B' : 'A', skb->len);
+		if (cs->debug & L1_DEB_HSCX_FIFO)
+			QuickHex(t, skb->data, skb->len);
+		debugl1(cs, tmp);
+	}
+
+	if (bcs->mode == L1_MODE_HDLC) {
+		len = make_raw_hdlc_data(skb->data, skb->len,
+					 bcs->hw.amd7930.tx_buff, RAW_BUFMAX);
+		if (len > 0)
+			amd7930_bxmit(0, bcs->channel,
+				      bcs->hw.amd7930.tx_buff, len,
+				      (void *) &Bchan_xmit_callback,
+				      (void *) bcs);
+		dev_kfree_skb(skb);
+	} else if (bcs->mode == L1_MODE_TRANS) {
+		amd7930_bxmit(0, bcs->channel,
+			      bcs->hw.amd7930.tx_buff, skb->len,
+			      (void *) &Bchan_xmt_bh,
+			      (void *) bcs);
+		bcs->hw.amd7930.tx_skb = skb;
+	} else {
+		dev_kfree_skb(skb);
+	}
+}
+
+static void
+Bchan_mode(struct BCState *bcs, int mode, int bc)
+{
+	struct IsdnCardState *cs = bcs->cs;
+
+	if (cs->debug & L1_DEB_HSCX) {
+		char tmp[40];
+		sprintf(tmp, "AMD 7930 mode %d bchan %d/%d",
+			mode, bc, bcs->channel);
+		debugl1(cs, tmp);
+	}
+	bcs->mode = mode;
+}
+
+/* Bchan_l2l1 is the entry point for upper layer routines that want to
+ * transmit on the B channel.  PH_DATA_REQ is a normal packet that
+ * we either start transmitting (if idle) or queue (if busy).
+ * PH_PULL_REQ can be called to request a callback message (PH_PULL_CNF)
+ * once the link is idle.  After a "pull" callback, the upper layer
+ * routines can use PH_PULL_IND to send data.
+ */
+
+static void
+Bchan_l2l1(struct PStack *st, int pr, void *arg)
+{
+	struct sk_buff *skb = arg;
+
+	switch (pr) {
+		case (PH_DATA_REQ):
+			if (test_bit(BC_FLG_BUSY, &st->l1.bcs->Flag)) {
+				skb_queue_tail(&st->l1.bcs->squeue, skb);
+			} else {
+				test_and_set_bit(BC_FLG_BUSY, &st->l1.bcs->Flag);
+				Bchan_fill_fifo(st->l1.bcs, skb);
+			}
+			break;
+		case (PH_PULL_IND):
+			if (test_bit(BC_FLG_BUSY, &st->l1.bcs->Flag)) {
+				printk(KERN_WARNING "amd7930: this shouldn't happen\n");
+				break;
+			}
+			test_and_set_bit(BC_FLG_BUSY, &st->l1.bcs->Flag);
+			Bchan_fill_fifo(st->l1.bcs, skb);
+			break;
+		case (PH_PULL_REQ):
+			if (!test_bit(BC_FLG_BUSY, &st->l1.bcs->Flag)) {
+				clear_bit(FLG_L1_PULL_REQ, &st->l1.Flags);
+				st->l1.l1l2(st, PH_PULL_CNF, NULL);
+			} else
+				set_bit(FLG_L1_PULL_REQ, &st->l1.Flags);
+			break;
+	}
+}
+
+/* Receiver callback and bottom half - decodes HDLC at leisure (if
+ * L1_MODE_HDLC) and passes newly received skb on via bcs->rqueue.  If
+ * a large packet is received, stick rv_skb (the buffer that the
+ * packet has been decoded into) on the receive queue and alloc a new
+ * (large) skb to act as buffer for future receives.  If a small
+ * packet is received, leave rv_skb alone, alloc a new skb of the
+ * correct size, and copy the packet into it
+ */
+
+static void
+Bchan_recv_callback(struct BCState *bcs)
+{
+	struct amd7930_hw *hw = &bcs->hw.amd7930;
+
+	hw->rv_buff_in += RCV_BUFSIZE/RCV_BUFBLKS;
+	hw->rv_buff_in %= RCV_BUFSIZE;
+
+	if (hw->rv_buff_in != hw->rv_buff_out) {
+		amd7930_brecv(0, bcs->channel,
+			      hw->rv_buff + hw->rv_buff_in,
+			      RCV_BUFSIZE/RCV_BUFBLKS,
+			      (void *) &Bchan_recv_callback, (void *) bcs);
+	}
+
+	queue_task(&hw->tq_rcv, &tq_immediate);
+	mark_bh(IMMEDIATE_BH);
+}
+
+static void
+Bchan_rcv_bh(struct BCState *bcs)
+{
+	struct IsdnCardState *cs = bcs->cs;
+	struct amd7930_hw *hw = &bcs->hw.amd7930;
+	struct sk_buff *skb;
+	int len;
+
+	if (cs->debug & L1_DEB_HSCX) {
+		char tmp[1024];
+
+		sprintf(tmp, "amd7930_Bchan_rcv (%d/%d)",
+			hw->rv_buff_in, hw->rv_buff_out);
+		debugl1(cs, tmp);
+		QuickHex(tmp, hw->rv_buff + hw->rv_buff_out,
+			 RCV_BUFSIZE/RCV_BUFBLKS);
+		debugl1(cs, tmp);
+	}
+
+	do {
+		if (bcs->mode == L1_MODE_HDLC) {
+			while ((len = read_raw_hdlc_data(hw->hdlc_state,
+							 hw->rv_buff + hw->rv_buff_out, RCV_BUFSIZE/RCV_BUFBLKS,
+							 hw->rv_skb->tail, HSCX_BUFMAX))) {
+				if (len > 0 && (cs->debug & L1_DEB_HSCX_FIFO)) {
+					char tmp[1024];
+					char *t = tmp;
+
+					t += sprintf(t, "amd7930_Bchan_rcv %c cnt %d", bcs->channel ? 'B' : 'A', len);
+					QuickHex(t, hw->rv_skb->tail, len);
+					debugl1(cs, tmp);
+				}
+
+				if (len > HSCX_BUFMAX/2) {
+					/* Large packet received */
+
+					if (!(skb = dev_alloc_skb(HSCX_BUFMAX))) {
+						printk(KERN_WARNING "amd7930: receive out of memory");
+					} else {
+						skb_put(hw->rv_skb, len);
+						skb_queue_tail(&bcs->rqueue, hw->rv_skb);
+						hw->rv_skb = skb;
+						bcs->event |= 1 << B_RCVBUFREADY;
+						queue_task(&bcs->tqueue, &tq_immediate);
+					}
+				} else if (len > 0) {
+					/* Small packet received */
+
+					if (!(skb = dev_alloc_skb(len))) {
+						printk(KERN_WARNING "amd7930: receive out of memory\n");
+					} else {
+						memcpy(skb_put(skb, len), hw->rv_skb->tail, len);
+						skb_queue_tail(&bcs->rqueue, skb);
+						bcs->event |= 1 << B_RCVBUFREADY;
+						queue_task(&bcs->tqueue, &tq_immediate);
+						mark_bh(IMMEDIATE_BH);
+					}
+				} else {
+					/* Reception Error */
+					/* printk("amd7930: B channel receive error\n"); */
+				}
+			}
+		} else if (bcs->mode == L1_MODE_TRANS) {
+			if (!(skb = dev_alloc_skb(RCV_BUFSIZE/RCV_BUFBLKS))) {
+				printk(KERN_WARNING "amd7930: receive out of memory\n");
+			} else {
+				memcpy(skb_put(skb, RCV_BUFSIZE/RCV_BUFBLKS),
+				       hw->rv_buff + hw->rv_buff_out,
+				       RCV_BUFSIZE/RCV_BUFBLKS);
+				skb_queue_tail(&bcs->rqueue, skb);
+				bcs->event |= 1 << B_RCVBUFREADY;
+				queue_task(&bcs->tqueue, &tq_immediate);
+				mark_bh(IMMEDIATE_BH);
+			}
+		}
+
+		if (hw->rv_buff_in == hw->rv_buff_out) {
+			/* Buffer was filled up - need to restart receiver */
+			amd7930_brecv(0, bcs->channel,
+				      hw->rv_buff + hw->rv_buff_in,
+				      RCV_BUFSIZE/RCV_BUFBLKS,
+				      (void *) &Bchan_recv_callback,
+				      (void *) bcs);
+		}
+
+		hw->rv_buff_out += RCV_BUFSIZE/RCV_BUFBLKS;
+		hw->rv_buff_out %= RCV_BUFSIZE;
+
+	} while (hw->rv_buff_in != hw->rv_buff_out);
+}
+
+static void
+Bchan_close(struct BCState *bcs)
+{
+	struct sk_buff *skb;
+
+	Bchan_mode(bcs, 0, 0);
+	amd7930_bclose(0, bcs->channel);
+
+	if (test_bit(BC_FLG_INIT, &bcs->Flag)) {
+		skb_queue_purge(&bcs->rqueue);
+		skb_queue_purge(&bcs->squeue);
+	}
+	test_and_clear_bit(BC_FLG_INIT, &bcs->Flag);
+}
+
+static int
+Bchan_open(struct BCState *bcs)
+{
+	struct amd7930_hw *hw = &bcs->hw.amd7930;
+
+	if (!test_and_set_bit(BC_FLG_INIT, &bcs->Flag)) {
+		skb_queue_head_init(&bcs->rqueue);
+		skb_queue_head_init(&bcs->squeue);
+	}
+	test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag);
+
+	amd7930_bopen(0, bcs->channel, 0xff);
+	hw->rv_buff_in = 0;
+	hw->rv_buff_out = 0;
+	hw->tx_skb = NULL;
+	init_hdlc_state(hw->hdlc_state, 0);
+	amd7930_brecv(0, bcs->channel,
+		      hw->rv_buff + hw->rv_buff_in, RCV_BUFSIZE/RCV_BUFBLKS,
+		      (void *) &Bchan_recv_callback, (void *) bcs);
+
+	bcs->event = 0;
+	bcs->tx_cnt = 0;
+	return (0);
+}
+
+static void
+Bchan_init(struct BCState *bcs)
+{
+	if (!(bcs->hw.amd7930.tx_buff = kmalloc(RAW_BUFMAX, GFP_ATOMIC))) {
+		printk(KERN_WARNING
+		       "HiSax: No memory for amd7930.tx_buff\n");
+		return;
+	}
+	if (!(bcs->hw.amd7930.rv_buff = kmalloc(RCV_BUFSIZE, GFP_ATOMIC))) {
+		printk(KERN_WARNING
+		       "HiSax: No memory for amd7930.rv_buff\n");
+		return;
+	}
+	if (!(bcs->hw.amd7930.rv_skb = dev_alloc_skb(HSCX_BUFMAX))) {
+		printk(KERN_WARNING
+		       "HiSax: No memory for amd7930.rv_skb\n");
+		return;
+	}
+	if (!(bcs->hw.amd7930.hdlc_state = kmalloc(sizeof(struct hdlc_state),
+						   GFP_ATOMIC))) {
+		printk(KERN_WARNING
+		       "HiSax: No memory for amd7930.hdlc_state\n");
+		return;
+	}
+
+	bcs->hw.amd7930.tq_rcv.sync = 0;
+	bcs->hw.amd7930.tq_rcv.routine = (void (*)(void *)) &Bchan_rcv_bh;
+	bcs->hw.amd7930.tq_rcv.data = (void *) bcs;
+
+	bcs->hw.amd7930.tq_xmt.sync = 0;
+	bcs->hw.amd7930.tq_xmt.routine = (void (*)(void *)) &Bchan_xmt_bh;
+	bcs->hw.amd7930.tq_xmt.data = (void *) bcs;
+}
+
+static void
+Bchan_manl1(struct PStack *st, int pr,
+	  void *arg)
+{
+	switch (pr) {
+		case (PH_ACTIVATE_REQ):
+			test_and_set_bit(BC_FLG_ACTIV, &st->l1.bcs->Flag);
+			Bchan_mode(st->l1.bcs, st->l1.mode, st->l1.bc);
+			st->l1.l1man(st, PH_ACTIVATE_CNF, NULL);
+			break;
+		case (PH_DEACTIVATE_REQ):
+			if (!test_bit(BC_FLG_BUSY, &st->l1.bcs->Flag))
+				Bchan_mode(st->l1.bcs, 0, 0);
+			test_and_clear_bit(BC_FLG_ACTIV, &st->l1.bcs->Flag);
+			break;
+	}
+}
+
+int
+setstack_amd7930(struct PStack *st, struct BCState *bcs)
+{
+	if (Bchan_open(bcs))
+		return (-1);
+	st->l1.bcs = bcs;
+	st->l2.l2l1 = Bchan_l2l1;
+	st->ma.manl1 = Bchan_manl1;
+	setstack_manager(st);
+	bcs->st = st;
+	return (0);
+}
+
+
+static void
+amd7930_drecv_callback(void *arg, int error, unsigned int count)
+{
+	struct IsdnCardState *cs = (struct IsdnCardState *) arg;
+	static struct tq_struct task;
+	struct sk_buff *skb;
+
+        /* NOTE: This function is called directly from an interrupt handler */
+
+	if (1) {
+		if (!(skb = alloc_skb(count, GFP_ATOMIC)))
+			printk(KERN_WARNING "HiSax: D receive out of memory\n");
+		else {
+			memcpy(skb_put(skb, count), cs->rcvbuf, count);
+			skb_queue_tail(&cs->rq, skb);
+		}
+
+		task.routine = (void *) DChannel_proc_rcv;
+		task.data = (void *) cs;
+		queue_task(&task, &tq_immediate);
+		mark_bh(IMMEDIATE_BH);
+	}
+
+	if (cs->debug & L1_DEB_ISAC_FIFO) {
+		char tmp[128];
+		char *t = tmp;
+
+		t += sprintf(t, "amd7930 Drecv cnt %d", count);
+		if (error) t += sprintf(t, " ERR %x", error);
+		QuickHex(t, cs->rcvbuf, count);
+		debugl1(cs, tmp);
+	}
+
+	amd7930_drecv(0, cs->rcvbuf, MAX_DFRAME_LEN,
+		      &amd7930_drecv_callback, cs);
+}
+
+static void
+amd7930_dxmit_callback(void *arg, int error)
+{
+	struct IsdnCardState *cs = (struct IsdnCardState *) arg;
+	static struct tq_struct task;
+
+        /* NOTE: This function is called directly from an interrupt handler */
+
+	/* may wish to do retransmission here, if error indicates collision */
+
+	if (cs->debug & L1_DEB_ISAC_FIFO) {
+		char tmp[128];
+		char *t = tmp;
+
+		t += sprintf(t, "amd7930 Dxmit cnt %d", cs->tx_skb->len);
+		if (error) t += sprintf(t, " ERR %x", error);
+		QuickHex(t, cs->tx_skb->data, cs->tx_skb->len);
+		debugl1(cs, tmp);
+	}
+
+	cs->tx_skb = NULL;
+
+	task.routine = (void *) DChannel_proc_xmt;
+	task.data = (void *) cs;
+	queue_task(&task, &tq_immediate);
+	mark_bh(IMMEDIATE_BH);
+}
+
+static void
+amd7930_Dchan_l2l1(struct PStack *st, int pr, void *arg)
+{
+	struct IsdnCardState *cs = (struct IsdnCardState *) st->l1.hardware;
+	struct sk_buff *skb = arg;
+	char str[64];
+
+	switch (pr) {
+		case (PH_DATA_REQ):
+			if (cs->tx_skb) {
+				skb_queue_tail(&cs->sq, skb);
+#ifdef L2FRAME_DEBUG		/* psa */
+				if (cs->debug & L1_DEB_LAPD)
+					Logl2Frame(cs, skb, "PH_DATA Queued", 0);
+#endif
+			} else {
+				if ((cs->dlogflag) && (!(skb->data[2] & 1))) {
+					/* I-FRAME */
+					LogFrame(cs, skb->data, skb->len);
+					sprintf(str, "Q.931 frame user->network tei %d", st->l2.tei);
+					dlogframe(cs, skb->data+4, skb->len-4,
+						  str);
+				}
+				cs->tx_skb = skb;
+				cs->tx_cnt = 0;
+#ifdef L2FRAME_DEBUG		/* psa */
+				if (cs->debug & L1_DEB_LAPD)
+					Logl2Frame(cs, skb, "PH_DATA", 0);
+#endif
+				amd7930_dxmit(0, skb->data, skb->len,
+					      &amd7930_dxmit_callback, cs);
+			}
+			break;
+		case (PH_PULL_IND):
+			if (cs->tx_skb) {
+				if (cs->debug & L1_DEB_WARN)
+					debugl1(cs, " l2l1 tx_skb exist this shouldn't happen");
+				skb_queue_tail(&cs->sq, skb);
+				break;
+			}
+			if ((cs->dlogflag) && (!(skb->data[2] & 1))) {	/* I-FRAME */
+				LogFrame(cs, skb->data, skb->len);
+				sprintf(str, "Q.931 frame user->network tei %d", st->l2.tei);
+				dlogframe(cs, skb->data + 4, skb->len - 4,
+					  str);
+			}
+			cs->tx_skb = skb;
+			cs->tx_cnt = 0;
+#ifdef L2FRAME_DEBUG		/* psa */
+			if (cs->debug & L1_DEB_LAPD)
+				Logl2Frame(cs, skb, "PH_DATA_PULLED", 0);
+#endif
+			amd7930_dxmit(0, cs->tx_skb->data, cs->tx_skb->len,
+				      &amd7930_dxmit_callback, cs);
+			break;
+		case (PH_PULL_REQ):
+#ifdef L2FRAME_DEBUG		/* psa */
+			if (cs->debug & L1_DEB_LAPD)
+				debugl1(cs, "-> PH_REQUEST_PULL");
+#endif
+			if (!cs->tx_skb) {
+				test_and_clear_bit(FLG_L1_PULL_REQ, &st->l1.Flags);
+				st->l1.l1l2(st, PH_PULL_CNF, NULL);
+			} else
+				test_and_set_bit(FLG_L1_PULL_REQ, &st->l1.Flags);
+			break;
+	}
+}
+
+int
+setDstack_amd7930(struct PStack *st, struct IsdnCardState *cs)
+{
+	st->l2.l2l1 = amd7930_Dchan_l2l1;
+	if (! cs->rcvbuf) {
+		printk("setDstack_amd7930: No cs->rcvbuf!\n");
+	} else {
+		amd7930_drecv(0, cs->rcvbuf, MAX_DFRAME_LEN,
+			      &amd7930_drecv_callback, cs);
+	}
+	return (0);
+}
+
+static void
+manl1_msg(struct IsdnCardState *cs, int msg, void *arg) {
+	struct PStack *st;
+
+	st = cs->stlist;
+	while (st) {
+		st->ma.manl1(st, msg, arg);
+		st = st->next;
+	}
+}
+
+static void
+amd7930_new_ph(struct IsdnCardState *cs)
+{
+	switch (amd7930_get_liu_state(0)) {
+	        case 3:
+			manl1_msg(cs, PH_POWERUP_CNF, NULL);
+                        break;
+
+	        case 7:
+			manl1_msg(cs, PH_I4_P8_IND, NULL);
+			break;
+
+	        case 8:
+			manl1_msg(cs, PH_RSYNC_IND, NULL);
+			break;
+	}
+}
+
+/* amd7930 LIU state change callback */
+
+static void
+amd7930_liu_callback(struct IsdnCardState *cs)
+{
+	static struct tq_struct task;
+
+	if (!cs)
+		return;
+
+	if (cs->debug & L1_DEB_ISAC) {
+		char tmp[32];
+		sprintf(tmp, "amd7930_liu state %d", amd7930_get_liu_state(0));
+		debugl1(cs, tmp);
+	}
+
+	task.sync = 0;
+	task.routine = (void *) &amd7930_new_ph;
+	task.data = (void *) cs;
+	queue_task(&task, &tq_immediate);
+	mark_bh(IMMEDIATE_BH);
+}
+
+void
+amd7930_l1cmd(struct IsdnCardState *cs, int msg, void *arg)
+{
+	u_char val;
+	char tmp[32];
+	
+	if (cs->debug & L1_DEB_ISAC) {
+		char tmp[32];
+		sprintf(tmp, "amd7930_l1cmd msg %x", msg);
+		debugl1(cs, tmp);
+	}
+
+	switch(msg) {
+		case PH_RESET_REQ:
+			if (amd7930_get_liu_state(0) <= 3)
+				amd7930_liu_activate(0,0);
+			else
+				amd7930_liu_deactivate(0);
+			break;
+		case PH_ENABLE_REQ:
+			break;
+		case PH_INFO3_REQ:
+			amd7930_liu_activate(0,0);
+			break;
+		case PH_TESTLOOP_REQ:
+			break;
+		default:
+			if (cs->debug & L1_DEB_WARN) {
+				sprintf(tmp, "amd7930_l1cmd unknown %4x", msg);
+				debugl1(cs, tmp);
+			}
+			break;
+	}
+}
+
+static void init_amd7930(struct IsdnCardState *cs)
+{
+	Bchan_init(&cs->bcs[0]);
+	Bchan_init(&cs->bcs[1]);
+	cs->bcs[0].BC_SetStack = setstack_amd7930;
+	cs->bcs[1].BC_SetStack = setstack_amd7930;
+	cs->bcs[0].BC_Close = Bchan_close;
+	cs->bcs[1].BC_Close = Bchan_close;
+	Bchan_mode(cs->bcs, 0, 0);
+	Bchan_mode(cs->bcs + 1, 0, 0);
+}
+
+void
+release_amd7930(struct IsdnCardState *cs)
+{
+}
+
+static int
+amd7930_card_msg(struct IsdnCardState *cs, int mt, void *arg)
+{
+	switch (mt) {
+		case CARD_RESET:
+			return(0);
+		case CARD_RELEASE:
+			release_amd7930(cs);
+			return(0);
+		case CARD_INIT:
+			cs->l1cmd = amd7930_l1cmd;
+			amd7930_liu_init(0, &amd7930_liu_callback, (void *)cs);
+			init_amd7930(cs);
+			return(0);
+		case CARD_TEST:
+			return(0);
+	}
+	return(0);
+}
+
+int __init
+setup_amd7930(struct IsdnCard *card)
+{
+	struct IsdnCardState *cs = card->cs;
+	char tmp[64];
+
+	strcpy(tmp, amd7930_revision);
+	printk(KERN_INFO "HiSax: AMD7930 driver Rev. %s\n", HiSax_getrev(tmp));
+	if (cs->typ != ISDN_CTYPE_AMD7930)
+		return (0);
+
+        cs->irq = amd7930_get_irqnum(0);
+        if (cs->irq == 0)
+		return (0);
+
+	cs->cardmsg = &amd7930_card_msg;
+
+	return (1);
+}
--- a/drivers/isdn/hisax/arcofi.c
+++ b/drivers/isdn/hisax/arcofi.c
@@ -1,4 +1,4 @@
-/* $Id: arcofi.c,v 1.1.4.1 2001/11/20 14:19:35 kai Exp $
+/* $Id: arcofi.c,v 1.14 2001/09/24 13:22:55 kai Exp $
  *
  * Ansteuerung ARCOFI 2165
  *
--- a/drivers/isdn/hisax/arcofi.h
+++ b/drivers/isdn/hisax/arcofi.h
@@ -1,4 +1,4 @@
-/* $Id: arcofi.h,v 1.1.4.1 2001/11/20 14:19:35 kai Exp $
+/* $Id$
  *
  * Ansteuerung ARCOFI 2165
  *
--- a/drivers/isdn/hisax/asuscom.c
+++ b/drivers/isdn/hisax/asuscom.c
@@ -1,4 +1,4 @@
-/* $Id: asuscom.c,v 1.1.4.1 2001/11/20 14:19:35 kai Exp $
+/* $Id: asuscom.c,v 1.14 2001/09/24 13:22:55 kai Exp $
  *
  * low level stuff for ASUSCOM NETWORK INC. ISDNLink cards
  *
@@ -14,7 +14,6 @@
 
 #define __NO_VERSION__
 #include <linux/init.h>
-#include <linux/isapnp.h>
 #include "hisax.h"
 #include "isac.h"
 #include "ipac.h"
@@ -23,7 +22,7 @@
 
 extern const char *CardType[];
 
-const char *Asuscom_revision = "$Revision: 1.1.4.1 $";
+const char *Asuscom_revision = "$Revision: 1.14 $";
 
 #define byteout(addr,val) outb(val,addr)
 #define bytein(addr) inb(addr)
@@ -310,27 +309,6 @@ Asus_card_msg(struct IsdnCardState *cs, 
 	return(0);
 }
 
-#ifdef __ISAPNP__
-static struct isapnp_device_id asus_ids[] __initdata = {
-	{ ISAPNP_VENDOR('A', 'S', 'U'), ISAPNP_FUNCTION(0x1688),
-	  ISAPNP_VENDOR('A', 'S', 'U'), ISAPNP_FUNCTION(0x1688), 
-	  (unsigned long) "Asus1688 PnP" },
-	{ ISAPNP_VENDOR('A', 'S', 'U'), ISAPNP_FUNCTION(0x1690),
-	  ISAPNP_VENDOR('A', 'S', 'U'), ISAPNP_FUNCTION(0x1690), 
-	  (unsigned long) "Asus1690 PnP" },
-	{ ISAPNP_VENDOR('S', 'I', 'E'), ISAPNP_FUNCTION(0x0020),
-	  ISAPNP_VENDOR('S', 'I', 'E'), ISAPNP_FUNCTION(0x0020), 
-	  (unsigned long) "Isurf2 PnP" },
-	{ ISAPNP_VENDOR('E', 'L', 'F'), ISAPNP_FUNCTION(0x0000),
-	  ISAPNP_VENDOR('E', 'L', 'F'), ISAPNP_FUNCTION(0x0000), 
-	  (unsigned long) "Iscas TE320" },
-	{ 0, }
-};
-
-static struct isapnp_device_id *adev = &asus_ids[0];
-static struct pci_bus *pnp_c __devinitdata = NULL;
-#endif
-
 int __init
 setup_asuscom(struct IsdnCard *card)
 {
@@ -343,45 +321,7 @@ setup_asuscom(struct IsdnCard *card)
 	printk(KERN_INFO "HiSax: Asuscom ISDNLink driver Rev. %s\n", HiSax_getrev(tmp));
 	if (cs->typ != ISDN_CTYPE_ASUSCOM)
 		return (0);
-#ifdef __ISAPNP__
-	if (!card->para[1] && isapnp_present()) {
-		struct pci_bus *pb;
-		struct pci_dev *pd;
-
-		while(adev->card_vendor) {
-			if ((pb = isapnp_find_card(adev->card_vendor,
-				adev->card_device, pnp_c))) {
-				pnp_c = pb;
-				pd = NULL;
-				if ((pd = isapnp_find_dev(pnp_c,
-					adev->vendor, adev->function, pd))) {
-					printk(KERN_INFO "HiSax: %s detected\n",
-						(char *)adev->driver_data);
-					pd->prepare(pd);
-					pd->deactivate(pd);
-					pd->activate(pd);
-					card->para[1] = pd->resource[0].start;
-					card->para[0] = pd->irq_resource[0].start;
-					if (!card->para[0] || !card->para[1]) {
-						printk(KERN_ERR "AsusPnP:some resources are missing %ld/%lx\n",
-						card->para[0], card->para[1]);
-						pd->deactivate(pd);
-						return(0);
-					}
-					break;
-				} else {
-					printk(KERN_ERR "AsusPnP: PnP error card found, no device\n");
-				}
-			}
-			adev++;
-			pnp_c=NULL;
-		} 
-		if (!adev->card_vendor) {
-			printk(KERN_INFO "AsusPnP: no ISAPnP card found\n");
-			return(0);
-		}
-	}
-#endif
+
 	bytecnt = 8;
 	cs->hw.asus.cfg_reg = card->para[1];
 	cs->irq = card->para[0];
--- a/drivers/isdn/hisax/avm_a1.c
+++ b/drivers/isdn/hisax/avm_a1.c
@@ -1,4 +1,4 @@
-/* $Id: avm_a1.c,v 1.1.4.1 2001/11/20 14:19:35 kai Exp $
+/* $Id: avm_a1.c,v 2.15 2001/09/24 13:22:55 kai Exp $
  *
  * low level stuff for AVM A1 (Fritz) isdn cards
  *
@@ -18,7 +18,7 @@
 #include "isdnl1.h"
 
 extern const char *CardType[];
-static const char *avm_revision = "$Revision: 1.1.4.1 $";
+static const char *avm_revision = "$Revision: 2.15 $";
 
 #define	 AVM_A1_STAT_ISAC	0x01
 #define	 AVM_A1_STAT_HSCX	0x02
--- a/drivers/isdn/hisax/avm_a1p.c
+++ b/drivers/isdn/hisax/avm_a1p.c
@@ -1,4 +1,4 @@
-/* $Id: avm_a1p.c,v 1.1.4.1 2001/11/20 14:19:35 kai Exp $
+/* $Id: avm_a1p.c,v 2.9 2001/09/24 13:22:55 kai Exp $
  *
  * low level stuff for the following AVM cards:
  * A1 PCMCIA
@@ -57,7 +57,7 @@
 #define byteout(addr,val) outb(val,addr)
 #define bytein(addr) inb(addr)
 
-static const char *avm_revision = "$Revision: 1.1.4.1 $";
+static const char *avm_revision = "$Revision: 2.9 $";
 
 static inline u_char
 ReadISAC(struct IsdnCardState *cs, u_char offset)
--- a/drivers/isdn/hisax/avm_pci.c
+++ b/drivers/isdn/hisax/avm_pci.c
@@ -1,4 +1,4 @@
-/* $Id: avm_pci.c,v 1.1.4.1 2001/11/20 14:19:35 kai Exp $
+/* $Id: avm_pci.c,v 1.29 2001/09/24 13:22:55 kai Exp $
  *
  * low level stuff for AVM Fritz!PCI and ISA PnP isdn cards
  *
@@ -19,11 +19,11 @@
 #include "isac.h"
 #include "isdnl1.h"
 #include <linux/pci.h>
-#include <linux/isapnp.h>
+#include <linux/isdn_compat.h>
 #include <linux/interrupt.h>
 
 extern const char *CardType[];
-static const char *avm_pci_rev = "$Revision: 1.1.4.1 $";
+static const char *avm_pci_rev = "$Revision: 1.29 $";
 
 #define  AVM_FRITZ_PCI		1
 #define  AVM_FRITZ_PNP		2
@@ -291,8 +291,7 @@ hdlc_empty_fifo(struct BCState *bcs, int
 			debugl1(cs, "hdlc_empty_fifo: incoming packet too large");
 		return;
 	}
-	p = bcs->hw.hdlc.rcvbuf + bcs->hw.hdlc.rcvidx;
-	ptr = (u_int *)p;
+	ptr = (u_int *) p = bcs->hw.hdlc.rcvbuf + bcs->hw.hdlc.rcvidx;
 	bcs->hw.hdlc.rcvidx += count;
 	if (cs->subtyp == AVM_FRITZ_PCI) {
 		outl(idx, cs->hw.avm.cfg_reg + 4);
@@ -353,8 +352,7 @@ hdlc_fill_fifo(struct BCState *bcs)
 	}
 	if ((cs->debug & L1_DEB_HSCX) && !(cs->debug & L1_DEB_HSCX_FIFO))
 		debugl1(cs, "hdlc_fill_fifo %d/%ld", count, bcs->tx_skb->len);
-	p = bcs->tx_skb->data;
-	ptr = (u_int *)p;
+	ptr = (u_int *) p = bcs->tx_skb->data;
 	skb_pull(bcs->tx_skb, count);
 	bcs->tx_cnt -= count;
 	bcs->hw.hdlc.count += count;
@@ -766,10 +764,6 @@ AVM_card_msg(struct IsdnCardState *cs, i
 }
 
 static struct pci_dev *dev_avm __initdata = NULL;
-#ifdef __ISAPNP__
-static struct pci_bus *bus_avm __initdata = NULL;
-static struct pci_dev *pnp_avm __initdata = NULL;
-#endif
 
 int __init
 setup_avm_pcipnp(struct IsdnCard *card)
@@ -783,47 +777,10 @@ setup_avm_pcipnp(struct IsdnCard *card)
 	if (cs->typ != ISDN_CTYPE_FRITZPCI)
 		return (0);
 	if (card->para[1]) {
-		/* old manual method */
 		cs->hw.avm.cfg_reg = card->para[1];
 		cs->irq = card->para[0];
 		cs->subtyp = AVM_FRITZ_PNP;
 	} else {
-#ifdef __ISAPNP__
-		if (isapnp_present()) {
-			struct pci_bus *ba;
-			if ((ba = isapnp_find_card(
-				ISAPNP_VENDOR('A', 'V', 'M'),
-				ISAPNP_FUNCTION(0x0900), bus_avm))) {
-				bus_avm = ba;
-				pnp_avm = NULL;
-				if ((pnp_avm = isapnp_find_dev(bus_avm,
-					ISAPNP_VENDOR('A', 'V', 'M'),
-					ISAPNP_FUNCTION(0x0900), pnp_avm))) {
-					pnp_avm->prepare(pnp_avm);
-					pnp_avm->deactivate(pnp_avm);
-					pnp_avm->activate(pnp_avm);
-					cs->hw.avm.cfg_reg =
-						pnp_avm->resource[0].start;
-					cs->irq = 
-						pnp_avm->irq_resource[0].start;
-					if (!cs->irq) {
-						printk(KERN_ERR "FritzPnP:No IRQ\n");
-						pnp_avm->deactivate(pnp_avm);
-						return(0);
-					}
-					if (!cs->hw.avm.cfg_reg) {
-						printk(KERN_ERR "FritzPnP:No IO address\n");
-						pnp_avm->deactivate(pnp_avm);
-						return(0);
-					}
-					cs->subtyp = AVM_FRITZ_PNP;
-					goto ready;
-				}
-			}
-		} else {
-			printk(KERN_INFO "FritzPnP: no ISA PnP present\n");
-		}
-#endif
 #if CONFIG_PCI
 		if (!pci_present()) {
 			printk(KERN_ERR "FritzPCI: no PCI bus present\n");
@@ -838,7 +795,7 @@ setup_avm_pcipnp(struct IsdnCard *card)
 			}
 			if (pci_enable_device(dev_avm))
 				return(0);
-			cs->hw.avm.cfg_reg = pci_resource_start(dev_avm, 1);
+			cs->hw.avm.cfg_reg = pci_resource_start_io(dev_avm, 1);
 			if (!cs->hw.avm.cfg_reg) {
 				printk(KERN_ERR "FritzPCI: No IO-Adr for PCI card found\n");
 				return(0);
@@ -854,7 +811,6 @@ setup_avm_pcipnp(struct IsdnCard *card)
 		return (0);
 #endif /* CONFIG_PCI */
 	}
-ready:
 	cs->hw.avm.isac = cs->hw.avm.cfg_reg + 0x10;
 	if (check_region((cs->hw.avm.cfg_reg), 32)) {
 		printk(KERN_WARNING
--- a/drivers/isdn/hisax/bkm_a4t.c
+++ b/drivers/isdn/hisax/bkm_a4t.c
@@ -1,4 +1,4 @@
-/* $Id: bkm_a4t.c,v 1.1.4.1 2001/11/20 14:19:35 kai Exp $
+/* $Id: bkm_a4t.c,v 1.22 2001/09/24 13:22:55 kai Exp $
  *
  * low level stuff for T-Berkom A4T
  *
@@ -20,11 +20,12 @@
 #include "jade.h"
 #include "isdnl1.h"
 #include <linux/pci.h>
+#include <linux/isdn_compat.h>
 #include "bkm_ax.h"
 
 extern const char *CardType[];
 
-const char *bkm_a4t_revision = "$Revision: 1.1.4.1 $";
+const char *bkm_a4t_revision = "$Revision: 1.22 $";
 
 
 static inline u_char
@@ -293,13 +294,13 @@ setup_bkm_a4t(struct IsdnCard *card)
 		u16 sub_sys;
 		u16 sub_vendor;
 
-		sub_vendor = dev_a4t->subsystem_vendor;
-		sub_sys = dev_a4t->subsystem_device;
+		pci_get_sub_vendor(dev_a4t,sub_vendor);
+		pci_get_sub_system(dev_a4t,sub_sys);
 		if ((sub_sys == PCI_DEVICE_ID_BERKOM_A4T) && (sub_vendor == PCI_VENDOR_ID_BERKOM)) {
 			if (pci_enable_device(dev_a4t))
 				return(0);
 			found = 1;
-			pci_memaddr = pci_resource_start(dev_a4t, 0);
+			pci_memaddr = pci_resource_start_mem(dev_a4t, 0);
 			cs->irq = dev_a4t->irq;
 			break;
 		}
--- a/drivers/isdn/hisax/bkm_a8.c
+++ b/drivers/isdn/hisax/bkm_a8.c
@@ -1,4 +1,4 @@
-/* $Id: bkm_a8.c,v 1.1.4.1 2001/11/20 14:19:35 kai Exp $
+/* $Id: bkm_a8.c,v 1.22 2001/09/24 13:22:55 kai Exp $
  *
  * low level stuff for Scitel Quadro (4*S0, passive)
  *
@@ -20,6 +20,7 @@
 #include "hscx.h"
 #include "isdnl1.h"
 #include <linux/pci.h>
+#include <linux/isdn_compat.h>
 #include "bkm_ax.h"
 
 #if CONFIG_PCI
@@ -28,7 +29,7 @@
 
 extern const char *CardType[];
 
-const char sct_quadro_revision[] = "$Revision: 1.1.4.1 $";
+const char sct_quadro_revision[] = "$Revision: 1.22 $";
 
 static const char *sct_quadro_subtypes[] =
 {
@@ -329,13 +330,13 @@ setup_sct_quadro(struct IsdnCard *card)
 		while ((dev_a8 = pci_find_device(PCI_VENDOR_ID_PLX,
 			PCI_DEVICE_ID_PLX_9050, dev_a8))) {
 			
-			sub_vendor_id = dev_a8->subsystem_vendor;
-			sub_sys_id = dev_a8->subsystem_device;
+			pci_get_sub_vendor(dev_a8,sub_vendor_id);
+			pci_get_sub_system(dev_a8,sub_sys_id);
 			if ((sub_sys_id == PCI_DEVICE_ID_BERKOM_SCITEL_QUADRO) &&
 				(sub_vendor_id == PCI_VENDOR_ID_BERKOM)) {
 				if (pci_enable_device(dev_a8))
 					return(0);
-				pci_ioaddr1 = pci_resource_start(dev_a8, 1);
+				pci_ioaddr1 = pci_resource_start_io(dev_a8, 1);
 				pci_irq = dev_a8->irq;
 				pci_bus = dev_a8->bus->number;
 				pci_device_fn = dev_a8->devfn;
@@ -365,7 +366,7 @@ setup_sct_quadro(struct IsdnCard *card)
 			pci_ioaddr1 &= PCI_BASE_ADDRESS_IO_MASK;
 			pcibios_write_config_dword(pci_bus, pci_device_fn,
 				PCI_BASE_ADDRESS_1, pci_ioaddr1);
-			dev_a8->resource[ 1].start = pci_ioaddr1;
+			get_pcibase(dev_a8, 1) = pci_ioaddr1;
 		}
 #endif /* End HACK */
 	}
--- a/drivers/isdn/hisax/bkm_ax.h
+++ b/drivers/isdn/hisax/bkm_ax.h
@@ -1,4 +1,4 @@
-/* $Id: bkm_ax.h,v 1.1.4.1 2001/11/20 14:19:35 kai Exp $
+/* $Id$
  *
  * low level decls for T-Berkom cards A4T and Scitel Quadro (4*S0, passive)
  *
--- a/drivers/isdn/hisax/callc.c
+++ b/drivers/isdn/hisax/callc.c
@@ -1,4 +1,4 @@
-/* $Id: callc.c,v 1.1.4.1 2001/11/20 14:19:35 kai Exp $
+/* $Id: callc.c,v 2.59 2002/02/09 21:19:11 keil Exp $
  *
  * Author       Karsten Keil
  * Copyright    by Karsten Keil      <keil@isdn4linux.de>
@@ -26,7 +26,7 @@
 #define MOD_USE_COUNT ( GET_USE_COUNT (&__this_module))
 #endif	/* MODULE */
 
-const char *lli_revision = "$Revision: 1.1.4.1 $";
+const char *lli_revision = "$Revision: 2.59 $";
 
 extern struct IsdnCard cards[];
 extern int nrcards;
@@ -145,9 +145,11 @@ enum {
 	EV_PROCEED,		/* 20 */
 	EV_ALERT,		/* 21 */ 
 	EV_REDIR,		/* 22 */ 
+	EV_ALERTING,		/* 23 */
+	EV_PROCEEDING,		/* 24 */
 };
 
-#define EVENT_COUNT (EV_REDIR + 1)
+#define EVENT_COUNT (EV_PROCEEDING + 1)
 
 static char *strEvent[] =
 {
@@ -174,6 +176,8 @@ static char *strEvent[] =
 	"EV_PROCEED",
 	"EV_ALERT",
 	"EV_REDIR",
+	"EV_ALERTING",
+	"EV_PROCEEDING",
 };
 
 
@@ -286,6 +290,22 @@ lli_prep_dialout(struct FsmInst *fi, int
 }
 
 static void
+lli_alerting(struct FsmInst *fi, int event, void *arg)
+{
+	struct Channel *chanp = fi->userdata;
+	
+	HL_LL(chanp, ISDN_STAT_ALERT);
+}
+
+static void
+lli_proceeding(struct FsmInst *fi, int event, void *arg)
+{
+	struct Channel *chanp = fi->userdata;
+	
+	HL_LL(chanp, ISDN_STAT_PROCEED);
+}
+
+static void
 lli_resume(struct FsmInst *fi, int event, void *arg)
 {
 	struct Channel *chanp = fi->userdata;
@@ -784,6 +804,8 @@ static struct FsmNode fnlist[] __initdat
         {ST_OUT_DIAL,           EV_DISCONNECT_IND,      lli_release_req},
         {ST_OUT_DIAL,           EV_RELEASE,             lli_dhup_close},
         {ST_OUT_DIAL,           EV_NOSETUP_RSP,         lli_no_setup_rsp},
+        {ST_OUT_DIAL,           EV_PROCEEDING,		lli_proceeding},
+        {ST_OUT_DIAL,           EV_ALERTING,		lli_alerting},
         {ST_OUT_DIAL,           EV_SETUP_ERR,           lli_error},
         {ST_IN_WAIT_LL,         EV_LEASED_REL,          lli_failure_l},
         {ST_IN_WAIT_LL,         EV_ACCEPTD,             lli_setup_rsp},
@@ -925,7 +947,7 @@ static void stat_redir_result(struct Isd
 	ic.driver = cs->myid;
 	ic.command = ISDN_STAT_REDIR;
 	ic.arg = chan; 
-	ic.parm.num[0] = result;
+	(ulong)(ic.parm.num[0]) = result;
 	cs->iif.statcallb(&ic);
 } /* stat_redir_result */
 
@@ -997,8 +1019,13 @@ dchan_l3l4(struct PStack *st, int pr, vo
 			FsmEvent(&chanp->fi, EV_RELEASE, NULL);
 			break;
 		case (CC_PROCEED_SEND | INDICATION):
+			break;
 		case (CC_PROCEEDING | INDICATION):
+			FsmEvent(&chanp->fi, EV_PROCEEDING, NULL);
+			break;
 		case (CC_ALERTING | INDICATION):
+			FsmEvent(&chanp->fi, EV_ALERTING, NULL);
+			break;
 		case (CC_PROGRESS | INDICATION):
 		case (CC_NOTIFY | INDICATION):
 			break;
--- a/drivers/isdn/hisax/cert.c
+++ b/drivers/isdn/hisax/cert.c
@@ -1,4 +1,4 @@
-/* $Id: cert.c,v 1.1.4.1 2001/11/20 14:19:35 kai Exp $
+/* $Id: cert.c,v 2.6 2001/09/24 13:22:56 kai Exp $
  *
  * Author       Karsten Keil
  * Copyright    by Karsten Keil      <keil@isdn4linux.de>
--- a/drivers/isdn/hisax/config.c
+++ b/drivers/isdn/hisax/config.c
@@ -1,4 +1,4 @@
-/* $Id: config.c,v 1.1.4.5 2001/12/09 19:19:26 kai Exp $
+/* $Id: config.c,v 2.84 2002/08/13 09:55:29 keil Exp $
  *
  * Author       Karsten Keil
  * Copyright    by Karsten Keil      <keil@isdn4linux.de>
@@ -24,6 +24,11 @@
 #include <linux/kernel_stat.h>
 #include <linux/tqueue.h>
 #include <linux/interrupt.h>
+
+#ifdef CONFIG_HISAX_HFC_USB
+#include "hisax_loadable.h"
+#endif
+
 #define HISAX_STATUS_BUFSIZE 4096
 #define INCLUDE_INLINE_FUNCS
 
@@ -75,8 +80,7 @@
  *   37 HFC 2BDS0 S+/SP         p0=irq p1=iobase
  *   38 Travers Technologies NETspider-U PCI card
  *   39 HFC 2BDS0-SP PCMCIA     p0=irq p1=iobase
- *   40 hotplug interface
- *   41 Formula-n enter:now ISDN PCI a/b   none
+ *   40 HFC-S USB               none
  *
  * protocol can be either ISDN_PTYPE_EURO or ISDN_PTYPE_1TR6 or ISDN_PTYPE_NI1
  *
@@ -95,11 +99,17 @@ const char *CardType[] = {
 	"Siemens I-Surf", "Acer P10", "HST Saphir", "Telekom A4T",
 	"Scitel Quadro", "Gazel", "HFC 2BDS0 PCI", "Winbond 6692",
 	"HFC 2BDS0 SX", "NETspider-U", "HFC-2BDS0-SP PCMCIA",
-	"Hotplug", "Formula-n enter:now PCI a/b", 
+	"HFC-S USB",
 };
 
 void HiSax_closecard(int cardnr);
 
+#ifdef CONFIG_HISAX_HFC_USB
+#define DEFAULT_CARD ISDN_CTYPE_HFC_USB
+#define DEFAULT_CFG {0,0,0,0}
+EXPORT_SYMBOL(hisax_register_hfcusb);
+#endif
+
 #ifdef CONFIG_HISAX_ELSA
 #define DEFAULT_CARD ISDN_CTYPE_ELSA
 #define DEFAULT_CFG {0,0,0,0}
@@ -339,19 +349,27 @@ EXPORT_SYMBOL(HiSax_closecard);
 	NULL, \
 }
 
-struct IsdnCard cards[HISAX_MAX_CARDS] = {
+#define EMPTY_CARD	{0, DEFAULT_PROTO, {0, 0, 0, 0}, NULL}
+
+struct IsdnCard cards[] = {
 	FIRST_CARD,
+	EMPTY_CARD,
+	EMPTY_CARD,
+	EMPTY_CARD,
+	EMPTY_CARD,
+	EMPTY_CARD,
+	EMPTY_CARD,
+	EMPTY_CARD,
 };
 
-#define HISAX_IDSIZE (HISAX_MAX_CARDS*8)
-static char HiSaxID[HISAX_IDSIZE] __devinitdata = { 0, };
+static char HiSaxID[64] __devinitdata = { 0, };
 
 char *HiSax_id __devinitdata = HiSaxID;
 #ifdef MODULE
 /* Variables for insmod */
-static int type[HISAX_MAX_CARDS] __devinitdata = { 0, };
-static int protocol[HISAX_MAX_CARDS] __devinitdata = { 0, };
-static int io[HISAX_MAX_CARDS] __devinitdata = { 0, };
+static int type[8] __devinitdata = { 0, };
+static int protocol[8] __devinitdata = { 0, };
+static int io[8] __devinitdata = { 0, };
 #undef IO0_IO1
 #ifdef CONFIG_HISAX_16_3
 #define IO0_IO1
@@ -361,27 +379,23 @@ static int io[HISAX_MAX_CARDS] __devinit
 #define IO0_IO1
 #endif
 #ifdef IO0_IO1
-static int io0[HISAX_MAX_CARDS] __devinitdata = { 0, };
-static int io1[HISAX_MAX_CARDS] __devinitdata = { 0, };
+static int io0[8] __devinitdata = { 0, };
+static int io1[8] __devinitdata = { 0, };
 #endif
-static int irq[HISAX_MAX_CARDS] __devinitdata = { 0, };
-static int mem[HISAX_MAX_CARDS] __devinitdata = { 0, };
+static int irq[8] __devinitdata = { 0, };
+static int mem[8] __devinitdata = { 0, };
 static char *id __devinitdata = HiSaxID;
 
-#define PARM_PARA "1-" __MODULE_STRING(HISAX_MAX_CARDS) "i"
-
-MODULE_DESCRIPTION("ISDN4Linux: Driver for passive ISDN cards");
 MODULE_AUTHOR("Karsten Keil");
-MODULE_LICENSE("GPL");
-MODULE_PARM(type, PARM_PARA);
-MODULE_PARM(protocol, PARM_PARA);
-MODULE_PARM(io, PARM_PARA);
-MODULE_PARM(irq, PARM_PARA);
-MODULE_PARM(mem, PARM_PARA);
+MODULE_PARM(type, "1-8i");
+MODULE_PARM(protocol, "1-8i");
+MODULE_PARM(io, "1-8i");
+MODULE_PARM(irq, "1-8i");
+MODULE_PARM(mem, "1-8i");
 MODULE_PARM(id, "s");
 #ifdef IO0_IO1
-MODULE_PARM(io0, PARM_PARA);
-MODULE_PARM(io1, PARM_PARA);
+MODULE_PARM(io0, "1-8i");
+MODULE_PARM(io1, "1-8i");
 #endif
 #endif /* MODULE */
 
@@ -432,6 +446,7 @@ void __init HiSaxVersion(void)
 }
 
 #ifndef MODULE
+#ifdef COMPAT_HAS_NEW_SETUP
 #define MAX_ARG	(HISAX_MAX_CARDS*5)
 static int __init HiSax_setup(char *line)
 {
@@ -440,12 +455,16 @@ static int __init HiSax_setup(char *line
 	char *str;
 
 	str = get_options(line, MAX_ARG, ints);
+#else
+void __init HiSax_setup(char *str, int *ints)
+{
+	int i, j, argc;
+#endif
 	argc = ints[0];
 	printk(KERN_DEBUG "HiSax_setup: argc(%d) str(%s)\n", argc, str);
 	i = 0;
 	j = 1;
 	while (argc && (i < HISAX_MAX_CARDS)) {
-		cards[i].protocol = DEFAULT_PROTO;
 		if (argc) {
 			cards[i].typ = ints[j];
 			j++;
@@ -473,19 +492,21 @@ static int __init HiSax_setup(char *line
 		}
 		i++;
 	}
-  	if (str && *str) {
-		if (strlen(str) < HISAX_IDSIZE)
-			strcpy(HiSaxID, str);
-		else
-			printk(KERN_WARNING "HiSax: ID too long!");
-	} else
+	if (str && *str) {
+		strcpy(HiSaxID, str);
+		HiSax_id = HiSaxID;
+	} else {
 		strcpy(HiSaxID, "HiSax");
-
-	HiSax_id = HiSaxID;
+		HiSax_id = HiSaxID;
+	}
+#ifdef COMPAT_HAS_NEW_SETUP
 	return 1;
 }
 
 __setup("hisax=", HiSax_setup);
+#else
+}
+#endif /* COMPAT_HAS_NEW_SETUP */
 #endif /* MODULES */
 
 #if CARD_TELES0
@@ -560,6 +581,10 @@ extern int setup_hfcs(struct IsdnCard *c
 extern int setup_hfcpci(struct IsdnCard *card);
 #endif
 
+#if CONFIG_HISAX_HFC_USB
+extern int setup_hfc_usb(struct IsdnCard *card);
+#endif
+
 #if CARD_HFC_SX
 extern int setup_hfcsx(struct IsdnCard *card);
 #endif
@@ -604,10 +629,6 @@ extern int setup_w6692(struct IsdnCard *
 extern int setup_netjet_u(struct IsdnCard *card);
 #endif
 
-#if CARD_FN_ENTERNOW_PCI
-extern int setup_enternow_pci(struct IsdnCard *card);
-#endif
-
 /*
  * Find card with given driverId
  */
@@ -899,7 +920,8 @@ static int __devinit init_card(struct Is
 	return 3;
 }
 
-static int __devinit checkcard(int cardnr, char *id, int *busy_flag)
+static int __devinit checkcard(int cardnr, char *id, int *busy_flag,
+			       void *load_drv)
 {
 	long flags;
 	int ret = 0;
@@ -1093,6 +1115,12 @@ static int __devinit checkcard(int cardn
 		ret = setup_hfcsx(card);
 		break;
 #endif
+#if CONFIG_HISAX_HFC_USB
+	case ISDN_CTYPE_HFC_USB:
+		cs->hw.hfcusb.drv = load_drv;
+		ret = setup_hfc_usb(card);
+		break;
+#endif
 #if CARD_NICCY
 	case ISDN_CTYPE_NICCY:
 		ret = setup_niccy(card);
@@ -1143,11 +1171,6 @@ static int __devinit checkcard(int cardn
 		ret = setup_netjet_u(card);
 		break;
 #endif
-#if CARD_FN_ENTERNOW_PCI
-	case ISDN_CTYPE_ENTERNOW:
-		ret = setup_enternow_pci(card);
-		break;
-#endif
 	case ISDN_CTYPE_DYNAMIC:
 		ret = 2;
 		break;
@@ -1186,6 +1209,9 @@ static int __devinit checkcard(int cardn
 	case ISDN_CTYPE_DYNAMIC:
 		ret = 0;
 		break;
+	case ISDN_CTYPE_HFC_USB:
+		ret = cs->cardmsg(cs, CARD_INIT, NULL);
+		break;
 	default:
 		ret = init_card(cs);
 		break;
@@ -1257,16 +1283,13 @@ int __devinit HiSax_inithardware(int *bu
 			else
 				sprintf(ids, "%s%d", id, i);
 		}
-		if (checkcard(i, ids, busy_flag)) {
+		if (checkcard(i, ids, busy_flag, NULL)) {
 			foundcards++;
 			i++;
 		} else {
-			/* make sure we don't oops the module */
-			if (cards[i].typ > 0 && cards[i].typ <= ISDN_CTYPE_COUNT) {
-				printk(KERN_WARNING
-			       		"HiSax: Card %s not installed !\n",
-			       		CardType[cards[i].typ]);
-			}
+			printk(KERN_WARNING
+			       "HiSax: Card %s not installed !\n",
+			       CardType[cards[i].typ]);
 			HiSax_shiftcards(i);
 			nrcards--;
 		}
@@ -1342,6 +1365,49 @@ void HiSax_reportcard(int cardnr, int se
 #endif
 }
 
+#ifdef CONFIG_HISAX_HFC_USB
+int
+hisax_register_hfcusb(struct hisax_drvreg *l1drv)
+{
+	int i;
+	char ids[30];
+
+	if (l1drv->version != HISAX_LOAD_VERSION)
+		return 1;
+
+	switch (l1drv->cmd) {
+	case HISAX_LOAD_CHKVER:
+		break;	/* success */
+
+	case HISAX_LOAD_REGISTER:
+		for (i = 0; i < HISAX_MAX_CARDS; i++) {
+			if (!cards[i].typ)
+				break;
+		}
+		if (i >= HISAX_MAX_CARDS)
+			return 1;	/* no space */
+		cards[i].typ = ISDN_CTYPE_HFC_USB;	/* setup type */
+		cards[i].protocol = DEFAULT_PROTO;
+		sprintf(ids, "%s%d", l1drv->drvname, i);
+		if (checkcard(i, ids, NULL, (void *) l1drv)) {
+			nrcards++;
+			return 0;
+		}
+		if (cards[i].cs)
+			kfree((void *) cards[i].cs);
+		cards[i].cs = NULL;
+		cards[i].typ = 0;	/* no card present */
+		return 1;
+		break;
+
+	default:
+		return 1;	/* unknown command */
+	}
+
+	return 0;
+}				/* hisax_register_hfcusb */
+#endif
+
 static int __init HiSax_init(void)
 {
 	int i, retval;
@@ -1408,8 +1474,6 @@ static int __init HiSax_init(void)
 		if (protocol[i]) {
 			cards[j].protocol = protocol[i];
 			nzproto++;
-		} else {
-			cards[j].protocol = DEFAULT_PROTO;
 		}
 		switch (type[i]) {
 		case ISDN_CTYPE_16_0:
@@ -1487,22 +1551,15 @@ static int __init HiSax_init(void)
 			} else {
 				/* QUADRO is a 4 BRI card */
 				cards[j++].para[0] = 1;
-				/* we need to check if further cards can be added */
-				if (j < HISAX_MAX_CARDS) {
-					cards[j].typ = ISDN_CTYPE_SCT_QUADRO;
-					cards[j].protocol = protocol[i];
-					cards[j++].para[0] = 2;
-				}
-				if (j < HISAX_MAX_CARDS) {
-					cards[j].typ = ISDN_CTYPE_SCT_QUADRO;
-					cards[j].protocol = protocol[i];
-					cards[j++].para[0] = 3;
-				}
-				if (j < HISAX_MAX_CARDS) {
-					cards[j].typ = ISDN_CTYPE_SCT_QUADRO;
-					cards[j].protocol = protocol[i];
-					cards[j].para[0] = 4;
-				}
+				cards[j].typ = ISDN_CTYPE_SCT_QUADRO;
+				cards[j].protocol = protocol[i];
+				cards[j++].para[0] = 2;
+				cards[j].typ = ISDN_CTYPE_SCT_QUADRO;
+				cards[j].protocol = protocol[i];
+				cards[j++].para[0] = 3;
+				cards[j].typ = ISDN_CTYPE_SCT_QUADRO;
+				cards[j].protocol = protocol[i];
+				cards[j].para[0] = 4;
 			}
 			break;
 		}
@@ -1526,10 +1583,15 @@ static int __init HiSax_init(void)
 	       nrcards, (nrcards > 1) ? "s" : "");
 
 	/* Install only, if at least one card found */
-	if (!HiSax_inithardware(NULL))
-		return -ENODEV;
+	if (!HiSax_inithardware(NULL)) {
+		retval = -EIO;
+		goto out_isdnl1;
+	}
+
 	return 0;
 
+ out_isdnl1:
+	Isdnl1Free();
  out_tei:
 	TeiFree();
  out_isdnl2:
@@ -1576,8 +1638,6 @@ int elsa_init_pcmcia(void *pcm_iob, int 
 		cards[i].typ = type[i];
 		if (protocol[i]) {
 			cards[i].protocol = protocol[i];
-		} else {
-			cards[i].protocol = DEFAULT_PROTO;
 		}
 	}
 	cards[0].para[0] = pcm_irq;
@@ -1595,8 +1655,7 @@ int elsa_init_pcmcia(void *pcm_iob, int 
 	printk(KERN_DEBUG "HiSax: Total %d card%s defined\n",
 	       nrcards, (nrcards > 1) ? "s" : "");
 
-	if (!HiSax_inithardware(busy_flag))
-		return -ENODEV;
+	HiSax_inithardware(busy_flag);
 	printk(KERN_NOTICE "HiSax: module installed\n");
 #endif
 	return 0;
@@ -1619,8 +1678,6 @@ int hfc_init_pcmcia(void *pcm_iob, int p
 		cards[i].typ = type[i];
 		if (protocol[i]) {
 			cards[i].protocol = protocol[i];
-		} else {
-			cards[i].protocol = DEFAULT_PROTO;
 		}
 	}
 	cards[0].para[0] = pcm_irq;
@@ -1638,8 +1695,7 @@ int hfc_init_pcmcia(void *pcm_iob, int p
 	printk(KERN_DEBUG "HiSax: Total %d card%s defined\n",
 	       nrcards, (nrcards > 1) ? "s" : "");
 
-	if (!HiSax_inithardware(busy_flag))
-		return -ENODEV;
+	HiSax_inithardware(busy_flag);
 	printk(KERN_NOTICE "HiSax: module installed\n");
 #endif
 	return 0;
@@ -1662,8 +1718,6 @@ int sedl_init_pcmcia(void *pcm_iob, int 
 		cards[i].typ = type[i];
 		if (protocol[i]) {
 			cards[i].protocol = protocol[i];
-		} else {
-			cards[i].protocol = DEFAULT_PROTO;
 		}
 	}
 	cards[0].para[0] = pcm_irq;
@@ -1681,8 +1735,7 @@ int sedl_init_pcmcia(void *pcm_iob, int 
 	printk(KERN_DEBUG "HiSax: Total %d card%s defined\n",
 	       nrcards, (nrcards > 1) ? "s" : "");
 
-	if (!HiSax_inithardware(busy_flag))
-		return -ENODEV;
+	HiSax_inithardware(busy_flag);
 	printk(KERN_NOTICE "HiSax: module installed\n");
 #endif
 	return 0;
@@ -1705,8 +1758,6 @@ int avm_a1_init_pcmcia(void *pcm_iob, in
 		cards[i].typ = type[i];
 		if (protocol[i]) {
 			cards[i].protocol = protocol[i];
-		} else {
-			cards[i].protocol = DEFAULT_PROTO;
 		}
 	}
 	cards[0].para[0] = pcm_irq;
@@ -1724,8 +1775,7 @@ int avm_a1_init_pcmcia(void *pcm_iob, in
 	printk(KERN_DEBUG "HiSax: Total %d card%s defined\n",
 	       nrcards, (nrcards > 1) ? "s" : "");
 
-	if (!HiSax_inithardware(busy_flag))
-		return -ENODEV;
+	HiSax_inithardware(busy_flag);
 	printk(KERN_NOTICE "HiSax: module installed\n");
 #endif
 	return 0;
@@ -1743,7 +1793,7 @@ int __devinit hisax_init_pcmcia(void *pc
 		sprintf(ids, "HiSax%d", nrcards);
 	else
 		sprintf(ids, "HiSax");
-	if (!checkcard(nrcards, ids, busy_flag)) {
+	if (!checkcard(nrcards, ids, busy_flag, NULL)) {
 		return -1;
 	}
 	ret = nrcards;
@@ -1785,7 +1835,7 @@ int hisax_register(struct hisax_d_if *hi
 	cards[i].protocol = protocol;
 	sprintf(id, "%s%d", name, i);
 	nrcards++;
-	retval = checkcard(i, id, 0);
+	retval = checkcard(i, id, 0, NULL);
 	if (retval == 0) { // yuck
 		cards[i].typ = 0;
 		nrcards--;
@@ -2117,9 +2167,6 @@ static struct pci_device_id hisax_pci_tb
 	{PCI_VENDOR_ID_EICON,    PCI_DEVICE_ID_EICON_DIVA20,     PCI_ANY_ID, PCI_ANY_ID},
 	{PCI_VENDOR_ID_EICON,    PCI_DEVICE_ID_EICON_DIVA20_U,   PCI_ANY_ID, PCI_ANY_ID},
 	{PCI_VENDOR_ID_EICON,    PCI_DEVICE_ID_EICON_DIVA201,    PCI_ANY_ID, PCI_ANY_ID},
-//#########################################################################################	
-	{PCI_VENDOR_ID_EICON,    PCI_DEVICE_ID_EICON_DIVA202,    PCI_ANY_ID, PCI_ANY_ID},
-//#########################################################################################	
 #endif
 #ifdef CONFIG_HISAX_ELSA
 	{PCI_VENDOR_ID_ELSA,     PCI_DEVICE_ID_ELSA_MICROLINK,   PCI_ANY_ID, PCI_ANY_ID},
@@ -2178,11 +2225,3 @@ MODULE_DEVICE_TABLE(pci, hisax_pci_tbl);
 
 module_init(HiSax_init);
 module_exit(HiSax_exit);
-
-EXPORT_SYMBOL(FsmNew);
-EXPORT_SYMBOL(FsmFree);
-EXPORT_SYMBOL(FsmEvent);
-EXPORT_SYMBOL(FsmChangeState);
-EXPORT_SYMBOL(FsmInitTimer);
-EXPORT_SYMBOL(FsmDelTimer);
-EXPORT_SYMBOL(FsmRestartTimer);
--- a/drivers/isdn/hisax/diva.c
+++ b/drivers/isdn/hisax/diva.c
@@ -1,4 +1,4 @@
-/* $Id: diva.c,v 1.1.4.2 2002/08/30 11:21:00 keil Exp $
+/* $Id: diva.c,v 1.33 2001/09/24 13:22:56 kai Exp $
  *
  * low level stuff for Eicon.Diehl Diva Family ISDN cards
  *
@@ -22,14 +22,13 @@
 #include "isac.h"
 #include "hscx.h"
 #include "ipac.h"
-#include "ipacx.h"
 #include "isdnl1.h"
 #include <linux/pci.h>
-#include <linux/isapnp.h>
+#include <linux/isdn_compat.h>
 
 extern const char *CardType[];
 
-const char *Diva_revision = "$Revision: 1.1.4.2 $";
+const char *Diva_revision = "$Revision: 1.33 $";
 
 #define byteout(addr,val) outb(val,addr)
 #define bytein(addr) inb(addr)
@@ -51,7 +50,6 @@ const char *Diva_revision = "$Revision: 
 #define DIVA_PCI	2
 #define DIVA_IPAC_ISA	3
 #define DIVA_IPAC_PCI	4
-#define DIVA_IPACX_PCI	5
 
 /* CTRL (Read) */
 #define DIVA_IRQ_STAT	0x01
@@ -71,12 +69,10 @@ const char *Diva_revision = "$Revision: 
 #define PITA_MISC_REG		0x1c
 #ifdef __BIG_ENDIAN
 #define PITA_PARA_SOFTRESET	0x00000001
-#define PITA_SER_SOFTRESET	0x00000002
 #define PITA_PARA_MPX_MODE	0x00000004
 #define PITA_INT0_ENABLE	0x00000200
 #else
 #define PITA_PARA_SOFTRESET	0x01000000
-#define PITA_SER_SOFTRESET	0x02000000
 #define PITA_PARA_MPX_MODE	0x04000000
 #define PITA_INT0_ENABLE	0x00020000
 #endif
@@ -244,47 +240,6 @@ MemWriteHSCX(struct IsdnCardState *cs, i
 	memwritereg(cs->hw.diva.cfg_reg, offset + (hscx ? 0x40 : 0), value);
 }
 
-/* IO-Functions for IPACX type cards */
-static u_char
-MemReadISAC_IPACX(struct IsdnCardState *cs, u_char offset)
-{
-	return (memreadreg(cs->hw.diva.cfg_reg, offset));
-}
-
-static void
-MemWriteISAC_IPACX(struct IsdnCardState *cs, u_char offset, u_char value)
-{
-	memwritereg(cs->hw.diva.cfg_reg, offset, value);
-}
-
-static void
-MemReadISACfifo_IPACX(struct IsdnCardState *cs, u_char * data, int size)
-{
-	while(size--)
-		*data++ = memreadreg(cs->hw.diva.cfg_reg, 0);
-}
-
-static void
-MemWriteISACfifo_IPACX(struct IsdnCardState *cs, u_char * data, int size)
-{
-	while(size--)
-		memwritereg(cs->hw.diva.cfg_reg, 0, *data++);
-}
-
-static u_char
-MemReadHSCX_IPACX(struct IsdnCardState *cs, int hscx, u_char offset)
-{
-	return(memreadreg(cs->hw.diva.cfg_reg, offset + 
-                    (hscx ? IPACX_OFF_B2 : IPACX_OFF_B1)));
-}
-
-static void
-MemWriteHSCX_IPACX(struct IsdnCardState *cs, int hscx, u_char offset, u_char value)
-{
-	memwritereg(cs->hw.diva.cfg_reg, offset + 
-              (hscx ? IPACX_OFF_B2 : IPACX_OFF_B1), value);
-}
-
 /*
  * fast interrupt HSCX stuff goes here
  */
@@ -595,7 +550,7 @@ Memhscx_int_main(struct IsdnCardState *c
 	u_char exval;
 	struct BCState *bcs;
 
-	if (val & 0x01) { // EXB
+	if (val & 0x01) {
 		bcs = cs->bcs + 1;
 		exval = MemReadHSCX(cs, 1, HSCX_EXIR);
 		if (exval & 0x40) {
@@ -622,7 +577,7 @@ Memhscx_int_main(struct IsdnCardState *c
 			debugl1(cs, "HSCX B interrupt %x", val);
 		Memhscx_interrupt(cs, val, 1);
 	}
-	if (val & 0x02) {	// EXA
+	if (val & 0x02) {
 		bcs = cs->bcs;
 		exval = MemReadHSCX(cs, 0, HSCX_EXIR);
 		if (exval & 0x40) {
@@ -644,7 +599,7 @@ Memhscx_int_main(struct IsdnCardState *c
 		} else if (cs->debug & L1_DEB_HSCX)
 			debugl1(cs, "HSCX A EXIR %x", exval);
 	}
-	if (val & 0x04) {	// ICA
+	if (val & 0x04) {
 		exval = MemReadHSCX(cs, 0, HSCX_ISTA);
 		if (cs->debug & L1_DEB_HSCX)
 			debugl1(cs, "HSCX A interrupt %x", exval);
@@ -705,31 +660,12 @@ Start_IPACPCI:
 	memwritereg(cs->hw.diva.cfg_reg, IPAC_MASK, 0xC0);
 }
 
-static void
-diva_irq_ipacx_pci(int intno, void *dev_id, struct pt_regs *regs)
-{
-	struct IsdnCardState *cs = dev_id;
-	u_char val;
-	u_char *cfg;
-
-	if (!cs) {
-		printk(KERN_WARNING "Diva: Spurious interrupt!\n");
-		return;
-	}
-	cfg = (u_char *) cs->hw.diva.pci_cfg;
-	val = *cfg;
-	if (!(val &PITA_INT0_STATUS)) return; // other shared IRQ
-  interrupt_ipacx(cs);      // handler for chip
-	*cfg = PITA_INT0_STATUS;  // Reset PLX interrupt
-}
-
 void
 release_io_diva(struct IsdnCardState *cs)
 {
 	int bytecnt;
 
-	if ((cs->subtyp == DIVA_IPAC_PCI) || 
-	    (cs->subtyp == DIVA_IPACX_PCI)   ) {
+	if (cs->subtyp == DIVA_IPAC_PCI) {
 		u_int *cfg = (unsigned int *)cs->hw.diva.pci_cfg;
 
 		*cfg = 0; /* disable INT0/1 */ 
@@ -776,16 +712,6 @@ reset_diva(struct IsdnCardState *cs)
 		set_current_state(TASK_UNINTERRUPTIBLE);
 		schedule_timeout((10*HZ)/1000);
 		memwritereg(cs->hw.diva.cfg_reg, IPAC_MASK, 0xc0);
-	} else if (cs->subtyp == DIVA_IPACX_PCI) {
-		unsigned int *ireg = (unsigned int *)(cs->hw.diva.pci_cfg +
-					PITA_MISC_REG);
-		*ireg = PITA_PARA_SOFTRESET | PITA_PARA_MPX_MODE;
-		set_current_state(TASK_UNINTERRUPTIBLE);
-		schedule_timeout((10*HZ)/1000);
-		*ireg = PITA_PARA_MPX_MODE | PITA_SER_SOFTRESET;
-		set_current_state(TASK_UNINTERRUPTIBLE);
-		schedule_timeout((10*HZ)/1000);
-		MemWriteISAC_IPACX(cs, IPACX_MASK, 0xff); // Interrupts off
 	} else { /* DIVA 2.0 */
 		cs->hw.diva.ctrl_reg = 0;        /* Reset On */
 		byteout(cs->hw.diva.ctrl, cs->hw.diva.ctrl_reg);
@@ -814,9 +740,7 @@ diva_led_handler(struct IsdnCardState *c
 {
 	int blink = 0;
 
-	if ((cs->subtyp == DIVA_IPAC_ISA) ||
-	    (cs->subtyp == DIVA_IPAC_PCI) ||
-	    (cs->subtyp == DIVA_IPACX_PCI)   )
+	if ((cs->subtyp == DIVA_IPAC_ISA) || (cs->subtyp == DIVA_IPAC_PCI))
 		return;
 	del_timer(&cs->hw.diva.tl);
 	if (cs->hw.diva.status & DIVA_ASSIGN)
@@ -859,12 +783,6 @@ Diva_card_msg(struct IsdnCardState *cs, 
 			release_io_diva(cs);
 			return(0);
 		case CARD_INIT:
-			if (cs->subtyp == DIVA_IPACX_PCI) {
-				ireg = (unsigned int *)cs->hw.diva.pci_cfg;
-				*ireg = PITA_INT0_ENABLE;
-			  init_ipacx(cs, 3); // init chip and enable interrupts
-        return (0);
-			}
 			if (cs->subtyp == DIVA_IPAC_PCI) {
 				ireg = (unsigned int *)cs->hw.diva.pci_cfg;
 				*ireg = PITA_INT0_ENABLE;
@@ -901,9 +819,7 @@ Diva_card_msg(struct IsdnCardState *cs, 
 			}
 			break;
 	}
-	if ((cs->subtyp != DIVA_IPAC_ISA) && 
-	    (cs->subtyp != DIVA_IPAC_PCI) &&
-	    (cs->subtyp != DIVA_IPACX_PCI)   )
+	if ((cs->subtyp != DIVA_IPAC_ISA) && (cs->subtyp != DIVA_IPAC_PCI))
 		diva_led_handler(cs);
 	return(0);
 }
@@ -911,40 +827,11 @@ Diva_card_msg(struct IsdnCardState *cs, 
 static struct pci_dev *dev_diva __initdata = NULL;
 static struct pci_dev *dev_diva_u __initdata = NULL;
 static struct pci_dev *dev_diva201 __initdata = NULL;
-static struct pci_dev *dev_diva202 __initdata = NULL;
-
-#ifdef __ISAPNP__
-static struct isapnp_device_id diva_ids[] __initdata = {
-	{ ISAPNP_VENDOR('G', 'D', 'I'), ISAPNP_FUNCTION(0x51),
-	  ISAPNP_VENDOR('G', 'D', 'I'), ISAPNP_FUNCTION(0x51), 
-	  (unsigned long) "Diva picola" },
-	{ ISAPNP_VENDOR('G', 'D', 'I'), ISAPNP_FUNCTION(0x51),
-	  ISAPNP_VENDOR('E', 'I', 'C'), ISAPNP_FUNCTION(0x51), 
-	  (unsigned long) "Diva picola" },
-	{ ISAPNP_VENDOR('G', 'D', 'I'), ISAPNP_FUNCTION(0x71),
-	  ISAPNP_VENDOR('G', 'D', 'I'), ISAPNP_FUNCTION(0x71), 
-	  (unsigned long) "Diva 2.0" },
-	{ ISAPNP_VENDOR('G', 'D', 'I'), ISAPNP_FUNCTION(0x71),
-	  ISAPNP_VENDOR('E', 'I', 'C'), ISAPNP_FUNCTION(0x71), 
-	  (unsigned long) "Diva 2.0" },
-	{ ISAPNP_VENDOR('G', 'D', 'I'), ISAPNP_FUNCTION(0xA1),
-	  ISAPNP_VENDOR('G', 'D', 'I'), ISAPNP_FUNCTION(0xA1), 
-	  (unsigned long) "Diva 2.01" },
-	{ ISAPNP_VENDOR('G', 'D', 'I'), ISAPNP_FUNCTION(0xA1),
-	  ISAPNP_VENDOR('E', 'I', 'C'), ISAPNP_FUNCTION(0xA1), 
-	  (unsigned long) "Diva 2.01" },
-	{ 0, }
-};
-
-static struct isapnp_device_id *pdev = &diva_ids[0];
-static struct pci_bus *pnp_c __devinitdata = NULL;
-#endif
-
 
 int __init
 setup_diva(struct IsdnCard *card)
 {
-	int bytecnt = 8;
+	int bytecnt;
 	u_char val;
 	struct IsdnCardState *cs = card->cs;
 	char tmp[64];
@@ -977,75 +864,8 @@ setup_diva(struct IsdnCard *card)
 			cs->hw.diva.hscx_adr = card->para[1] + DIVA_HSCX_ADR;
 		}
 		cs->irq = card->para[0];
+		bytecnt = 8;
 	} else {
-#ifdef __ISAPNP__
-		if (isapnp_present()) {
-			struct pci_bus *pb;
-			struct pci_dev *pd;
-
-			while(pdev->card_vendor) {
-				if ((pb = isapnp_find_card(pdev->card_vendor,
-					pdev->card_device, pnp_c))) {
-					pnp_c = pb;
-					pd = NULL;
-					if ((pd = isapnp_find_dev(pnp_c,
-						pdev->vendor, pdev->function, pd))) {
-						printk(KERN_INFO "HiSax: %s detected\n",
-							(char *)pdev->driver_data);
-						pd->prepare(pd);
-						pd->deactivate(pd);
-						pd->activate(pd);
-						card->para[1] =
-							pd->resource[0].start;
-						card->para[0] =
-							pd->irq_resource[0].start;
-						if (!card->para[0] || !card->para[1]) {
-							printk(KERN_ERR "Diva PnP:some resources are missing %ld/%lx\n",
-								card->para[0], card->para[1]);
-							pd->deactivate(pd);
-							return(0);
-						}
-						cs->hw.diva.cfg_reg  = card->para[1];
-						cs->irq = card->para[0];
-						if (pdev->function == ISAPNP_FUNCTION(0xA1)) {
-							cs->subtyp = DIVA_IPAC_ISA;
-							cs->hw.diva.ctrl = 0;
-							cs->hw.diva.isac =
-								card->para[1] + DIVA_IPAC_DATA;
-							cs->hw.diva.hscx =
-								card->para[1] + DIVA_IPAC_DATA;
-							cs->hw.diva.isac_adr =
-								card->para[1] + DIVA_IPAC_ADR;
-							cs->hw.diva.hscx_adr =
-								card->para[1] + DIVA_IPAC_ADR;
-							test_and_set_bit(HW_IPAC, &cs->HW_Flags);
-						} else {
-							cs->subtyp = DIVA_ISA;
-							cs->hw.diva.ctrl =
-								card->para[1] + DIVA_ISA_CTRL;
-							cs->hw.diva.isac =
-								card->para[1] + DIVA_ISA_ISAC_DATA;
-							cs->hw.diva.hscx =
-								card->para[1] + DIVA_HSCX_DATA;
-							cs->hw.diva.isac_adr =
-								card->para[1] + DIVA_ISA_ISAC_ADR;
-							cs->hw.diva.hscx_adr =
-								card->para[1] + DIVA_HSCX_ADR;
-						}
-						goto ready;
-					} else {
-						printk(KERN_ERR "Diva PnP: PnP error card found, no device\n");
-						return(0);
-					}
-				}
-				pdev++;
-				pnp_c=NULL;
-			} 
-			if (!pdev->card_vendor) {
-				printk(KERN_INFO "Diva PnP: no ISAPnP card found\n");
-			}
-		}
-#endif
 #if CONFIG_PCI
 		if (!pci_present()) {
 			printk(KERN_ERR "Diva: no PCI bus present\n");
@@ -1059,14 +879,14 @@ setup_diva(struct IsdnCard *card)
 				return(0);
 			cs->subtyp = DIVA_PCI;
 			cs->irq = dev_diva->irq;
-			cs->hw.diva.cfg_reg = pci_resource_start(dev_diva, 2);
+			cs->hw.diva.cfg_reg = pci_resource_start_io(dev_diva, 2);
 		} else if ((dev_diva_u = pci_find_device(PCI_VENDOR_ID_EICON,
 			PCI_DEVICE_ID_EICON_DIVA20_U, dev_diva_u))) {
 			if (pci_enable_device(dev_diva_u))
 				return(0);
 			cs->subtyp = DIVA_PCI;
 			cs->irq = dev_diva_u->irq;
-			cs->hw.diva.cfg_reg = pci_resource_start(dev_diva_u, 2);
+			cs->hw.diva.cfg_reg = pci_resource_start_io(dev_diva_u, 2);
 		} else if ((dev_diva201 = pci_find_device(PCI_VENDOR_ID_EICON,
 			PCI_DEVICE_ID_EICON_DIVA201, dev_diva201))) {
 			if (pci_enable_device(dev_diva201))
@@ -1074,19 +894,9 @@ setup_diva(struct IsdnCard *card)
 			cs->subtyp = DIVA_IPAC_PCI;
 			cs->irq = dev_diva201->irq;
 			cs->hw.diva.pci_cfg =
-				(ulong) ioremap(pci_resource_start(dev_diva201, 0), 4096);
+				(ulong) ioremap(pci_resource_start_mem(dev_diva201, 0), 4096);
 			cs->hw.diva.cfg_reg =
-				(ulong) ioremap(pci_resource_start(dev_diva201, 1), 4096);
-		} else if ((dev_diva202 = pci_find_device(PCI_VENDOR_ID_EICON,
-			PCI_DEVICE_ID_EICON_DIVA202, dev_diva202))) {
-			if (pci_enable_device(dev_diva202))
-				return(0);
-			cs->subtyp = DIVA_IPACX_PCI;
-			cs->irq = dev_diva202->irq;
-			cs->hw.diva.pci_cfg =
-				(ulong) ioremap(pci_resource_start(dev_diva202, 0), 4096);
-			cs->hw.diva.cfg_reg =
-				(ulong) ioremap(pci_resource_start(dev_diva202, 1), 4096);
+				(ulong) ioremap(pci_resource_start_mem(dev_diva201, 1), 4096);
 		} else {
 			printk(KERN_WARNING "Diva: No PCI card found\n");
 			return(0);
@@ -1107,8 +917,7 @@ setup_diva(struct IsdnCard *card)
 		printk(KERN_WARNING "Diva: unable to config DIVA PCI\n");
 		return (0);
 #endif /* CONFIG_PCI */
-		if ((cs->subtyp == DIVA_IPAC_PCI) ||
-		    (cs->subtyp == DIVA_IPACX_PCI)   ) {
+		if (cs->subtyp == DIVA_IPAC_PCI) {
 			cs->hw.diva.ctrl = 0;
 			cs->hw.diva.isac = 0;
 			cs->hw.diva.hscx = 0;
@@ -1125,23 +934,18 @@ setup_diva(struct IsdnCard *card)
 			bytecnt = 32;
 		}
 	}
-ready:
+
 	printk(KERN_INFO
 		"Diva: %s card configured at %#lx IRQ %d\n",
 		(cs->subtyp == DIVA_PCI) ? "PCI" :
 		(cs->subtyp == DIVA_ISA) ? "ISA" : 
-		(cs->subtyp == DIVA_IPAC_ISA) ? "IPAC ISA" :
-		(cs->subtyp == DIVA_IPAC_PCI) ? "IPAC PCI" : "IPACX PCI",
+		(cs->subtyp == DIVA_IPAC_ISA) ? "IPAC ISA" : "IPAC PCI",
 		cs->hw.diva.cfg_reg, cs->irq);
-	if ((cs->subtyp == DIVA_IPAC_PCI)  || 
-	    (cs->subtyp == DIVA_IPACX_PCI) || 
-	    (cs->subtyp == DIVA_PCI)         )
-		printk(KERN_INFO "Diva: %s space at %#lx\n",
-			(cs->subtyp == DIVA_PCI) ? "PCI" :
-			(cs->subtyp == DIVA_IPAC_PCI) ? "IPAC PCI" : "IPACX PCI",
+	if ((cs->subtyp == DIVA_IPAC_PCI) || (cs->subtyp == DIVA_PCI))
+		printk(KERN_INFO "Diva: %s PCI space at %#lx\n",
+			(cs->subtyp == DIVA_PCI) ? "PCI" : "IPAC PCI",
 			cs->hw.diva.pci_cfg);
-	if ((cs->subtyp != DIVA_IPAC_PCI) &&
-	    (cs->subtyp != DIVA_IPACX_PCI)   ) {
+	if (cs->subtyp != DIVA_IPAC_PCI) {
 		if (check_region(cs->hw.diva.cfg_reg, bytecnt)) {
 			printk(KERN_WARNING
 			       "HiSax: %s config port %lx-%lx already in use\n",
@@ -1177,17 +981,6 @@ ready:
 		cs->irq_func = &diva_irq_ipac_pci;
 		val = memreadreg(cs->hw.diva.cfg_reg, IPAC_ID);
 		printk(KERN_INFO "Diva: IPAC version %x\n", val);
-	} else if (cs->subtyp == DIVA_IPACX_PCI) {
-		cs->readisac  = &MemReadISAC_IPACX;
-		cs->writeisac = &MemWriteISAC_IPACX;
-		cs->readisacfifo  = &MemReadISACfifo_IPACX;
-		cs->writeisacfifo = &MemWriteISACfifo_IPACX;
-		cs->BC_Read_Reg  = &MemReadHSCX_IPACX;
-		cs->BC_Write_Reg = &MemWriteHSCX_IPACX;
-		cs->BC_Send_Data = 0; // function located in ipacx module
-		cs->irq_func = &diva_irq_ipacx_pci;
-		printk(KERN_INFO "Diva: IPACX Design Id: %x\n", 
-            MemReadISAC_IPACX(cs, IPACX_ID) &0x3F);
 	} else { /* DIVA 2.0 */
 		cs->hw.diva.tl.function = (void *) diva_led_handler;
 		cs->hw.diva.tl.data = (long) cs;
--- a/drivers/isdn/hisax/elsa.c
+++ b/drivers/isdn/hisax/elsa.c
@@ -1,4 +1,4 @@
-/* $Id: elsa.c,v 1.1.4.1 2001/11/20 14:19:35 kai Exp $
+/* $Id: elsa.c,v 2.32 2001/09/24 13:22:56 kai Exp $
  *
  * low level stuff for Elsa isdn cards
  *
@@ -28,13 +28,13 @@
 #include "hscx.h"
 #include "isdnl1.h"
 #include <linux/pci.h>
-#include <linux/isapnp.h>
+#include <linux/isdn_compat.h>
 #include <linux/serial.h>
 #include <linux/serial_reg.h>
 
 extern const char *CardType[];
 
-const char *Elsa_revision = "$Revision: 1.1.4.1 $";
+const char *Elsa_revision = "$Revision: 2.32 $";
 const char *Elsa_Types[] =
 {"None", "PC", "PCC-8", "PCC-16", "PCF", "PCF-Pro",
  "PCMCIA", "QS 1000", "QS 3000", "Microlink PCI", "QS 3000 PCI", 
@@ -864,21 +864,6 @@ probe_elsa(struct IsdnCardState *cs)
 static 	struct pci_dev *dev_qs1000 __devinitdata = NULL;
 static 	struct pci_dev *dev_qs3000 __devinitdata = NULL;
 
-#ifdef __ISAPNP__
-static struct isapnp_device_id elsa_ids[] __initdata = {
-	{ ISAPNP_VENDOR('E', 'L', 'S'), ISAPNP_FUNCTION(0x0133),
-	  ISAPNP_VENDOR('E', 'L', 'S'), ISAPNP_FUNCTION(0x0133), 
-	  (unsigned long) "Elsa QS1000" },
-	{ ISAPNP_VENDOR('E', 'L', 'S'), ISAPNP_FUNCTION(0x0134),
-	  ISAPNP_VENDOR('E', 'L', 'S'), ISAPNP_FUNCTION(0x0134), 
-	  (unsigned long) "Elsa QS3000" },
-	{ 0, }
-};
-
-static struct isapnp_device_id *pdev = &elsa_ids[0];
-static struct pci_bus *pnp_c __devinitdata = NULL;
-#endif
-
 int __devinit
 setup_elsa(struct IsdnCard *card)
 {
@@ -893,7 +878,6 @@ setup_elsa(struct IsdnCard *card)
 	cs->hw.elsa.ctrl_reg = 0;
 	cs->hw.elsa.status = 0;
 	cs->hw.elsa.MFlag = 0;
-	cs->subtyp = 0;
 	if (cs->typ == ISDN_CTYPE_ELSA) {
 		cs->hw.elsa.base = card->para[0];
 		printk(KERN_INFO "Elsa: Microlink IO probing\n");
@@ -955,60 +939,9 @@ setup_elsa(struct IsdnCard *card)
 			return (0);
 		}
 	} else if (cs->typ == ISDN_CTYPE_ELSA_PNP) {
-#ifdef __ISAPNP__
-		if (!card->para[1] && isapnp_present()) {
-			struct pci_bus *pb;
-			struct pci_dev *pd;
-
-			while(pdev->card_vendor) {
-				if ((pb = isapnp_find_card(pdev->card_vendor,
-					pdev->card_device, pnp_c))) {
-					pnp_c = pb;
-					pd = NULL;
-					if ((pd = isapnp_find_dev(pnp_c,
-						pdev->vendor, pdev->function, pd))) {
-						printk(KERN_INFO "HiSax: %s detected\n",
-							(char *)pdev->driver_data);
-						pd->prepare(pd);
-						pd->deactivate(pd);
-						pd->activate(pd);
-						card->para[1] =
-							pd->resource[0].start;
-						card->para[0] =
-							pd->irq_resource[0].start;
-						if (!card->para[0] || !card->para[1]) {
-							printk(KERN_ERR "Elsa PnP:some resources are missing %ld/%lx\n",
-								card->para[0], card->para[1]);
-							pd->deactivate(pd);
-							return(0);
-						}
-						if (pdev->function == ISAPNP_FUNCTION(0x133))
-							cs->subtyp = ELSA_QS1000;
-						else
-							cs->subtyp = ELSA_QS3000;
-						break;
-					} else {
-						printk(KERN_ERR "Elsa PnP: PnP error card found, no device\n");
-						return(0);
-					}
-				}
-				pdev++;
-				pnp_c=NULL;
-			} 
-			if (!pdev->card_vendor) {
-				printk(KERN_INFO "Elsa PnP: no ISAPnP card found\n");
-				return(0);
-			}
-		}
-#endif
-		if (card->para[1] && card->para[0]) { 
-			cs->hw.elsa.base = card->para[1];
-			cs->irq = card->para[0];
-			if (!cs->subtyp)
-				cs->subtyp = ELSA_QS1000;
-		} else {
-			printk(KERN_ERR "Elsa PnP: no parameter\n");
-		}
+		cs->hw.elsa.base = card->para[1];
+		cs->irq = card->para[0];
+		cs->subtyp = ELSA_QS1000;
 		cs->hw.elsa.cfg = cs->hw.elsa.base + ELSA_CONFIG;
 		cs->hw.elsa.ale = cs->hw.elsa.base + ELSA_ALE;
 		cs->hw.elsa.isac = cs->hw.elsa.base + ELSA_ISAC;
@@ -1058,16 +991,16 @@ setup_elsa(struct IsdnCard *card)
 				return(0);
 			cs->subtyp = ELSA_QS1000PCI;
 			cs->irq = dev_qs1000->irq;
-			cs->hw.elsa.cfg = pci_resource_start(dev_qs1000, 1);
-			cs->hw.elsa.base = pci_resource_start(dev_qs1000, 3);
+			cs->hw.elsa.cfg = pci_resource_start_io(dev_qs1000, 1);
+			cs->hw.elsa.base = pci_resource_start_io(dev_qs1000, 3);
 		} else if ((dev_qs3000 = pci_find_device(PCI_VENDOR_ID_ELSA,
 			PCI_DEVICE_ID_ELSA_QS3000, dev_qs3000))) {
 			if (pci_enable_device(dev_qs3000))
 				return(0);
 			cs->subtyp = ELSA_QS3000PCI;
 			cs->irq = dev_qs3000->irq;
-			cs->hw.elsa.cfg = pci_resource_start(dev_qs3000, 1);
-			cs->hw.elsa.base = pci_resource_start(dev_qs3000, 3);
+			cs->hw.elsa.cfg = pci_resource_start_io(dev_qs3000, 1);
+			cs->hw.elsa.base = pci_resource_start_io(dev_qs3000, 3);
 		} else {
 			printk(KERN_WARNING "Elsa: No PCI card found\n");
 			return(0);
@@ -1123,7 +1056,6 @@ setup_elsa(struct IsdnCard *card)
 			break;
 		case ELSA_PCFPRO:
 		case ELSA_PCF:
-		case ELSA_QS3000:
 		case ELSA_QS3000PCI:
 			bytecnt = 16;
 			break;
--- a/drivers/isdn/hisax/elsa_cs.c
+++ b/drivers/isdn/hisax/elsa_cs.c
@@ -72,7 +72,7 @@ static int pc_debug = PCMCIA_DEBUG;
 MODULE_PARM(pc_debug, "i");
 #define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args);
 static char *version =
-"elsa_cs.c $Revision: 1.1.4.1 $ $Date: 2001/11/20 14:19:35 $ (K.Lichtenwalder)";
+"elsa_cs.c $Revision: 1.2 $ $Date: 2001/09/24 13:22:56 $ (K.Lichtenwalder)";
 #else
 #define DEBUG(n, args...)
 #endif
--- a/drivers/isdn/hisax/elsa_ser.c
+++ b/drivers/isdn/hisax/elsa_ser.c
@@ -1,4 +1,4 @@
-/* $Id: elsa_ser.c,v 1.1.4.1 2001/11/20 14:19:35 kai Exp $
+/* $Id: elsa_ser.c,v 2.14 2001/09/24 13:22:56 kai Exp $
  *
  * stuff for the serial modem on ELSA cards
  *
@@ -396,6 +396,74 @@ static inline void transmit_chars(struct
 	}
 }
 
+#if 0
+static inline void check_modem_status(struct IsdnCardState *cs)
+{
+	int	status;
+	struct async_struct *info = cs->hw.elsa.info;
+	struct	async_icount *icount;
+	
+	status = serial_inp(info, UART_MSR);
+
+	if (status & UART_MSR_ANY_DELTA) {
+		icount = &info->state->icount;
+		/* update input line counters */
+		if (status & UART_MSR_TERI)
+			icount->rng++;
+		if (status & UART_MSR_DDSR)
+			icount->dsr++;
+		if (status & UART_MSR_DDCD) {
+			icount->dcd++;
+		}
+		if (status & UART_MSR_DCTS)
+			icount->cts++;
+//		wake_up(&info->delta_msr_wait);
+	}
+
+	if ((info->flags & ASYNC_CHECK_CD) && (status & UART_MSR_DDCD)) {
+#if (defined(SERIAL_DEBUG_OPEN) || defined(SERIAL_DEBUG_INTR))
+		printk("ttys%d CD now %s...", info->line,
+		       (status & UART_MSR_DCD) ? "on" : "off");
+#endif		
+		if (status & UART_MSR_DCD)
+//			wake_up(&info->open_wait);
+;
+		else if (!((info->flags & ASYNC_CALLOUT_ACTIVE) &&
+			   (info->flags & ASYNC_CALLOUT_NOHUP))) {
+#ifdef SERIAL_DEBUG_OPEN
+			printk("doing serial hangup...");
+#endif
+			if (info->tty)
+				tty_hangup(info->tty);
+		}
+	}
+#if 0
+	if (info->flags & ASYNC_CTS_FLOW) {
+		if (info->tty->hw_stopped) {
+			if (status & UART_MSR_CTS) {
+#if (defined(SERIAL_DEBUG_INTR) || defined(SERIAL_DEBUG_FLOW))
+				printk("CTS tx start...");
+#endif
+				info->tty->hw_stopped = 0;
+				info->IER |= UART_IER_THRI;
+				serial_outp(info, UART_IER, info->IER);
+//				rs_sched_event(info, RS_EVENT_WRITE_WAKEUP);
+				return;
+			}
+		} else {
+			if (!(status & UART_MSR_CTS)) {
+#if (defined(SERIAL_DEBUG_INTR) || defined(SERIAL_DEBUG_FLOW))
+				printk("CTS tx stop...");
+#endif
+				info->tty->hw_stopped = 1;
+				info->IER &= ~UART_IER_THRI;
+				serial_outp(info, UART_IER, info->IER);
+			}
+		}
+	}
+#endif 0
+}
+#endif
 
 static void rs_interrupt_elsa(int irq, struct IsdnCardState *cs)
 {
--- a/drivers/isdn/hisax/fsm.c
+++ b/drivers/isdn/hisax/fsm.c
@@ -1,4 +1,4 @@
-/* $Id: fsm.c,v 1.1.4.1 2001/11/20 14:19:35 kai Exp $
+/* $Id$
  *
  * Finite state machine
  *
@@ -21,6 +21,14 @@
 
 #define FSM_TIMER_DEBUG 0
 
+EXPORT_SYMBOL(FsmNew);
+EXPORT_SYMBOL(FsmFree);
+EXPORT_SYMBOL(FsmEvent);
+EXPORT_SYMBOL(FsmChangeState);
+EXPORT_SYMBOL(FsmInitTimer);
+EXPORT_SYMBOL(FsmDelTimer);
+EXPORT_SYMBOL(FsmRestartTimer);
+
 int __init
 FsmNew(struct Fsm *fsm, struct FsmNode *fnlist, int fncount)
 {
--- a/drivers/isdn/hisax/fsm.h
+++ b/drivers/isdn/hisax/fsm.h
@@ -1,4 +1,4 @@
-/* $Id: fsm.h,v 1.1.2.1 2001/11/20 14:19:35 kai Exp $
+/* $Id$
  *
  * Finite state machine
  *
--- a/drivers/isdn/hisax/gazel.c
+++ b/drivers/isdn/hisax/gazel.c
@@ -1,4 +1,4 @@
-/* $Id: gazel.c,v 1.1.4.1 2001/11/20 14:19:35 kai Exp $
+/* $Id: gazel.c,v 2.19 2001/09/24 13:22:56 kai Exp $
  *
  * low level stuff for Gazel isdn cards
  *
@@ -20,9 +20,10 @@
 #include "isdnl1.h"
 #include "ipac.h"
 #include <linux/pci.h>
+#include <linux/isdn_compat.h>
 
 extern const char *CardType[];
-const char *gazel_revision = "$Revision: 1.1.4.1 $";
+const char *gazel_revision = "$Revision: 2.19 $";
 
 #define R647      1
 #define R685      2
@@ -563,8 +564,8 @@ setup_gazelpci(struct IsdnCardState *cs)
 			if (pci_enable_device(dev_tel))
 				return 1;
 			pci_irq = dev_tel->irq;
-			pci_ioaddr0 = pci_resource_start(dev_tel, 1);
-			pci_ioaddr1 = pci_resource_start(dev_tel, 2);
+			pci_ioaddr0 = pci_resource_start_io(dev_tel, 1);
+			pci_ioaddr1 = pci_resource_start_io(dev_tel, 2);
 			found = 1;
 		}
 		if (found)
--- a/drivers/isdn/hisax/hfc_2bds0.c
+++ b/drivers/isdn/hisax/hfc_2bds0.c
@@ -1,4 +1,4 @@
-/* $Id: hfc_2bds0.c,v 1.1.4.1 2001/11/20 14:19:35 kai Exp $
+/* $Id: hfc_2bds0.c,v 1.18 2001/09/24 13:22:56 kai Exp $
  *
  * specific routines for CCD's HFC 2BDS0
  *
@@ -616,6 +616,17 @@ hfcd_bh(struct IsdnCardState *cs)
 */
 	if (!cs)
 		return;
+#if 0	
+	if (test_and_clear_bit(D_CLEARBUSY, &cs->event)) {
+		if (cs->debug)
+			debugl1(cs, "D-Channel Busy cleared");
+		stptr = cs->stlist;
+		while (stptr != NULL) {
+			stptr->l1.l1l2(stptr, PH_PAUSE | CONFIRM, NULL);
+			stptr = stptr->next;
+		}
+	}
+#endif
 	if (test_and_clear_bit(D_L1STATECHANGE, &cs->event)) {
 		switch (cs->dc.hfcd.ph_state) {
 			case (0):
@@ -1090,6 +1101,32 @@ HFCD_l1hw(struct PStack *st, int pr, voi
 			cs->hw.hfcD.mst_m |= HFCD_MASTER;
 			cs->writeisac(cs, HFCD_MST_MODE, cs->hw.hfcD.mst_m);
 			break;
+#if 0
+		case (HW_TESTLOOP | REQUEST):
+			u_char val = 0;
+			if (1 & (int) arg)
+				val |= 0x0c;
+			if (2 & (int) arg)
+				val |= 0x3;
+			if (test_bit(HW_IOM1, &cs->HW_Flags)) {
+				/* IOM 1 Mode */
+				if (!val) {
+					cs->writeisac(cs, ISAC_SPCR, 0xa);
+					cs->writeisac(cs, ISAC_ADF1, 0x2);
+				} else {
+					cs->writeisac(cs, ISAC_SPCR, val);
+					cs->writeisac(cs, ISAC_ADF1, 0xa);
+				}
+			} else {
+				/* IOM 2 Mode */
+				cs->writeisac(cs, ISAC_SPCR, val);
+				if (val)
+					cs->writeisac(cs, ISAC_ADF1, 0x8);
+				else
+					cs->writeisac(cs, ISAC_ADF1, 0x0);
+			}
+			break;
+#endif
 		default:
 			if (cs->debug & L1_DEB_WARN)
 				debugl1(cs, "hfcd_l1hw unknown pr %4x", pr);
@@ -1106,6 +1143,20 @@ setstack_hfcd(struct PStack *st, struct 
 static void
 hfc_dbusy_timer(struct IsdnCardState *cs)
 {
+#if 0
+	struct PStack *stptr;
+	if (test_bit(FLG_DBUSY_TIMER, &cs->HW_Flags)) {
+		if (cs->debug)
+			debugl1(cs, "D-Channel Busy");
+		test_and_set_bit(FLG_L1_DBUSY, &cs->HW_Flags);
+		stptr = cs->stlist;
+		
+		while (stptr != NULL) {
+			stptr->l1.l1l2(stptr, PH_PAUSE | INDICATION, NULL);
+			stptr = stptr->next;
+		}
+	}
+#endif
 }
 
 unsigned int __init
--- a/drivers/isdn/hisax/hfc_2bds0.h
+++ b/drivers/isdn/hisax/hfc_2bds0.h
@@ -1,4 +1,4 @@
-/* $Id: hfc_2bds0.h,v 1.1.4.1 2001/11/20 14:19:35 kai Exp $
+/* $Id: hfc_2bds0.h,v 1.6 2001/09/24 13:22:56 kai Exp $
  *
  * specific defines for CCD's HFC 2BDS0
  *
--- a/drivers/isdn/hisax/hfc_2bs0.c
+++ b/drivers/isdn/hisax/hfc_2bs0.c
@@ -1,4 +1,4 @@
-/* $Id: hfc_2bs0.c,v 1.1.4.1 2001/11/20 14:19:35 kai Exp $
+/* $Id: hfc_2bs0.c,v 1.20 2001/09/24 13:22:56 kai Exp $
  *
  * specific routines for CCD's HFC 2BS0
  *
--- a/drivers/isdn/hisax/hfc_2bs0.h
+++ b/drivers/isdn/hisax/hfc_2bs0.h
@@ -1,4 +1,4 @@
-/* $Id: hfc_2bs0.h,v 1.1.4.1 2001/11/20 14:19:35 kai Exp $
+/* $Id: hfc_2bs0.h,v 1.5 2001/09/24 13:22:56 kai Exp $
  *
  * specific defines for CCD's HFC 2BS0
  *
--- a/drivers/isdn/hisax/hfc_pci.c
+++ b/drivers/isdn/hisax/hfc_pci.c
@@ -1,4 +1,4 @@
-/* $Id: hfc_pci.c,v 1.1.4.1 2001/11/20 14:19:35 kai Exp $
+/* $Id: hfc_pci.c,v 1.48 2001/09/24 13:22:56 kai Exp $
  *
  * low level driver for CCD´s hfc-pci based cards
  *
@@ -22,11 +22,12 @@
 #include "hfc_pci.h"
 #include "isdnl1.h"
 #include <linux/pci.h>
+#include <linux/isdn_compat.h>
 #include <linux/interrupt.h>
 
 extern const char *CardType[];
 
-static const char *hfcpci_revision = "$Revision: 1.1.4.1 $";
+static const char *hfcpci_revision = "$Revision: 1.48 $";
 
 /* table entry in the PCI devices list */
 typedef struct {
@@ -76,8 +77,6 @@ release_io_hfcpci(struct IsdnCardState *
 {
 	unsigned long flags;
 
-	printk(KERN_INFO "HiSax: release hfcpci at %p\n",
-		cs->hw.hfcpci.pci_io);
 	save_flags(flags);
 	cli();
 	cs->hw.hfcpci.int_m2 = 0;	/* interrupt output off ! */
@@ -88,11 +87,13 @@ release_io_hfcpci(struct IsdnCardState *
 	set_current_state(TASK_UNINTERRUPTIBLE);
 	schedule_timeout((30 * HZ) / 1000);	/* Timeout 30ms */
 	Write_hfc(cs, HFCPCI_CIRM, 0);	/* Reset Off */
+#if CONFIG_PCI
 	pcibios_write_config_word(cs->hw.hfcpci.pci_bus, cs->hw.hfcpci.pci_device_fn, PCI_COMMAND, 0);	/* disable memory mapped ports + busmaster */
+#endif				/* CONFIG_PCI */
 	del_timer(&cs->hw.hfcpci.timer);
 	kfree(cs->hw.hfcpci.share_start);
 	cs->hw.hfcpci.share_start = NULL;
-	iounmap((void *)cs->hw.hfcpci.pci_io);
+	vfree(cs->hw.hfcpci.pci_io);
 }
 
 /********************************************************************************/
@@ -687,10 +688,6 @@ hfcpci_fill_fifo(struct BCState *bcs)
 				debugl1(cs, "hfcpci_fill_fifo_trans %d frame length %d discarded",
 					bcs->channel, bcs->tx_skb->len);
 
-			if (bcs->st->lli.l1writewakeup &&
-                           (PACKET_NOACK != bcs->tx_skb->pkt_type))
-				bcs->st->lli.l1writewakeup(bcs->st, bcs->tx_skb->len);
-
 			dev_kfree_skb_any(bcs->tx_skb);
 			cli();
 			bcs->tx_skb = skb_dequeue(&bcs->squeue);	/* fetch next data */
@@ -1146,6 +1143,20 @@ hfcpci_interrupt(int intno, void *dev_id
 static void
 hfcpci_dbusy_timer(struct IsdnCardState *cs)
 {
+#if 0
+	struct PStack *stptr;
+	if (test_bit(FLG_DBUSY_TIMER, &cs->HW_Flags)) {
+		if (cs->debug)
+			debugl1(cs, "D-Channel Busy");
+		test_and_set_bit(FLG_L1_DBUSY, &cs->HW_Flags);
+		stptr = cs->stlist;
+
+		while (stptr != NULL) {
+			stptr->l1.l1l2(stptr, PH_PAUSE | INDICATION, NULL);
+			stptr = stptr->next;
+		}
+	}
+#endif
 }
 
 /*************************************/
@@ -1550,6 +1561,17 @@ hfcpci_bh(struct IsdnCardState *cs)
  */
 	if (!cs)
 		return;
+#if 0
+	if (test_and_clear_bit(D_CLEARBUSY, &cs->event)) {
+		if (cs->debug)
+			debugl1(cs, "D-Channel Busy cleared");
+		stptr = cs->stlist;
+		while (stptr != NULL) {
+			stptr->l1.l1l2(stptr, PH_PAUSE | CONFIRM, NULL);
+			stptr = stptr->next;
+		}
+	}
+#endif
 	if (test_and_clear_bit(D_L1STATECHANGE, &cs->event)) {
 		if (!cs->hw.hfcpci.nt_mode)
 			switch (cs->dc.hfcpci.ph_state) {
@@ -1712,7 +1734,7 @@ setup_hfcpci(struct IsdnCard *card)
 				if (pci_enable_device(tmp_hfcpci))
 					continue;
 				pci_set_master(tmp_hfcpci);
-				if ((card->para[0]) && (card->para[0] != (tmp_hfcpci->resource[ 0].start & PCI_BASE_ADDRESS_IO_MASK)))
+				if ((card->para[0]) && (card->para[0] != (get_pcibase(tmp_hfcpci, 0) & PCI_BASE_ADDRESS_IO_MASK)))
 					continue;
 				else
 					break;
@@ -1729,7 +1751,7 @@ setup_hfcpci(struct IsdnCard *card)
 				printk(KERN_WARNING "HFC-PCI: No IRQ for PCI card found\n");
 				return (0);
 			}
-			cs->hw.hfcpci.pci_io = (char *) dev_hfcpci->resource[ 1].start;
+			cs->hw.hfcpci.pci_io = (char *) get_pcibase(dev_hfcpci, 1);
 			printk(KERN_INFO "HiSax: HFC-PCI card manufacturer: %s card name: %s\n", id_list[i].vendor_name, id_list[i].card_name);
 		} else {
 			printk(KERN_WARNING "HFC-PCI: No PCI card found\n");
@@ -1746,7 +1768,7 @@ setup_hfcpci(struct IsdnCard *card)
 			printk(KERN_WARNING "HFC-PCI: Error allocating memory for FIFO!\n");
 			return 0;
 		}
-		cs->hw.hfcpci.fifos = (void *)
+		(ulong) cs->hw.hfcpci.fifos =
 		    (((ulong) cs->hw.hfcpci.share_start) & ~0x7FFF) + 0x8000;
 		pcibios_write_config_dword(cs->hw.hfcpci.pci_bus,
 				       cs->hw.hfcpci.pci_device_fn, 0x80,
--- a/drivers/isdn/hisax/hfc_pci.h
+++ b/drivers/isdn/hisax/hfc_pci.h
@@ -1,4 +1,4 @@
-/* $Id: hfc_pci.h,v 1.1.4.1 2001/11/20 14:19:35 kai Exp $
+/* $Id: hfc_pci.h,v 1.10 2001/09/24 13:22:56 kai Exp $
  *
  * specific defines for CCD's HFC 2BDS0 PCI chips
  *
--- a/drivers/isdn/hisax/hfc_sx.c
+++ b/drivers/isdn/hisax/hfc_sx.c
@@ -1,4 +1,4 @@
-/* $Id: hfc_sx.c,v 1.1.4.1 2001/11/20 14:19:35 kai Exp $
+/* $Id: hfc_sx.c,v 1.12 2001/09/24 13:22:56 kai Exp $
  *
  * level driver for CCD´s hfc-s+/sp based cards
  *
@@ -17,11 +17,10 @@
 #include "hfc_sx.h"
 #include "isdnl1.h"
 #include <linux/interrupt.h>
-#include <linux/isapnp.h>
 
 extern const char *CardType[];
 
-static const char *hfcsx_revision = "$Revision: 1.1.4.1 $";
+static const char *hfcsx_revision = "$Revision: 1.12 $";
 
 /***************************************/
 /* IRQ-table for CCDs demo board       */
@@ -940,6 +939,20 @@ hfcsx_interrupt(int intno, void *dev_id,
 static void
 hfcsx_dbusy_timer(struct IsdnCardState *cs)
 {
+#if 0
+	struct PStack *stptr;
+	if (test_bit(FLG_DBUSY_TIMER, &cs->HW_Flags)) {
+		if (cs->debug)
+			debugl1(cs, "D-Channel Busy");
+		test_and_set_bit(FLG_L1_DBUSY, &cs->HW_Flags);
+		stptr = cs->stlist;
+
+		while (stptr != NULL) {
+			stptr->l1.l1l2(stptr, PH_PAUSE | INDICATION, NULL);
+			stptr = stptr->next;
+		}
+	}
+#endif
 }
 
 /*************************************/
@@ -1333,6 +1346,17 @@ hfcsx_bh(struct IsdnCardState *cs)
  */
 	if (!cs)
 		return;
+#if 0
+	if (test_and_clear_bit(D_CLEARBUSY, &cs->event)) {
+		if (cs->debug)
+			debugl1(cs, "D-Channel Busy cleared");
+		stptr = cs->stlist;
+		while (stptr != NULL) {
+			stptr->l1.l1l2(stptr, PH_PAUSE | CONFIRM, NULL);
+			stptr = stptr->next;
+		}
+	}
+#endif
 	if (test_and_clear_bit(D_L1STATECHANGE, &cs->event)) {
 		if (!cs->hw.hfcsx.nt_mode)
 			switch (cs->dc.hfcsx.ph_state) {
@@ -1461,17 +1485,7 @@ hfcsx_card_msg(struct IsdnCardState *cs,
 	return (0);
 }
 
-#ifdef __ISAPNP__
-static struct isapnp_device_id hfc_ids[] __initdata = {
-	{ ISAPNP_VENDOR('T', 'A', 'G'), ISAPNP_FUNCTION(0x2620),
-	  ISAPNP_VENDOR('T', 'A', 'G'), ISAPNP_FUNCTION(0x2620), 
-	  (unsigned long) "Teles 16.3c2" },
-	{ 0, }
-};
 
-static struct isapnp_device_id *hdev = &hfc_ids[0];
-static struct pci_bus *pnp_c __devinitdata = NULL;
-#endif
 
 int __devinit
 setup_hfcsx(struct IsdnCard *card)
@@ -1482,45 +1496,6 @@ setup_hfcsx(struct IsdnCard *card)
 
 	strcpy(tmp, hfcsx_revision);
 	printk(KERN_INFO "HiSax: HFC-SX driver Rev. %s\n", HiSax_getrev(tmp));
-#ifdef __ISAPNP__
-	if (!card->para[1] && isapnp_present()) {
-		struct pci_bus *pb;
-		struct pci_dev *pd;
-
-		while(hdev->card_vendor) {
-			if ((pb = isapnp_find_card(hdev->card_vendor,
-				hdev->card_device, pnp_c))) {
-				pnp_c = pb;
-				pd = NULL;
-				if ((pd = isapnp_find_dev(pnp_c,
-					hdev->vendor, hdev->function, pd))) {
-					printk(KERN_INFO "HiSax: %s detected\n",
-						(char *)hdev->driver_data);
-					pd->prepare(pd);
-					pd->deactivate(pd);
-					pd->activate(pd);
-					card->para[1] = pd->resource[0].start;
-					card->para[0] = pd->irq_resource[0].start;
-					if (!card->para[0] || !card->para[1]) {
-						printk(KERN_ERR "HFC PnP:some resources are missing %ld/%lx\n",
-						card->para[0], card->para[1]);
-						pd->deactivate(pd);
-						return(0);
-					}
-					break;
-				} else {
-					printk(KERN_ERR "HFC PnP: PnP error card found, no device\n");
-				}
-			}
-			hdev++;
-			pnp_c=NULL;
-		} 
-		if (!hdev->card_vendor) {
-			printk(KERN_INFO "HFC PnP: no ISAPnP card found\n");
-			return(0);
-		}
-	}
-#endif
 	cs->hw.hfcsx.base = card->para[1] & 0xfffe;
 	cs->irq = card->para[0];
 	cs->hw.hfcsx.int_s1 = 0;
@@ -1603,3 +1578,7 @@ setup_hfcsx(struct IsdnCard *card)
 	cs->auxcmd = &hfcsx_auxcmd;
 	return (1);
 }
+
+
+
+
--- a/drivers/isdn/hisax/hfc_sx.h
+++ b/drivers/isdn/hisax/hfc_sx.h
@@ -1,4 +1,4 @@
-/* $Id: hfc_sx.h,v 1.1.4.1 2001/11/20 14:19:35 kai Exp $
+/* $Id$
  *
  * specific defines for CCD's HFC 2BDS0 S+,SP chips
  *
--- /dev/null
+++ b/drivers/isdn/hisax/hfc_usb.c
@@ -0,0 +1,1189 @@
+/* $Id: hfc_usb.c,v 2.3 2001/07/06 21:30:11 werner Exp $
+ *
+ *
+ *
+ * Author       (C) 2001 Werner Cornelius (werner@isdn-development.de)
+ *              modular driver for Colognechip HFC-USB chip
+ *              as plugin for HiSax isdn driver
+ *              type approval valid for HFC-S USB based TAs
+ *
+ * Copyright 2001  by Werner Cornelius (werner@isdn-development.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/types.h>
+#include <linux/stddef.h>
+#include <linux/timer.h>
+#include <linux/config.h>
+#include <linux/isdn_compat.h>
+#include <linux/init.h>
+#include "hisax.h"
+#include <linux/module.h>
+#include <linux/kernel_stat.h>
+#include <linux/tqueue.h>
+#include <linux/usb.h>
+#include <linux/kernel.h>
+#include <linux/smp_lock.h>
+#include <linux/sched.h>
+#include "hisax_loadable.h"
+
+#define INCLUDE_INLINE_FUNCS
+
+/***********/
+/* defines */
+/***********/
+#define HFC_CTRL_TIMEOUT 5	/* 5ms timeout writing/reading regs */
+#define HFC_TIMER_T3     7000	/* timeout for l1 activation timer */
+
+#define HFCUSB_L1_STATECHANGE   0	/* L1 state changed */
+#define HFCUSB_L1_DRX           1	/* D-frame received */
+#define HFCUSB_L1_ERX           2	/* E-frame received */
+#define HFCUSB_L1_DTX           4	/* D-frames completed */
+
+#define MAX_BCH_SIZE        2048	/* allowed B-channel packet size */
+
+#define HFCUSB_RX_THRESHOLD 64	/* threshold for fifo report bit rx */
+#define HFCUSB_TX_THRESHOLD 64	/* threshold for fifo report bit tx */
+
+#define HFCUSB_CHIP_ID    0x16	/* Chip ID register index */
+#define HFCUSB_CIRM       0x00	/* cirm register index */
+#define HFCUSB_USB_SIZE   0x07	/* int length register */
+#define HFCUSB_USB_SIZE_I 0x06	/* iso length register */
+#define HFCUSB_F_CROSS    0x0b	/* bit order register */
+#define HFCUSB_CLKDEL     0x37	/* bit delay register */
+#define HFCUSB_CON_HDLC   0xfa	/* channel connect register */
+#define HFCUSB_HDLC_PAR   0xfb
+#define HFCUSB_SCTRL      0x31	/* S-bus control register (tx) */
+#define HFCUSB_SCTRL_E    0x32	/* same for E and special funcs */
+#define HFCUSB_SCTRL_R    0x33	/* S-bus control register (rx) */
+#define HFCUSB_F_THRES    0x0c	/* threshold register */
+#define HFCUSB_FIFO       0x0f	/* fifo select register */
+#define HFCUSB_F_USAGE    0x1a	/* fifo usage register */
+#define HFCUSB_MST_MODE0  0x14
+#define HFCUSB_MST_MODE1  0x15
+#define HFCUSB_P_DATA     0x1f
+#define HFCUSB_INC_RES_F  0x0e
+#define HFCUSB_STATES     0x30
+
+#define HFCUSB_CHIPID 0x40	/* ID value of HFC-USB */
+
+/******************/
+/* fifo registers */
+/******************/
+#define HFCUSB_NUM_FIFOS   8	/* maximum number of fifos */
+#define HFCUSB_B1_TX       0	/* index for B1 transmit bulk/int */
+#define HFCUSB_B1_RX       1	/* index for B1 receive bulk/int */
+#define HFCUSB_B2_TX       2
+#define HFCUSB_B2_RX       3
+#define HFCUSB_D_TX        4
+#define HFCUSB_D_RX        5
+#define HFCUSB_PCM_TX      6
+#define HFCUSB_PCM_RX      7
+
+/************/
+/* LED mask */
+/************/
+#define LED_DRIVER         0x1
+#define LED_L1             0x2
+#define LED_BCH            0x4
+
+/**********/
+/* macros */
+/**********/
+#define Write_hfc(a,b,c) usb_control_msg((a)->dev,(a)->ctrl_out_pipe,0,0x40,(c),(b),0,0,HFC_CTRL_TIMEOUT)
+#define Read_hfc(a,b,c) usb_control_msg((a)->dev,(a)->ctrl_in_pipe,1,0xC0,0,(b),(c),1,HFC_CTRL_TIMEOUT)
+
+#ifdef COMPAT_HAS_USB_IDTAB
+/****************************************/
+/* data defining the devices to be used */
+/****************************************/
+static __devinitdata const struct usb_device_id hfc_usb_idtab[3] = {
+	{USB_DEVICE(0x959, 0x2bd0)},	/* Colognechip ROM */
+	{USB_DEVICE(0x7b0, 0x0006)},	/* USB TA 128 */
+	{}			/* end with an all-zeroes entry */
+};
+#endif
+
+/*************************************************/
+/* entry and size of output/input control buffer */
+/*************************************************/
+#define HFC_CTRL_BUFSIZE 32
+typedef struct {
+	__u8 hfc_reg;		/* register number */
+	__u8 reg_val;		/* value to be written (or read) */
+} ctrl_buft;
+
+/***************************************************************/
+/* structure defining input+output fifos (interrupt/bulk mode) */
+/***************************************************************/
+struct hfcusb_data;		/* forward definition */
+typedef struct {
+	int fifonum;		/* fifo index attached to this structure */
+	__u8 fifo_mask;		/* mask for this fifo */
+	int active;		/* fifo is currently active */
+	struct hfcusb_data *hfc;	/* pointer to main structure */
+	int pipe;		/* address of endpoint */
+	__u8 usb_maxlen;	/* maximum length for usb transfer */
+	int max_size;		/* maximum size of receive/send packet */
+	int transmode;		/* transparent mode selected */
+	int framenum;		/* number of frame when last tx completed */
+	int rx_offset;		/* offset inside rx buffer */
+	int next_complete;	/* complete marker */
+	__u8 *act_ptr;		/* pointer to next data */
+	__u8 intervall;		/* interrupt interval */
+	struct sk_buff *buff;	/* actual used buffer */
+	urb_t urb;		/* transfer structure for usb routines */
+	__u8 buffer[128];	/* buffer incoming/outgoing data */
+} usb_fifo;
+
+/*********************************************/
+/* structure holding all data for one device */
+/*********************************************/
+typedef struct hfcusb_data {
+	struct hisax_drvreg regd;	/* register data and callbacks */
+	struct usb_device *dev;	/* our device */
+	int if_used;		/* used interface number */
+	int alt_used;		/* used alternate config */
+	int ctrl_paksize;	/* control pipe packet size */
+	int ctrl_in_pipe, ctrl_out_pipe;	/* handles for control pipe */
+
+	/* control pipe background handling */
+	ctrl_buft ctrl_buff[HFC_CTRL_BUFSIZE];	/* buffer holding queued data */
+	volatile int ctrl_in_idx, ctrl_out_idx, ctrl_cnt;	/* input/output pointer + count */
+	urb_t ctrl_urb;		/* transfer structure for control channel */
+	devrequest ctrl_write;	/* buffer for control write request */
+	devrequest ctrl_read;	/* same for read request */
+
+	volatile __u8 dfifo_fill;	/* value read from tx d-fifo */
+	volatile __u8 active_fifos;	/* fifos currently active as bit mask */
+	volatile __u8 threshold_mask;	/* threshold actually reported */
+	volatile __u8 service_request;	/* fifo needs service from task */
+	volatile __u8 ctrl_fifo;	/* last selected fifo */
+	volatile __u8 bch_enables;	/* or mask for sctrl_r and sctrl register values */
+        volatile __u8 led_req;          /* request status of adapters leds */ 
+        volatile __u8 led_act;          /* active status of adapters leds */ 
+	usb_fifo fifos[HFCUSB_NUM_FIFOS];	/* structure holding all fifo data */
+
+	/* layer 1 activation/deactivation handling */
+	volatile __u8 l1_state;	/* actual l1 state */
+	volatile ulong l1_event;	/* event mask */
+	struct tq_struct l1_tq;	/* l1 bh structure */
+	struct timer_list t3_timer;	/* timer for activation/deactivation */
+	struct timer_list t4_timer;	/* timer for activation/deactivation */
+} hfcusb_data;
+
+#if 0
+static void
+usb_dump_urb(purb_t purb)
+{
+	printk("urb                   :%p\n", purb);
+	printk("next                  :%p\n", purb->next);
+	printk("dev                   :%p\n", purb->dev);
+	printk("pipe                  :%08X\n", purb->pipe);
+	printk("status                :%d\n", purb->status);
+	printk("transfer_flags        :%08X\n", purb->transfer_flags);
+	printk("transfer_buffer       :%p\n", purb->transfer_buffer);
+	printk("transfer_buffer_length:%d\n",
+	       purb->transfer_buffer_length);
+	printk("actual_length         :%d\n", purb->actual_length);
+	printk("setup_packet          :%p\n", purb->setup_packet);
+	printk("start_frame           :%d\n", purb->start_frame);
+	printk("number_of_packets     :%d\n", purb->number_of_packets);
+	printk("interval              :%d\n", purb->interval);
+	printk("error_count           :%d\n", purb->error_count);
+	printk("context               :%p\n", purb->context);
+	printk("complete              :%p\n", purb->complete);
+}
+#endif
+
+/*************************************************************************/
+/* bottom half handler for L1 activation/deactiavtaion + D-chan + E-chan */
+/*************************************************************************/
+static void
+usb_l1d_bh(hfcusb_data * hfc)
+{
+
+	while (hfc->l1_event) {
+		if (test_and_clear_bit
+		    (HFCUSB_L1_STATECHANGE, &hfc->l1_event)) {
+			if (hfc->l1_state == 7)
+			    hfc->led_req |= LED_L1;
+			else
+			    hfc->led_req &= ~LED_L1;
+			if ((hfc->l1_state == 7) ||
+			    (hfc->l1_state == 3))
+			    hfc->regd.dch_l1l2(hfc->regd.arg_hisax,
+					       (hfc->l1_state ==
+						7) ? (PH_ACTIVATE |
+						      INDICATION)
+					       : (PH_DEACTIVATE | INDICATION),
+					       NULL);
+		}
+		if (test_and_clear_bit(HFCUSB_L1_DRX, &hfc->l1_event)) {
+			hfc->regd.dch_l1l2(hfc->regd.arg_hisax,
+					   PH_DATA | INDICATION,
+					   (void *) 0);
+		}
+		if (test_and_clear_bit(HFCUSB_L1_ERX, &hfc->l1_event)) {
+			hfc->regd.dch_l1l2(hfc->regd.arg_hisax,
+					   PH_DATA | INDICATION,
+					   (void *) 1);
+		}
+		if (test_and_clear_bit(HFCUSB_L1_DTX, &hfc->l1_event)) {
+			hfc->regd.dch_l1l2(hfc->regd.arg_hisax,
+					   PH_DATA | CONFIRM, NULL);
+		}
+	}			/* while */
+}				/* usb_l1d_bh */
+
+/******************************************************/
+/* start next background transfer for control channel */
+/******************************************************/
+static void
+ctrl_start_transfer(hfcusb_data * hfc)
+{
+
+	if (hfc->ctrl_cnt) {
+		switch (hfc->ctrl_buff[hfc->ctrl_out_idx].hfc_reg) {
+			case HFCUSB_F_USAGE:
+				hfc->ctrl_urb.pipe = hfc->ctrl_in_pipe;
+				hfc->ctrl_urb.setup_packet =
+				    (u_char *) & hfc->ctrl_read;
+				hfc->ctrl_urb.transfer_buffer_length = 1;
+				hfc->ctrl_read.index =
+				    hfc->ctrl_buff[hfc->ctrl_out_idx].
+				    hfc_reg;
+				hfc->ctrl_urb.transfer_buffer =
+				    (char *) &hfc->dfifo_fill;
+				break;
+
+			default:	/* write register */
+				hfc->ctrl_urb.pipe = hfc->ctrl_out_pipe;
+				hfc->ctrl_urb.setup_packet =
+				    (u_char *) & hfc->ctrl_write;
+				hfc->ctrl_urb.transfer_buffer = NULL;
+				hfc->ctrl_urb.transfer_buffer_length = 0;
+				hfc->ctrl_write.index =
+				    hfc->ctrl_buff[hfc->ctrl_out_idx].
+				    hfc_reg;
+				hfc->ctrl_write.value =
+				    hfc->ctrl_buff[hfc->ctrl_out_idx].
+				    reg_val;
+				break;
+		}
+		usb_submit_urb(&hfc->ctrl_urb);	/* start transfer */
+	}
+}				/* ctrl_start_transfer */
+
+/************************************/
+/* queue a control transfer request */
+/* return 0 on success.             */
+/************************************/
+static int
+queue_control_request(hfcusb_data * hfc, __u8 reg, __u8 val)
+{
+	ctrl_buft *buf;
+
+	if (hfc->ctrl_cnt >= HFC_CTRL_BUFSIZE)
+		return (1);	/* no space left */
+	buf = hfc->ctrl_buff + hfc->ctrl_in_idx;	/* pointer to new index */
+	buf->hfc_reg = reg;
+	buf->reg_val = val;
+	if (++hfc->ctrl_in_idx >= HFC_CTRL_BUFSIZE)
+		hfc->ctrl_in_idx = 0;	/* pointer wrap */
+	if (++hfc->ctrl_cnt == 1)
+		ctrl_start_transfer(hfc);
+	return (0);
+}				/* queue_control_request */
+
+/**************************************/
+/* called when timer t3 or t4 expires */
+/**************************************/
+static void
+l1_timer_expire(hfcusb_data * hfc)
+{
+    if (timer_pending(&hfc->t4_timer))
+	del_timer(&hfc->t4_timer);
+    queue_control_request(hfc, HFCUSB_STATES, 0x40);
+    test_and_set_bit(HFCUSB_L1_STATECHANGE,
+		     &hfc->l1_event);
+    queue_task(&hfc->l1_tq, &tq_immediate);
+    mark_bh(IMMEDIATE_BH);
+} /* l1_timer_expire */
+
+/**************************************************/
+/* (re)fills a tx-fifo urb. Queuing is done later */
+/**************************************************/
+static void
+fill_tx_urb(usb_fifo * fifo)
+{
+	struct sk_buff *skb;
+	long flags;
+	int i, ii = 0;
+
+	fifo->urb.dev = fifo->hfc->dev;
+	if ((fifo->buff)
+	    && (fifo->urb.transfer_buffer_length < fifo->usb_maxlen)) {
+		switch (fifo->fifonum) {
+			case HFCUSB_B1_TX:
+			case HFCUSB_B2_TX:
+				skb = fifo->buff;
+				fifo->buff = NULL;
+				fifo->hfc->regd.bch_l1l2(fifo->hfc->regd.
+							 arg_hisax,
+							 (fifo->fifonum ==
+							  HFCUSB_B1_TX) ? 0
+							 : 1,
+							 (PH_DATA |
+							  CONFIRM),
+							 (void *) skb);
+				fifo->hfc->service_request |=
+				    fifo->fifo_mask;
+				return;
+			case HFCUSB_D_TX:
+				dev_kfree_skb_any(fifo->buff);
+				fifo->buff = NULL;
+				save_flags(flags);
+				cli();
+				fifo->hfc->dfifo_fill = 0xff;	/* currently invalid data */
+				queue_control_request(fifo->hfc,
+						      HFCUSB_FIFO,
+						      HFCUSB_D_TX);
+				queue_control_request(fifo->hfc,
+						      HFCUSB_F_USAGE, 0);
+				restore_flags(flags);
+				return;
+			default:
+				return;	/* error, invalid fifo */
+		}
+	}
+
+	/* check if new buffer needed */
+	if (!fifo->buff) {
+		switch (fifo->fifonum) {
+			case HFCUSB_B1_TX:
+				if (fifo->hfc->regd.bsk[0])
+					fifo->buff = *fifo->hfc->regd.bsk[0];	/* B1-channel tx buffer */
+				break;
+			case HFCUSB_B2_TX:
+				if (fifo->hfc->regd.bsk[1])
+					fifo->buff = *fifo->hfc->regd.bsk[1];	/* B2-channel tx buffer */
+				break;
+			case HFCUSB_D_TX:
+				if (fifo->hfc->regd.dsq)
+					fifo->buff = skb_dequeue(fifo->hfc->regd.dsq);	/* D-channel tx queue */
+				break;
+			default:
+				return;	/* error, invalid fifo */
+		}
+		if (!fifo->buff) {
+			fifo->active = 0;	/* we are inactive now */
+			fifo->hfc->active_fifos &= ~fifo->fifo_mask;
+			if (fifo->fifonum == HFCUSB_D_TX) {
+				test_and_set_bit(HFCUSB_L1_DTX,
+						 &fifo->hfc->l1_event);
+				queue_task(&fifo->hfc->l1_tq,
+					   &tq_immediate);
+				mark_bh(IMMEDIATE_BH);
+			}
+			return;
+		}
+		fifo->act_ptr = fifo->buff->data;	/* start of data */
+		fifo->active = 1;
+		ii = 1;
+		fifo->hfc->active_fifos |= fifo->fifo_mask;
+		fifo->hfc->service_request &= ~fifo->fifo_mask;
+	}
+	/* fillup the send buffer */
+	i = fifo->buff->len - (fifo->act_ptr - fifo->buff->data);	/* remaining length */
+	fifo->buffer[0] = !fifo->transmode;	/* not eof */
+	if (i > (fifo->usb_maxlen - ii)) {
+		i = fifo->usb_maxlen - ii;
+	}
+	if (i)
+		memcpy(fifo->buffer + ii, fifo->act_ptr, i);
+	fifo->urb.transfer_buffer_length = i + ii;
+        fifo->rx_offset = ii;
+}				/* fill_tx_urb */
+
+/************************************************/
+/* transmit completion routine for all tx fifos */
+/************************************************/
+static void
+tx_complete(purb_t urb)
+{
+	usb_fifo *fifo = (usb_fifo *) urb->context;	/* pointer to our fifo */
+
+	fifo->hfc->service_request &= ~fifo->fifo_mask;	/* no further handling */
+	fifo->framenum = usb_get_current_frame_number(fifo->hfc->dev);
+
+	/* check for deactivation or error */
+	if ((!fifo->active) || (urb->status)) {
+		fifo->hfc->active_fifos &= ~fifo->fifo_mask;	/* we are inactive */
+		fifo->active = 0;
+		if ((fifo->buff) && (fifo->fifonum == HFCUSB_D_TX)) {
+			dev_kfree_skb_any(fifo->buff);
+		}
+		fifo->buff = NULL;
+		return;
+	}
+	fifo->act_ptr += (urb->transfer_buffer_length - fifo->rx_offset);	/* adjust pointer */
+	fill_tx_urb(fifo);	/* refill the urb */
+	fifo->hfc->threshold_mask |= fifo->fifo_mask;	/* assume threshold reached */
+	if (fifo->buff)
+		fifo->hfc->service_request |= fifo->fifo_mask;	/* need to restart */
+}				/* tx_complete */
+
+/***********************************************/
+/* receive completion routine for all rx fifos */
+/***********************************************/
+static void
+rx_complete(purb_t urb)
+{
+	usb_fifo *fifo = (usb_fifo *) urb->context;	/* pointer to our fifo */
+	hfcusb_data *hfc = fifo->hfc;
+	usb_fifo *txfifo;
+	__u8 last_state;
+	int i, ii, currcnt, hdlci;
+	struct sk_buff *skb;
+
+	urb->dev = hfc->dev; /* security init */
+	if ((!fifo->active) || (urb->status)) {
+		hfc->service_request &= ~fifo->fifo_mask;	/* no further handling */
+		hfc->active_fifos &= ~fifo->fifo_mask;	/* we are inactive */
+		fifo->urb.interval = 0;	/* cancel automatic rescheduling */
+		if (fifo->buff) {
+			dev_kfree_skb_any(fifo->buff);
+			fifo->buff = NULL;
+		}
+		return;
+	}
+
+	/* first check for any status changes */
+	if ((urb->actual_length < fifo->rx_offset)
+	    || (urb->actual_length > fifo->usb_maxlen))
+		return;		/* error condition */
+
+	if (fifo->rx_offset) {
+		hfc->threshold_mask = fifo->buffer[1];	/* update threshold status */
+		fifo->next_complete = fifo->buffer[0] & 1;
+		if ((fifo->fifonum == HFCUSB_D_RX) &&
+		    (hfc->led_req != hfc->led_act))
+		    queue_control_request(hfc, HFCUSB_P_DATA, hfc->led_req);
+
+		/* check if rescheduling needed */
+		if ((i =
+		     hfc->service_request & hfc->active_fifos & ~hfc->
+		     threshold_mask)) {
+			currcnt =
+			    usb_get_current_frame_number(hfc->dev);
+			txfifo = hfc->fifos + HFCUSB_B1_TX;
+			ii = 3;
+			while (ii--) {
+				if ((i & txfifo->fifo_mask)
+				    && (currcnt != txfifo->framenum)) {
+					hfc->service_request &=
+					    ~txfifo->fifo_mask;
+					if (!txfifo->buff)
+						fill_tx_urb(txfifo);
+					if (txfifo->buff)
+						usb_submit_urb(&txfifo->
+							       urb);
+				}
+				txfifo += 2;
+			}
+		}
+
+		/* handle l1 events */
+		if ((fifo->buffer[0] >> 4) != hfc->l1_state) {
+			last_state = hfc->l1_state;
+			hfc->l1_state = fifo->buffer[0] >> 4;	/* update status */
+			if (timer_pending(&hfc->t4_timer))
+			    del_timer(&hfc->t4_timer);
+			if (((hfc->l1_state == 3) && 
+			     ((last_state == 7) || 
+			      (last_state == 8))) || 
+			    ((timer_pending(&hfc->t3_timer) &&
+			    (hfc->l1_state == 8)))) {
+			    hfc->t4_timer.expires = jiffies + 2;
+			    add_timer(&hfc->t4_timer);
+			} else { 
+				if (timer_pending(&hfc->t3_timer)
+				    && (hfc->l1_state == 7))
+					del_timer(&hfc->t3_timer);	/* no longer needed */
+				test_and_set_bit(HFCUSB_L1_STATECHANGE,
+						 &hfc->l1_event);
+				queue_task(&hfc->l1_tq, &tq_immediate);
+				mark_bh(IMMEDIATE_BH);
+			}
+		}
+	}
+
+	/* check the length for data and move if present */
+	if (fifo->next_complete || (urb->actual_length > fifo->rx_offset)) {
+		i = fifo->buff->len + urb->actual_length - fifo->rx_offset;	/* new total length */
+		hdlci = (fifo->transmode) ? 0 : 3;
+		if (i <= (fifo->max_size + hdlci)) {
+			memcpy(fifo->act_ptr,
+			       fifo->buffer + fifo->rx_offset,
+			       urb->actual_length - fifo->rx_offset);
+			fifo->act_ptr +=
+			    (urb->actual_length - fifo->rx_offset);
+			fifo->buff->len +=
+			    (urb->actual_length - fifo->rx_offset);
+		} else
+			fifo->buff->len = fifo->max_size + 4;	/* mark frame as to long */
+		if (fifo->next_complete && (urb->actual_length < fifo->usb_maxlen)) {
+		    /* the frame is complete */
+		    fifo->next_complete = 0;
+		    if (((!*(fifo->act_ptr - 1)) || fifo->transmode) &&
+			(fifo->buff->len >= (hdlci + 1))
+			&& (fifo->buff->len <=
+			    (fifo->max_size + hdlci)) &&
+			((skb = dev_alloc_skb(fifo->max_size + hdlci)) != NULL)) {
+			fifo->buff->len -= hdlci;	/* adjust size */
+			switch (fifo->fifonum) {
+			    case HFCUSB_D_RX:
+				skb_queue_tail(hfc->regd.
+					       drq,
+					       fifo->buff);
+				test_and_set_bit
+				    (HFCUSB_L1_DRX,
+				     &hfc->l1_event);
+				queue_task(&hfc->l1_tq,
+					   &tq_immediate);
+				mark_bh(IMMEDIATE_BH);
+				break;
+
+			    case HFCUSB_B1_RX:
+				if (hfc->regd.brq[0]) {
+				    skb_queue_tail
+					(hfc->regd.
+					 brq[0],
+					 fifo->buff);
+				    hfc->regd.
+					bch_l1l2(hfc->
+						 regd.
+						 arg_hisax,
+						 0,
+						 PH_DATA
+						 |
+						 INDICATION,
+						 (void *)
+						 fifo->
+						 buff);
+				} else
+				    dev_kfree_skb_any
+					(fifo->buff);
+				break;
+				
+			    case HFCUSB_B2_RX:
+				if (hfc->regd.brq[1]) {
+				    skb_queue_tail
+					(hfc->regd.
+					 brq[1],
+					 fifo->buff);
+				    hfc->regd.
+					bch_l1l2(hfc->
+						 regd.
+						 arg_hisax,
+						 1,
+						 PH_DATA
+						 |
+						 INDICATION,
+						 (void
+						  *)
+						 fifo->
+						 buff);
+				} else
+				    dev_kfree_skb_any
+					(fifo->buff);
+				break;
+
+			    case HFCUSB_PCM_RX:
+				skb_queue_tail(&hfc->regd.
+					       erq,
+					       fifo->buff);
+				test_and_set_bit
+				    (HFCUSB_L1_ERX,
+				     &hfc->l1_event);
+				queue_task(&hfc->l1_tq,
+					   &tq_immediate);
+				mark_bh(IMMEDIATE_BH);
+				break;
+
+			    default:
+				dev_kfree_skb_any(fifo->
+						  buff);
+				break;
+			}
+			fifo->buff = skb;
+		    } 
+		    fifo->buff->len = 0;	/* reset counter */
+		    fifo->act_ptr = fifo->buff->data;	/* and pointer */
+		}
+	}
+	fifo->rx_offset = (urb->actual_length < fifo->usb_maxlen) ? 2 : 0;
+}				/* rx_complete */
+
+/***************************************************/
+/* start the interrupt transfer for the given fifo */
+/***************************************************/
+static void
+start_rx_fifo(usb_fifo * fifo)
+{
+	if (fifo->buff)
+		return;		/* still active */
+	if (!
+	    (fifo->buff =
+	     dev_alloc_skb(fifo->max_size + (fifo->transmode ? 0 : 3))))
+		return;
+	fifo->act_ptr = fifo->buff->data;
+	FILL_INT_URB(&fifo->urb, fifo->hfc->dev, fifo->pipe, fifo->buffer,
+		     fifo->usb_maxlen, rx_complete, fifo, fifo->intervall);
+	fifo->next_complete = 0;
+	fifo->rx_offset = 2;
+	fifo->active = 1;	/* must be marked active */
+	fifo->hfc->active_fifos |= fifo->fifo_mask;
+	if (usb_submit_urb(&fifo->urb)) {
+		fifo->active = 0;
+		fifo->hfc->active_fifos &= ~fifo->fifo_mask;
+		dev_kfree_skb_any(fifo->buff);
+		fifo->buff = NULL;
+	}
+}				/* start_rx_fifo */
+
+/***************************************************************/
+/* control completion routine handling background control cmds */
+/***************************************************************/
+static void
+ctrl_complete(purb_t urb)
+{
+	hfcusb_data *hfc = (hfcusb_data *) urb->context;
+
+	urb->dev = hfc->dev;
+	if (hfc->ctrl_cnt) {
+		switch (hfc->ctrl_buff[hfc->ctrl_out_idx].hfc_reg) {
+			case HFCUSB_FIFO:
+				hfc->ctrl_fifo =
+				    hfc->ctrl_buff[hfc->ctrl_out_idx].
+				    reg_val;
+				break;
+			case HFCUSB_F_USAGE:
+				if (!hfc->dfifo_fill) {
+					fill_tx_urb(hfc->fifos +
+						    HFCUSB_D_TX);
+					if (hfc->fifos[HFCUSB_D_TX].buff)
+						usb_submit_urb(&hfc->
+							       fifos
+							       [HFCUSB_D_TX].
+							       urb);
+				} else {
+					queue_control_request(hfc,
+							      HFCUSB_FIFO,
+							      HFCUSB_D_TX);
+					queue_control_request(hfc,
+							      HFCUSB_F_USAGE,
+							      0);
+				}
+				break;
+			case HFCUSB_SCTRL_R:
+				switch (hfc->ctrl_fifo) {
+					case HFCUSB_B1_RX:
+						if (hfc->bch_enables & 1)
+							start_rx_fifo(hfc->
+								      fifos
+								      +
+								      HFCUSB_B1_RX);
+						break;
+					case HFCUSB_B2_RX:
+						if (hfc->bch_enables & 2)
+							start_rx_fifo(hfc->
+								      fifos
+								      +
+								      HFCUSB_B2_RX);
+						break;
+				}
+				if (hfc->bch_enables & 3)
+				    hfc->led_req |= LED_BCH;
+				else
+				    hfc->led_req &= ~LED_BCH;
+				break;
+			case HFCUSB_P_DATA:
+				hfc->led_act =
+				    hfc->ctrl_buff[hfc->ctrl_out_idx].
+				    reg_val;
+				break;
+		}
+		hfc->ctrl_cnt--;	/* decrement actual count */
+		if (++hfc->ctrl_out_idx >= HFC_CTRL_BUFSIZE)
+			hfc->ctrl_out_idx = 0;	/* pointer wrap */
+		ctrl_start_transfer(hfc);	/* start next transfer */
+	}
+}				/* ctrl_complete */
+
+/*****************************************/
+/* Layer 1 + D channel access from HiSax */
+/*****************************************/
+static void
+hfcusb_l1_access(void *drvarg, int pr, void *arg)
+{
+	hfcusb_data *hfc = (hfcusb_data *) drvarg;
+
+	switch (pr) {
+		case (PH_DATA | REQUEST):
+		case (PH_PULL | INDICATION):
+			skb_queue_tail(hfc->regd.dsq,
+				       (struct sk_buff *) arg);
+			if (!hfc->fifos[HFCUSB_D_TX].active
+			    && !hfc->dfifo_fill) {
+				fill_tx_urb(hfc->fifos + HFCUSB_D_TX);
+				hfc->active_fifos |=
+				    hfc->fifos[HFCUSB_D_TX].fifo_mask;
+				usb_submit_urb(&hfc->fifos[HFCUSB_D_TX].
+					       urb);
+			}
+			break;
+		case (PH_ACTIVATE | REQUEST):
+		    switch (hfc->l1_state) {
+			case 6:
+			case 8:
+				hfc->regd.dch_l1l2(hfc->regd.arg_hisax,
+						   (PH_DEACTIVATE |
+						   INDICATION), NULL);
+
+				break;
+			case 7:
+				hfc->regd.dch_l1l2(hfc->regd.arg_hisax,
+						   (PH_ACTIVATE |
+						   INDICATION), NULL);
+
+				break;
+			default:
+				queue_control_request(hfc, HFCUSB_STATES, 0x60);	/* start activation */
+				hfc->t3_timer.expires =
+				    jiffies + (HFC_TIMER_T3 * HZ) / 1000;
+				if (!timer_pending(&hfc->t3_timer))
+					add_timer(&hfc->t3_timer);
+				break;
+		    }
+		    break;
+
+		case (PH_DEACTIVATE | REQUEST):
+			queue_control_request(hfc, HFCUSB_STATES, 0x40);	/* start deactivation */
+			break;
+		default:
+			printk(KERN_INFO "unknown hfcusb l1_access 0x%x\n",
+			       pr);
+			break;
+	}
+}				/* hfcusb_l1_access */
+
+/*******************************/
+/* B channel access from HiSax */
+/*******************************/
+static void
+hfcusb_bch_access(void *drvarg, int chan, int pr, void *arg)
+{
+	hfcusb_data *hfc = (hfcusb_data *) drvarg;
+	usb_fifo *fifo = hfc->fifos + (chan ? HFCUSB_B2_TX : HFCUSB_B1_TX);
+	long flags;
+
+	switch (pr) {
+		case (PH_DATA | REQUEST):
+		case (PH_PULL | INDICATION):
+			save_flags(flags);
+			cli();
+			if (!fifo->active) {
+				fill_tx_urb(fifo);
+				hfc->active_fifos |= fifo->fifo_mask;
+				usb_submit_urb(&fifo->urb);
+			}
+			restore_flags(flags);
+			break;
+		case (PH_ACTIVATE | REQUEST):
+			if (!((int) arg)) {
+				hfc->bch_enables &= ~(1 << chan);
+				if (fifo->active) {
+					fifo->active = 0;
+					usb_unlink_urb(&fifo->urb);
+				}
+				save_flags(flags);
+				cli();
+				queue_control_request(hfc, HFCUSB_FIFO,
+						      fifo->fifonum);
+				queue_control_request(hfc,
+						      HFCUSB_INC_RES_F, 2);
+				queue_control_request(hfc, HFCUSB_CON_HDLC,
+						      9);
+				queue_control_request(hfc, HFCUSB_SCTRL,
+						      0x40 +
+						      hfc->bch_enables);
+				queue_control_request(hfc, HFCUSB_SCTRL_R,
+						      hfc->bch_enables);
+				restore_flags(flags);
+				fifo++;
+				if (fifo->active) {
+					fifo->active = 0;
+					usb_unlink_urb(&fifo->urb);
+				}
+				return;	/* fifo deactivated */
+			}
+			fifo->transmode = ((int) arg == L1_MODE_TRANS);
+			fifo->max_size =
+			    ((fifo->transmode) ? fifo->
+			     usb_maxlen : MAX_BCH_SIZE);
+			(fifo + 1)->transmode = fifo->transmode;
+			(fifo + 1)->max_size = fifo->max_size;
+			hfc->bch_enables |= (1 << chan);
+			save_flags(flags);
+			cli();
+			queue_control_request(hfc, HFCUSB_FIFO,
+					      fifo->fifonum);
+			queue_control_request(hfc, HFCUSB_CON_HDLC,
+					      ((!fifo->
+						transmode) ? 9 : 11));
+			queue_control_request(hfc, HFCUSB_INC_RES_F, 2);
+			queue_control_request(hfc, HFCUSB_SCTRL,
+					      0x40 + hfc->bch_enables);
+			if ((int) arg == L1_MODE_HDLC)
+				queue_control_request(hfc, HFCUSB_CON_HDLC,
+						      8);
+			queue_control_request(hfc, HFCUSB_FIFO,
+					      fifo->fifonum + 1);
+			queue_control_request(hfc, HFCUSB_CON_HDLC,
+					      ((!fifo->
+						transmode) ? 8 : 10));
+			queue_control_request(hfc, HFCUSB_INC_RES_F, 2);
+			queue_control_request(hfc, HFCUSB_SCTRL_R,
+					      hfc->bch_enables);
+			restore_flags(flags);
+
+			break;
+
+		default:
+			printk(KERN_INFO
+			       "unknown hfcusb bch_access chan %d 0x%x\n",
+			       chan, pr);
+			break;
+	}
+}				/* hfcusb_bch_access */
+
+/***************************************************************************/
+/* usb_init is called once when a new matching device is detected to setup */
+/* main parmeters. It registers the driver at the main hisax module.       */
+/* on success 0 is returned.                                               */
+/***************************************************************************/
+static int
+usb_init(hfcusb_data * hfc)
+{
+	usb_fifo *fifo;
+	int i;
+	u_char b;
+
+	/* check the chip id */
+	if ((Read_hfc(hfc, HFCUSB_CHIP_ID, &b) != 1) ||
+	    (b != HFCUSB_CHIPID)) {
+		printk(KERN_INFO "HFC-USB: Invalid chip id 0x%02x\n", b);
+		return (1);
+	}
+
+	/* first set the needed config, interface and alternate */
+	usb_set_configuration(hfc->dev, 1);
+	usb_set_interface(hfc->dev, hfc->if_used, hfc->alt_used);
+
+        /* init the led state request */
+	hfc->led_req = LED_DRIVER;
+
+	/* now we initialise the chip */
+	Write_hfc(hfc, HFCUSB_CIRM, 0x10);	/* aux = output, reset off */
+	Write_hfc(hfc, HFCUSB_P_DATA, 0);       /* leds = off */
+	Write_hfc(hfc, HFCUSB_USB_SIZE,
+		  (hfc->fifos[HFCUSB_B1_TX].usb_maxlen >> 3) |
+		  ((hfc->fifos[HFCUSB_B1_RX].usb_maxlen >> 3) << 4));
+
+	/* enable PCM/GCI master mode */
+	Write_hfc(hfc, HFCUSB_MST_MODE1, 0);	/* set default values */
+	Write_hfc(hfc, HFCUSB_MST_MODE0, 1);	/* enable master mode */
+
+	/* init the fifos */
+	Write_hfc(hfc, HFCUSB_F_THRES, (HFCUSB_TX_THRESHOLD >> 3) |
+		  ((HFCUSB_RX_THRESHOLD >> 3) << 4));
+
+	for (i = 0, fifo = hfc->fifos + i; i < HFCUSB_NUM_FIFOS;
+	     i++, fifo++) {
+		Write_hfc(hfc, HFCUSB_FIFO, i);	/* select the desired fifo */
+
+		fifo->transmode = 0;	/* hdlc mode selected */
+		fifo->buff = NULL;	/* init buffer pointer */
+		fifo->max_size =
+		    (i <= HFCUSB_B2_RX) ? MAX_BCH_SIZE : MAX_DFRAME_LEN;
+		Write_hfc(hfc, HFCUSB_HDLC_PAR, ((i <= HFCUSB_B2_RX) ? 0 : 2));	/* data length */
+		Write_hfc(hfc, HFCUSB_CON_HDLC, ((i & 1) ? 0x08 : 0x09));	/* rx hdlc, tx fill 1 */
+		Write_hfc(hfc, HFCUSB_INC_RES_F, 2);	/* reset the fifo */
+	}
+
+	Write_hfc(hfc, HFCUSB_CLKDEL, 0x0f);	/* clock delay value */
+	Write_hfc(hfc, HFCUSB_STATES, 3 | 0x10);	/* set deactivated mode */
+	Write_hfc(hfc, HFCUSB_STATES, 3);	/* enable state machine */
+
+	Write_hfc(hfc, HFCUSB_SCTRL_R, 0);	/* disable both B receivers */
+	Write_hfc(hfc, HFCUSB_SCTRL, 0x40);	/* disable B transmitters + cap mode */
+
+	/* init the l1 timer */
+	init_timer(&hfc->t3_timer);
+	hfc->t3_timer.data = (long) hfc;
+	hfc->t3_timer.function = (void *) l1_timer_expire;
+	hfc->t4_timer.data = (long) hfc;
+	hfc->t4_timer.function = (void *) l1_timer_expire;
+	hfc->l1_tq.routine = (void *) (void *) usb_l1d_bh;
+	hfc->l1_tq.sync = 0;
+	hfc->l1_tq.data = hfc;
+
+	/* init the background control machinery */
+	hfc->ctrl_read.requesttype = 0xc0;
+	hfc->ctrl_read.request = 1;
+	hfc->ctrl_read.length = 1;
+	hfc->ctrl_write.requesttype = 0x40;
+	hfc->ctrl_write.request = 0;
+	hfc->ctrl_write.length = 0;
+	FILL_CONTROL_URB(&hfc->ctrl_urb, hfc->dev, hfc->ctrl_out_pipe,
+			 (u_char *) & hfc->ctrl_write, NULL, 0,
+			 ctrl_complete, hfc);
+
+	/* init the TX-urbs */
+	fifo = hfc->fifos + HFCUSB_D_TX;
+	FILL_BULK_URB(&fifo->urb, hfc->dev, fifo->pipe,
+		      (u_char *) fifo->buffer, 0, tx_complete, fifo);
+	fifo = hfc->fifos + HFCUSB_B1_TX;
+	FILL_BULK_URB(&fifo->urb, hfc->dev, fifo->pipe,
+		      (u_char *) fifo->buffer, 0, tx_complete, fifo);
+	fifo = hfc->fifos + HFCUSB_B2_TX;
+	FILL_BULK_URB(&fifo->urb, hfc->dev, fifo->pipe,
+		      (u_char *) fifo->buffer, 0, tx_complete, fifo);
+
+	/* init the E-buffer */
+	skb_queue_head_init(&hfc->regd.erq);
+
+	/* now register ourself at hisax */
+	hfc->regd.version = HISAX_LOAD_VERSION;	/* set our version */
+	hfc->regd.cmd = HISAX_LOAD_REGISTER;	/* register command */
+	hfc->regd.argl1 = (void *) hfc;	/* argument for our local routine */
+	hfc->regd.dch_l2l1 = hfcusb_l1_access;
+	hfc->regd.bch_l2l1 = hfcusb_bch_access;
+	hfc->regd.drvname = "hfc_usb";
+	if (hisax_register_hfcusb(&hfc->regd)) {
+		printk(KERN_INFO "HFC-USB failed to register at hisax\n");
+		Write_hfc(hfc, HFCUSB_CIRM, 0x08);	/* aux = input, reset on */
+		return (1);
+	}
+
+	/* startup the D- and E-channel fifos */
+	start_rx_fifo(hfc->fifos + HFCUSB_D_RX);	/* D-fifo */
+	if (hfc->fifos[HFCUSB_PCM_RX].pipe)
+		start_rx_fifo(hfc->fifos + HFCUSB_PCM_RX);	/* E-fifo */
+
+	return (0);
+}				/* usb_init */
+
+/*************************************************/
+/* function called to probe a new plugged device */
+/*************************************************/
+static void *
+hfc_usb_probe(struct usb_device *dev, unsigned int interface
+#ifdef COMPAT_HAS_USB_IDTAB
+	      , const struct usb_device_id *id_table)
+#else
+    )
+#endif
+{
+	hfcusb_data *context;
+	struct usb_interface *ifp = dev->actconfig->interface + interface;
+	struct usb_interface_descriptor *ifdp =
+	    ifp->altsetting + ifp->act_altsetting;
+	struct usb_endpoint_descriptor *epd;
+	int i, idx, ep_msk;
+
+#ifdef COMPAT_HAS_USB_IDTAB
+	if (id_table && (dev->descriptor.idVendor == id_table->idVendor) &&
+	    (dev->descriptor.idProduct == id_table->idProduct) &&
+#else
+	if ((((dev->descriptor.idVendor == 0x959) &&
+	    (dev->descriptor.idProduct == 0x2bd0)) ||
+	    ((dev->descriptor.idVendor == 0x7b0) &&
+	    (dev->descriptor.idProduct == 0x0006))) &&
+#endif
+	    (ifdp->bNumEndpoints >= 6) && (ifdp->bNumEndpoints <= 16)) {
+		if (!(context = kmalloc(sizeof(hfcusb_data), GFP_KERNEL))) {
+			return (NULL);	/* got no mem */
+		};
+		memset(context, 0, sizeof(hfcusb_data));	/* clear the structure */
+		i = ifdp->bNumEndpoints;	/* get number of endpoints */
+		ep_msk = 0;	/* none found */
+		epd = ifdp->endpoint;	/* first endpoint descriptor */
+		while (i-- && ((ep_msk & 0xcf) != 0xcf)) {
+
+			idx = (((epd->bEndpointAddress & 0x7f) - 1) << 1);	/* get endpoint base */
+			if (idx < 7) {
+				switch (epd->bmAttributes) {
+					case USB_ENDPOINT_XFER_INT:
+						if (!
+						    (epd->
+						     bEndpointAddress &
+						     0x80))
+							break;	/* only interrupt in allowed */
+						idx++;	/* input index is odd */
+						context->fifos[idx].pipe =
+						    usb_rcvintpipe(dev,
+								   epd->
+								   bEndpointAddress);
+						break;
+
+					case USB_ENDPOINT_XFER_BULK:
+						if (epd->
+						    bEndpointAddress &
+						    0x80)
+							break;	/* only bulk out allowed */
+						context->fifos[idx].pipe =
+						    usb_sndbulkpipe(dev,
+								    epd->
+								    bEndpointAddress);
+						break;
+					default:
+						context->fifos[idx].pipe = 0;	/* reset data */
+				}	/* switch attribute */
+
+				if (context->fifos[idx].pipe) {
+					context->fifos[idx].fifonum = idx;
+					context->fifos[idx].fifo_mask =
+					    1 << idx;
+					context->fifos[idx].hfc = context;
+					context->fifos[idx].usb_maxlen =
+					    epd->wMaxPacketSize;
+					context->fifos[idx].intervall =
+					    epd->bInterval;
+					ep_msk |= (1 << idx);
+				} else
+					ep_msk &= ~(1 << idx);
+			}	/* idx < 7 */
+			epd++;
+		}
+
+		if ((ep_msk & 0x3f) != 0x3f) {
+			kfree(context);
+			return (NULL);
+		}
+		MOD_INC_USE_COUNT;	/* lock our module */
+		context->dev = dev;	/* save device */
+		context->if_used = interface;	/* save used interface */
+		context->alt_used = ifp->act_altsetting;	/* and alternate config */
+		context->ctrl_paksize = dev->descriptor.bMaxPacketSize0;	/* control size */
+
+		/* create the control pipes needed for register access */
+		context->ctrl_in_pipe = usb_rcvctrlpipe(context->dev, 0);
+		context->ctrl_out_pipe = usb_sndctrlpipe(context->dev, 0);
+
+		/* init the chip and register the driver */
+		if (usb_init(context)) {
+			kfree(context);
+			MOD_DEC_USE_COUNT;
+			return (NULL);
+		}
+
+		printk(KERN_INFO
+		       "HFC-USB: New device if=%d alt=%d registered\n",
+		       context->if_used, context->alt_used);
+		return (context);
+	}
+
+	return (NULL);		/* no matching entry */
+}				/* hfc_usb_probe */
+
+/****************************************************/
+/* function called when an active device is removed */
+/****************************************************/
+static void
+hfc_usb_disconnect(struct usb_device *usbdev, void *drv_context)
+{
+	hfcusb_data *context = drv_context;
+	int i;
+	struct sk_buff *skb;
+
+	/* tell all fifos to terminate */
+	for (i = 0; i < HFCUSB_NUM_FIFOS; i++)
+		if (context->fifos[i].active) {
+			context->fifos[i].active = 0;
+			usb_unlink_urb(&context->fifos[i].urb);
+		}
+	while (context->active_fifos) {
+		set_current_state(TASK_INTERRUPTIBLE);
+		/* Timeout 10ms */
+		schedule_timeout((10 * HZ) / 1000);
+	}
+	if (timer_pending(&context->t3_timer))
+		del_timer(&context->t3_timer);
+	context->regd.release_driver(context->regd.arg_hisax);
+	while ((skb = skb_dequeue(&context->regd.erq)) != NULL)
+		dev_kfree_skb_any(skb);
+
+	kfree(context);		/* free our structure again */
+	MOD_DEC_USE_COUNT;	/* and decrement the usage counter */
+}				/* hfc_usb_disconnect */
+
+/************************************/
+/* our driver information structure */
+/************************************/
+static struct usb_driver hfc_drv = {
+	name:"hfc_usb",
+#ifdef COMPAT_HAS_USB_IDTAB
+	id_table:hfc_usb_idtab,
+#endif
+	probe:hfc_usb_probe,
+	disconnect:hfc_usb_disconnect,
+};
+
+static void __exit
+hfc_usb_exit(void)
+{
+
+	usb_deregister(&hfc_drv);	/* release our driver */
+	printk(KERN_INFO "HFC-USB module removed\n");
+}
+
+static int __init
+hfc_usb_init(void)
+{
+	struct hisax_drvreg drv;
+
+	drv.version = HISAX_LOAD_VERSION;	/* set our version */
+	drv.cmd = HISAX_LOAD_CHKVER;	/* check command only */
+	if (hisax_register_hfcusb(&drv)) {
+		printk(KERN_INFO "HFC-USB <-> hisax version conflict\n");
+		return (-1);	/* unable to register */
+	}
+	if (usb_register(&hfc_drv)) {
+		printk(KERN_INFO
+		       "Unable to register HFC-USB module at usb stack\n");
+		return (-1);	/* unable to register */
+	}
+
+	printk(KERN_INFO "HFC-USB module loaded\n");
+	return (0);
+}
+
+module_init(hfc_usb_init);
+module_exit(hfc_usb_exit);
--- /dev/null
+++ b/drivers/isdn/hisax/hfc_usbr.c
@@ -0,0 +1,471 @@
+/* $Id: hfc_usbr.c,v 2.5 2001/07/06 21:30:11 werner Exp $
+
+ * hfc_usb.c  low level driver for CCD´s hfc-usb single chip controllers
+ *            type approval valid for HFC-S USB based TAs
+ *
+ * Author     Werner Cornelius (werner@isdn-development.de)
+ *
+ * Copyright 2001  by Werner Cornelius (werner@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.
+ *
+ */
+
+#define __NO_VERSION__
+#include <linux/init.h>
+#include "hisax.h"
+#include "isdnl1.h"
+#include "hisax_loadable.h"
+
+extern const char *CardType[];
+
+static const char *hfcusb_revision = "$Revision: 2.5 $";
+
+/*********************************/
+/* schedule a new b_channel task */
+/*********************************/
+static void
+hfcusb_sched_event(struct BCState *bcs, int event)
+{
+	bcs->event |= 1 << event;
+	queue_task(&bcs->tqueue, &tq_immediate);
+	mark_bh(IMMEDIATE_BH);
+}
+
+/************************************************/
+/* select a b-channel entry matching and active */
+/************************************************/
+static
+struct BCState *
+Sel_BCS(struct IsdnCardState *cs, int channel)
+{
+	if (cs->bcs[0].mode && (cs->bcs[0].channel == channel))
+		return (&cs->bcs[0]);
+	else if (cs->bcs[1].mode && (cs->bcs[1].channel == channel))
+		return (&cs->bcs[1]);
+	else
+		return (NULL);
+}
+
+/**********************************************/
+/* transfer function (D-channel from l2 to l1 */
+/**********************************************/
+static void
+hfcusb_d_l2l1(struct PStack *st, int pr, void *arg)
+{
+	struct IsdnCardState *cs = st->l1.hardware;
+	struct hisax_drvreg *drv = cs->hw.hfcusb.drv;
+
+	if (drv) {
+		switch (pr) {
+			case (PH_DATA | REQUEST):
+			case (PH_PULL | INDICATION):
+				cs->hw.hfcusb.dch_tx_busy = 1;
+				break;
+			case (PH_PULL | REQUEST):
+				if (!cs->hw.hfcusb.dch_tx_busy) {
+					test_and_clear_bit(FLG_L1_PULL_REQ,
+							   &st->l1.Flags);
+					st->l1.l1l2(st, PH_PULL | CONFIRM,
+						    NULL);
+				} else
+					test_and_set_bit(FLG_L1_PULL_REQ,
+							 &st->l1.Flags);
+				return;
+		}
+		drv->dch_l2l1(drv, pr, arg);
+	} else
+		debugl1(cs, "hfcusb l2l1 called without existing driver");
+}				/* hfcusb_d_l2l1 */
+
+/*****************************/
+/* E-channel receive routine */
+/*****************************/
+static void
+EChannel_proc_rcv(struct IsdnCardState *cs)
+{
+	u_char *ptr;
+	struct sk_buff *skb;
+	struct hisax_drvreg *usbdrv =
+	    (struct hisax_drvreg *) cs->hw.hfcusb.drv;
+
+
+	while ((skb = skb_dequeue(&usbdrv->erq)) != NULL) {
+		if (cs->debug & DEB_DLOG_HEX) {
+			ptr = cs->dlog;
+			if ((skb->len) < MAX_DLOG_SPACE / 3 - 10) {
+				*ptr++ = 'E';
+				*ptr++ = 'C';
+				*ptr++ = 'H';
+				*ptr++ = 'O';
+				*ptr++ = ':';
+				ptr += QuickHex(ptr, skb->data, skb->len);
+				ptr--;
+				*ptr++ = '\n';
+				*ptr = 0;
+				HiSax_putstatus(cs, NULL, cs->dlog);
+			} else
+				HiSax_putstatus(cs, "LogEcho: ",
+						"warning Frame too big (%d)",
+						skb->len);
+		}
+		dev_kfree_skb_any(skb);
+	}
+}
+
+/******************************************/
+/* transfer function called from L1 to L2 */
+/******************************************/
+static void
+hfcusb_d_l1l2(void *cs1, int pr, void *arg)
+{
+	struct IsdnCardState *cs = (struct IsdnCardState *) cs1;
+
+	switch (pr) {
+		case (PH_DATA | INDICATION):
+			if (!((int) arg))
+				DChannel_proc_rcv(cs);
+			else
+				EChannel_proc_rcv(cs);
+			break;
+
+		case (PH_DATA | CONFIRM):
+			cs->hw.hfcusb.dch_tx_busy = 0;
+			DChannel_proc_xmt(cs);
+			break;
+
+		case (PH_ACTIVATE | INDICATION):
+		case (PH_ACTIVATE | CONFIRM):
+			cs->stlist->l1.l1l2(cs->stlist, pr, arg);
+			if (cs->debug & L1_DEB_ISAC)
+				debugl1(cs, "layer 1 activated");
+			break;
+
+		case (PH_DEACTIVATE | INDICATION):
+		case (PH_DEACTIVATE | CONFIRM):
+			cs->stlist->l1.l1l2(cs->stlist, pr, arg);
+			if (cs->debug & L1_DEB_ISAC)
+				debugl1(cs, "layer 1 deactivated");
+			break;
+
+		default:
+			debugl1(cs, "unknown l1 msg 0x%x ", pr);
+	}
+}				/* hfcusb_d_l1l2 */
+
+
+/******************************************/
+/* transfer function called from L1 to L2 */
+/******************************************/
+static void
+hfcusb_b_l1l2(void *cs1, int chan, int pr, void *arg)
+{
+	struct IsdnCardState *cs = (struct IsdnCardState *) cs1;
+	struct BCState *bcs = Sel_BCS(cs, chan);
+
+	switch (pr) {
+		case (PH_DATA | INDICATION):
+			if (!bcs)
+				return;
+			hfcusb_sched_event(bcs, B_RCVBUFREADY);
+			break;
+
+		case (PH_DATA | CONFIRM):
+			if (!bcs)
+				return;
+			bcs->tx_cnt -= bcs->tx_skb->len;
+			if (bcs->st->lli.l1writewakeup &&
+			    (PACKET_NOACK != bcs->tx_skb->pkt_type))
+				bcs->st->lli.l1writewakeup(bcs->st,
+							   bcs->tx_skb->
+							   len);
+			dev_kfree_skb_any(bcs->tx_skb);
+			bcs->tx_skb = skb_dequeue(&bcs->squeue);
+			break;
+
+		case (PH_ACTIVATE | INDICATION):
+		case (PH_ACTIVATE | CONFIRM):
+			cs->stlist->l1.l1l2(cs->stlist, pr, arg);
+			if (cs->debug & L1_DEB_ISAC)
+				debugl1(cs, "layer 1 activated");
+			break;
+
+		case (PH_DEACTIVATE | INDICATION):
+		case (PH_DEACTIVATE | CONFIRM):
+			cs->stlist->l1.l1l2(cs->stlist, pr, arg);
+			if (cs->debug & L1_DEB_ISAC)
+				debugl1(cs, "layer 1 deactivated");
+			break;
+
+		default:
+			debugl1(cs, "unknown l1 b msg 0x%x ", pr);
+	}
+}				/* hfcusb_b_l1l2 */
+
+
+/***********************************************/
+/* called during init setting l1 stack pointer */
+/***********************************************/
+void
+setstack_hfcusb(struct PStack *st, struct IsdnCardState *cs)
+{
+	st->l2.l2l1 = hfcusb_d_l2l1;
+}
+
+/**************************************/
+/* send B-channel data if not blocked */
+/**************************************/
+static void
+hfcusb_send_data(struct BCState *bcs)
+{
+	struct IsdnCardState *cs = bcs->cs;
+	struct hisax_drvreg *drv =
+	    (struct hisax_drvreg *) cs->hw.hfcusb.drv;
+
+	if (!drv)
+		return;
+	drv->bch_l2l1(drv->argl1, bcs->channel, PH_DATA | REQUEST,
+		      bcs->tx_skb);
+}
+
+/***************************************************************/
+/* activate/deactivate hardware for selected channels and mode */
+/***************************************************************/
+void
+mode_hfcusb(struct BCState *bcs, int mode, int bc)
+{
+	struct IsdnCardState *cs = bcs->cs;
+	struct hisax_drvreg *drv = cs->hw.hfcusb.drv;
+
+	if (!drv)
+		return;
+	if (cs->debug & L1_DEB_HSCX)
+		debugl1(cs, "HFCUSB bchannel mode %d bchan %d/%d",
+			mode, bc, bcs->channel);
+	bcs->mode = mode;
+	bcs->channel = bc;
+	if (mode) {
+		drv->bsk[bc] = &bcs->tx_skb;
+		drv->brq[bc] = &bcs->rqueue;
+	}
+	drv->bch_l2l1(drv->argl1, bc, PH_ACTIVATE | REQUEST,
+		      (void *) mode);
+	if (!mode) {
+		drv->bsk[bc] = NULL;
+		drv->brq[bc] = NULL;
+	}
+}
+
+/******************************/
+/* Layer2 -> Layer 1 Transfer */
+/******************************/
+static void
+hfcusb_b_l2l1(struct PStack *st, int pr, void *arg)
+{
+	struct sk_buff *skb = arg;
+	struct hisax_drvreg *drv = st->l1.bcs->cs->hw.hfcusb.drv;
+	long flags;
+
+	switch (pr) {
+		case (PH_DATA | REQUEST):
+			save_flags(flags);
+			cli();
+			if (st->l1.bcs->tx_skb) {
+				skb_queue_tail(&st->l1.bcs->squeue, skb);
+				restore_flags(flags);
+			} else {
+				st->l1.bcs->tx_skb = skb;
+				st->l1.bcs->cs->BC_Send_Data(st->l1.bcs);
+				restore_flags(flags);
+			}
+			break;
+		case (PH_PULL | INDICATION):
+			if (st->l1.bcs->tx_skb) {
+				printk(KERN_WARNING
+				       "hfc_l2l1: this shouldn't happen\n");
+				break;
+			}
+			save_flags(flags);
+			cli();
+			st->l1.bcs->tx_skb = skb;
+			st->l1.bcs->cs->BC_Send_Data(st->l1.bcs);
+			restore_flags(flags);
+			break;
+		case (PH_PULL | REQUEST):
+			if (!st->l1.bcs->tx_skb) {
+				test_and_clear_bit(FLG_L1_PULL_REQ,
+						   &st->l1.Flags);
+				st->l1.l1l2(st, PH_PULL | CONFIRM, NULL);
+			} else
+				test_and_set_bit(FLG_L1_PULL_REQ,
+						 &st->l1.Flags);
+			break;
+		case (PH_ACTIVATE | REQUEST):
+			if (drv) {
+				test_and_set_bit(BC_FLG_ACTIV,
+						 &st->l1.bcs->Flag);
+				mode_hfcusb(st->l1.bcs, st->l1.mode,
+					    st->l1.bc);
+				l1_msg_b(st, pr, arg);
+			}
+			break;
+		case (PH_DEACTIVATE | REQUEST):
+			l1_msg_b(st, pr, arg);
+			break;
+		case (PH_DEACTIVATE | CONFIRM):
+			test_and_clear_bit(BC_FLG_ACTIV,
+					   &st->l1.bcs->Flag);
+			test_and_clear_bit(BC_FLG_BUSY, &st->l1.bcs->Flag);
+			mode_hfcusb(st->l1.bcs, 0, st->l1.bc);
+			st->l1.l1l2(st, PH_DEACTIVATE | CONFIRM, NULL);
+			break;
+	}
+}
+
+/******************************************/
+/* deactivate B-channel access and queues */
+/******************************************/
+static void
+close_hfcusb(struct BCState *bcs)
+{
+	mode_hfcusb(bcs, 0, bcs->channel);
+	if (test_and_clear_bit(BC_FLG_INIT, &bcs->Flag)) {
+		skb_queue_purge(&bcs->rqueue);
+		skb_queue_purge(&bcs->squeue);
+		if (bcs->tx_skb) {
+			dev_kfree_skb_any(bcs->tx_skb);
+			bcs->tx_skb = NULL;
+			test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag);
+		}
+	}
+}
+
+/*************************************/
+/* init B-channel queues and control */
+/*************************************/
+static int
+open_hfcusbstate(struct IsdnCardState *cs, struct BCState *bcs)
+{
+	if (!test_and_set_bit(BC_FLG_INIT, &bcs->Flag)) {
+		skb_queue_head_init(&bcs->rqueue);
+		skb_queue_head_init(&bcs->squeue);
+	}
+	bcs->tx_skb = NULL;
+	test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag);
+	bcs->event = 0;
+	bcs->tx_cnt = 0;
+	return (0);
+}
+
+/*********************************/
+/* inits the stack for B-channel */
+/*********************************/
+static int
+setstack_2b(struct PStack *st, struct BCState *bcs)
+{
+	bcs->channel = st->l1.bc;
+	if (open_hfcusbstate(st->l1.hardware, bcs))
+		return (-1);
+	st->l1.bcs = bcs;
+	st->l2.l2l1 = hfcusb_b_l2l1;
+	setstack_manager(st);
+	bcs->st = st;
+	setstack_l1_B(st);
+	return (0);
+}
+
+/********************************/
+/* called for card init message */
+/********************************/
+void __devinit
+inithfcusb(struct IsdnCardState *cs)
+{
+	cs->setstack_d = setstack_hfcusb;
+	cs->BC_Send_Data = &hfcusb_send_data;
+	cs->bcs[0].BC_SetStack = setstack_2b;
+	cs->bcs[1].BC_SetStack = setstack_2b;
+	cs->bcs[0].BC_Close = close_hfcusb;
+	cs->bcs[1].BC_Close = close_hfcusb;
+	mode_hfcusb(cs->bcs, 0, 0);
+	mode_hfcusb(cs->bcs + 1, 0, 1);
+}
+
+
+
+/*******************************************/
+/* handle card messages from control layer */
+/*******************************************/
+static int
+hfcusb_card_msg(struct IsdnCardState *cs, int mt, void *arg)
+{
+	if (cs->debug & L1_DEB_ISAC)
+		debugl1(cs, "HFCUSB: card_msg %x", mt);
+	switch (mt) {
+		case CARD_INIT:
+			inithfcusb(cs);
+			return (0);
+		case CARD_RELEASE:
+		case CARD_RESET:
+		case CARD_TEST:
+			return (0);
+	}
+	return (0);
+}
+
+
+extern void
+ HiSax_closecard(int cardnr);
+/*****************************/
+/* release a driver instance */
+/* called when hardware is   */
+/* no longer present.        */
+/*****************************/
+static void
+release_hfcdrv(void *arg)
+{
+	struct IsdnCardState *cs = (struct IsdnCardState *) arg;
+
+	cs->hw.hfcusb.drv = NULL;	/* disable any further use of driver */
+	HiSax_closecard(cs->cardnr);
+}				/* release_hfcdrv */
+
+/*********************************************/
+/* called once when a new device is detected */
+/* initialises local data                    */
+/*********************************************/
+int
+setup_hfc_usb(struct IsdnCard *card)
+{
+	struct IsdnCardState *cs = card->cs;
+	char tmp[64];
+	struct hisax_drvreg *usbdrv =
+	    (struct hisax_drvreg *) cs->hw.hfcusb.drv;
+
+	if (!usbdrv)
+		return (0);	/* no driver data present */
+
+	strcpy(tmp, hfcusb_revision);
+	printk(KERN_INFO "HiSax: HFC-USB driver Rev. %s\n",
+	       HiSax_getrev(tmp));
+
+	usbdrv->release_driver = &release_hfcdrv;	/* release routine */
+	usbdrv->arg_hisax = (void *) cs;	/* parameter for calling */
+	usbdrv->dch_l1l2 = &hfcusb_d_l1l2;	/* access from L1 to HiSax */
+	usbdrv->bch_l1l2 = &hfcusb_b_l1l2;
+	usbdrv->drq = &cs->rq;
+	usbdrv->dsq = &cs->sq;
+	cs->cardmsg = &hfcusb_card_msg;
+	return (1);		/* success */
+}
--- a/drivers/isdn/hisax/hfcscard.c
+++ b/drivers/isdn/hisax/hfcscard.c
@@ -1,4 +1,4 @@
-/* $Id: hfcscard.c,v 1.1.4.1 2001/11/20 14:19:35 kai Exp $
+/* $Id: hfcscard.c,v 1.10 2001/09/24 13:22:56 kai Exp $
  *
  * low level stuff for hfcs based cards (Teles3c, ACER P10)
  *
@@ -12,14 +12,13 @@
 
 #define __NO_VERSION__
 #include <linux/init.h>
-#include <linux/isapnp.h>
 #include "hisax.h"
 #include "hfc_2bds0.h"
 #include "isdnl1.h"
 
 extern const char *CardType[];
 
-static const char *hfcs_revision = "$Revision: 1.1.4.1 $";
+static const char *hfcs_revision = "$Revision: 1.10 $";
 
 static void
 hfcs_interrupt(int intno, void *dev_id, struct pt_regs *regs)
@@ -140,36 +139,6 @@ hfcs_card_msg(struct IsdnCardState *cs, 
 	return(0);
 }
 
-#ifdef __ISAPNP__
-static struct isapnp_device_id hfc_ids[] __initdata = {
-	{ ISAPNP_VENDOR('A', 'N', 'X'), ISAPNP_FUNCTION(0x1114),
-	  ISAPNP_VENDOR('A', 'N', 'X'), ISAPNP_FUNCTION(0x1114), 
-	  (unsigned long) "Acer P10" },
-	{ ISAPNP_VENDOR('B', 'I', 'L'), ISAPNP_FUNCTION(0x0002),
-	  ISAPNP_VENDOR('B', 'I', 'L'), ISAPNP_FUNCTION(0x0002), 
-	  (unsigned long) "Billion 2" },
-	{ ISAPNP_VENDOR('B', 'I', 'L'), ISAPNP_FUNCTION(0x0001),
-	  ISAPNP_VENDOR('B', 'I', 'L'), ISAPNP_FUNCTION(0x0001), 
-	  (unsigned long) "Billion 1" },
-	{ ISAPNP_VENDOR('T', 'A', 'G'), ISAPNP_FUNCTION(0x7410),
-	  ISAPNP_VENDOR('T', 'A', 'G'), ISAPNP_FUNCTION(0x7410), 
-	  (unsigned long) "IStar PnP" },
-	{ ISAPNP_VENDOR('T', 'A', 'G'), ISAPNP_FUNCTION(0x2610),
-	  ISAPNP_VENDOR('T', 'A', 'G'), ISAPNP_FUNCTION(0x2610), 
-	  (unsigned long) "Teles 16.3c" },
-	{ ISAPNP_VENDOR('S', 'F', 'M'), ISAPNP_FUNCTION(0x0001),
-	  ISAPNP_VENDOR('S', 'F', 'M'), ISAPNP_FUNCTION(0x0001), 
-	  (unsigned long) "Tornado Tipa C" },
-	{ ISAPNP_VENDOR('K', 'Y', 'E'), ISAPNP_FUNCTION(0x0001),
-	  ISAPNP_VENDOR('K', 'Y', 'E'), ISAPNP_FUNCTION(0x0001), 
-	  (unsigned long) "Genius Speed Surfer" },
-	{ 0, }
-};
-
-static struct isapnp_device_id *hdev = &hfc_ids[0];
-static struct pci_bus *pnp_c __devinitdata = NULL;
-#endif
-
 int __init
 setup_hfcs(struct IsdnCard *card)
 {
@@ -178,46 +147,6 @@ setup_hfcs(struct IsdnCard *card)
 
 	strcpy(tmp, hfcs_revision);
 	printk(KERN_INFO "HiSax: HFC-S driver Rev. %s\n", HiSax_getrev(tmp));
-
-#ifdef __ISAPNP__
-	if (!card->para[1] && isapnp_present()) {
-		struct pci_bus *pb;
-		struct pci_dev *pd;
-
-		while(hdev->card_vendor) {
-			if ((pb = isapnp_find_card(hdev->card_vendor,
-				hdev->card_device, pnp_c))) {
-				pnp_c = pb;
-				pd = NULL;
-				if ((pd = isapnp_find_dev(pnp_c,
-					hdev->vendor, hdev->function, pd))) {
-					printk(KERN_INFO "HiSax: %s detected\n",
-						(char *)hdev->driver_data);
-					pd->prepare(pd);
-					pd->deactivate(pd);
-					pd->activate(pd);
-					card->para[1] = pd->resource[0].start;
-					card->para[0] = pd->irq_resource[0].start;
-					if (!card->para[0] || !card->para[1]) {
-						printk(KERN_ERR "HFC PnP:some resources are missing %ld/%lx\n",
-						card->para[0], card->para[1]);
-						pd->deactivate(pd);
-						return(0);
-					}
-					break;
-				} else {
-					printk(KERN_ERR "HFC PnP: PnP error card found, no device\n");
-				}
-			}
-			hdev++;
-			pnp_c=NULL;
-		} 
-		if (!hdev->card_vendor) {
-			printk(KERN_INFO "HFC PnP: no ISAPnP card found\n");
-			return(0);
-		}
-	}
-#endif
 	cs->hw.hfcD.addr = card->para[1] & 0xfffe;
 	cs->irq = card->para[0];
 	cs->hw.hfcD.cip = 0;
--- a/drivers/isdn/hisax/hisax.h
+++ b/drivers/isdn/hisax/hisax.h
@@ -1,4 +1,4 @@
-/* $Id: hisax.h,v 1.1.4.2 2001/12/09 19:15:28 kai Exp $
+/* $Id: hisax.h,v 2.64 2001/09/24 13:22:56 kai Exp $
  *
  * Basic declarations, defines and prototypes
  *
@@ -24,7 +24,9 @@
 #include <linux/isdnif.h>
 #include <linux/tty.h>
 #include <linux/serial_reg.h>
+#ifndef COMPAT_NO_SOFTNET
 #include <linux/netdevice.h>
+#endif
 
 #define ERROR_STATISTIC
 
@@ -68,9 +70,6 @@
 #define DL_DATA		0x0220
 #define DL_FLUSH	0x0224
 #define DL_UNIT_DATA	0x0230
-
-#define MDL_BC_RELEASE  0x0278  // Formula-n enter:now
-#define MDL_BC_ASSIGN   0x027C  // Formula-n enter:now
 #define MDL_ASSIGN	0x0280
 #define MDL_REMOVE	0x0284
 #define MDL_ERROR	0x0288
@@ -472,8 +471,6 @@ struct amd7930_hw {
 #define BC_FLG_FTI_RUN	13
 #define BC_FLG_LL_OK	14
 #define BC_FLG_LL_CONN	15
-#define BC_FLG_FTI_FTS	16
-#define BC_FLG_FRH_WAIT	17
 
 #define L1_MODE_NULL	0
 #define L1_MODE_TRANS	1
@@ -695,6 +692,13 @@ struct hfcPCI_hw {
 	struct timer_list timer;
 };
 
+#ifdef CONFIG_HISAX_HFC_USB
+struct hfcUSB_hw {  
+        void *drv; /* pointer to driver structure */
+        int dch_tx_busy;
+};
+#endif
+
 struct hfcSX_hw {
         unsigned long base;
 	unsigned char cirm;
@@ -838,17 +842,6 @@ struct w6692_chip {
 	int ph_state;
 };
 
-struct amd7930_chip {
-	u_char lmr1;
-	u_char ph_state;
-	u_char old_state;
-	u_char flg_t3;
-	unsigned int tx_xmtlen;
-	struct timer_list timer3;
-	void (*ph_command) (struct IsdnCardState *, u_char, char *);
-	void (*setIrqMask) (struct IsdnCardState *, u_char);
-};
-
 struct icc_chip {
 	int ph_state;
 	u_char *mon_tx;
@@ -902,6 +895,9 @@ struct IsdnCardState {
 		struct njet_hw njet;
 		struct hfcD_hw hfcD;
 		struct hfcPCI_hw hfcpci;
+#ifdef CONFIG_HISAX_HFC_USB
+	        struct hfcUSB_hw hfcusb;
+#endif
 		struct hfcSX_hw hfcsx;
 		struct ix1_hw niccy;
 		struct isurf_hw isurf;
@@ -945,7 +941,6 @@ struct IsdnCardState {
 		struct hfcpci_chip hfcpci;
 		struct hfcsx_chip hfcsx;
 		struct w6692_chip w6692;
-		struct amd7930_chip amd7930;
 		struct icc_chip icc;
 	} dc;
 	u_char *rcvbuf;
@@ -967,6 +962,8 @@ struct IsdnCardState {
 #define  MON0_TX	4
 #define  MON1_TX	8
 
+#define	 HISAX_MAX_CARDS	8
+
 #define  ISDN_CTYPE_16_0	1
 #define  ISDN_CTYPE_8_0		2
 #define  ISDN_CTYPE_16_3	3
@@ -1006,8 +1003,8 @@ struct IsdnCardState {
 #define  ISDN_CTYPE_HFC_SX      37
 #define  ISDN_CTYPE_NETJET_U	38
 #define  ISDN_CTYPE_HFC_SP_PCMCIA      39
-#define  ISDN_CTYPE_DYNAMIC     40
-#define  ISDN_CTYPE_ENTERNOW	41
+#define  ISDN_CTYPE_HFC_USB     40
+#define  ISDN_CTYPE_DYNAMIC     41
 #define  ISDN_CTYPE_COUNT	41
 
 
@@ -1267,10 +1264,6 @@ struct IsdnCardState {
 #define CARD_NETJET_U 0
 #endif
 
-#ifdef CONFIG_HISAX_ENTERNOW_PCI
-#define CARD_FN_ENTERNOW_PCI 1
-#endif
-
 #define TEI_PER_CARD 1
 
 /* L1 Debug */
--- a/drivers/isdn/hisax/hisax_debug.h
+++ b/drivers/isdn/hisax/hisax_debug.h
@@ -28,7 +28,7 @@
 
 #define DBG(level, format, arg...) do { \
 if (level & __debug_variable) \
-printk(KERN_DEBUG "%s: " format "\n" , __FUNCTION__ , ## arg); \
+printk(KERN_DEBUG __FUNCTION__ ": " format "\n" , ## arg); \
 } while (0)
 
 #define DBG_PACKET(level,data,count) \
--- a/drivers/isdn/hisax/hisax_fcpcipnp.c
+++ b/drivers/isdn/hisax/hisax_fcpcipnp.c
@@ -20,22 +20,19 @@
  *
  * o POWER PC
  * o clean up debugging
- * o tx_skb at PH_DEACTIVATE time
  */
 
 #include <linux/version.h>
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/pci.h>
-#include <linux/isapnp.h>
+#include "hisax_isapnp.h"
 #include <linux/kmod.h>
 #include <linux/slab.h>
 #include <linux/skbuff.h>
 #include <linux/netdevice.h>
-
-#include <asm/io.h>
-
 #include "hisax_fcpcipnp.h"
+#include "hisax_isac.h"
 
 // debugging cruft
 #define __debug_variable debug
@@ -46,10 +43,14 @@ static int debug = 0;
 MODULE_PARM(debug, "i");
 #endif
 
-MODULE_AUTHOR("Kai Germaschewski <kai.germaschewski@gmx.de>/Karsten Keil <kkeil@suse.de>");
+MODULE_AUTHOR("Kai Germaschewski <kai.germaschewski@gmx.de>");
 MODULE_DESCRIPTION("AVM Fritz!PCI/PnP ISDN driver");
 
-static struct pci_device_id fcpci_ids[] __devinitdata = {
+#ifndef PCI_DEVICE_ID_AVM_A1_V2
+#define PCI_DEVICE_ID_AVM_A1_V2 0x0e00
+#endif
+
+static struct pci_device_id fcpci_ids[] __initdata = {
 	{ PCI_VENDOR_ID_AVM, PCI_DEVICE_ID_AVM_A1   , PCI_ANY_ID, PCI_ANY_ID,
 	  0, 0, (unsigned long) "Fritz!Card PCI" },
 	{ PCI_VENDOR_ID_AVM, PCI_DEVICE_ID_AVM_A1_V2, PCI_ANY_ID, PCI_ANY_ID,
@@ -58,7 +59,7 @@ static struct pci_device_id fcpci_ids[] 
 };
 MODULE_DEVICE_TABLE(pci, fcpci_ids);
 
-static struct isapnp_device_id fcpnp_ids[] __devinitdata = {
+static struct isapnp_device_id fcpnp_ids[] __initdata = {
 	{ ISAPNP_VENDOR('A', 'V', 'M'), ISAPNP_FUNCTION(0x0900),
 	  ISAPNP_VENDOR('A', 'V', 'M'), ISAPNP_FUNCTION(0x0900), 
 	  (unsigned long) "Fritz!Card PnP" },
@@ -68,7 +69,8 @@ MODULE_DEVICE_TABLE(isapnp, fcpnp_ids);
 
 static int protocol = 2;       /* EURO-ISDN Default */
 MODULE_PARM(protocol, "i");
-MODULE_LICENSE("GPL");
+
+static LIST_HEAD(adapter_list);
 
 // ----------------------------------------------------------------------
 
@@ -147,7 +149,7 @@ static unsigned char fcpci_read_isac(str
 	outb(idx, adapter->io + AVM_INDEX);
 	val = inb(adapter->io + AVM_DATA + (offset & 0xf));
  	spin_unlock_irqrestore(&adapter->hw_lock, flags);
-	DBG(0x1000, " port %#x, value %#x",
+	DBG(0x1000, __FUNCTION__ " port %#x, value %#x",
 	    offset, val);
 	return val;
 }
@@ -160,7 +162,7 @@ static void fcpci_write_isac(struct isac
 		AVM_IDX_ISAC_REG_HIGH : AVM_IDX_ISAC_REG_LOW;
 	unsigned long flags;
 
-	DBG(0x1000, " port %#x, value %#x",
+	DBG(0x1000, __FUNCTION__ " port %#x, value %#x",
 	    offset, value);
 	spin_lock_irqsave(&adapter->hw_lock, flags);
 	outb(idx, adapter->io + AVM_INDEX);
@@ -240,7 +242,7 @@ static unsigned char fcpci2_read_isac(st
 	outl(offset, adapter->io + AVM_ISACSX_INDEX);
 	val = inl(adapter->io + AVM_ISACSX_DATA);
  	spin_unlock_irqrestore(&adapter->hw_lock, flags);
-	DBG(0x1000, " port %#x, value %#x",
+	DBG(0x1000, __FUNCTION__ " port %#x, value %#x",
 	    offset, val);
 
 	return val;
@@ -252,7 +254,7 @@ static void fcpci2_write_isac(struct isa
 	struct fritz_adapter *adapter = isac->priv;
 	unsigned long flags;
 
-	DBG(0x1000, " port %#x, value %#x",
+	DBG(0x1000, __FUNCTION__ " port %#x, value %#x",
 	    offset, value);
 	spin_lock_irqsave(&adapter->hw_lock, flags);
 	outl(offset, adapter->io + AVM_ISACSX_INDEX);
@@ -375,6 +377,9 @@ static void hdlc_fill_fifo(struct fritz_
 
 	DBG(0x40, "hdlc_fill_fifo");
 
+	if (!skb)
+		BUG();
+
 	if (skb->len == 0)
 		BUG();
 
@@ -515,7 +520,6 @@ static inline void hdlc_xdu_irq(struct f
 	}
 	skb_push(bcs->tx_skb, bcs->tx_cnt);
 	bcs->tx_cnt = 0;
-	hdlc_fill_fifo(bcs);
 }
 
 static inline void hdlc_xpr_irq(struct fritz_bcs *bcs)
@@ -536,7 +540,7 @@ static inline void hdlc_xpr_irq(struct f
 	dev_kfree_skb_irq(skb);
 }
 
-static void hdlc_irq_one(struct fritz_bcs *bcs, u32 stat)
+static void hdlc_irq(struct fritz_bcs *bcs, u32 stat)
 {
 	DBG(0x10, "ch%d stat %#x", bcs->channel, stat);
 	if (stat & HDLC_INT_RPR) {
@@ -553,7 +557,7 @@ static void hdlc_irq_one(struct fritz_bc
 	}
 }
 
-static inline void hdlc_irq(struct fritz_adapter *adapter)
+static inline void hdlc_interrupt(struct fritz_adapter *adapter)
 {
 	int nr;
 	u32 stat;
@@ -562,7 +566,7 @@ static inline void hdlc_irq(struct fritz
 		stat = adapter->read_hdlc_status(adapter, nr);
 		DBG(0x10, "HDLC %c stat %#x", 'A' + nr, stat);
 		if (stat & HDLC_INT_MASK)
-			hdlc_irq_one(&adapter->bcs[nr], stat);
+			hdlc_irq(&adapter->bcs[nr], stat);
 	}
 }
 
@@ -584,14 +588,14 @@ static void modehdlc(struct fritz_bcs *b
 		adapter->write_ctrl(bcs, 5);
 		break;
 	case L1_MODE_TRANS:
+		bcs->ctrl.sr.mode = HDLC_MODE_TRANS;
+		adapter->write_ctrl(bcs, 5);
+		bcs->ctrl.sr.cmd = HDLC_CMD_XRS;
+		adapter->write_ctrl(bcs, 1);
+		bcs->ctrl.sr.cmd = 0;
+		break;
 	case L1_MODE_HDLC:
-		bcs->rcvidx = 0;
-		bcs->tx_cnt = 0;
-		bcs->tx_skb = NULL;
-		if (mode == L1_MODE_TRANS)
-			bcs->ctrl.sr.mode = HDLC_MODE_TRANS;
-		else
-			bcs->ctrl.sr.mode = HDLC_MODE_ITF_FLG;
+		bcs->ctrl.sr.mode = HDLC_MODE_ITF_FLG;
 		adapter->write_ctrl(bcs, 5);
 		bcs->ctrl.sr.cmd = HDLC_CMD_XRS;
 		adapter->write_ctrl(bcs, 1);
@@ -645,10 +649,10 @@ static void fcpci2_irq(int intno, void *
 		return;
 	DBG(2, "STATUS0 %#x", val);
 	if (val & AVM_STATUS0_IRQ_ISAC)
-		isacsx_irq(&adapter->isac);
+		isacsx_interrupt(&adapter->isac);
 
 	if (val & AVM_STATUS0_IRQ_HDLC)
-		hdlc_irq(adapter);
+		hdlc_interrupt(adapter);
 }
 
 static void fcpci_irq(int intno, void *dev, struct pt_regs *regs)
@@ -662,10 +666,10 @@ static void fcpci_irq(int intno, void *d
 		return;
 	DBG(2, "sval %#x", sval);
 	if (!(sval & AVM_STATUS0_IRQ_ISAC))
-		isac_irq(&adapter->isac);
+		isac_interrupt(&adapter->isac);
 
 	if (!(sval & AVM_STATUS0_IRQ_HDLC))
-		hdlc_irq(adapter);
+		hdlc_interrupt(adapter);
 }
 
 // ----------------------------------------------------------------------
@@ -681,11 +685,6 @@ static inline void fcpci_init(struct fri
 {
 	outb(AVM_STATUS0_DIS_TIMER | AVM_STATUS0_RES_TIMER | 
 	     AVM_STATUS0_ENA_IRQ, adapter->io + AVM_STATUS0);
-
-	outb(AVM_STATUS1_ENA_IOM | adapter->irq, 
-	     adapter->io + AVM_STATUS1);
-	set_current_state(TASK_UNINTERRUPTIBLE);
-	schedule_timeout(50*HZ / 1000); /* Timeout 50ms */
 }
 
 // ----------------------------------------------------------------------
@@ -693,6 +692,7 @@ static inline void fcpci_init(struct fri
 static int __devinit fcpcipnp_setup(struct fritz_adapter *adapter)
 {
 	u32 val = 0;
+	struct pci_dev *pdev = adapter->pci_dev;
 	int retval;
 
 	DBG(1,"");
@@ -700,21 +700,21 @@ static int __devinit fcpcipnp_setup(stru
 	isac_init(&adapter->isac); // FIXME is this okay now
 
 	retval = -EBUSY;
-	if (!request_region(adapter->io, 32, "fcpcipnp"))
+	if (!request_region(adapter->io, 32, "hisax_fcpcipnp"))
 		goto err;
 
 	switch (adapter->type) {
 	case AVM_FRITZ_PCIV2:
-		retval = request_irq(adapter->irq, fcpci2_irq, SA_SHIRQ, 
-				     "fcpcipnp", adapter);
+		retval = request_irq(pdev->irq, fcpci2_irq, SA_SHIRQ, 
+				     "hisax_fcpcipnp", adapter);
 		break;
 	case AVM_FRITZ_PCI:
-		retval = request_irq(adapter->irq, fcpci_irq, SA_SHIRQ,
-				     "fcpcipnp", adapter);
+		retval = request_irq(pdev->irq, fcpci_irq, SA_SHIRQ,
+				     "hisax_fcpcipnp", adapter);
 		break;
 	case AVM_FRITZ_PNP:
-		retval = request_irq(adapter->irq, fcpci_irq, 0,
-				     "fcpcipnp", adapter);
+		retval = request_irq(pdev->irq, fcpci_irq, 0,
+				     "hisax_fcpcipnp", adapter);
 		break;
 	}
 	if (retval)
@@ -808,11 +808,23 @@ static int __devinit fcpcipnp_setup(stru
 
 static void __devexit fcpcipnp_release(struct fritz_adapter *adapter)
 {
+	struct pci_dev *pdev = adapter->pci_dev;
+
 	DBG(1,"");
 
 	outb(0, adapter->io + AVM_STATUS0);
-	free_irq(adapter->irq, adapter);
+	free_irq(pdev->irq, adapter);
 	release_region(adapter->io, 32);
+
+	switch (adapter->type) {
+	case AVM_FRITZ_PCI:
+	case AVM_FRITZ_PCIV2:
+		pci_disable_device(pdev);
+		break;
+	case AVM_FRITZ_PNP:
+		pdev->deactivate(pdev);
+		break;
+	}
 }
 
 // ----------------------------------------------------------------------
@@ -830,6 +842,8 @@ new_adapter(struct pci_dev *pdev)
 
 	memset(adapter, 0, sizeof(struct fritz_adapter));
 
+	adapter->pci_dev = pdev;
+
 	SET_MODULE_OWNER(&adapter->isac.hisax_d_if);
 	adapter->isac.hisax_d_if.ifc.priv = &adapter->isac;
 	adapter->isac.hisax_d_if.ifc.l2l1 = isac_d_l2l1;
@@ -840,6 +854,7 @@ new_adapter(struct pci_dev *pdev)
 		adapter->bcs[i].b_if.ifc.priv = &adapter->bcs[i];
 		adapter->bcs[i].b_if.ifc.l2l1 = fritz_b_l2l1;
 	}
+	list_add(&adapter->list, &adapter_list);
 
 	pci_set_drvdata(pdev, adapter);
 
@@ -854,6 +869,7 @@ new_adapter(struct pci_dev *pdev)
 static void delete_adapter(struct fritz_adapter *adapter)
 {
 	hisax_unregister(&adapter->isac.hisax_d_if);
+	list_del(&adapter->list);
 	kfree(adapter);
 }
 
@@ -863,12 +879,15 @@ static int __devinit fcpci_probe(struct 
 	struct fritz_adapter *adapter;
 	int retval;
 
+	printk(KERN_INFO "hisax_fcpcipnp: found adapter %s at %s\n",
+	       (char *) ent->driver_data, pdev->slot_name);
+
 	retval = -ENOMEM;
 	adapter = new_adapter(pdev);
 	if (!adapter)
 		goto err;
 
-	if (pdev->device == PCI_DEVICE_ID_AVM_A1_V2) 
+	if (pdev->device == 0x0e00) 
 		adapter->type = AVM_FRITZ_PCIV2;
 	else
 		adapter->type = AVM_FRITZ_PCI;
@@ -876,12 +895,7 @@ static int __devinit fcpci_probe(struct 
 	retval = pci_enable_device(pdev);
 	if (retval)
 		goto err_free;
-
 	adapter->io = pci_resource_start(pdev, 1);
-	adapter->irq = pdev->irq;
-
-	printk(KERN_INFO "hisax_fcpcipnp: found adapter %s at %s\n",
-	       (char *) ent->driver_data, pdev->slot_name);
 
 	retval = fcpcipnp_setup(adapter);
 	if (retval)
@@ -901,6 +915,9 @@ static int __devinit fcpnp_probe(struct 
 	struct fritz_adapter *adapter;
 	int retval;
 
+	printk(KERN_INFO "hisax_fcpcipnp: found adapter %s\n",
+	       (char *) ent->driver_data);
+
 	retval = -ENOMEM;
 	adapter = new_adapter(pdev);
 	if (!adapter)
@@ -912,11 +929,8 @@ static int __devinit fcpnp_probe(struct 
 	pdev->deactivate(pdev); // why?
 	pdev->activate(pdev);
 	adapter->io = pdev->resource[0].start;
-	adapter->irq = pdev->irq_resource[0].start;
-
-	printk(KERN_INFO "hisax_fcpcipnp: found adapter %s at IO %#x irq %d\n",
-	       (char *) ent->driver_data, adapter->io, adapter->irq);
-
+	pdev->irq = pdev->irq_resource[0].start;
+	
 	retval = fcpcipnp_setup(adapter);
 	if (retval)
 		goto err_free;
@@ -929,43 +943,35 @@ static int __devinit fcpnp_probe(struct 
 	return retval;
 }
 
-static void __devexit fcpci_remove(struct pci_dev *pdev)
-{
-	struct fritz_adapter *adapter = pci_get_drvdata(pdev);
-
-	fcpcipnp_release(adapter);
-	pci_disable_device(pdev);
-	delete_adapter(adapter);
-}
-
-static void __devexit fcpnp_remove(struct pci_dev *pdev)
+static void __devexit fcpcipnp_remove(struct pci_dev *pdev)
 {
 	struct fritz_adapter *adapter = pci_get_drvdata(pdev);
 
 	fcpcipnp_release(adapter);
-	pdev->deactivate(pdev);
 	delete_adapter(adapter);
 }
 
 static struct pci_driver fcpci_driver = {
-	name:     "fcpci",
-	probe:    fcpci_probe,
-	remove:   __devexit_p(fcpci_remove),
+	name: "fcpci",
+	probe: fcpci_probe,
+	remove: fcpcipnp_remove,
 	id_table: fcpci_ids,
 };
 
 static struct isapnp_driver fcpnp_driver = {
-	name:     "fcpnp",
-	probe:    fcpnp_probe,
-	remove:   __devexit_p(fcpnp_remove),
+	name: "fcpnp",
+	probe: fcpnp_probe,
+	remove: fcpcipnp_remove,
 	id_table: fcpnp_ids,
 };
 
-static int __init hisax_fcpcipnp_init(void)
+static LIST_HEAD(isapnp_drivers);
+
+static int __init hisax_fcpci_init(void)
 {
 	int retval, pci_nr_found;
 
-	printk(KERN_INFO "hisax_fcpcipnp: Fritz!Card PCI/PCIv2/PnP ISDN driver v0.0.1\n");
+	printk(KERN_INFO "hisax_fcpcipnp: Fritz!PCI/PnP ISDN driver v0.0.1\n");
 
 	retval = pci_register_driver(&fcpci_driver);
 	if (retval < 0)
@@ -976,15 +982,14 @@ static int __init hisax_fcpcipnp_init(vo
 	if (retval < 0)
 		goto out_unregister_pci;
 
-#if !defined(CONFIG_HOTPLUG) || defined(MODULE)
+#if !defined(CONFIG_HOTPLUG) && defined(MODULE)
 	if (pci_nr_found + retval == 0) {
 		retval = -ENODEV;
 		goto out_unregister_isapnp;
-	}
 #endif
 	return 0;
 
-#if !defined(CONFIG_HOTPLUG) || defined(MODULE)
+#if !defined(CONFIG_HOTPLUG) && defined(MODULE)
  out_unregister_isapnp:
 	isapnp_unregister_driver(&fcpnp_driver);
 #endif
@@ -994,11 +999,15 @@ static int __init hisax_fcpcipnp_init(vo
 	return retval;
 }
 
-static void __exit hisax_fcpcipnp_exit(void)
+static void __exit hisax_fcpci_exit(void)
 {
 	isapnp_unregister_driver(&fcpnp_driver);
 	pci_unregister_driver(&fcpci_driver);
 }
 
-module_init(hisax_fcpcipnp_init);
-module_exit(hisax_fcpcipnp_exit);
+module_init(hisax_fcpci_init);
+module_exit(hisax_fcpci_exit);
+
+#ifdef __ISAPNP__
+#include "hisax_isapnp.c"
+#endif
--- a/drivers/isdn/hisax/hisax_fcpcipnp.h
+++ b/drivers/isdn/hisax/hisax_fcpcipnp.h
@@ -43,10 +43,12 @@ struct fritz_bcs {
 };
 
 struct fritz_adapter {
+	struct list_head list;
+	struct pci_dev *pci_dev;
+
 	int type;
 	spinlock_t hw_lock;
 	unsigned int io;
-	unsigned int irq;
 	struct isac isac;
 
 	struct fritz_bcs bcs[2];
--- a/drivers/isdn/hisax/hisax_isac.c
+++ b/drivers/isdn/hisax/hisax_isac.c
@@ -34,7 +34,7 @@
 static int debug = 1;
 MODULE_PARM(debug, "i");
 
-static char *ISACVer[] = {
+static char *ISACVer[] __devinitdata = {
   "2086/2186 V1.1", 
   "2085 B1", 
   "2085 B2",
@@ -42,10 +42,6 @@ static char *ISACVer[] = {
 };
 #endif
 
-MODULE_AUTHOR("Kai Germaschewski <kai.germaschewski@gmx.de>/Karsten Keil <kkeil@suse.de>");
-MODULE_DESCRIPTION("ISAC/ISAC-SX driver");
-MODULE_LICENSE("GPL");
-
 #define DBG_WARN      0x0001
 #define DBG_IRQ       0x0002
 #define DBG_L1M       0x0004
@@ -438,7 +434,7 @@ static void l1m_debug(struct FsmInst *fi
 	va_end(args);
 }
 
-static void isac_version(struct isac *cs)
+static void __devinit isac_version(struct isac *cs)
 {
 	int val;
 
@@ -602,7 +598,7 @@ static inline void isac_exi_interrupt(st
 	}
 }
 
-void isac_irq(struct isac *isac)
+void isac_interrupt(struct isac *isac)
 {
 	unsigned char val;
 
@@ -635,8 +631,6 @@ void isac_irq(struct isac *isac)
 	if (val & ISAC_ISTA_SIN) {
 		DBG(DBG_WARN, "SIN");
 	}
-	isac->write_isac(isac, ISAC_MASK, 0xff);
-	isac->write_isac(isac, ISAC_MASK, 0x00);
 }
 
 // ======================================================================
@@ -742,7 +736,7 @@ static inline void isacsx_icd_interrupt(
 	}
 }
 
-void isacsx_irq(struct isac *isac)
+void isacsx_interrupt(struct isac *isac)
 {
 	unsigned char val;
 
@@ -755,7 +749,7 @@ void isacsx_irq(struct isac *isac)
 		isacsx_cic_interrupt(isac);
 }
 
-void isac_init(struct isac *isac)
+void __devinit isac_init(struct isac *isac)
 {
 	isac->tx_skb = NULL;
 	isac->l1m.fsm = &l1fsm;
@@ -770,7 +764,7 @@ void isac_init(struct isac *isac)
 	FsmInitTimer(&isac->l1m, &isac->timer);
 }
 
-void isac_setup(struct isac *isac)
+void __devinit isac_setup(struct isac *isac)
 {
 	int val, eval;
 
@@ -781,7 +775,7 @@ void isac_setup(struct isac *isac)
 
   	isac->write_isac(isac, ISAC_MASK, 0xff);
   	isac->mocr = 0xaa;
-	if (test_bit(ISAC_IOM1, &isac->flags)) {
+	if (test_bit(HW_IOM1, &isac->flags)) {
 		/* IOM 1 Mode */
 		isac->write_isac(isac, ISAC_ADF2, 0x0);
 		isac->write_isac(isac, ISAC_SPCR, 0xa);
@@ -817,7 +811,7 @@ void isac_setup(struct isac *isac)
 	FsmEvent(&isac->l1m, (val >> 2) & 0xf, NULL);
 
 	isac->write_isac(isac, ISAC_MASK, 0x0);
-	// RESET Receiver and Transmitter
+	/* RESET Receiver and Transmitter */
 	isac->write_isac(isac, ISAC_CMDR, ISAC_CMDR_XRES | ISAC_CMDR_RRES);
 }
 
@@ -888,10 +882,10 @@ EXPORT_SYMBOL(isac_init);
 EXPORT_SYMBOL(isac_d_l2l1);
 
 EXPORT_SYMBOL(isacsx_setup);
-EXPORT_SYMBOL(isacsx_irq);
+EXPORT_SYMBOL(isacsx_interrupt);
 
 EXPORT_SYMBOL(isac_setup);
-EXPORT_SYMBOL(isac_irq);
+EXPORT_SYMBOL(isac_interrupt);
 
 module_init(hisax_isac_init);
 module_exit(hisax_isac_exit);
--- a/drivers/isdn/hisax/hisax_isac.h
+++ b/drivers/isdn/hisax/hisax_isac.h
@@ -8,7 +8,7 @@
 #define TIMER3_VALUE 7000
 #define MAX_DFRAME_LEN_L1 300
 
-#define ISAC_IOM1	0
+#define HW_IOM1	0
 
 struct isac {
 	void *priv;
@@ -37,9 +37,9 @@ void isac_init(struct isac *isac);
 void isac_d_l2l1(struct hisax_if *hisax_d_if, int pr, void *arg);
 
 void isac_setup(struct isac *isac);
-void isac_irq(struct isac *isac);
+void isac_interrupt(struct isac *isac);
 
 void isacsx_setup(struct isac *isac);
-void isacsx_irq(struct isac *isac);
+void isacsx_interrupt(struct isac *isac);
 
 #endif
--- /dev/null
+++ b/drivers/isdn/hisax/hisax_isapnp.c
@@ -0,0 +1,105 @@
+// FIXME copied
+static const struct isapnp_device_id *
+isapnp_match_device(const struct isapnp_device_id *ids, struct pci_dev *dev)
+{
+	DBG(1,"");
+
+	while (ids->card_vendor || ids->card_device) {
+		if ((ids->card_vendor == ISAPNP_ANY_ID || ids->card_vendor == dev->bus->vendor) &&
+		    (ids->card_device == ISAPNP_ANY_ID || ids->card_device == dev->bus->device) &&
+                    (ids->vendor == ISAPNP_ANY_ID || ids->vendor == dev->vendor) &&
+                    (ids->function == ISAPNP_ANY_ID || ids->function == dev->device))
+			return ids;
+		ids++;
+	}
+	return NULL;
+}
+
+/**
+ * pci_dev_driver - get the pci_driver of a device
+ * @dev: the device to query
+ *
+ * Returns the appropriate pci_driver structure or %NULL if there is no 
+ * registered driver for the device.
+ */
+struct pci_driver *isapnp_dev_driver(const struct pci_dev *dev)
+{
+	return dev->driver;
+}
+
+static int isapnp_announce_device(struct isapnp_driver *drv, struct pci_dev *dev)
+{
+	const struct isapnp_device_id *id;
+	int ret = 0;
+
+	DBG(1,"");
+
+	if (drv->id_table) {
+		id = isapnp_match_device(drv->id_table, dev);
+		if (!id) {
+			ret = 0;
+			goto out;
+		}
+	} else
+		id = NULL;
+
+//	dev_probe_lock();
+	if (drv->probe(dev, id) >= 0) {
+		dev->driver = (struct pci_driver *) drv;
+		ret = 1;
+	}
+//	dev_probe_unlock();
+out:
+	return ret;
+}
+
+/**
+ * FIXME pci_register_driver - register a new pci driver
+ * @drv: the driver structure to register
+ * 
+ * Adds the driver structure to the list of registered drivers
+ * Returns the number of pci devices which were claimed by the driver
+ * during registration.  The driver remains registered even if the
+ * return value is zero.
+ */
+int isapnp_register_driver(struct isapnp_driver *drv)
+{
+	struct pci_dev *dev;
+	int count = 0;
+
+	DBG(1,"");
+
+	list_add_tail(&drv->node, &isapnp_drivers);
+	isapnp_for_each_dev(dev) {
+		if (!isapnp_dev_driver(dev))
+			count += isapnp_announce_device(drv, dev);
+	}
+	return count;
+}
+
+/**
+ * pci_unregister_driver - unregister a pci driver
+ * @drv: the driver structure to unregister
+ * 
+ * Deletes the driver structure from the list of registered PCI drivers,
+ * gives it a chance to clean up by calling its remove() function for
+ * each device it was responsible for, and marks those devices as
+ * driverless.
+ */
+
+void isapnp_unregister_driver(struct isapnp_driver *drv)
+{
+	struct pci_dev *dev;
+
+	DBG(1,"");
+
+	list_del(&drv->node);
+	isapnp_for_each_dev(dev) {
+		if (dev->driver == (struct pci_driver *) drv) {
+			if (drv->remove)
+				drv->remove(dev);
+			dev->driver = NULL;
+		}
+	}
+}
+
--- /dev/null
+++ b/drivers/isdn/hisax/hisax_isapnp.h
@@ -0,0 +1,33 @@
+#ifndef __HISAX_ISAPNP_H__
+#define __HISAX_ISAPNP_H__
+
+#include <linux/isapnp.h>
+
+#ifdef COMPAT_NEED_ISAPNP_DRIVER
+struct isapnp_driver {
+	struct list_head node;
+	char *name;
+	const struct isapnp_device_id *id_table;	/* NULL if wants all devices */
+	int  (*probe)  (struct pci_dev *dev, const struct isapnp_device_id *id);	/* New device inserted */
+	void (*remove) (struct pci_dev *dev);	/* Device removed (NULL if not a hot-plug capable driver) */
+};
+#endif
+#ifdef __ISAPNP__
+
+int isapnp_register_driver(struct isapnp_driver *drv);
+void isapnp_unregister_driver(struct isapnp_driver *drv);
+
+#else
+
+static inline int isapnp_register_driver(struct isapnp_driver *drv) 
+{ 
+	return 0;
+}
+
+static inline void isapnp_unregister_driver(struct isapnp_driver *drv) 
+{ 
+}
+
+#endif
+
+#endif
--- /dev/null
+++ b/drivers/isdn/hisax/hisax_loadable.h
@@ -0,0 +1,74 @@
+/* $Id: hisax_loadable.h,v 2.1 2001/06/08 22:19:16 werner Exp $
+ *
+ *
+ * Author       (C) 2001 Werner Cornelius (werner@isdn-development.de)
+ *              modular driver for Colognechip HFC-USB chip
+ *              as plugin for HiSax isdn driver
+ *
+ * Copyright 2001  by Werner Cornelius (werner@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/types.h>
+#include <linux/skbuff.h>
+
+/***************************************/
+/* additional defines for l1 constants */
+/***************************************/
+#define B1_DATA       0x1f0
+#define B1_SETMODE    0x1f4
+#define B2_DATA       0x1f8
+#define B2_SETMODE    0x1fc
+
+
+/********************************************************/
+/* structure used for register and release of L1 driver */
+/********************************************************/
+struct hisax_drvreg {
+	int version;		/* actual version for check */
+	int cmd;		/* command code */
+
+	/* function pointers set by hisax during register call */
+	void (*release_driver) (void *arg_hisax);	/* set by hisax, release function for driver */
+	void (*dch_l1l2) (void *arg_hisax, int pr, void *arg);	/* set by hisax, notify dch+l1 events */
+	void (*bch_l1l2) (void *arg_hisax, int chan, int pr, void *arg);	/* set by hisax, notify bch events */
+	void *arg_hisax;	/* argument when calling hisax main */
+	struct sk_buff_head *drq;	/* pointer to D-receive queue */
+	struct sk_buff_head *dsq;	/* pointer to D-send queue */
+	struct sk_buff_head erq;	/* E-receive queue */
+	struct sk_buff_head *brq[2];	/* pointer to B-receive queues */
+	struct sk_buff **bsk[2];	/* pointer to B-transmit buffer */
+
+	/* function pointers set by l1 driver before calling the register function */
+	void (*dch_l2l1) (void *argl1, int pr, void *arg);	/* function dch+l1 from hisax -> l1 */
+	void (*bch_l2l1) (void *argl1, int chan, int pr, void *arg);	/* function bch from hisax -> l1 */
+	void *argl1;		/* pointer to l1 data structure when calling l1 */
+
+	char *drvname;		/* driver name for hisax usage */
+};
+
+/**************************/
+/* constants and commands */
+/**************************/
+#define HISAX_LOAD_VERSION  4	/* change when interface changes */
+#define HISAX_LOAD_CHKVER   0	/* check version command (returns 0 on success) */
+#define HISAX_LOAD_REGISTER 1	/* register the L1 driver and return 0 on success */
+
+/***************************************/
+/* definition of the register function */
+/***************************************/
+extern int hisax_register_hfcusb(struct hisax_drvreg *l1drv);
--- a/drivers/isdn/hisax/hscx.c
+++ b/drivers/isdn/hisax/hscx.c
@@ -1,4 +1,4 @@
-/* $Id: hscx.c,v 1.1.4.1 2001/11/20 14:19:36 kai Exp $
+/* $Id: hscx.c,v 1.24 2001/09/24 13:22:56 kai Exp $
  *
  * HSCX specific routines
  *
--- a/drivers/isdn/hisax/hscx.h
+++ b/drivers/isdn/hisax/hscx.h
@@ -1,4 +1,4 @@
-/* $Id: hscx.h,v 1.1.4.1 2001/11/20 14:19:36 kai Exp $
+/* $Id: hscx.h,v 1.8 2001/09/24 13:22:56 kai Exp $
  *
  * HSCX specific defines
  *
--- a/drivers/isdn/hisax/hscx_irq.c
+++ b/drivers/isdn/hisax/hscx_irq.c
@@ -1,4 +1,4 @@
-/* $Id: hscx_irq.c,v 1.1.4.1 2001/11/20 14:19:36 kai Exp $
+/* $Id: hscx_irq.c,v 1.18 2001/09/24 13:22:56 kai Exp $
  *
  * low level b-channel stuff for Siemens HSCX
  *
--- a/drivers/isdn/hisax/icc.c
+++ b/drivers/isdn/hisax/icc.c
@@ -1,4 +1,4 @@
-/* $Id: icc.c,v 1.1.4.1 2001/11/20 14:19:36 kai Exp $
+/* $Id: icc.c,v 1.8 2001/09/24 13:22:56 kai Exp $
  *
  * ICC specific routines
  *
--- a/drivers/isdn/hisax/icc.h
+++ b/drivers/isdn/hisax/icc.h
@@ -1,4 +1,4 @@
-/* $Id: icc.h,v 1.1.4.1 2001/11/20 14:19:36 kai Exp $
+/* $Id: icc.h,v 1.4 2001/09/24 13:22:56 kai Exp $
  *
  * ICC specific routines
  *
--- a/drivers/isdn/hisax/ipac.h
+++ b/drivers/isdn/hisax/ipac.h
@@ -1,4 +1,4 @@
-/* $Id: ipac.h,v 1.1.4.1 2001/11/20 14:19:36 kai Exp $
+/* $Id: ipac.h,v 1.7 2001/09/24 13:22:56 kai Exp $
  *
  * IPAC specific defines
  *
--- a/drivers/isdn/hisax/isac.c
+++ b/drivers/isdn/hisax/isac.c
@@ -1,4 +1,4 @@
-/* $Id: isac.c,v 1.1.4.1 2001/11/20 14:19:36 kai Exp $
+/* $Id: isac.c,v 1.31 2001/09/24 13:22:56 kai Exp $
  *
  * ISAC specific routines
  *
--- a/drivers/isdn/hisax/isac.h
+++ b/drivers/isdn/hisax/isac.h
@@ -1,4 +1,4 @@
-/* $Id: isac.h,v 1.1.4.1 2001/11/20 14:19:36 kai Exp $
+/* $Id: isac.h,v 1.9 2001/09/24 13:22:56 kai Exp $
  *
  * ISAC specific defines
  *
--- a/drivers/isdn/hisax/isar.c
+++ b/drivers/isdn/hisax/isar.c
@@ -1,4 +1,4 @@
-/* $Id: isar.c,v 1.1.4.1 2001/11/20 14:19:36 kai Exp $
+/* $Id: isar.c,v 1.22 2001/09/23 12:00:05 keil Exp $
  *
  * isar.c   ISAR (Siemens PSB 7110) specific routines
  *
@@ -21,12 +21,10 @@
 #define DLE	0x10
 #define ETX	0x03
 
-#define FAXMODCNT	13
-const	u_char	faxmodulation[] = {3,24,48,72,73,74,96,97,98,121,122,145,146};
-static	u_int	modmask = 0x1fff;
-static	int	frm_extra_delay = 2;
-static	int	para_TOA = 6;
-const   u_char  *FC1_CMD[] = {"FAE", "FTS", "FRS", "FTM", "FRM", "FTH", "FRH", "CTRL" };
+
+const u_char faxmodulation_s[] = "3,24,48,72,73,74,96,97,98,121,122,145,146"; 
+const u_char faxmodulation[] = {3,24,48,72,73,74,96,97,98,121,122,145,146}; 
+#define FAXMODCNT 13
 
 void isar_setup(struct IsdnCardState *cs);
 static void isar_pump_cmd(struct BCState *bcs, u_char cmd, u_char para);
@@ -127,7 +125,7 @@ get_irq_infos(struct IsdnCardState *cs, 
 	ireg->clsb = cs->BC_Read_Reg(cs, 1, ISAR_CTRL_L);
 #if DUMP_MBOXFRAME
 	if (cs->debug & L1_DEB_HSCX)
-		debugl1(cs, "irq_stat(%02x,%02x,%d)", ireg->iis, ireg->cmsb,
+		debugl1(cs, "rcv_mbox(%02x,%02x,%d)", ireg->iis, ireg->cmsb,
 			ireg->clsb);
 #endif
 }
@@ -414,7 +412,6 @@ isar_load_firmware(struct IsdnCardState 
 	}
 	cs->debug = debug;
 	isar_setup(cs);
-
 	ret = 0;
 reterrflg:
 	restore_flags(flags);
@@ -428,21 +425,6 @@ reterror:
 	return(ret);
 }
 
-static inline void
-ll_deliver_faxstat(struct BCState *bcs, u_char status)
-{
-        isdn_ctrl ic;
-	struct Channel *chanp = (struct Channel *) bcs->st->lli.userdata;
- 
-	if (bcs->cs->debug & L1_DEB_HSCX)
-		debugl1(bcs->cs, "HL->LL FAXIND %x", status);
-	ic.driver = bcs->cs->myid;
-	ic.command = ISDN_STAT_FAXIND;
-	ic.arg = chanp->chan;
-	ic.parm.aux.cmd = status;
-	bcs->cs->iif.statcallb(&ic);
-}
-
 extern void BChannel_bh(struct BCState *);
 #define B_LL_NOCARRIER	8
 #define B_LL_CONNECT	9
@@ -599,6 +581,7 @@ isar_rcv_frame(struct IsdnCardState *cs,
 				if (ireg->cmsb & SART_NMD) { /* ABORT */
 					if (cs->debug & L1_DEB_WARN)
 						debugl1(cs, "isar_rcv_frame: no more data");
+					cs->BC_Write_Reg(cs, 1, ISAR_IIA, 0);
 					bcs->hw.isar.rcvidx = 0;
 					send_DLE_ETX(bcs);
 					sendmsg(cs, SET_DPS(bcs->hw.isar.dpath) |
@@ -609,6 +592,7 @@ isar_rcv_frame(struct IsdnCardState *cs,
 				}
 			} else {
 				printk(KERN_WARNING "HiSax: skb out of memory\n");
+				cs->BC_Write_Reg(cs, 1, ISAR_IIA, 0);
 			}
 			break;
 		}
@@ -633,9 +617,8 @@ isar_rcv_frame(struct IsdnCardState *cs,
 			bcs->hw.isar.rcvidx = 0;
 			cs->BC_Write_Reg(cs, 1, ISAR_IIA, 0);
 		} else {
-			if (ireg->cmsb & HDLC_FSD) {
+			if (ireg->cmsb & HDLC_FSD)
 				bcs->hw.isar.rcvidx = 0;
-			}
 			ptr = bcs->hw.isar.rcvbuf + bcs->hw.isar.rcvidx;
 			bcs->hw.isar.rcvidx += ireg->clsb;
 			rcv_mbox(cs, ireg, ptr);
@@ -646,8 +629,6 @@ isar_rcv_frame(struct IsdnCardState *cs,
 					if (cs->debug & L1_DEB_WARN)
 						debugl1(cs, "isar frame to short %d",
 							bcs->hw.isar.rcvidx);
-					printk(KERN_WARNING "ISAR: frame to short %d\n",
-						bcs->hw.isar.rcvidx);
 				} else if (!(skb = dev_alloc_skb(bcs->hw.isar.rcvidx))) {
 					printk(KERN_WARNING "ISAR: receive out of memory\n");
 				} else {
@@ -658,7 +639,6 @@ isar_rcv_frame(struct IsdnCardState *cs,
 					isar_sched_event(bcs, B_RCVBUFREADY);
 					send_DLE_ETX(bcs);
 					isar_sched_event(bcs, B_LL_OK);
-					test_and_clear_bit(BC_FLG_FRH_WAIT, &bcs->Flag);
 				}
 				bcs->hw.isar.rcvidx = 0;
 			}
@@ -666,14 +646,13 @@ isar_rcv_frame(struct IsdnCardState *cs,
 		if (ireg->cmsb & SART_NMD) { /* ABORT */
 			if (cs->debug & L1_DEB_WARN)
 				debugl1(cs, "isar_rcv_frame: no more data");
+			cs->BC_Write_Reg(cs, 1, ISAR_IIA, 0);
 			bcs->hw.isar.rcvidx = 0;
+			send_DLE_ETX(bcs);
 			sendmsg(cs, SET_DPS(bcs->hw.isar.dpath) |
 				ISAR_HIS_PUMPCTRL, PCTRL_CMD_ESC, 0, NULL);
 			bcs->hw.isar.state = STFAX_ESCAPE;
-			if (test_and_clear_bit(BC_FLG_FRH_WAIT, &bcs->Flag)) {
-				send_DLE_ETX(bcs);
-				isar_sched_event(bcs, B_LL_NOCARRIER);
-			}
+			isar_sched_event(bcs, B_LL_NOCARRIER);
 		}
 		break;
 	default:
@@ -977,6 +956,21 @@ isar_pump_statev_modem(struct BCState *b
 	}
 }
 
+static inline void
+ll_deliver_faxstat(struct BCState *bcs, u_char status)
+{
+        isdn_ctrl ic;
+	struct Channel *chanp = (struct Channel *) bcs->st->lli.userdata;
+ 
+	if (bcs->cs->debug & L1_DEB_HSCX)
+		debugl1(bcs->cs, "HL->LL FAXIND %x", status);
+	ic.driver = bcs->cs->myid;
+	ic.command = ISDN_STAT_FAXIND;
+	ic.arg = chanp->chan;
+	ic.parm.aux.cmd = status;
+	bcs->cs->iif.statcallb(&ic);
+}
+
 static void
 isar_pump_statev_fax(struct BCState *bcs, u_char devt) {
 	struct IsdnCardState *cs = bcs->cs;
@@ -1081,22 +1075,19 @@ isar_pump_statev_fax(struct BCState *bcs
 			if (cs->debug & L1_DEB_HSCX)
 				debugl1(cs, "pump stev RSP_DISC");
 			if (bcs->hw.isar.state == STFAX_ESCAPE) {
-				p1 = 5;
 				switch(bcs->hw.isar.newcmd) {
 					case 0:
 						bcs->hw.isar.state = STFAX_READY;
 						break;
-					case PCTRL_CMD_FTM:
-						p1 = 2;
 					case PCTRL_CMD_FTH:
+					case PCTRL_CMD_FTM:
+						p1 = 10;
 						sendmsg(cs, dps | ISAR_HIS_PUMPCTRL,
 							PCTRL_CMD_SILON, 1, &p1);
 						bcs->hw.isar.state = STFAX_SILDET;
 						break;
-					case PCTRL_CMD_FRM:
-						if (frm_extra_delay)
-							mdelay(frm_extra_delay);
 					case PCTRL_CMD_FRH:
+					case PCTRL_CMD_FRM:
 						p1 = bcs->hw.isar.mod = bcs->hw.isar.newmod;
 						bcs->hw.isar.newmod = 0;
 						bcs->hw.isar.cmd = bcs->hw.isar.newcmd;
@@ -1215,9 +1206,6 @@ isar_int_main(struct IsdnCardState *cs)
 					isar_pump_statev_modem(bcs, ireg->cmsb);
 				} else if (bcs->mode == L1_MODE_FAX) {
 					isar_pump_statev_fax(bcs, ireg->cmsb);
-				} else if (ireg->cmsb == PSEV_10MS_TIMER) {
-					if (cs->debug & L1_DEB_HSCX)
-						debugl1(cs, "pump stev TIMER");
 				} else {
 					if (cs->debug & L1_DEB_WARN)
 						debugl1(cs, "isar IIS_PSTEV pmode %d stat %x",
@@ -1278,9 +1266,6 @@ ftimer_handler(struct BCState *bcs) {
 	if (test_and_clear_bit(BC_FLG_LL_CONN, &bcs->Flag)) {
 		isar_sched_event(bcs, B_LL_CONNECT);
 	}
-	if (test_and_clear_bit(BC_FLG_FTI_FTS, &bcs->Flag)) {
-		isar_sched_event(bcs, B_LL_OK);
-	}
 }
 
 static void
@@ -1303,7 +1288,7 @@ setup_pump(struct BCState *bcs) {
 			} else {
 				param[5] = PV32P6_ATN;
 			}
-			param[0] = para_TOA; /* 6 db */
+			param[0] = 6; /* 6 db */
 			param[1] = PV32P2_V23R | PV32P2_V22A | PV32P2_V22B |
 				   PV32P2_V22C | PV32P2_V21 | PV32P2_BEL; 
 			param[2] = PV32P3_AMOD | PV32P3_V32B | PV32P3_V23B;
@@ -1319,7 +1304,7 @@ setup_pump(struct BCState *bcs) {
 			} else {
 				param[1] = PFAXP2_ATN;
 			}
-			param[0] = para_TOA; /* 6 db */
+			param[0] = 6; /* 6 db */
 			sendmsg(cs, dps | ISAR_HIS_PUMPCFG, ctrl, 2, param);
 			bcs->hw.isar.state = STFAX_NULL;
 			bcs->hw.isar.newcmd = 0;
@@ -1348,6 +1333,7 @@ setup_sart(struct BCState *bcs) {
 				"\0\0");
 			break;
 		case L1_MODE_HDLC:
+		case L1_MODE_FAX:
 			param[0] = 0;
 			sendmsg(cs, dps | ISAR_HIS_SARTCFG, SMODE_HDLC, 1,
 				param);
@@ -1359,9 +1345,6 @@ setup_sart(struct BCState *bcs) {
 			sendmsg(cs, dps | ISAR_HIS_SARTCFG, ctrl, 2,
 				param);
 			break;
-		case L1_MODE_FAX:
-			/* SART must not configured with FAX */
-			break;
 	}
 	udelay(1000);
 	sendmsg(cs, dps | ISAR_HIS_BSTREQ, 0, 0, NULL);
@@ -1465,7 +1448,6 @@ isar_pump_cmd(struct BCState *bcs, u_cha
 
 	switch(cmd) {
 		case ISDN_FAX_CLASS1_FTM:
-			test_and_clear_bit(BC_FLG_FRH_WAIT, &bcs->Flag);
 			if (bcs->hw.isar.state == STFAX_READY) {
 				p1 = para;
 				ctrl = PCTRL_CMD_FTM;
@@ -1489,7 +1471,6 @@ isar_pump_cmd(struct BCState *bcs, u_cha
 			}
 			break;
 		case ISDN_FAX_CLASS1_FTH:
-			test_and_clear_bit(BC_FLG_FRH_WAIT, &bcs->Flag);
 			if (bcs->hw.isar.state == STFAX_READY) {
 				p1 = para;
 				ctrl = PCTRL_CMD_FTH;
@@ -1513,7 +1494,6 @@ isar_pump_cmd(struct BCState *bcs, u_cha
 			}
 			break;
 		case ISDN_FAX_CLASS1_FRM:
-			test_and_clear_bit(BC_FLG_FRH_WAIT, &bcs->Flag);
 			if (bcs->hw.isar.state == STFAX_READY) {
 				p1 = para;
 				ctrl = PCTRL_CMD_FRM;
@@ -1537,7 +1517,6 @@ isar_pump_cmd(struct BCState *bcs, u_cha
 			}
 			break;
 		case ISDN_FAX_CLASS1_FRH:
-			test_and_set_bit(BC_FLG_FRH_WAIT, &bcs->Flag);
 			if (bcs->hw.isar.state == STFAX_READY) {
 				p1 = para;
 				ctrl = PCTRL_CMD_FRH;
@@ -1560,11 +1539,6 @@ isar_pump_cmd(struct BCState *bcs, u_cha
 				bcs->hw.isar.state = STFAX_ESCAPE; 
 			}
 			break;
-		case ISDN_FAXPUMP_HALT:
-			bcs->hw.isar.state = STFAX_NULL;
-			nom = 0;
-			ctrl = PCTRL_CMD_HALT;
-			break;
 	}
 	if (ctrl)
 		sendmsg(cs, dps | ISAR_HIS_PUMPCTRL, ctrl, nom, &p1);
@@ -1658,15 +1632,6 @@ isar_l2l1(struct PStack *st, int pr, voi
 			l1_msg_b(st, pr, arg);
 			break;
 		case (PH_DEACTIVATE | CONFIRM):
-			switch(st->l1.mode) {
-				case L1_MODE_TRANS:
-				case L1_MODE_HDLC:
-				case L1_MODE_V32:
-					break;
-				case L1_MODE_FAX:
-					isar_pump_cmd(st->l1.bcs, ISDN_FAXPUMP_HALT, 0);
-					break;
-			}
 			test_and_clear_bit(BC_FLG_ACTIV, &st->l1.bcs->Flag);
 			test_and_clear_bit(BC_FLG_BUSY, &st->l1.bcs->Flag);
 			if (st->l1.bcs->cs->debug & L1_DEB_HSCX)
@@ -1758,51 +1723,6 @@ isar_auxcmd(struct IsdnCardState *cs, is
 						test_and_set_bit(BC_FLG_DLEETX,
 							&bcs->Flag);
 					break;
-				case ISDN_FAX_CLASS1_FTS:
-					if (ic->parm.aux.subcmd == AT_QUERY) {
-						ic->command = ISDN_STAT_FAXIND;
-						ic->parm.aux.cmd = ISDN_FAX_CLASS1_OK;
-						cs->iif.statcallb(ic);
-						return(0);
-					} else if (ic->parm.aux.subcmd == AT_EQ_QUERY) {
-						strcpy(ic->parm.aux.para, "0-255");
-						ic->command = ISDN_STAT_FAXIND;
-						ic->parm.aux.cmd = ISDN_FAX_CLASS1_QUERY;
-						cs->iif.statcallb(ic);
-						return(0);
-					} else if (ic->parm.aux.subcmd == AT_EQ_VALUE) {
-						if (cs->debug & L1_DEB_HSCX)
-							debugl1(cs, "isar_auxcmd %s=%d",
-								FC1_CMD[ic->parm.aux.cmd], ic->parm.aux.para[0]);
-						if (bcs->hw.isar.state == STFAX_READY) {
-							if (! ic->parm.aux.para[0]) {
-								ic->command = ISDN_STAT_FAXIND;
-								ic->parm.aux.cmd = ISDN_FAX_CLASS1_OK;
-								cs->iif.statcallb(ic);
-								return(0);
-							}
-							if (! test_and_set_bit(BC_FLG_FTI_RUN, &bcs->Flag)) {
-								/* n*10 ms */
-								bcs->hw.isar.ftimer.expires =
-									jiffies + ((ic->parm.aux.para[0] * 10 * HZ)/1000);
-								test_and_set_bit(BC_FLG_FTI_FTS, &bcs->Flag);
-								add_timer(&bcs->hw.isar.ftimer);
-								return(0);
-							} else {
-								if (cs->debug)
-									debugl1(cs, "isar FTS=%d and FTI busy",
-										ic->parm.aux.para[0]);
-							}
-						} else {
-							if (cs->debug)
-								debugl1(cs, "isar FTS=%d and isar.state not ready(%x)",
-									ic->parm.aux.para[0],bcs->hw.isar.state);
-						}
-						ic->command = ISDN_STAT_FAXIND;
-						ic->parm.aux.cmd = ISDN_FAX_CLASS1_ERROR;
-						cs->iif.statcallb(ic);
-					}
-					break;
 				case ISDN_FAX_CLASS1_FRM:
 				case ISDN_FAX_CLASS1_FRH:
 				case ISDN_FAX_CLASS1_FTM:
@@ -1815,24 +1735,16 @@ isar_auxcmd(struct IsdnCardState *cs, is
 						cs->iif.statcallb(ic);
 						return(0);
 					} else if (ic->parm.aux.subcmd == AT_EQ_QUERY) {
-						char *p = ic->parm.aux.para;
-						for(i=0;i<FAXMODCNT;i++)
-							if ((1<<i) & modmask)
-								p += sprintf(p, "%d,", faxmodulation[i]);
-						p--;
-						*p=0;
+						strcpy(ic->parm.aux.para, faxmodulation_s);
 						ic->command = ISDN_STAT_FAXIND;
 						ic->parm.aux.cmd = ISDN_FAX_CLASS1_QUERY;
 						cs->iif.statcallb(ic);
 						return(0);
 					} else if (ic->parm.aux.subcmd == AT_EQ_VALUE) {
-						if (cs->debug & L1_DEB_HSCX)
-							debugl1(cs, "isar_auxcmd %s=%d",
-								FC1_CMD[ic->parm.aux.cmd], ic->parm.aux.para[0]);
 						for(i=0;i<FAXMODCNT;i++)
 							if (faxmodulation[i]==ic->parm.aux.para[0])
 								break;
-						if ((i < FAXMODCNT) && ((1<<i) & modmask) && 
+						if ((FAXMODCNT > i) && 
 							test_bit(BC_FLG_INIT, &bcs->Flag)) {
 							isar_pump_cmd(bcs,
 								ic->parm.aux.cmd,
@@ -1850,7 +1762,7 @@ isar_auxcmd(struct IsdnCardState *cs, is
 			break;
 		case (ISDN_CMD_IOCTL):
 			switch (ic->arg) {
-				case 9: /* load firmware */
+				case (9): /* load firmware */
 					features = ISDN_FEATURE_L2_MODEM |
 						ISDN_FEATURE_L2_FAX |
 						ISDN_FEATURE_L3_FCLASS1;
@@ -1860,26 +1772,6 @@ isar_auxcmd(struct IsdnCardState *cs, is
 					else 
 						ll_run(cs, features);
 					break;
-				case 20:
-					features = *(unsigned int *) ic->parm.num;
-					printk(KERN_DEBUG "HiSax: max modulation old(%04x) new(%04x)\n",
-						modmask, features);
-					modmask = features;
-					break;
-				case 21:
-					features = *(unsigned int *) ic->parm.num;
-					printk(KERN_DEBUG "HiSax: FRM extra delay old(%d) new(%d) ms\n",
-						frm_extra_delay, features);
-					if (features >= 0)
-						frm_extra_delay = features;
-					break;
-				case 22:
-					features = *(unsigned int *) ic->parm.num;
-					printk(KERN_DEBUG "HiSax: TOA old(%d) new(%d) db\n",
-						para_TOA, features);
-					if (features >= 0 && features < 32)
-						para_TOA = features;
-					break;
 				default:
 					printk(KERN_DEBUG "HiSax: invalid ioctl %d\n",
 					       (int) ic->arg);
--- a/drivers/isdn/hisax/isar.h
+++ b/drivers/isdn/hisax/isar.h
@@ -1,4 +1,4 @@
-/* $Id: isar.h,v 1.1.4.1 2001/11/20 14:19:36 kai Exp $
+/* $Id: isar.h,v 1.11 2001/09/24 13:22:56 kai Exp $
  *
  * ISAR (Siemens PSB 7110) specific defines
  *
@@ -28,8 +28,6 @@
 #define ISAR_HIS_FIRM		0x1e
 #define ISAR_HIS_STDSP		0x08
 #define ISAR_HIS_DIAG		0x05
-#define ISAR_HIS_WAITSTATE	0x27
-#define ISAR_HIS_TIMERIRQ	0x25
 #define ISAR_HIS_P0CFG		0x3c
 #define ISAR_HIS_P12CFG		0x24
 #define ISAR_HIS_SARTCFG	0x25	
@@ -45,10 +43,6 @@
 #define ISAR_HIS_DPS2		0x80
 #define SET_DPS(x)		((x<<6) & 0xc0)
 
-#define ISAR_CMD_TIMERIRQ_OFF	0x20
-#define ISAR_CMD_TIMERIRQ_ON	0x21
-
-
 #define ISAR_IIS_MSCMSD		0x3f
 #define ISAR_IIS_VNR		0x15
 #define ISAR_IIS_DKEY		0x03
@@ -213,8 +207,6 @@
 #define STFAX_ESCAPE	5
 #define STFAX_SILDET	6
 
-#define ISDN_FAXPUMP_HALT	100
-
 extern int ISARVersion(struct IsdnCardState *cs, char *s);
 extern void isar_int_main(struct IsdnCardState *cs);
 extern void initisar(struct IsdnCardState *cs);
--- a/drivers/isdn/hisax/isdnl1.c
+++ b/drivers/isdn/hisax/isdnl1.c
@@ -1,4 +1,4 @@
-/* $Id: isdnl1.c,v 1.1.4.1 2001/11/20 14:19:36 kai Exp $
+/* $Id: isdnl1.c,v 2.46 2001/09/24 13:22:56 kai Exp $
  *
  * common low level stuff for Siemens Chipsetbased isdn cards
  *
@@ -18,7 +18,7 @@
  *
  */
 
-const char *l1_revision = "$Revision: 1.1.4.1 $";
+const char *l1_revision = "$Revision: 2.46 $";
 
 #define __NO_VERSION__
 #include <linux/init.h>
--- a/drivers/isdn/hisax/isdnl1.h
+++ b/drivers/isdn/hisax/isdnl1.h
@@ -1,4 +1,4 @@
-/* $Id: isdnl1.h,v 1.1.4.1 2001/11/20 14:19:36 kai Exp $
+/* $Id: isdnl1.h,v 2.12 2001/09/24 13:22:56 kai Exp $
  *
  * Layer 1 defines
  *
--- a/drivers/isdn/hisax/isdnl2.c
+++ b/drivers/isdn/hisax/isdnl2.c
@@ -1,4 +1,4 @@
-/* $Id: isdnl2.c,v 1.1.4.1 2001/11/20 14:19:36 kai Exp $
+/* $Id: isdnl2.c,v 2.30 2001/09/24 13:22:56 kai Exp $
  *
  * Author       Karsten Keil
  *              based on the teles driver from Jan den Ouden
@@ -20,7 +20,7 @@
 #include "hisax.h"
 #include "isdnl2.h"
 
-const char *l2_revision = "$Revision: 1.1.4.1 $";
+const char *l2_revision = "$Revision: 2.30 $";
 
 static void l2m_debug(struct FsmInst *fi, char *fmt, ...);
 
@@ -1418,8 +1418,8 @@ l2_st5_tei_remove(struct FsmInst *fi, in
 	freewin(st);
 	st->l2.tei = -1;
 	stop_t200(st, 17);
-	st5_dl_release_l2l3(st);
 	FsmChangeState(fi, ST_L2_1);
+	st5_dl_release_l2l3(st);
 }
 
 static void
--- a/drivers/isdn/hisax/isdnl2.h
+++ b/drivers/isdn/hisax/isdnl2.h
@@ -1,4 +1,4 @@
-/* $Id: isdnl2.h,v 1.1.4.1 2001/11/20 14:19:36 kai Exp $
+/* $Id$
  *
  * Layer 2 defines
  *
--- a/drivers/isdn/hisax/isdnl3.c
+++ b/drivers/isdn/hisax/isdnl3.c
@@ -1,4 +1,4 @@
-/* $Id: isdnl3.c,v 1.1.4.1 2001/11/20 14:19:36 kai Exp $
+/* $Id: isdnl3.c,v 2.22 2001/09/24 13:22:56 kai Exp $
  *
  * Author       Karsten Keil
  *              based on the teles driver from Jan den Ouden
@@ -21,7 +21,7 @@
 #include "isdnl3.h"
 #include <linux/config.h>
 
-const char *l3_revision = "$Revision: 1.1.4.1 $";
+const char *l3_revision = "$Revision: 2.22 $";
 
 static struct Fsm l3fsm;
 
--- a/drivers/isdn/hisax/isdnl3.h
+++ b/drivers/isdn/hisax/isdnl3.h
@@ -1,4 +1,4 @@
-/* $Id: isdnl3.h,v 1.1.4.1 2001/11/20 14:19:36 kai Exp $
+/* $Id$
  *
  * This software may be used and distributed according to the terms
  * of the GNU General Public License, incorporated herein by reference.
--- a/drivers/isdn/hisax/isurf.c
+++ b/drivers/isdn/hisax/isurf.c
@@ -1,4 +1,4 @@
-/* $Id: isurf.c,v 1.1.4.1 2001/11/20 14:19:36 kai Exp $
+/* $Id: isurf.c,v 1.12 2001/09/24 13:22:56 kai Exp $
  *
  * low level stuff for Siemens I-Surf/I-Talk cards
  *
@@ -16,11 +16,10 @@
 #include "isac.h"
 #include "isar.h"
 #include "isdnl1.h"
-#include <linux/isapnp.h>
 
 extern const char *CardType[];
 
-static const char *ISurf_revision = "$Revision: 1.1.4.1 $";
+static const char *ISurf_revision = "$Revision: 1.12 $";
 
 #define byteout(addr,val) outb(val,addr)
 #define bytein(addr) inb(addr)
@@ -128,8 +127,10 @@ void
 release_io_isurf(struct IsdnCardState *cs)
 {
 	release_region(cs->hw.isurf.reset, 1);
+#ifdef COMPAT_HAS_ISA_IOREMAP
 	iounmap((unsigned char *)cs->hw.isurf.isar);
 	release_mem_region(cs->hw.isurf.phymem, ISURF_IOMEM_SIZE);
+#endif
 }
 
 static void
@@ -194,10 +195,6 @@ isurf_auxcmd(struct IsdnCardState *cs, i
 	return(isar_auxcmd(cs, ic));
 }
 
-#ifdef __ISAPNP__
-static struct pci_bus *pnp_surf __devinitdata = NULL;
-#endif
-
 int __init
 setup_isurf(struct IsdnCard *card)
 {
@@ -215,58 +212,9 @@ setup_isurf(struct IsdnCard *card)
 		cs->hw.isurf.phymem = card->para[2];
 		cs->irq = card->para[0];
 	} else {
-#ifdef __ISAPNP__
-		struct pci_bus *pb;
-		struct pci_dev *pd;
-
-		if (isapnp_present()) {
-			cs->subtyp = 0;
-			if ((pb = isapnp_find_card(
-				ISAPNP_VENDOR('S', 'I', 'E'),
-				ISAPNP_FUNCTION(0x0010), pnp_surf))) {
-				pnp_surf = pb;
-				pd = NULL;
-				if (!(pd = isapnp_find_dev(pnp_surf,
-					ISAPNP_VENDOR('S', 'I', 'E'),
-					ISAPNP_FUNCTION(0x0010), pd))) {
-					printk(KERN_ERR "ISurfPnP: PnP error card found, no device\n");
-					return (0);
-				}
-				pd->prepare(pd);
-				pd->deactivate(pd);
-				pd->activate(pd);
-				/* The ISA-PnP logic apparently
-				 * expects upper limit address to be
-				 * set. Since the isa-pnp module
-				 * doesn't do this, so we have to make
-				 * up for it.
-				 */
-				isapnp_cfg_begin(pd->bus->number, pd->devfn);
-				isapnp_write_word(ISAPNP_CFG_MEM+3, 
-					pd->resource[8].end >> 8);
-				isapnp_cfg_end();
-				cs->hw.isurf.reset = pd->resource[0].start;
-				cs->hw.isurf.phymem = pd->resource[8].start;
-				cs->irq = pd->irq_resource[0].start;
-				if (!cs->irq || !cs->hw.isurf.reset || !cs->hw.isurf.phymem) {
-					printk(KERN_ERR "ISurfPnP:some resources are missing %d/%x/%lx\n",
-						cs->irq, cs->hw.isurf.reset, cs->hw.isurf.phymem);
-					pd->deactivate(pd);
-					return(0);
-				}
-			} else {
-				printk(KERN_INFO "ISurfPnP: no ISAPnP card found\n");
-				return(0);
-			}
-		} else {
-			printk(KERN_INFO "ISurfPnP: no ISAPnP bus found\n");
-			return(0);
-		}
-#else
 		printk(KERN_WARNING "HiSax: %s port/mem not set\n",
 			CardType[card->typ]);
 		return (0);
-#endif
 	}
 	if (check_region(cs->hw.isurf.reset, 1)) {
 		printk(KERN_WARNING
@@ -277,6 +225,7 @@ setup_isurf(struct IsdnCard *card)
 	} else {
 		request_region(cs->hw.isurf.reset, 1, "isurf isdn");
 	}
+#ifdef COMPAT_HAS_ISA_IOREMAP
 	if (check_mem_region(cs->hw.isurf.phymem, ISURF_IOMEM_SIZE)) {
 		printk(KERN_WARNING
 			"HiSax: %s memory region %lx-%lx already in use\n",
@@ -292,6 +241,10 @@ setup_isurf(struct IsdnCard *card)
 	cs->hw.isurf.isar =
 		(unsigned long) ioremap(cs->hw.isurf.phymem, ISURF_IOMEM_SIZE);
 	cs->hw.isurf.isac = cs->hw.isurf.isar + ISURF_ISAC_OFFSET;
+#else
+	cs->hw.isurf.isar = cs->hw.isurf.phymem + ISURF_ISAR_OFFSET;
+	cs->hw.isurf.isac = cs->hw.isurf.phymem + ISURF_ISAC_OFFSET;
+#endif
 	printk(KERN_INFO
 	       "ISurf: defined at 0x%x 0x%lx IRQ %d\n",
 	       cs->hw.isurf.reset,
--- a/drivers/isdn/hisax/ix1_micro.c
+++ b/drivers/isdn/hisax/ix1_micro.c
@@ -1,4 +1,4 @@
-/* $Id: ix1_micro.c,v 1.1.4.1 2001/11/20 14:19:36 kai Exp $
+/* $Id: ix1_micro.c,v 2.12 2001/09/24 13:22:56 kai Exp $
  *
  * low level stuff for ITK ix1-micro Rev.2 isdn cards
  * derived from the original file teles3.c from Karsten Keil
@@ -19,14 +19,13 @@
 
 #define __NO_VERSION__
 #include <linux/init.h>
-#include <linux/isapnp.h>
 #include "hisax.h"
 #include "isac.h"
 #include "hscx.h"
 #include "isdnl1.h"
 
 extern const char *CardType[];
-const char *ix1_revision = "$Revision: 1.1.4.1 $";
+const char *ix1_revision = "$Revision: 2.12 $";
 
 #define byteout(addr,val) outb(val,addr)
 #define bytein(addr) inb(addr)
@@ -219,21 +218,6 @@ ix1_card_msg(struct IsdnCardState *cs, i
 	return(0);
 }
 
-#ifdef __ISAPNP__
-static struct isapnp_device_id itk_ids[] __initdata = {
-	{ ISAPNP_VENDOR('I', 'T', 'K'), ISAPNP_FUNCTION(0x25),
-	  ISAPNP_VENDOR('I', 'T', 'K'), ISAPNP_FUNCTION(0x25), 
-	  (unsigned long) "ITK micro 2" },
-	{ ISAPNP_VENDOR('I', 'T', 'K'), ISAPNP_FUNCTION(0x29),
-	  ISAPNP_VENDOR('I', 'T', 'K'), ISAPNP_FUNCTION(0x29), 
-	  (unsigned long) "ITK micro 2." },
-	{ 0, }
-};
-
-static struct isapnp_device_id *idev = &itk_ids[0];
-static struct pci_bus *pnp_c __devinitdata = NULL;
-#endif
-
 
 int __init
 setup_ix1micro(struct IsdnCard *card)
@@ -246,45 +230,6 @@ setup_ix1micro(struct IsdnCard *card)
 	if (cs->typ != ISDN_CTYPE_IX1MICROR2)
 		return (0);
 
-#ifdef __ISAPNP__
-	if (!card->para[1] && isapnp_present()) {
-		struct pci_bus *pb;
-		struct pci_dev *pd;
-
-		while(idev->card_vendor) {
-			if ((pb = isapnp_find_card(idev->card_vendor,
-				idev->card_device, pnp_c))) {
-				pnp_c = pb;
-				pd = NULL;
-				if ((pd = isapnp_find_dev(pnp_c,
-					idev->vendor, idev->function, pd))) {
-					printk(KERN_INFO "HiSax: %s detected\n",
-						(char *)idev->driver_data);
-					pd->prepare(pd);
-					pd->deactivate(pd);
-					pd->activate(pd);
-					card->para[1] = pd->resource[0].start;
-					card->para[0] = pd->irq_resource[0].start;
-					if (!card->para[0] || !card->para[1]) {
-						printk(KERN_ERR "ITK PnP:some resources are missing %ld/%lx\n",
-						card->para[0], card->para[1]);
-						pd->deactivate(pd);
-						return(0);
-					}
-					break;
-				} else {
-					printk(KERN_ERR "ITK PnP: PnP error card found, no device\n");
-				}
-			}
-			idev++;
-			pnp_c=NULL;
-		} 
-		if (!idev->card_vendor) {
-			printk(KERN_INFO "ITK PnP: no ISAPnP card found\n");
-			return(0);
-		}
-	}
-#endif
 	/* IO-Ports */
 	cs->hw.ix1.isac_ale = card->para[1] + ISAC_COMMAND_OFFSET;
 	cs->hw.ix1.hscx_ale = card->para[1] + HSCX_COMMAND_OFFSET;
--- a/drivers/isdn/hisax/jade.c
+++ b/drivers/isdn/hisax/jade.c
@@ -1,4 +1,4 @@
-/* $Id: jade.c,v 1.1.4.1 2001/11/20 14:19:36 kai Exp $
+/* $Id: jade.c,v 1.9 2001/09/24 13:22:56 kai Exp $
  *
  * JADE stuff (derived from original hscx.c)
  *
--- a/drivers/isdn/hisax/jade.h
+++ b/drivers/isdn/hisax/jade.h
@@ -1,4 +1,4 @@
-/* $Id: jade.h,v 1.1.4.1 2001/11/20 14:19:36 kai Exp $
+/* $Id: jade.h,v 1.5 2001/09/24 13:22:56 kai Exp $
  *
  * JADE specific defines
  *
--- a/drivers/isdn/hisax/jade_irq.c
+++ b/drivers/isdn/hisax/jade_irq.c
@@ -1,4 +1,4 @@
-/* $Id: jade_irq.c,v 1.1.4.1 2001/11/20 14:19:36 kai Exp $
+/* $Id: jade_irq.c,v 1.7 2001/09/24 13:22:56 kai Exp $
  *
  * Low level JADE IRQ stuff (derived from original hscx_irq.c)
  *
--- a/drivers/isdn/hisax/l3_1tr6.c
+++ b/drivers/isdn/hisax/l3_1tr6.c
@@ -1,4 +1,4 @@
-/* $Id: l3_1tr6.c,v 1.1.4.1 2001/11/20 14:19:36 kai Exp $
+/* $Id: l3_1tr6.c,v 2.15 2001/09/24 13:22:56 kai Exp $
  *
  * German 1TR6 D-channel protocol
  *
@@ -20,7 +20,7 @@
 #include <linux/ctype.h>
 
 extern char *HiSax_getrev(const char *revision);
-const char *l3_1tr6_revision = "$Revision: 1.1.4.1 $";
+const char *l3_1tr6_revision = "$Revision: 2.15 $";
 
 #define MsgHead(ptr, cref, mty, dis) \
 	*ptr++ = dis; \
--- a/drivers/isdn/hisax/l3_1tr6.h
+++ b/drivers/isdn/hisax/l3_1tr6.h
@@ -1,4 +1,4 @@
-/* $Id: l3_1tr6.h,v 1.1.4.1 2001/11/20 14:19:36 kai Exp $
+/* $Id$
  *
  * German 1TR6 D-channel protocol defines
  *
--- a/drivers/isdn/hisax/l3dss1.c
+++ b/drivers/isdn/hisax/l3dss1.c
@@ -1,4 +1,4 @@
-/* $Id: l3dss1.c,v 1.1.4.1 2001/11/20 14:19:36 kai Exp $
+/* $Id: l3dss1.c,v 2.32 2001/09/24 13:22:56 kai Exp $
  *
  * EURO/DSS1 D-channel protocol
  *
@@ -27,7 +27,7 @@
 #include <linux/config.h>
 
 extern char *HiSax_getrev(const char *revision);
-const char *dss1_revision = "$Revision: 1.1.4.1 $";
+const char *dss1_revision = "$Revision: 2.32 $";
 
 #define EXT_BEARER_CAPS 1
 
--- a/drivers/isdn/hisax/l3dss1.h
+++ b/drivers/isdn/hisax/l3dss1.h
@@ -1,4 +1,4 @@
-/* $Id: l3dss1.h,v 1.1.4.1 2001/11/20 14:19:36 kai Exp $
+/* $Id$
  *
  * DSS1 (Euro) D-channel protocol defines
  *
--- a/drivers/isdn/hisax/l3ni1.c
+++ b/drivers/isdn/hisax/l3ni1.c
@@ -1,4 +1,4 @@
-/* $Id: l3ni1.c,v 1.1.4.1 2001/11/20 14:19:36 kai Exp $
+/* $Id: l3ni1.c,v 2.8 2001/09/24 13:22:56 kai Exp $
  *
  * NI1 D-channel protocol
  *
@@ -25,7 +25,7 @@
 #include <linux/ctype.h>
 
 extern char *HiSax_getrev(const char *revision);
-const char *ni1_revision = "$Revision: 1.1.4.1 $";
+const char *ni1_revision = "$Revision: 2.8 $";
 
 #define EXT_BEARER_CAPS 1
 
--- a/drivers/isdn/hisax/l3ni1.h
+++ b/drivers/isdn/hisax/l3ni1.h
@@ -1,4 +1,4 @@
-/* $Id: l3ni1.h,v 1.1.4.1 2001/11/20 14:19:36 kai Exp $
+/* $Id$
  *
  * NI1 D-channel protocol
  *
--- a/drivers/isdn/hisax/lmgr.c
+++ b/drivers/isdn/hisax/lmgr.c
@@ -1,4 +1,4 @@
-/* $Id: lmgr.c,v 1.1.4.1 2001/11/20 14:19:36 kai Exp $
+/* $Id$
  *
  * Layermanagement module
  *
--- a/drivers/isdn/hisax/md5sums.asc
+++ b/drivers/isdn/hisax/md5sums.asc
@@ -1,33 +1,22 @@
------BEGIN PGP SIGNED MESSAGE-----
-Hash: SHA1
-
 # This are valid md5sums for certificated HiSax driver.
 # The certification is valid only if the md5sums of all files match.
 # The certification is valid only for ELSA Microlink PCI,
-# Eicon Technology Diva 2.01 PCI, Sedlbauer SpeedFax+,
-# HFC-S PCI A based cards and HFC-S USB based ISDN
-# terminal adapters in the moment.
+# Eicon Technology Diva 2.01 PCI, Sedlbauer SpeedFax+, 
+# HFC-S PCI A based cards and HFC-S USB based isdn tas 
+# in the moment.
 # Read ../../../Documentation/isdn/HiSax.cert for more informations.
 # 
-cd4a9917e1147039d5dfc66440d42054  isac.c
-211840e78b56c9d4753be9c85da21a50  isdnl1.c
-5ce9b1fff42a02f9c2eb4fb81c701b1f  isdnl2.c
-6948de0c43513dd23c6706feb5fc2209  isdnl3.c
-3730780b69368218d756024165efea79  tei.c
-16e72710eb58da01415b877490f5d2ac  callc.c
-6abc55c77e0f3149ae9334f3257a1a1a  cert.c
-27bdb2800d4590e00da20eff241edc47  l3dss1.c
-df8bb877b854c4302d396b554e4e84ef  l3_1tr6.c
-9d8b4bed15370063d1b16e47080f50e1  elsa.c
-210f4a3f1eebca70229d786b15cf3e90  diva.c
-4ddf21079dd77e892380f789bae250a7  sedlbauer.c
-8200d818771e3cbdef2a3c3e818d25ac  hfc_pci.c
+6f9433a8b696076562562d090e3c420f  isac.c
+13c3eed869f5139f44c563e3a8fea1f5  isdnl1.c
+addcff863b0ff1e366c0f2ae9fa6e81e  isdnl2.c
+7076deb94a363945c21ea27aca4a720a  isdnl3.c
+51c603829b6cc4f8421f744ad657ceff  tei.c
+669050ab5079f02887ed0239d86e5474  callc.c
+ecacd146b8f8881ef9349935dab3df4a  cert.c
+fadeb3b85bb23bc1ac48470c0848d6fa  l3dss1.c
+cf7dec9fac6283716904d26b99188476  l3_1tr6.c
+2f75c8765e1be13d114d5f4433cf364b  elsa.c
+b4cf8a4dceed9ea6dcba65a85b4eecc7  diva.c
+dee3f8f40c6fe78a4b57729804b7e6cd  sedlbauer.c
+0d79fe6dfc5bfaa4826970c41a6d273d  hfc_pci.c
 # end of md5sums
------BEGIN PGP SIGNATURE-----
-Version: GnuPG v1.0.6 (GNU/Linux)
-Comment: For info see http://www.gnupg.org
-
-iD8DBQE9rE91DiY0VZsg4ukRAkKfAJ4xWUfqjc0hW+V+JPue5yr7mrt+RwCdGdSf
-GIKgAEdRLzERmpt/bCCwAbY=
-=FaHw
------END PGP SIGNATURE-----
--- a/drivers/isdn/hisax/mic.c
+++ b/drivers/isdn/hisax/mic.c
@@ -1,4 +1,4 @@
-/* $Id: mic.c,v 1.1.4.1 2001/11/20 14:19:36 kai Exp $
+/* $Id: mic.c,v 1.12 2001/09/24 13:22:56 kai Exp $
  *
  * low level stuff for mic cards
  *
@@ -19,7 +19,7 @@
 
 extern const char *CardType[];
 
-const char *mic_revision = "$Revision: 1.1.4.1 $";
+const char *mic_revision = "$Revision: 1.12 $";
 
 #define byteout(addr,val) outb(val,addr)
 #define bytein(addr) inb(addr)
--- a/drivers/isdn/hisax/netjet.c
+++ b/drivers/isdn/hisax/netjet.c
@@ -1,4 +1,4 @@
-/* $Id: netjet.c,v 1.1.4.1 2001/11/20 14:19:36 kai Exp $
+/* $Id: netjet.c,v 1.29 2001/09/24 13:22:56 kai Exp $
  *
  * low level stuff for Traverse Technologie NETJet ISDN cards
  *
@@ -8,9 +8,7 @@
  * This software may be used and distributed according to the terms
  * of the GNU General Public License, incorporated herein by reference.
  *
- * Thanks to Traverse Technologies Australia for documents and information
- *
- * 16-Apr-2002 - led code added - Guy Ellis (guy@traverse.com.au)
+ * Thanks to Traverse Technologie Australia for documents and information
  *
  */
 
@@ -26,7 +24,7 @@
 #include <asm/io.h>
 #include "netjet.h"
 
-const char *NETjet_revision = "$Revision: 1.1.4.1 $";
+const char *NETjet_revision = "$Revision: 1.29 $";
 
 /* Interface functions */
 
@@ -135,7 +133,6 @@ void
 mode_tiger(struct BCState *bcs, int mode, int bc)
 {
 	struct IsdnCardState *cs = bcs->cs;
-        u_char led;
 
 	if (cs->debug & L1_DEB_HSCX)
 		debugl1(cs, "Tiger mode %d bchan %d/%d",
@@ -157,15 +154,6 @@ mode_tiger(struct BCState *bcs, int mode
 					cs->hw.njet.dmactrl);
 				byteout(cs->hw.njet.base + NETJET_IRQMASK0, 0);
 			}
-                        if (cs->typ == ISDN_CTYPE_NETJET_S)
-                        {
-                                // led off
-                                led = bc & 0x01;
-                                led = 0x01 << (6 + led); // convert to mask
-                                led = ~led;
-                                cs->hw.njet.auxd &= led;
-                                byteout(cs->hw.njet.auxa, cs->hw.njet.auxd);
-                        }
 			break;
 		case (L1_MODE_TRANS):
 			break;
@@ -191,14 +179,6 @@ mode_tiger(struct BCState *bcs, int mode
 			bcs->hw.tiger.sendp = bcs->hw.tiger.send;
 			bcs->hw.tiger.free = NETJET_DMA_TXSIZE;
 			test_and_set_bit(BC_FLG_EMPTY, &bcs->Flag);
-                        if (cs->typ == ISDN_CTYPE_NETJET_S)
-                        {
-                                // led on
-                                led = bc & 0x01;
-                                led = 0x01 << (6 + led); // convert to mask
-                                cs->hw.njet.auxd |= led;
-                                byteout(cs->hw.njet.auxa, cs->hw.njet.auxd);
-                        }
 			break;
 	}
 	if (cs->debug & L1_DEB_HSCX)
@@ -874,13 +854,9 @@ tiger_l2l1(struct PStack *st, int pr, vo
 		case (PH_ACTIVATE | REQUEST):
 			test_and_set_bit(BC_FLG_ACTIV, &st->l1.bcs->Flag);
 			mode_tiger(st->l1.bcs, st->l1.mode, st->l1.bc);
-			/* 2001/10/04 Christoph Ersfeld, Formula-n Europe AG */
-			st->l1.bcs->cs->cardmsg(st->l1.bcs->cs, MDL_BC_ASSIGN, (void *)(&st->l1.bc));
 			l1_msg_b(st, pr, arg);
 			break;
 		case (PH_DEACTIVATE | REQUEST):
-			/* 2001/10/04 Christoph Ersfeld, Formula-n Europe AG */
-			st->l1.bcs->cs->cardmsg(st->l1.bcs->cs, MDL_BC_RELEASE, (void *)(&st->l1.bc));
 			l1_msg_b(st, pr, arg);
 			break;
 		case (PH_DEACTIVATE | CONFIRM):
--- a/drivers/isdn/hisax/netjet.h
+++ b/drivers/isdn/hisax/netjet.h
@@ -1,4 +1,4 @@
-/* $Id: netjet.h,v 1.1.4.1 2001/11/20 14:19:36 kai Exp $
+/* $Id: netjet.h,v 2.8 2001/09/24 13:22:56 kai Exp $
  *
  * NETjet common header file
  *
--- a/drivers/isdn/hisax/niccy.c
+++ b/drivers/isdn/hisax/niccy.c
@@ -1,4 +1,4 @@
-/* $Id: niccy.c,v 1.1.4.1 2001/11/20 14:19:36 kai Exp $
+/* $Id: niccy.c,v 1.21 2001/10/20 22:05:00 kai Exp $
  *
  * low level stuff for Dr. Neuhaus NICCY PnP and NICCY PCI and
  * compatible (SAGEM cybermodem)
@@ -22,10 +22,10 @@
 #include "hscx.h"
 #include "isdnl1.h"
 #include <linux/pci.h>
-#include <linux/isapnp.h>
+#include <linux/isdn_compat.h>
 
 extern const char *CardType[];
-const char *niccy_revision = "$Revision: 1.1.4.1 $";
+const char *niccy_revision = "$Revision: 1.21 $";
 
 #define byteout(addr,val) outb(val,addr)
 #define bytein(addr) inb(addr)
@@ -239,9 +239,6 @@ niccy_card_msg(struct IsdnCardState *cs,
 }
 
 static struct pci_dev *niccy_dev __initdata = NULL;
-#ifdef __ISAPNP__
-static struct pci_bus *pnp_c __devinitdata = NULL;
-#endif
 
 int __init
 setup_niccy(struct IsdnCard *card)
@@ -253,39 +250,7 @@ setup_niccy(struct IsdnCard *card)
 	printk(KERN_INFO "HiSax: Niccy driver Rev. %s\n", HiSax_getrev(tmp));
 	if (cs->typ != ISDN_CTYPE_NICCY)
 		return (0);
-#ifdef __ISAPNP__
-	if (!card->para[1] && isapnp_present()) {
-		struct pci_bus *pb;
-		struct pci_dev *pd;
-
-		if ((pb = isapnp_find_card(
-			ISAPNP_VENDOR('S', 'D', 'A'),
-			ISAPNP_FUNCTION(0x0150), pnp_c))) {
-			pnp_c = pb;
-			pd = NULL;
-			if (!(pd = isapnp_find_dev(pnp_c,
-				ISAPNP_VENDOR('S', 'D', 'A'),
-				ISAPNP_FUNCTION(0x0150), pd))) {
-				printk(KERN_ERR "NiccyPnP: PnP error card found, no device\n");
-				return (0);
-			}
-			pd->prepare(pd);
-			pd->deactivate(pd);
-			pd->activate(pd);
-			card->para[1] = pd->resource[0].start;
-			card->para[2] = pd->resource[1].start;
-			card->para[0] = pd->irq_resource[0].start;
-			if (!card->para[0] || !card->para[1] || !card->para[2]) {
-				printk(KERN_ERR "NiccyPnP:some resources are missing %ld/%lx/%lx\n",
-					card->para[0], card->para[1], card->para[2]);
-				pd->deactivate(pd);
-				return(0);
-			}
-		} else {
-			printk(KERN_INFO "NiccyPnP: no ISAPnP card found\n");
-		}
-	}
-#endif
+
 	if (card->para[1]) {
 		cs->hw.niccy.isac = card->para[1] + ISAC_PNP;
 		cs->hw.niccy.hscx = card->para[1] + HSCX_PNP;
@@ -331,12 +296,12 @@ setup_niccy(struct IsdnCard *card)
 				return(0);
 			}
 			cs->irq = niccy_dev->irq;
-			cs->hw.niccy.cfg_reg = pci_resource_start(niccy_dev, 0);
+			cs->hw.niccy.cfg_reg = pci_resource_start_io(niccy_dev, 0);
 			if (!cs->hw.niccy.cfg_reg) {
 				printk(KERN_WARNING "Niccy: No IO-Adr for PCI cfg found\n");
 				return(0);
 			}
-			pci_ioaddr = pci_resource_start(niccy_dev, 1);
+			pci_ioaddr = pci_resource_start_io(niccy_dev, 1);
 			if (!pci_ioaddr) {
 				printk(KERN_WARNING "Niccy: No IO-Adr for PCI card found\n");
 				return(0);
--- a/drivers/isdn/hisax/nj_s.c
+++ b/drivers/isdn/hisax/nj_s.c
@@ -1,4 +1,4 @@
-/* $Id: nj_s.c,v 1.1.4.1 2001/11/20 14:19:36 kai Exp $
+/* $Id: nj_s.c,v 2.13 2001/09/24 13:22:56 kai Exp $
  *
  * This software may be used and distributed according to the terms
  * of the GNU General Public License, incorporated herein by reference.
@@ -12,11 +12,12 @@
 #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: 1.1.4.1 $";
+const char *NETjet_S_revision = "$Revision: 2.13 $";
 
 static u_char dummyrr(struct IsdnCardState *cs, int chan, u_char off)
 {
@@ -130,7 +131,6 @@ NETjet_S_card_msg(struct IsdnCardState *
 			release_io_netjet(cs);
 			return(0);
 		case CARD_INIT:
-			reset_netjet_s(cs);
 			inittiger(cs);
 			clear_pending_isac_ints(cs);
 			initisac(cs);
@@ -180,19 +180,11 @@ setup_netjet_s(struct IsdnCard *card)
 				printk(KERN_WARNING "NETjet-S: No IRQ for PCI card found\n");
 				return(0);
 			}
-			cs->hw.njet.base = pci_resource_start(dev_netjet, 0);
+			cs->hw.njet.base = pci_resource_start_io(dev_netjet, 0);
 			if (!cs->hw.njet.base) {
 				printk(KERN_WARNING "NETjet-S: No IO-Adr for PCI card found\n");
 				return(0);
 			}
-			/* 2001/10/04 Christoph Ersfeld, Formula-n Europe AG www.formula-n.com */
-			if ((dev_netjet->subsystem_vendor == 0x55) &&
-				(dev_netjet->subsystem_device == 0x02)) {
-				printk(KERN_WARNING "Netjet: You tried to load this driver with an incompatible TigerJet-card\n");
-				printk(KERN_WARNING "Use type=41 for Formula-n enter:now ISDN PCI and compatible\n");
-				return(0);
-			}
-			/* end new code */
 		} else {
 			printk(KERN_WARNING "NETjet-S: No PCI card found\n");
 			return(0);
@@ -263,6 +255,7 @@ setup_netjet_s(struct IsdnCard *card)
 	} else {
 		request_region(cs->hw.njet.base, bytecnt, "netjet-s isdn");
 	}
+	reset_netjet_s(cs);
 	cs->readisac  = &NETjet_ReadIC;
 	cs->writeisac = &NETjet_WriteIC;
 	cs->readisacfifo  = &NETjet_ReadICfifo;
--- a/drivers/isdn/hisax/nj_u.c
+++ b/drivers/isdn/hisax/nj_u.c
@@ -1,4 +1,4 @@
-/* $Id: nj_u.c,v 1.1.4.1 2001/11/20 14:19:36 kai Exp $ 
+/* $Id: nj_u.c,v 2.14 2001/09/24 13:22:56 kai Exp $ 
  *
  * This software may be used and distributed according to the terms
  * of the GNU General Public License, incorporated herein by reference.
@@ -12,11 +12,12 @@
 #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: 1.1.4.1 $";
+const char *NETjet_U_revision = "$Revision: 2.14 $";
 
 static u_char dummyrr(struct IsdnCardState *cs, int chan, u_char off)
 {
@@ -181,7 +182,7 @@ setup_netjet_u(struct IsdnCard *card)
 				printk(KERN_WARNING "NETspider-U: No IRQ for PCI card found\n");
 				return(0);
 			}
-			cs->hw.njet.base = pci_resource_start(dev_netjet, 0);
+			cs->hw.njet.base = pci_resource_start_io(dev_netjet, 0);
 			if (!cs->hw.njet.base) {
 				printk(KERN_WARNING "NETspider-U: No IO-Adr for PCI card found\n");
 				return(0);
--- a/drivers/isdn/hisax/q931.c
+++ b/drivers/isdn/hisax/q931.c
@@ -1,4 +1,4 @@
-/* $Id: q931.c,v 1.1.4.1 2001/11/20 14:19:36 kai Exp $
+/* $Id: q931.c,v 1.12 2001/09/24 13:22:56 kai Exp $
  *
  * code to decode ITU Q.931 call control messages
  *
@@ -197,6 +197,31 @@ struct MessageType mt_n1[] =
 
 #define MT_N1_LEN (sizeof(mt_n1) / sizeof(struct MessageType))
 
+#if 0
+static struct MessageType fac_1tr6[] =
+{
+	{FAC_Sperre, "Sperre"},
+	{FAC_Forward1, "Forward 1"},
+	{FAC_Forward2, "Forward 2"},
+	{FAC_Konferenz, "Konferenz"},
+	{FAC_GrabBchan, "Grab Bchannel"},
+	{FAC_Reactivate, "Reactivate"},
+	{FAC_Konferenz3, "Dreier Konferenz"},
+	{FAC_Dienstwechsel1, "Einseitiger Dienstwechsel"},
+	{FAC_Dienstwechsel2, "Zweiseitiger Dienstwechsel"},
+	{FAC_NummernIdent, "Rufnummer-Identifizierung"},
+	{FAC_GBG, "GBG"},
+	{FAC_DisplayUebergeben, "Display Uebergeben"},
+	{FAC_DisplayUmgeleitet, "Display Umgeleitet"},
+	{FAC_Unterdruecke, "Unterdruecke Rufnummer"},
+	{FAC_Deactivate, "Deactivate"},
+	{FAC_Activate, "Activate"},
+	{FAC_SPV, "SPV"},
+	{FAC_Rueckwechsel, "Rueckwechsel"},
+	{FAC_Umleitung, "Umleitung"}
+};
+#define FAC_1TR6_LEN (sizeof(fac_1tr6) / sizeof(struct MessageType))
+#endif
 
 static int
 prbits(char *dest, u_char b, int start, int len)
--- /dev/null
+++ b/drivers/isdn/hisax/rawhdlc.c
@@ -0,0 +1,543 @@
+/* $Id: rawhdlc.c,v 1.7 2001/09/24 13:22:57 kai Exp $
+ *
+ * support routines for cards that don't support HDLC
+ *
+ * Author     Brent Baccala
+ * Copyright  by Karsten Keil <keil@isdn4linux.de>
+ *            by Brent Baccala <baccala@FreeSoft.org>
+ *
+ * This software may be used and distributed according to the terms
+ * of the GNU General Public License, incorporated herein by reference.
+ *
+ *
+ * Some passive ISDN cards, such as the Traverse NETJet and the AMD 7930,
+ * don't perform HDLC encapsulation over the B channel.  Drivers for
+ * such cards use support routines in this file to perform B channel HDLC.
+ *
+ * Bit-synchronous HDLC encapsulation is a means of encapsulating packets
+ * over a continuously transmitting serial communications link.
+ * It looks like this:
+ *
+ *      11111111101111110...........0111111011111111111
+ *      iiiiiiiiiffffffffdddddddddddffffffffiiiiiiiiiii
+ *
+ *      i = idle     f = flag     d = data
+ *
+ * When idle, the channel sends a continuous string of ones (mark
+ * idle; illustrated), or a continuous string of flag characters (flag
+ * idle).  The beginning of a data frame is marked by a flag character
+ * (01111110), then comes the actual data, followed by another flag
+ * character, after which another frame may be sent immediately (a
+ * single flag may serve as both the end of one frame and the start of
+ * the next), or the link may return to idle.  Obviously, the flag
+ * character can not appear anywhere in the data (or a false
+ * end-of-frame would occur), so the transmitter performs
+ * "bit-stuffing" - inserting a zero bit after every five one bits,
+ * irregardless of the original bit after the five ones.  Byte
+ * ordering is irrelevent at this point - the data is treated as a
+ * string of bits, not bytes.  Since no more than 5 ones may now occur
+ * in a row, the flag sequence, with its 6 ones, is unique.
+ *
+ * Upon reception, a zero bit that occur after 5 one bits is simply
+ * discarded.  A series of 6 one bits is end-of-frame, and a series of
+ * 7 one bits is an abort.  Once bit-stuffing has been corrected for,
+ * an integer number of bytes should now be present.  The last two
+ * of these bytes form the Frame Check Sequence, a CRC that is verified
+ * and then discarded.  Note that bit-stuffing is performed on the FCS
+ * just as if it were regular data.
+ *
+ *
+ *
+ * int make_raw_hdlc_data(u_char *src, u_int slen,
+ *                        u_char *dst, u_int dsize)
+ *
+ *   Used for transmission.  Copies slen bytes from src to dst, performing
+ *   HDLC encapsulation (flag bytes, bit-stuffing, CRC) in the process.
+ *   dsize is size of destination buffer, and should be at least
+ *   ((6*slen)/5)+5 bytes to ensure adequate space will be available.
+ *   Function returns length (in bytes) of valid destination buffer, or
+ *   0 upon destination overflow.
+ *
+ * void init_hdlc_state(struct hdlc_state *stateptr, int mode)
+ *
+ *   Initializes hdlc_state structure before first call to read_raw_hdlc_data
+ *
+ *   mode = 0: Sane mode
+ *   mode = 1/2: 
+ *             Insane mode; NETJet use a shared unsigned int memory block (
+ * 	       with busmaster DMA), the bit pattern of every word is 
+ *  	       <8 B1> <8 B2> <8 Mon> <2 D> <4 C/I> <MX> <MR>
+ *	       according to Siemens IOM-2 interface, so we have to handle
+ *             the src buffer as unsigned int and have to shift/mask the
+ *             B-channel bytes.
+ *             mode 1 -> B1  mode 2  -> B2 data is used
+ *
+ * int read_raw_hdlc_data(struct hdlc_state *saved_state,
+ *                        u_char *src, u_int slen,
+ *                        u_char *dst, u_int dsize)
+ *
+ *   Used for reception.  Scans source buffer bit-by-bit looking for
+ *   valid HDLC frames, which are copied to destination buffer.  HDLC
+ *   state information is stored in a structure, which allows this
+ *   function to process frames spread across several blocks of raw
+ *   HDLC data.  Part of the state information is bit offsets into
+ *   the source and destination buffers.
+ *
+ *   A return value >0 indicates the length of a valid frame, now
+ *   stored in the destination buffer.  In this case, the source
+ *   buffer might not be completely processed, so this function should
+ *   be called again with the same source buffer, possibly with a
+ *   different destination buffer.
+ *
+ *   A return value of zero indicates that the source buffer was
+ *   completely processed without finding a valid end-of-packet;
+ *   however, we might be in the middle of packet reception, so
+ *   the function should be called again with the next block of
+ *   raw HDLC data and the same destination buffer.  It is NOT
+ *   permitted to change the destination buffer in this case,
+ *   since data may already have begun to be stored there.
+ *
+ *   A return value of -1 indicates some kind of error - destination
+ *   buffer overflow, CRC check failed, frame not a multiple of 8
+ *   bits.  Destination buffer probably contains invalid data, which
+ *   should be discarded.  Call function again with same source buffer
+ *   and a new (or same) destination buffer.
+ *
+ *   Suggested calling sequence:
+ *
+ *      init_hdlc_state(...);
+ *      for (EACH_RAW_DATA_BLOCK) {
+ *         while (len = read_raw_hdlc_data(...)) {
+ *             if (len == -1) DISCARD_FRAME;
+ *             else PROCESS_FRAME;
+ *         }
+ *      }
+ *
+ *
+ * Test the code in this file as follows:
+ *    gcc -DDEBUGME -o rawhdlctest rawhdlc.c
+ *    ./rawhdlctest < rawdata
+ *
+ * The file "rawdata" can be easily generated from a HISAX B-channel
+ * hex dump (CF CF CF 02 ...) using the following perl script:
+ *
+ * while(<>) {
+ *     @hexlist = split ' ';
+ *     while ($hexstr = shift(@hexlist)) {
+ *         printf "%c", hex($hexstr);
+ *     }
+ * }
+ *
+ */
+
+#ifdef DEBUGME
+#include <stdio.h>
+#endif
+
+#include <linux/types.h>
+#include <linux/ppp_defs.h>
+#include "rawhdlc.h"
+
+/* There's actually an identical copy of this table in the PPP code
+ * (ppp_crc16_table), but I don't want this code dependent on PPP
+ */
+
+// static 
+__u16 fcstab[256] =
+{
+	0x0000, 0x1189, 0x2312, 0x329b, 0x4624, 0x57ad, 0x6536, 0x74bf,
+	0x8c48, 0x9dc1, 0xaf5a, 0xbed3, 0xca6c, 0xdbe5, 0xe97e, 0xf8f7,
+	0x1081, 0x0108, 0x3393, 0x221a, 0x56a5, 0x472c, 0x75b7, 0x643e,
+	0x9cc9, 0x8d40, 0xbfdb, 0xae52, 0xdaed, 0xcb64, 0xf9ff, 0xe876,
+	0x2102, 0x308b, 0x0210, 0x1399, 0x6726, 0x76af, 0x4434, 0x55bd,
+	0xad4a, 0xbcc3, 0x8e58, 0x9fd1, 0xeb6e, 0xfae7, 0xc87c, 0xd9f5,
+	0x3183, 0x200a, 0x1291, 0x0318, 0x77a7, 0x662e, 0x54b5, 0x453c,
+	0xbdcb, 0xac42, 0x9ed9, 0x8f50, 0xfbef, 0xea66, 0xd8fd, 0xc974,
+	0x4204, 0x538d, 0x6116, 0x709f, 0x0420, 0x15a9, 0x2732, 0x36bb,
+	0xce4c, 0xdfc5, 0xed5e, 0xfcd7, 0x8868, 0x99e1, 0xab7a, 0xbaf3,
+	0x5285, 0x430c, 0x7197, 0x601e, 0x14a1, 0x0528, 0x37b3, 0x263a,
+	0xdecd, 0xcf44, 0xfddf, 0xec56, 0x98e9, 0x8960, 0xbbfb, 0xaa72,
+	0x6306, 0x728f, 0x4014, 0x519d, 0x2522, 0x34ab, 0x0630, 0x17b9,
+	0xef4e, 0xfec7, 0xcc5c, 0xddd5, 0xa96a, 0xb8e3, 0x8a78, 0x9bf1,
+	0x7387, 0x620e, 0x5095, 0x411c, 0x35a3, 0x242a, 0x16b1, 0x0738,
+	0xffcf, 0xee46, 0xdcdd, 0xcd54, 0xb9eb, 0xa862, 0x9af9, 0x8b70,
+	0x8408, 0x9581, 0xa71a, 0xb693, 0xc22c, 0xd3a5, 0xe13e, 0xf0b7,
+	0x0840, 0x19c9, 0x2b52, 0x3adb, 0x4e64, 0x5fed, 0x6d76, 0x7cff,
+	0x9489, 0x8500, 0xb79b, 0xa612, 0xd2ad, 0xc324, 0xf1bf, 0xe036,
+	0x18c1, 0x0948, 0x3bd3, 0x2a5a, 0x5ee5, 0x4f6c, 0x7df7, 0x6c7e,
+	0xa50a, 0xb483, 0x8618, 0x9791, 0xe32e, 0xf2a7, 0xc03c, 0xd1b5,
+	0x2942, 0x38cb, 0x0a50, 0x1bd9, 0x6f66, 0x7eef, 0x4c74, 0x5dfd,
+	0xb58b, 0xa402, 0x9699, 0x8710, 0xf3af, 0xe226, 0xd0bd, 0xc134,
+	0x39c3, 0x284a, 0x1ad1, 0x0b58, 0x7fe7, 0x6e6e, 0x5cf5, 0x4d7c,
+	0xc60c, 0xd785, 0xe51e, 0xf497, 0x8028, 0x91a1, 0xa33a, 0xb2b3,
+	0x4a44, 0x5bcd, 0x6956, 0x78df, 0x0c60, 0x1de9, 0x2f72, 0x3efb,
+	0xd68d, 0xc704, 0xf59f, 0xe416, 0x90a9, 0x8120, 0xb3bb, 0xa232,
+	0x5ac5, 0x4b4c, 0x79d7, 0x685e, 0x1ce1, 0x0d68, 0x3ff3, 0x2e7a,
+	0xe70e, 0xf687, 0xc41c, 0xd595, 0xa12a, 0xb0a3, 0x8238, 0x93b1,
+	0x6b46, 0x7acf, 0x4854, 0x59dd, 0x2d62, 0x3ceb, 0x0e70, 0x1ff9,
+	0xf78f, 0xe606, 0xd49d, 0xc514, 0xb1ab, 0xa022, 0x92b9, 0x8330,
+	0x7bc7, 0x6a4e, 0x58d5, 0x495c, 0x3de3, 0x2c6a, 0x1ef1, 0x0f78
+};
+
+#define HDLC_ZERO_SEARCH 0
+#define HDLC_FLAG_SEARCH 1
+#define HDLC_FLAG_FOUND  2
+#define HDLC_FRAME_FOUND 3
+#define HDLC_NULL 4
+#define HDLC_PART 5
+#define HDLC_FULL 6
+
+#define HDLC_FLAG_VALUE	0x7e
+
+
+#define MAKE_RAW_BYTE for (j=0; j<8; j++) { \
+			bitcnt++;\
+			out_val >>= 1;\
+			if (val & 1) {\
+				s_one++;\
+				out_val |= 0x80;\
+			} else {\
+				s_one = 0;\
+				out_val &= 0x7f;\
+			}\
+			if (bitcnt==8) {\
+				if (d_cnt == dsize) return 0;\
+				dst[d_cnt++] = out_val;\
+				bitcnt = 0;\
+			}\
+			if (s_one == 5) {\
+				out_val >>= 1;\
+				out_val &= 0x7f;\
+				bitcnt++;\
+				s_one = 0;\
+			}\
+			if (bitcnt==8) {\
+				if (d_cnt == dsize) return 0;\
+				dst[d_cnt++] = out_val;\
+				bitcnt = 0;\
+			}\
+			val >>= 1;\
+		}
+
+/* Optimization suggestion: If needed, this function could be
+ * dramatically sped up using a state machine.  Each state would
+ * correspond to having seen N one bits, and being offset M bits into
+ * the current output byte.  N ranges from 0 to 4, M from 0 to 7, so
+ * we need 5*8 = 35 states.  Each state would have a table with 256
+ * entries, one for each input character.  Each entry would contain
+ * three output characters, an output state, an a byte increment
+ * that's either 1 or 2.  All this could fit in four bytes; so we need
+ * 4 bytes * 256 characters = 1 KB for each state (35 KB total).  Zero
+ * the output buffer before you start.  For each character in your
+ * input, you look it up in the current state's table and get three
+ * bytes to be or'ed into the output at the current byte offset, and
+ * an byte increment to move your pointer forward.  A simple Perl
+ * script could generate the tables.  Given HDLC semantics, probably
+ * would be better to set output to all 1s, then use ands instead of ors.
+ * A smaller state machine could operate on nibbles instead of bytes.
+ * A state machine for 32-bit architectures could use word offsets
+ * instead of byte offsets, requiring 5*32 = 160 states; probably
+ * best to work on nibbles in such a case.
+ */
+
+
+int make_raw_hdlc_data(u_char *src, u_int slen, u_char *dst, u_int dsize)
+{
+	register u_int i,d_cnt=0;
+	register u_char j;
+	register u_char val;
+	register u_char s_one = 0;
+	register u_char out_val = 0;
+	register u_char bitcnt = 0;
+	u_int fcs;
+	
+	
+	dst[d_cnt++] = HDLC_FLAG_VALUE;
+	fcs = PPP_INITFCS;
+	for (i=0; i<slen; i++) {
+		val = src[i];
+		fcs = PPP_FCS (fcs, val);
+		MAKE_RAW_BYTE;
+	}
+	fcs ^= 0xffff;
+	val = fcs & 0xff;
+	MAKE_RAW_BYTE;
+	val = (fcs>>8) & 0xff;
+	MAKE_RAW_BYTE;
+	val = HDLC_FLAG_VALUE;
+	for (j=0; j<8; j++) { 
+		bitcnt++;
+		out_val >>= 1;
+		if (val & 1)
+			out_val |= 0x80;
+		else
+			out_val &= 0x7f;
+		if (bitcnt==8) {
+			if (d_cnt == dsize) return 0;
+			dst[d_cnt++] = out_val;
+			bitcnt = 0;
+		}
+		val >>= 1;
+	}
+	if (bitcnt) {
+		while (8>bitcnt++) {
+			out_val >>= 1;
+			out_val |= 0x80;
+		}
+		if (d_cnt == dsize) return 0;
+		dst[d_cnt++] = out_val;
+	}
+
+	return d_cnt;
+}
+
+void init_hdlc_state(struct hdlc_state *stateptr, int mode)
+{
+	stateptr->state = HDLC_ZERO_SEARCH;
+	stateptr->r_one = 0;
+	stateptr->r_val = 0;
+	stateptr->o_bitcnt = 0;
+	stateptr->i_bitcnt = 0;
+	stateptr->insane_mode = mode;
+}
+
+/* Optimization suggestion: A similar state machine could surely
+ * be developed for this function as well.
+ */
+
+int read_raw_hdlc_data(struct hdlc_state *saved_state,
+                       u_char *src, u_int slen, u_char *dst, u_int dsize)
+{
+	int retval=0;
+	register u_char val;
+	register u_char state = saved_state->state;
+	register u_char r_one = saved_state->r_one;
+	register u_char r_val = saved_state->r_val;
+	register u_int o_bitcnt = saved_state->o_bitcnt;
+	register u_int i_bitcnt = saved_state->i_bitcnt;
+	register u_int fcs    = saved_state->fcs;
+	register u_int *isrc = (u_int *) src;
+        
+	/* Use i_bitcnt (bit offset into source buffer) to reload "val"
+	 * in case we're starting up again partway through a source buffer
+	 */
+
+	if ((i_bitcnt >> 3) < slen) {
+		if (saved_state->insane_mode==1) {
+			val = isrc[(i_bitcnt >> 3)] & 0xff;
+		} else if (saved_state->insane_mode==2) {
+			val = (isrc[i_bitcnt >> 3] >>8) & 0xff;
+		} else {
+			val = src[i_bitcnt >> 3];
+		}
+		val >>= i_bitcnt & 7;
+	}
+
+	/* One bit per loop.  Keep going until we've got something to
+	 * report (retval != 0), or we exhaust the source buffer
+	 */
+
+	while ((retval == 0) && ((i_bitcnt >> 3) < slen)) {
+		if ((i_bitcnt & 7) == 0) {
+			if (saved_state->insane_mode==1) {
+				val = isrc[(i_bitcnt >> 3)] & 0xff;
+			} else if (saved_state->insane_mode==2) {
+				val = (isrc[i_bitcnt >> 3] >>8) & 0xff;
+			} else {
+				val = src[i_bitcnt >> 3];
+			}
+#ifdef DEBUGME
+			printf("Input byte %d: 0x%2x\n", i_bitcnt>>3, val);
+#endif
+			if (val == 0xff) {
+				state = HDLC_ZERO_SEARCH;
+				o_bitcnt = 0;
+				r_one = 0;
+				i_bitcnt += 8;
+				continue;
+			}
+		}
+
+#ifdef DEBUGME
+		/* printf("Data bit=%d (%d/%d)\n", val&1, i_bitcnt>>3, i_bitcnt&7);*/
+#endif
+
+		if (state == HDLC_ZERO_SEARCH) {
+			if (val & 1) {
+				r_one++;
+			} else {
+				r_one=0;
+				state= HDLC_FLAG_SEARCH;
+			}
+		} else if (state == HDLC_FLAG_SEARCH) { 
+			if (val & 1) {
+				r_one++;
+				if (r_one>6) {
+					state=HDLC_ZERO_SEARCH;
+				}
+			} else {
+				if (r_one==6) {
+					o_bitcnt=0;
+					r_val=0;
+					state=HDLC_FLAG_FOUND;
+				}
+				r_one=0;
+			}
+		} else if (state ==  HDLC_FLAG_FOUND) {
+			if (val & 1) {
+				r_one++;
+				if (r_one>6) {
+					state=HDLC_ZERO_SEARCH;
+				} else {
+					r_val >>= 1;
+					r_val |= 0x80;
+					o_bitcnt++;
+				}
+			} else {
+				if (r_one==6) {
+					o_bitcnt=0;
+					r_val=0;
+					r_one=0;
+					i_bitcnt++;
+					val >>= 1;
+					continue;
+				} else if (r_one!=5) {
+					r_val >>= 1;
+					r_val &= 0x7f;
+					o_bitcnt++;
+				}
+				r_one=0;	
+			}
+			if ((state != HDLC_ZERO_SEARCH) &&
+				!(o_bitcnt & 7)) {
+#ifdef DEBUGME
+				printf("HDLC_FRAME_FOUND at i_bitcnt:%d\n",i_bitcnt);
+#endif
+				state=HDLC_FRAME_FOUND;
+				fcs = PPP_INITFCS;
+				dst[0] = r_val;
+				fcs = PPP_FCS (fcs, r_val);
+			}
+		} else if (state ==  HDLC_FRAME_FOUND) {
+			if (val & 1) {
+				r_one++;
+				if (r_one>6) {
+					state=HDLC_ZERO_SEARCH;
+					o_bitcnt=0;
+				} else {
+					r_val >>= 1;
+					r_val |= 0x80;
+					o_bitcnt++;
+				}
+			} else {
+				if (r_one==6) {
+					r_val=0; 
+					r_one=0;
+					o_bitcnt++;
+					if (o_bitcnt & 7) {
+						/* Alignment error */
+#ifdef DEBUGME
+						printf("Alignment error\n");
+#endif
+						state=HDLC_FLAG_SEARCH;
+						retval = -1;
+					} else if (fcs==PPP_GOODFCS) {
+						/* Valid frame */
+						state=HDLC_FLAG_FOUND;
+						retval = (o_bitcnt>>3)-3;
+					} else {
+						/* CRC error */
+#ifdef DEBUGME
+						printf("CRC error; fcs was 0x%x, should have been 0x%x\n", fcs, PPP_GOODFCS);
+#endif
+						state=HDLC_FLAG_FOUND;
+						retval = -1;
+					}
+				} else if (r_one==5) {
+					r_one=0;
+					i_bitcnt++;
+					val >>= 1;
+					continue;
+				} else {
+					r_val >>= 1;
+					r_val &= 0x7f;
+					o_bitcnt++;
+				}
+				r_one=0;	
+			}
+			if ((state == HDLC_FRAME_FOUND) &&
+				!(o_bitcnt & 7)) {
+				if ((o_bitcnt>>3)>=dsize) {
+					/* Buffer overflow error */
+#ifdef DEBUGME
+					printf("Buffer overflow error\n");
+#endif
+					r_val=0; 
+					state=HDLC_FLAG_SEARCH;
+					retval = -1;
+				} else {
+					dst[(o_bitcnt>>3)-1] = r_val;
+					fcs = PPP_FCS (fcs, r_val);
+#ifdef DEBUGME
+					printf("Output byte %d: 0x%02x; FCS 0x%04x\n", (o_bitcnt>>3)-1, r_val, fcs);
+#endif
+				}
+			}
+		}
+		i_bitcnt ++;
+		val >>= 1;
+	}
+
+	/* We exhausted the source buffer before anything else happened
+	 * (retval==0).  Reset i_bitcnt in expectation of a new source
+	 * buffer.  Other, we either had an error or a valid frame, so
+	 * reset o_bitcnt in expectation of a new destination buffer.
+	 */
+
+	if (retval == 0) {
+		i_bitcnt = 0;
+	} else {
+		o_bitcnt = 0;
+	}
+
+	saved_state->state = state;
+	saved_state->r_one = r_one;
+	saved_state->r_val = r_val;
+	saved_state->fcs = fcs;
+	saved_state->o_bitcnt = o_bitcnt;
+	saved_state->i_bitcnt = i_bitcnt;
+
+	return (retval);
+}
+
+
+
+#ifdef DEBUGME
+
+char buffer[1024];
+char obuffer[1024];
+
+main()
+{
+  int buflen=0;
+  int len;
+  struct hdlc_state hdlc_state;
+
+  while((buffer[buflen] = getc(stdin)) != EOF && buflen<1024) buflen++;
+
+  printf("buflen = %d\n", buflen);
+
+  init_hdlc_state(&hdlc_state, 0);
+
+  while (len = read_raw_hdlc_data(&hdlc_state,buffer,buflen,obuffer,1024)) {
+    if (len == -1) printf("Error @ byte %d/bit %d\n",
+			  hdlc_state.i_bitcnt>>3, hdlc_state.i_bitcnt & 7);
+    else {
+      printf("Frame received: len %d\n", len);
+    }
+  }
+
+  printf("Done\n");
+}
+
+#endif
--- /dev/null
+++ b/drivers/isdn/hisax/rawhdlc.h
@@ -0,0 +1,28 @@
+/* $Id: rawhdlc.h,v 1.5 2001/09/24 13:22:57 kai Exp $
+ *
+ * Author     Brent Baccala
+ * Copyright  by Brent Baccala <baccala@FreeSoft.org>
+ *
+ * This software may be used and distributed according to the terms
+ * of the GNU General Public License, incorporated herein by reference.
+ *
+ */
+
+#ifndef RAWHDLC_H
+struct hdlc_state {
+	char insane_mode;
+	u_char state;
+	u_char r_one;
+	u_char r_val;
+	u_int o_bitcnt;
+	u_int i_bitcnt;
+	u_int fcs;
+};
+
+
+int make_raw_hdlc_data(u_char *src, u_int slen, u_char *dst, u_int dsize);
+void init_hdlc_state(struct hdlc_state *stateptr, int mode);
+int read_raw_hdlc_data(struct hdlc_state *saved_state,
+                       u_char *src, u_int slen, u_char *dst, u_int dsize);
+#define RAWHDLC_H
+#endif
--- a/drivers/isdn/hisax/s0box.c
+++ b/drivers/isdn/hisax/s0box.c
@@ -1,4 +1,4 @@
-/* $Id: s0box.c,v 1.1.4.1 2001/11/20 14:19:36 kai Exp $
+/* $Id: s0box.c,v 2.6 2001/09/24 13:22:57 kai Exp $
  *
  * low level stuff for Creatix S0BOX
  *
@@ -18,7 +18,7 @@
 #include "isdnl1.h"
 
 extern const char *CardType[];
-const char *s0box_revision = "$Revision: 1.1.4.1 $";
+const char *s0box_revision = "$Revision: 2.6 $";
 
 static inline void
 writereg(unsigned int padr, signed int addr, u_char off, u_char val) {
--- a/drivers/isdn/hisax/saphir.c
+++ b/drivers/isdn/hisax/saphir.c
@@ -1,4 +1,4 @@
-/* $Id: saphir.c,v 1.1.4.1 2001/11/20 14:19:36 kai Exp $
+/* $Id: saphir.c,v 1.10 2001/09/24 13:22:57 kai Exp $
  *
  * low level stuff for HST Saphir 1
  *
@@ -20,7 +20,7 @@
 #include "isdnl1.h"
 
 extern const char *CardType[];
-static char *saphir_rev = "$Revision: 1.1.4.1 $";
+static char *saphir_rev = "$Revision: 1.10 $";
 
 #define byteout(addr,val) outb(val,addr)
 #define bytein(addr) inb(addr)
--- a/drivers/isdn/hisax/sedlbauer.c
+++ b/drivers/isdn/hisax/sedlbauer.c
@@ -1,4 +1,4 @@
-/* $Id: sedlbauer.c,v 1.1.4.1 2001/11/20 14:19:36 kai Exp $
+/* $Id: sedlbauer.c,v 1.34 2002/02/09 21:00:57 keil Exp $
  *
  * low level stuff for Sedlbauer cards
  * includes support for the Sedlbauer speed star (speed star II),
@@ -48,18 +48,19 @@
 #include "isar.h"
 #include "isdnl1.h"
 #include <linux/pci.h>
-#include <linux/isapnp.h>
+#include <linux/isdn_compat.h>
 
 extern const char *CardType[];
 
-const char *Sedlbauer_revision = "$Revision: 1.1.4.1 $";
+const char *Sedlbauer_revision = "$Revision: 1.34 $";
 
 const char *Sedlbauer_Types[] =
 	{"None", "speed card/win", "speed star", "speed fax+",
 	"speed win II / ISDN PC/104", "speed star II", "speed pci",
-	"speed fax+ pyramid", "speed fax+ pci"};
+	"speed fax+ pyramid", "speed fax+ pci", "HST Saphir III"};
 
 #define PCI_SUBVENDOR_SPEEDFAX_PYRAMID	0x51
+#define PCI_SUBVENDOR_HST_SAPHIR3	0x52
 #define PCI_SUBVENDOR_SEDLBAUER_PCI	0x53
 #define PCI_SUBVENDOR_SPEEDFAX_PCI	0x54
 #define PCI_SUB_ID_SEDLBAUER		0x01
@@ -72,6 +73,7 @@ const char *Sedlbauer_Types[] =
 #define SEDL_SPEED_PCI   	6
 #define SEDL_SPEEDFAX_PYRAMID	7
 #define SEDL_SPEEDFAX_PCI	8
+#define HST_SAPHIR3		9
 
 #define SEDL_CHIP_TEST		0
 #define SEDL_CHIP_ISAC_HSCX	1
@@ -531,21 +533,6 @@ Sedl_card_msg(struct IsdnCardState *cs, 
 
 static struct pci_dev *dev_sedl __devinitdata = NULL;
 
-#ifdef __ISAPNP__
-static struct isapnp_device_id sedl_ids[] __initdata = {
-	{ ISAPNP_VENDOR('S', 'A', 'G'), ISAPNP_FUNCTION(0x01),
-	  ISAPNP_VENDOR('S', 'A', 'G'), ISAPNP_FUNCTION(0x01), 
-	  (unsigned long) "Speed win" },
-	{ ISAPNP_VENDOR('S', 'A', 'G'), ISAPNP_FUNCTION(0x02),
-	  ISAPNP_VENDOR('S', 'A', 'G'), ISAPNP_FUNCTION(0x02), 
-	  (unsigned long) "Speed Fax+" },
-	{ 0, }
-};
-
-static struct isapnp_device_id *pdev = &sedl_ids[0];
-static struct pci_bus *pnp_c __devinitdata = NULL;
-#endif
-
 int __devinit
 setup_sedlbauer(struct IsdnCard *card)
 {
@@ -581,57 +568,6 @@ setup_sedlbauer(struct IsdnCard *card)
 			bytecnt = 16;
 		}
 	} else {
-#ifdef __ISAPNP__
-		if (isapnp_present()) {
-			struct pci_bus *pb;
-			struct pci_dev *pd;
-
-			while(pdev->card_vendor) {
-				if ((pb = isapnp_find_card(pdev->card_vendor,
-					pdev->card_device, pnp_c))) {
-					pnp_c = pb;
-					pd = NULL;
-					if ((pd = isapnp_find_dev(pnp_c,
-						pdev->vendor, pdev->function, pd))) {
-						printk(KERN_INFO "HiSax: %s detected\n",
-							(char *)pdev->driver_data);
-						pd->prepare(pd);
-						pd->deactivate(pd);
-						pd->activate(pd);
-						card->para[1] =
-							pd->resource[0].start;
-						card->para[0] =
-							pd->irq_resource[0].start;
-						if (!card->para[0] || !card->para[1]) {
-							printk(KERN_ERR "Sedlbauer PnP:some resources are missing %ld/%lx\n",
-								card->para[0], card->para[1]);
-							pd->deactivate(pd);
-							return(0);
-						}
-						cs->hw.sedl.cfg_reg = card->para[1];
-						cs->irq = card->para[0];
-						if (pdev->function == ISAPNP_FUNCTION(0x2)) {
-							cs->subtyp = SEDL_SPEED_FAX;
-							cs->hw.sedl.chip = SEDL_CHIP_ISAC_ISAR;
-							bytecnt = 16;
-						} else {
-							cs->subtyp = SEDL_SPEED_CARD_WIN;
-							cs->hw.sedl.chip = SEDL_CHIP_TEST;
-						}
-						goto ready;
-					} else {
-						printk(KERN_ERR "Sedlbauer PnP: PnP error card found, no device\n");
-						return(0);
-					}
-				}
-				pdev++;
-				pnp_c=NULL;
-			} 
-			if (!pdev->card_vendor) {
-				printk(KERN_INFO "Sedlbauer PnP: no ISAPnP card found\n");
-			}
-		}
-#endif
 /* Probe for Sedlbauer speed pci */
 #if CONFIG_PCI
 		if (!pci_present()) {
@@ -647,15 +583,15 @@ setup_sedlbauer(struct IsdnCard *card)
 				printk(KERN_WARNING "Sedlbauer: No IRQ for PCI card found\n");
 				return(0);
 			}
-			cs->hw.sedl.cfg_reg = pci_resource_start(dev_sedl, 0);
+			cs->hw.sedl.cfg_reg = pci_resource_start_io(dev_sedl, 0);
 		} else {
 			printk(KERN_WARNING "Sedlbauer: No PCI card found\n");
 			return(0);
 		}
 		cs->irq_flags |= SA_SHIRQ;
 		cs->hw.sedl.bus = SEDL_BUS_PCI;
-		sub_vendor_id = dev_sedl->subsystem_vendor;
-		sub_id = dev_sedl->subsystem_device;
+		pci_get_sub_vendor(dev_sedl,sub_vendor_id);
+		pci_get_sub_system(dev_sedl,sub_id);
 		printk(KERN_INFO "Sedlbauer: PCI subvendor:%x subid %x\n",
 			sub_vendor_id, sub_id);
 		printk(KERN_INFO "Sedlbauer: PCI base adr %#x\n",
@@ -670,6 +606,9 @@ setup_sedlbauer(struct IsdnCard *card)
 		} else if (sub_vendor_id == PCI_SUBVENDOR_SPEEDFAX_PCI) {
 			cs->hw.sedl.chip = SEDL_CHIP_ISAC_ISAR;
 			cs->subtyp = SEDL_SPEEDFAX_PCI;
+		} else if (sub_vendor_id == PCI_SUBVENDOR_HST_SAPHIR3) {
+			cs->hw.sedl.chip = SEDL_CHIP_IPAC;
+			cs->subtyp = HST_SAPHIR3;
 		} else if (sub_vendor_id == PCI_SUBVENDOR_SEDLBAUER_PCI) {
 			cs->hw.sedl.chip = SEDL_CHIP_IPAC;
 			cs->subtyp = SEDL_SPEED_PCI;
@@ -683,8 +622,8 @@ setup_sedlbauer(struct IsdnCard *card)
 		cs->hw.sedl.reset_off = SEDL_ISAR_PCI_ISAR_RESET_OFF;
 		byteout(cs->hw.sedl.cfg_reg, 0xff);
 		byteout(cs->hw.sedl.cfg_reg, 0x00);
-		byteout(cs->hw.sedl.cfg_reg+ 2, 0xdd);
-		byteout(cs->hw.sedl.cfg_reg+ 5, 0x02);
+		byteout(cs->hw.sedl.cfg_reg +2, 0xdd);
+		byteout(cs->hw.sedl.cfg_reg +5, 0x02);
 		byteout(cs->hw.sedl.cfg_reg +3, cs->hw.sedl.reset_on);
 		save_flags(flags);
 		sti();
@@ -697,7 +636,7 @@ setup_sedlbauer(struct IsdnCard *card)
 		return (0);
 #endif /* CONFIG_PCI */
 	}	
-ready:	
+	
 	/* In case of the sedlbauer pcmcia card, this region is in use,
 	 * reserved for us by the card manager. So we do not check it
 	 * here, it would fail.
--- a/drivers/isdn/hisax/sportster.c
+++ b/drivers/isdn/hisax/sportster.c
@@ -1,4 +1,4 @@
-/* $Id: sportster.c,v 1.1.4.1 2001/11/20 14:19:36 kai Exp $
+/* $Id: sportster.c,v 1.16 2001/09/24 13:22:57 kai Exp $
  *
  * low level stuff for USR Sportster internal TA
  *
@@ -20,7 +20,7 @@
 #include "isdnl1.h"
 
 extern const char *CardType[];
-const char *sportster_revision = "$Revision: 1.1.4.1 $";
+const char *sportster_revision = "$Revision: 1.16 $";
 
 #define byteout(addr,val) outb(val,addr)
 #define bytein(addr) inb(addr)
--- /dev/null
+++ b/drivers/isdn/hisax/st5481-debug.h
@@ -0,0 +1,103 @@
+#define ST5481_DEBUG 0x0
+
+#if ST5481_DEBUG
+
+
+/*
+  DEBUG flags. Set compile option  ST5481_DEBUG with the following bits set to trace
+  the given subsections:
+
+  0x01:  USB
+  0x02:  D
+  0x04:  B
+  0x08:  PH
+  0x10:  PACKET_DUMP D out
+  0x20:  ISO_DUMP D out
+  0x40:  PACKET_DUMP D in
+  0x80:  ISO_DUMP in
+  0x100: PACKET_DUMP B out
+  0x200: ISO_DUMP B out
+  0x400: PACKET_DUMP B in
+*/
+
+#define DBG(level, format, arg...) \
+if (level &  ST5481_DEBUG) \
+printk(KERN_DEBUG __FUNCTION__ ": " format "\n" , ## arg) \
+
+static inline void 
+dump_packet(const char *name,const u_char *data,int pkt_len)
+{
+#define DUMP_HDR_SIZE 200
+#define DUMP_TLR_SIZE 8
+	if (pkt_len) {
+		int i,len1,len2;
+
+		printk(KERN_DEBUG "%s: length=%d,data=",name,pkt_len);
+
+		if (pkt_len >  DUMP_HDR_SIZE+ DUMP_TLR_SIZE) {
+			len1 = DUMP_HDR_SIZE;
+			len2 = DUMP_TLR_SIZE;
+		} else {
+			len1 = pkt_len > DUMP_HDR_SIZE ? DUMP_HDR_SIZE : pkt_len;
+			len2 = 0;			
+		}
+		for (i = 0; i < len1; ++i) {
+		 	printk ("%.2x", data[i]);
+		}
+		if (len2) {
+		 	printk ("..");
+			for (i = pkt_len-DUMP_TLR_SIZE; i < pkt_len; ++i) {
+				printk ("%.2x", data[i]);
+			}
+		}
+		printk ("\n");
+	}
+#undef DUMP_HDR_SIZE
+#undef DUMP_TLR_SIZE
+}
+
+static inline void 
+dump_iso_packet(const char *name,urb_t *urb)
+{
+	int i,j;
+	int len,ofs;
+	u_char *data;
+
+	printk(KERN_DEBUG "%s: packets=%d,errors=%d\n",
+	       name,urb->number_of_packets,urb->error_count);
+	for (i = 0; i  < urb->number_of_packets; ++i) {
+		if (urb->pipe & USB_DIR_IN) {
+			len = urb->iso_frame_desc[i].actual_length;
+		} else {
+			len = urb->iso_frame_desc[i].length;
+		}
+		ofs = urb->iso_frame_desc[i].offset;
+		printk(KERN_DEBUG "len=%.2d,ofs=%.3d ",len,ofs);
+		if (len) {
+			data = urb->transfer_buffer+ofs;
+			for (j=0; j < len; j++) {
+				printk ("%.2x", data[j]);
+			}
+		}
+		printk("\n");
+	}
+}
+
+#define DUMP_PACKET(level,data,count) \
+  if (level & ST5481_DEBUG) dump_packet(__FUNCTION__,data,count)
+#define DUMP_SKB(level,skb) \
+  if ((level & ST5481_DEBUG) && skb) dump_packet(__FUNCTION__,skb->data,skb->len)
+#define DUMP_ISO_PACKET(level,urb) \
+  if (level & ST5481_DEBUG) dump_iso_packet(__FUNCTION__,urb)
+
+#else
+
+#define DBG(level,format, arg...) do {} while (0)
+#define DUMP_PACKET(level,data,count) do {} while (0)
+#define DUMP_SKB(level,skb) do {} while (0)
+#define DUMP_ISO_PACKET(level,urb) do {} while (0)
+
+#endif
+
+
+
--- a/drivers/isdn/hisax/st5481.h
+++ b/drivers/isdn/hisax/st5481.h
@@ -219,15 +219,15 @@ enum {
 #define L1_EVENT_COUNT (EV_TIMER3 + 1)
 
 #define ERR(format, arg...) \
-printk(KERN_ERR "%s:%s: " format "\n" , __FILE__,  __FUNCTION__ , ## arg)
+printk(KERN_ERR __FILE__ ": " __FUNCTION__ ": " format "\n" , ## arg)
 
 #define WARN(format, arg...) \
-printk(KERN_WARNING "%s:%s: " format "\n" , __FILE__,  __FUNCTION__ , ## arg)
+printk(KERN_WARNING __FILE__ ": " __FUNCTION__ ": " format "\n" , ## arg)
 
 #define INFO(format, arg...) \
-printk(KERN_INFO "%s:%s: " format "\n" , __FILE__,  __FUNCTION__ , ## arg)
+printk(KERN_INFO __FILE__ ": " __FUNCTION__ ": " format "\n" , ## arg)
 
-#include "isdnhdlc.h"
+#include "st5481_hdlc.h"
 #include "fsm.h"
 #include "hisax_if.h"
 #include <linux/skbuff.h>
@@ -236,7 +236,7 @@ printk(KERN_INFO "%s:%s: " format "\n" ,
  * FIFO handling
  */
 
-/* Generic FIFO structure */
+/* Generic FIFO structure */ 
 struct fifo {
 	u_char r,w,count,size;
 	spinlock_t lock;
@@ -270,7 +270,7 @@ static inline int fifo_add(struct fifo *
 		index = -1;
 	} else {
 		// Return index where to get the next data to add to the FIFO
-		index = fifo->w++ & (fifo->size-1);
+		index = fifo->w++ & (fifo->size-1); 
 		fifo->count++;
 	}
 	spin_unlock_irqrestore(&fifo->lock, flags);
@@ -289,13 +289,13 @@ static inline int fifo_remove(struct fif
 		return -1;
 	}
 
-	spin_lock_irqsave(&fifo->lock, flags);
+	spin_lock_irqsave(&fifo->lock, flags);		
 	if (!fifo->count) {
 		// FIFO empty
 		index = -1;
 	} else {
 		// Return index where to get the next data from the FIFO
-		index = fifo->r++ & (fifo->size-1);
+		index = fifo->r++ & (fifo->size-1); 
 		fifo->count--;
 	}
 	spin_unlock_irqrestore(&fifo->lock, flags);
@@ -309,7 +309,7 @@ static inline int fifo_remove(struct fif
 typedef void (*ctrl_complete_t)(void *);
 
 typedef struct ctrl_msg {
-	struct usb_ctrlrequest dr;
+	devrequest dr;
 	ctrl_complete_t complete;
 	void *context;
 } ctrl_msg; 
@@ -336,7 +336,7 @@ struct st5481_intr {
 };
 
 struct st5481_d_out {
-	struct isdnhdlc_vars hdlc_state;
+	struct hdlc_vars hdlc_state;
 	struct urb *urb[2]; /* double buffering */
 	unsigned long busy;
 	struct sk_buff *tx_skb;
@@ -344,7 +344,7 @@ struct st5481_d_out {
 };
 
 struct st5481_b_out {
-	struct isdnhdlc_vars hdlc_state;
+	struct hdlc_vars hdlc_state;
 	struct urb *urb[2]; /* double buffering */
 	u_char flow_event;
 	u_long busy;
@@ -352,7 +352,7 @@ struct st5481_b_out {
 };
 
 struct st5481_in {
-	struct isdnhdlc_vars hdlc_state;
+	struct hdlc_vars hdlc_state;
 	struct urb *urb[2]; /* double buffering */
 	int mode;
 	int bufsize;
@@ -478,7 +478,7 @@ extern int st5481_debug;
   if (level & __debug_variable) dump_iso_packet(__FUNCTION__,urb)
 
 static void __attribute__((unused))
-dump_iso_packet(const char *name,struct urb *urb)
+dump_iso_packet(const char *name,urb_t *urb)
 {
 	int i,j;
 	int len,ofs;
--- a/drivers/isdn/hisax/st5481_b.c
+++ b/drivers/isdn/hisax/st5481_b.c
@@ -67,28 +67,24 @@ static void usb_b_out(struct st5481_bcs 
 				bytes_sent = buf_size - len;
 				if (skb->len < bytes_sent)
 					bytes_sent = skb->len;
-				{	/* swap tx bytes to get hearable audio data */
-					register unsigned char *src  = skb->data;
-					register unsigned char *dest = urb->transfer_buffer+len;
-					register unsigned int count;
-					for (count = 0; count < bytes_sent; count++)
-						*dest++ = isdnhdlc_bit_rev_tab[*src++];
-				}
+
+				memcpy(urb->transfer_buffer+len, skb->data, bytes_sent);
+				
 				len += bytes_sent;
 			} else {
-				len += isdnhdlc_encode(&b_out->hdlc_state,
-						       skb->data, skb->len, &bytes_sent,
-						       urb->transfer_buffer+len, buf_size-len);
+				len += hdlc_encode(&b_out->hdlc_state, 
+						   skb->data, skb->len, &bytes_sent,
+						   urb->transfer_buffer+len, buf_size-len);
 			}
 
 			skb_pull(skb, bytes_sent);
-
+			
 			if (!skb->len) {
 				// Frame sent
 				b_out->tx_skb = NULL;
 				B_L1L2(bcs, PH_DATA | CONFIRM, (void *) skb->truesize);
 				dev_kfree_skb_any(skb);
-
+				
 /* 				if (!(bcs->tx_skb = skb_dequeue(&bcs->sq))) { */
 /* 					st5481B_sched_event(bcs, B_XMTBUFREADY); */
 /* 				} */
@@ -99,9 +95,9 @@ static void usb_b_out(struct st5481_bcs 
 				len = buf_size;
 			} else {
 				// Send flags
-				len += isdnhdlc_encode(&b_out->hdlc_state,
-						       NULL, 0, &bytes_sent,
-						       urb->transfer_buffer+len, buf_size-len);
+				len += hdlc_encode(&b_out->hdlc_state, 
+						   NULL, 0, &bytes_sent,
+						   urb->transfer_buffer+len, buf_size-len);
 			}
 		}	
 	}
@@ -213,7 +209,7 @@ static void st5481B_mode(struct st5481_b
 	if (bcs->mode != L1_MODE_NULL) {
 		// Open the B channel
 		if (bcs->mode != L1_MODE_TRANS) {
-			isdnhdlc_out_init(&b_out->hdlc_state, 0, bcs->mode == L1_MODE_HDLC_56K);
+			hdlc_out_init(&b_out->hdlc_state, 0, bcs->mode == L1_MODE_HDLC_56K);
 		}
 		st5481_usb_pipe_reset(adapter, (bcs->channel+1)*2, NULL, NULL);
 	
@@ -279,7 +275,7 @@ static int __devinit st5481_setup_b_out(
 				      usb_b_out_complete, bcs);
 }
 
-static void st5481_release_b_out(struct st5481_bcs *bcs)
+static void __devexit st5481_release_b_out(struct st5481_bcs *bcs)
 {
 	struct st5481_b_out *b_out = &bcs->b_out;
 
@@ -320,7 +316,7 @@ int __devinit st5481_setup_b(struct st54
 /*
  * Release buffers and URBs for the B channels
  */
-void st5481_release_b(struct st5481_bcs *bcs)
+void __devexit st5481_release_b(struct st5481_bcs *bcs)
 {
 	DBG(4,"");
 
--- a/drivers/isdn/hisax/st5481_d.c
+++ b/drivers/isdn/hisax/st5481_d.c
@@ -162,8 +162,8 @@ static struct FsmNode L1FnList[] __initd
 	{ST_L1_F8, EV_TIMER3,            l1_timer3},
 	{ST_L1_F8, EV_IND_DP,            l1_go_f3},
 	{ST_L1_F8, EV_IND_AP,            l1_go_f6},
-	{ST_L1_F8, EV_IND_AI8,           l1_go_f7},
-	{ST_L1_F8, EV_IND_AI10,          l1_go_f7},
+	{ST_L1_F8, EV_IND_AI8,           l1_go_f8},
+	{ST_L1_F8, EV_IND_AI10,          l1_go_f8},
 	{ST_L1_F8, EV_IND_RSY,           l1_ignore},
 };
 
@@ -297,7 +297,7 @@ static void usb_d_out(struct st5481_adap
 	unsigned int num_packets, packet_offset;
 	int len, buf_size, bytes_sent;
 	struct sk_buff *skb;
-	struct iso_packet_descriptor *desc;
+	iso_packet_descriptor_t *desc;
 
 	if (d_out->fsm.state != ST_DOUT_NORMAL)
 		return;
@@ -313,15 +313,15 @@ static void usb_d_out(struct st5481_adap
 	buf_size = NUM_ISO_PACKETS_D * SIZE_ISO_PACKETS_D_OUT;
 	
 	if (skb) {
-		len = isdnhdlc_encode(&d_out->hdlc_state,
-				      skb->data, skb->len, &bytes_sent,
-				      urb->transfer_buffer, buf_size);
+		len = hdlc_encode(&d_out->hdlc_state, 
+				  skb->data, skb->len, &bytes_sent,
+				  urb->transfer_buffer, buf_size);
 		skb_pull(skb,bytes_sent);
 	} else {
 		// Send flags or idle
-		len = isdnhdlc_encode(&d_out->hdlc_state,
-				      NULL, 0, &bytes_sent,
-				      urb->transfer_buffer, buf_size);
+		len = hdlc_encode(&d_out->hdlc_state, 
+				  NULL, 0, &bytes_sent,
+				  urb->transfer_buffer, buf_size);
 	}
 	
 	if (len < buf_size) {
@@ -413,7 +413,7 @@ static void dout_start_xmit(struct FsmIn
 
 	DBG(2,"len=%d",skb->len);
 
-	isdnhdlc_out_init(&d_out->hdlc_state, 1, 0);
+	hdlc_out_init(&d_out->hdlc_state, 1, 0);
 
 	if (test_and_set_bit(buf_nr, &d_out->busy)) {
 		WARN("ep %d urb %d busy %#lx", EP_D_OUT, buf_nr, d_out->busy);
@@ -422,9 +422,9 @@ static void dout_start_xmit(struct FsmIn
 	urb = d_out->urb[buf_nr];
 
 	DBG_SKB(0x10, skb);
-	len = isdnhdlc_encode(&d_out->hdlc_state,
-			      skb->data, skb->len, &bytes_sent,
-			      urb->transfer_buffer, 16);
+	len = hdlc_encode(&d_out->hdlc_state, 
+			  skb->data, skb->len, &bytes_sent,
+			  urb->transfer_buffer, 16);
 	skb_pull(skb, bytes_sent);
 
 	if(len < 16)
@@ -673,7 +673,7 @@ static int __devinit st5481_setup_d_out(
 				      usb_d_out_complete, adapter);
 }
 
-static void st5481_release_d_out(struct st5481_adapter *adapter)
+static void __devexit st5481_release_d_out(struct st5481_adapter *adapter)
 {
 	struct st5481_d_out *d_out = &adapter->d_out;
 
@@ -723,7 +723,7 @@ int __devinit st5481_setup_d(struct st54
 	return retval;
 }
 
-void st5481_release_d(struct st5481_adapter *adapter)
+void __devexit st5481_release_d(struct st5481_adapter *adapter)
 {
 	DBG(2,"");
 
--- a/drivers/isdn/hisax/st5481_init.c
+++ b/drivers/isdn/hisax/st5481_init.c
@@ -14,6 +14,7 @@
  * TODO:
  *
  * b layer1 delay?
+ * hdlc as module
  * hotplug / unregister issues
  * mod_inc/dec_use_count
  * unify parts of d/b channel usb handling
@@ -177,7 +178,7 @@ MODULE_DEVICE_TABLE (usb, st5481_ids);
 static struct usb_driver st5481_usb_driver = {
 	name: "st5481_usb",
 	probe: probe_st5481,
-	disconnect: __devexit_p(disconnect_st5481),
+	disconnect: disconnect_st5481,
 	id_table: st5481_ids,
 };
 
--- a/drivers/isdn/hisax/st5481_usb.c
+++ b/drivers/isdn/hisax/st5481_usb.c
@@ -41,9 +41,9 @@ static void usb_next_ctrl_msg(struct urb
 		(unsigned char *)&ctrl->msg_fifo.data[r_index];
 	
 	DBG(1,"request=0x%02x,value=0x%04x,index=%x",
-	    ((struct ctrl_msg *)urb->setup_packet)->dr.bRequest,
-	    ((struct ctrl_msg *)urb->setup_packet)->dr.wValue,
-	    ((struct ctrl_msg *)urb->setup_packet)->dr.wIndex);
+	    ((struct ctrl_msg *)urb->setup_packet)->dr.request,
+	    ((struct ctrl_msg *)urb->setup_packet)->dr.value,
+	    ((struct ctrl_msg *)urb->setup_packet)->dr.index);
 
 	// Prepare the URB
 	urb->dev = adapter->usb_dev;
@@ -69,11 +69,11 @@ void usb_ctrl_msg(struct st5481_adapter 
 	}
 	ctrl_msg = &ctrl->msg_fifo.data[w_index]; 
    
-	ctrl_msg->dr.bRequestType = requesttype;
-	ctrl_msg->dr.bRequest = request;
-	ctrl_msg->dr.wValue = cpu_to_le16p(&value);
-	ctrl_msg->dr.wIndex = cpu_to_le16p(&index);
-	ctrl_msg->dr.wLength = 0;
+	ctrl_msg->dr.requesttype = requesttype;
+	ctrl_msg->dr.request = request;
+	ctrl_msg->dr.value = cpu_to_le16p(&value);
+	ctrl_msg->dr.index = cpu_to_le16p(&index);
+	ctrl_msg->dr.length = 0;
 	ctrl_msg->complete = complete;
 	ctrl_msg->context = context;
 
@@ -140,17 +140,17 @@ static void usb_ctrl_complete(struct urb
 
 	ctrl_msg = (struct ctrl_msg *)urb->setup_packet;
 	
-	if (ctrl_msg->dr.bRequest == USB_REQ_CLEAR_FEATURE) {
+	if (ctrl_msg->dr.request == USB_REQ_CLEAR_FEATURE) {
 	        /* Special case handling for pipe reset */
-		le16_to_cpus(&ctrl_msg->dr.wIndex);
+		le16_to_cpus(&ctrl_msg->dr.index);
 		usb_endpoint_running(adapter->usb_dev,
-				     ctrl_msg->dr.wIndex & ~USB_DIR_IN, 
-				     (ctrl_msg->dr.wIndex & USB_DIR_IN) == 0);
+				     ctrl_msg->dr.index & ~USB_DIR_IN, 
+				     (ctrl_msg->dr.index & USB_DIR_IN) == 0);
 
 		/* toggle is reset on clear */
 		usb_settoggle(adapter->usb_dev, 
-			      ctrl_msg->dr.wIndex & ~USB_DIR_IN, 
-			      (ctrl_msg->dr.wIndex & USB_DIR_IN) == 0,
+			      ctrl_msg->dr.index & ~USB_DIR_IN, 
+			      (ctrl_msg->dr.index & USB_DIR_IN) == 0,
 			      0);
 
 
@@ -235,7 +235,7 @@ int __devinit st5481_setup_usb(struct st
 	struct usb_interface_descriptor *altsetting;
 	struct usb_endpoint_descriptor *endpoint;
 	int status;
-	struct urb *urb;
+	urb_t *urb;
 	u_char *buf;
 	
 	DBG(1,"");
@@ -307,7 +307,7 @@ int __devinit st5481_setup_usb(struct st
  * Release buffers and URBs for the interrupt and control
  * endpoint.
  */
-void st5481_release_usb(struct st5481_adapter *adapter)
+void __devexit st5481_release_usb(struct st5481_adapter *adapter)
 {
 	struct st5481_intr *intr = &adapter->intr;
 	struct st5481_ctrl *ctrl = &adapter->ctrl;
@@ -443,7 +443,7 @@ st5481_setup_isocpipes(struct urb* urb[2
 	return retval;
 }
 
-void st5481_release_isocpipes(struct urb* urb[2])
+void __devexit st5481_release_isocpipes(struct urb* urb[2])
 {
 	int j;
 
@@ -484,18 +484,16 @@ static void usb_in_complete(struct urb *
 	ptr = urb->transfer_buffer;
 	while (len > 0) {
 		if (in->mode == L1_MODE_TRANS) {
-			/* swap rx bytes to get hearable audio */
-			register unsigned char *dest = in->rcvbuf;
+			memcpy(in->rcvbuf, ptr, len);
 			status = len;
-			for (; len; len--)
-				*dest++ = isdnhdlc_bit_rev_tab[*ptr++];
+			len = 0;
 		} else {
-			status = isdnhdlc_decode(&in->hdlc_state, ptr, len, &count,
-					         in->rcvbuf, in->bufsize);
+			status = hdlc_decode(&in->hdlc_state, ptr, len, &count,
+					     in->rcvbuf, in->bufsize);
 			ptr += count;
 			len -= count;
 		}
-
+		
 		if (status > 0) {
 			// Good frame received
 			DBG(4,"count=%d",status);
@@ -549,7 +547,7 @@ int __devinit st5481_setup_in(struct st5
 	return retval;
 }
 
-void st5481_release_in(struct st5481_in *in)
+void __devexit st5481_release_in(struct st5481_in *in)
 {
 	DBG(2,"");
 
@@ -562,8 +560,7 @@ void st5481_release_in(struct st5481_in 
  */
 int st5481_isoc_flatten(struct urb *urb)
 {
-	struct iso_packet_descriptor *pipd;
-	struct iso_packet_descriptor *pend;
+	piso_packet_descriptor_t pipd,pend;
 	unsigned char *src,*dst;
 	unsigned int len;
 	
@@ -624,10 +621,15 @@ void st5481_in_mode(struct st5481_in *in
 
 	if (in->mode != L1_MODE_NULL) {
 		if (in->mode != L1_MODE_TRANS)
-			isdnhdlc_rcv_init(&in->hdlc_state,
-				          in->mode == L1_MODE_HDLC_56K);
+			hdlc_rcv_init(&in->hdlc_state,
+				      in->mode == L1_MODE_HDLC_56K);
 		
 		st5481_usb_pipe_reset(in->adapter, in->ep, NULL, NULL);
+#if 0
+		st5481_usb_device_ctrl_msg(in->adapter, in->counter,
+					   in->packet_size,
+					   st5481_start_rcv, in);
+#endif
 		st5481_usb_device_ctrl_msg(in->adapter, in->counter,
 					   in->packet_size,
 					   NULL, NULL);
--- a/drivers/isdn/hisax/tei.c
+++ b/drivers/isdn/hisax/tei.c
@@ -1,4 +1,4 @@
-/* $Id: tei.c,v 1.1.4.1 2001/11/20 14:19:36 kai Exp $
+/* $Id: tei.c,v 2.20 2001/09/24 13:22:57 kai Exp $
  *
  * Author       Karsten Keil
  *              based on the teles driver from Jan den Ouden
@@ -21,7 +21,7 @@
 #include <linux/init.h>
 #include <linux/random.h>
 
-const char *tei_revision = "$Revision: 1.1.4.1 $";
+const char *tei_revision = "$Revision: 2.20 $";
 
 #define ID_REQUEST	1
 #define ID_ASSIGNED	2
--- a/drivers/isdn/hisax/teleint.c
+++ b/drivers/isdn/hisax/teleint.c
@@ -1,4 +1,4 @@
-/* $Id: teleint.c,v 1.1.4.1 2001/11/20 14:19:36 kai Exp $
+/* $Id: teleint.c,v 1.16 2001/09/24 13:22:57 kai Exp $
  *
  * low level stuff for TeleInt isdn cards
  *
@@ -19,7 +19,7 @@
 
 extern const char *CardType[];
 
-const char *TeleInt_revision = "$Revision: 1.1.4.1 $";
+const char *TeleInt_revision = "$Revision: 1.16 $";
 
 #define byteout(addr,val) outb(val,addr)
 #define bytein(addr) inb(addr)
--- a/drivers/isdn/hisax/teles0.c
+++ b/drivers/isdn/hisax/teles0.c
@@ -1,4 +1,4 @@
-/* $Id: teles0.c,v 1.1.4.1 2001/11/20 14:19:36 kai Exp $
+/* $Id: teles0.c,v 2.15 2001/09/24 13:22:57 kai Exp $
  *
  * low level stuff for Teles Memory IO isdn cards
  *
@@ -24,7 +24,7 @@
 
 extern const char *CardType[];
 
-const char *teles0_revision = "$Revision: 1.1.4.1 $";
+const char *teles0_revision = "$Revision: 2.15 $";
 
 #define TELES_IOMEM_SIZE	0x400
 #define byteout(addr,val) outb(val,addr)
@@ -189,8 +189,10 @@ release_io_teles0(struct IsdnCardState *
 {
 	if (cs->hw.teles0.cfg_reg)
 		release_region(cs->hw.teles0.cfg_reg, 8);
+#ifdef COMPAT_HAS_ISA_IOREMAP
 	iounmap((unsigned char *)cs->hw.teles0.membase);
 	release_mem_region(cs->hw.teles0.phymem, TELES_IOMEM_SIZE);
+#endif
 }
 
 static int
@@ -327,6 +329,7 @@ setup_teles0(struct IsdnCard *card)
 	/* 16.0 and 8.0 designed for IOM1 */
 	test_and_set_bit(HW_IOM1, &cs->HW_Flags);
 	cs->hw.teles0.phymem = card->para[1];
+#ifdef COMPAT_HAS_ISA_IOREMAP
 	if (check_mem_region(cs->hw.teles0.phymem, TELES_IOMEM_SIZE)) {
 		printk(KERN_WARNING
 			"HiSax: %s memory region %lx-%lx already in use\n",
@@ -342,6 +345,9 @@ setup_teles0(struct IsdnCard *card)
 	}
 	cs->hw.teles0.membase =
 		(unsigned long) ioremap(cs->hw.teles0.phymem, TELES_IOMEM_SIZE);
+#else
+	cs->hw.teles0.membase = cs->hw.teles0.phymem;
+#endif
 	printk(KERN_INFO
 	       "HiSax: %s config irq:%d mem:0x%lX cfg:0x%X\n",
 	       CardType[cs->typ], cs->irq,
--- a/drivers/isdn/hisax/teles3.c
+++ b/drivers/isdn/hisax/teles3.c
@@ -1,4 +1,4 @@
-/* $Id: teles3.c,v 1.1.4.1 2001/11/20 14:19:36 kai Exp $
+/* $Id: teles3.c,v 2.19 2001/09/24 13:22:57 kai Exp $
  *
  * low level stuff for Teles 16.3 & PNP isdn cards
  *
@@ -15,14 +15,13 @@
  */
 #define __NO_VERSION__
 #include <linux/init.h>
-#include <linux/isapnp.h>
 #include "hisax.h"
 #include "isac.h"
 #include "hscx.h"
 #include "isdnl1.h"
 
 extern const char *CardType[];
-const char *teles3_revision = "$Revision: 1.1.4.1 $";
+const char *teles3_revision = "$Revision: 2.19 $";
 
 #define byteout(addr,val) outb(val,addr)
 #define bytein(addr) inb(addr)
@@ -255,24 +254,6 @@ Teles_card_msg(struct IsdnCardState *cs,
 	return(0);
 }
 
-#ifdef __ISAPNP__
-static struct isapnp_device_id teles_ids[] __initdata = {
-	{ ISAPNP_VENDOR('T', 'A', 'G'), ISAPNP_FUNCTION(0x2110),
-	  ISAPNP_VENDOR('T', 'A', 'G'), ISAPNP_FUNCTION(0x2110), 
-	  (unsigned long) "Teles 16.3 PnP" },
-	{ ISAPNP_VENDOR('C', 'T', 'X'), ISAPNP_FUNCTION(0x0),
-	  ISAPNP_VENDOR('C', 'T', 'X'), ISAPNP_FUNCTION(0x0), 
-	  (unsigned long) "Creatix 16.3 PnP" },
-	{ ISAPNP_VENDOR('C', 'P', 'Q'), ISAPNP_FUNCTION(0x1002),
-	  ISAPNP_VENDOR('C', 'P', 'Q'), ISAPNP_FUNCTION(0x1002), 
-	  (unsigned long) "Compaq ISDN S0" },
-	{ 0, }
-};
-
-static struct isapnp_device_id *tdev = &teles_ids[0];
-static struct pci_bus *pnp_c __devinitdata = NULL;
-#endif
-
 int __devinit
 setup_teles3(struct IsdnCard *card)
 {
@@ -286,47 +267,6 @@ setup_teles3(struct IsdnCard *card)
 	    && (cs->typ != ISDN_CTYPE_TELESPCMCIA) && (cs->typ != ISDN_CTYPE_COMPAQ_ISA))
 		return (0);
 
-#ifdef __ISAPNP__
-	if (!card->para[1] && isapnp_present()) {
-		struct pci_bus *pb;
-		struct pci_dev *pd;
-
-		while(tdev->card_vendor) {
-			if ((pb = isapnp_find_card(tdev->card_vendor,
-				tdev->card_device, pnp_c))) {
-				pnp_c = pb;
-				pd = NULL;
-				if ((pd = isapnp_find_dev(pnp_c,
-					tdev->vendor, tdev->function, pd))) {
-					printk(KERN_INFO "HiSax: %s detected\n",
-						(char *)tdev->driver_data);
-					pd->prepare(pd);
-					pd->deactivate(pd);
-					pd->activate(pd);
-					card->para[3] = pd->resource[2].start;
-					card->para[2] = pd->resource[1].start;
-					card->para[1] = pd->resource[0].start;
-					card->para[0] = pd->irq_resource[0].start;
-					if (!card->para[0] || !card->para[1] || !card->para[2]) {
-						printk(KERN_ERR "Teles PnP:some resources are missing %ld/%lx/%lx\n",
-						card->para[0], card->para[1], card->para[2]);
-						pd->deactivate(pd);
-						return(0);
-					}
-					break;
-				} else {
-					printk(KERN_ERR "Teles PnP: PnP error card found, no device\n");
-				}
-			}
-			tdev++;
-			pnp_c=NULL;
-		} 
-		if (!tdev->card_vendor) {
-			printk(KERN_INFO "Teles PnP: no ISAPnP card found\n");
-			return(0);
-		}
-	}
-#endif
 	if (cs->typ == ISDN_CTYPE_16_3) {
 		cs->hw.teles3.cfg_reg = card->para[1];
 		switch (cs->hw.teles3.cfg_reg) {
--- a/drivers/isdn/hisax/telespci.c
+++ b/drivers/isdn/hisax/telespci.c
@@ -1,4 +1,4 @@
-/* $Id: telespci.c,v 1.1.4.1 2001/11/20 14:19:36 kai Exp $
+/* $Id: telespci.c,v 2.23 2001/09/24 13:22:57 kai Exp $
  *
  * low level stuff for Teles PCI isdn cards
  *
@@ -20,9 +20,10 @@
 #include "hscx.h"
 #include "isdnl1.h"
 #include <linux/pci.h>
+#include <linux/isdn_compat.h>
 
 extern const char *CardType[];
-const char *telespci_revision = "$Revision: 1.1.4.1 $";
+const char *telespci_revision = "$Revision: 2.23 $";
 
 #define ZORAN_PO_RQ_PEN	0x02000000
 #define ZORAN_PO_WR	0x00800000
@@ -307,10 +308,10 @@ setup_telespci(struct IsdnCard *card)
 			printk(KERN_WARNING "Teles: No IRQ for PCI card found\n");
 			return(0);
 		}
-		cs->hw.teles0.membase = (u_long) ioremap(pci_resource_start(dev_tel, 0),
+		cs->hw.teles0.membase = (u_long) ioremap(pci_resource_start_mem(dev_tel, 0),
 			PAGE_SIZE);
 		printk(KERN_INFO "Found: Zoran, base-address: 0x%lx, irq: 0x%x\n",
-			pci_resource_start(dev_tel, 0), dev_tel->irq);
+			pci_resource_start_mem(dev_tel, 0), dev_tel->irq);
 	} else {
 		printk(KERN_WARNING "TelesPCI: No PCI card found\n");
 		return(0);
--- a/drivers/isdn/hisax/w6692.c
+++ b/drivers/isdn/hisax/w6692.c
@@ -1,4 +1,4 @@
-/* $Id: w6692.c,v 1.1.4.1 2001/11/20 14:19:36 kai Exp $
+/* $Id: w6692.c,v 1.18 2001/09/24 13:22:57 kai Exp $
  *
  * Winbond W6692 specific routines
  *
@@ -18,6 +18,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 {
@@ -29,20 +30,14 @@ typedef struct {
 
 static const PCI_ENTRY id_list[] =
 {
-	{PCI_VENDOR_ID_WINBOND2, PCI_DEVICE_ID_WINBOND2_6692, "Winbond", "W6692"},
 	{PCI_VENDOR_ID_DYNALINK, PCI_DEVICE_ID_DYNALINK_IS64PH, "Dynalink/AsusCom", "IS64PH"},
-	{0, 0, "U.S.Robotics", "ISDN PCI Card TA"}
+	{PCI_VENDOR_ID_WINBOND2, PCI_DEVICE_ID_WINBOND2_6692, "Winbond", "W6692"},
+	{0, 0, NULL, NULL}
 };
 
-#define W6692_SV_USR   0x16ec
-#define W6692_SD_USR   0x3409
-#define W6692_WINBOND  0
-#define W6692_DYNALINK 1
-#define W6692_USR      2
-
 extern const char *CardType[];
 
-const char *w6692_revision = "$Revision: 1.1.4.1 $";
+const char *w6692_revision = "$Revision: 1.18 $";
 
 #define DBUSY_TIMER_VALUE 80
 
@@ -675,6 +670,16 @@ setstack_W6692(struct PStack *st, struct
 static void
 DC_Close_W6692(struct IsdnCardState *cs)
 {
+#if 0
+	if (cs->dc.w6692.mon_rx) {
+		kfree(cs->dc.w6692.mon_rx);
+		cs->dc.w6692.mon_rx = NULL;
+	}
+	if (cs->dc.w6692.mon_tx) {
+		kfree(cs->dc.w6692.mon_tx);
+		cs->dc.w6692.mon_tx = NULL;
+	}
+#endif
 }
 
 static void
@@ -865,38 +870,31 @@ setstack_w6692(struct PStack *st, struct
 	return (0);
 }
 
-void resetW6692(struct IsdnCardState *cs)
-{
-	cs->writeW6692(cs, W_D_CTL, W_D_CTL_SRST);
-	schedule_timeout((10*HZ)/1000);
-	cs->writeW6692(cs, W_D_CTL, 0x00);
-	schedule_timeout((10*HZ)/1000);
-	cs->writeW6692(cs, W_IMASK, 0xff);
-	cs->writeW6692(cs, W_D_SAM, 0xff);
-	cs->writeW6692(cs, W_D_TAM, 0xff);
-	cs->writeW6692(cs, W_D_EXIM, 0x00);
-	cs->writeW6692(cs, W_D_MODE, W_D_MODE_RACT);
-	cs->writeW6692(cs, W_IMASK, 0x18);
-	if (cs->subtyp == W6692_USR) {
-		/* seems that USR implemented some power control features
-		 * Pin 79 is connected to the oscilator circuit so we
-		 * have to handle it here
-		 */
-		cs->writeW6692(cs, W_PCTL, 0x80);
-		cs->writeW6692(cs, W_XDATA, 0x00);
-	}
-}
-
 void __init initW6692(struct IsdnCardState *cs, int part)
 {
 	if (part & 1) {
 		cs->tqueue.routine = (void *) (void *) W6692_bh;
 		cs->setstack_d = setstack_W6692;
 		cs->DC_Close = DC_Close_W6692;
+#if 0
+		cs->dc.w6692.mon_tx = NULL;
+		cs->dc.w6692.mon_rx = NULL;
+#endif
 		cs->dbusytimer.function = (void *) dbusy_timer_handler;
 		cs->dbusytimer.data = (long) cs;
 		init_timer(&cs->dbusytimer);
-		resetW6692(cs);
+
+		cs->writeW6692(cs, W_D_CTL, W_D_CTL_SRST);
+		cs->writeW6692(cs, W_D_CTL, 0x00);
+		cs->writeW6692(cs, W_IMASK, 0xff);
+#if 0
+		cs->dc.w6692.mocr = 0xaa;
+#endif
+		cs->writeW6692(cs, W_D_SAM, 0xff);
+		cs->writeW6692(cs, W_D_TAM, 0xff);
+		cs->writeW6692(cs, W_D_EXIM, 0x00);
+		cs->writeW6692(cs, W_D_MODE, W_D_MODE_RACT);
+		cs->writeW6692(cs, W_IMASK, 0x18);
 		ph_command(cs, W_L1CMD_RST);
 		cs->dc.w6692.ph_state = W_L1CMD_RST;
 		W6692_new_ph(cs);
@@ -963,14 +961,9 @@ w6692_card_msg(struct IsdnCardState *cs,
 {
 	switch (mt) {
 		case CARD_RESET:
-			resetW6692(cs);
 			return (0);
 		case CARD_RELEASE:
-			cs->writeW6692(cs, W_IMASK, 0xff);
 			release_region(cs->hw.w6692.iobase, 256);
-			if (cs->subtyp == W6692_USR) {
-				cs->writeW6692(cs, W_XDATA, 0x04);
-			}
 			return (0);
 		case CARD_INIT:
 			initW6692(cs, 3);
@@ -1013,7 +1006,6 @@ setup_w6692(struct IsdnCard *card)
 		if (dev_w6692) {
 			if (pci_enable_device(dev_w6692))
 				continue;
-			cs->subtyp = id_idx;
 			break;
 		}
 		id_idx++;
@@ -1023,14 +1015,7 @@ setup_w6692(struct IsdnCard *card)
 		pci_irq = dev_w6692->irq;
 		/* I think address 0 is allways the configuration area */
 		/* and address 1 is the real IO space KKe 03.09.99 */
-		pci_ioaddr = pci_resource_start(dev_w6692, 1);
-		/* USR ISDN PCI card TA need some special handling */
-		if (cs->subtyp == W6692_WINBOND) {
-			if ((W6692_SV_USR == dev_w6692->subsystem_vendor) &&
-			    (W6692_SD_USR == dev_w6692->subsystem_device)) {
-				cs->subtyp = W6692_USR;
-			}
-		}
+		pci_ioaddr = pci_resource_start_io(dev_w6692, 1);
 	}
 	if (!found) {
 		printk(KERN_WARNING "W6692: No PCI card found\n");
@@ -1047,18 +1032,18 @@ setup_w6692(struct IsdnCard *card)
 	}
 	cs->hw.w6692.iobase = pci_ioaddr;
 	printk(KERN_INFO "Found: %s %s, I/O base: 0x%x, irq: %d\n",
-	       id_list[cs->subtyp].vendor_name, id_list[cs->subtyp].card_name,
-	       pci_ioaddr, pci_irq);
+	       id_list[id_idx].vendor_name, id_list[id_idx].card_name,
+	       pci_ioaddr, dev_w6692->irq);
 	if (check_region((cs->hw.w6692.iobase), 256)) {
 		printk(KERN_WARNING
 		       "HiSax: %s I/O ports %x-%x already in use\n",
-		       id_list[cs->subtyp].card_name,
+		       id_list[id_idx].card_name,
 		       cs->hw.w6692.iobase,
 		       cs->hw.w6692.iobase + 255);
 		return (0);
 	} else {
 		request_region(cs->hw.w6692.iobase, 256,
-			       id_list[cs->subtyp].card_name);
+			       id_list[id_idx].card_name);
 	}
 #else
 	printk(KERN_WARNING "HiSax: W6692 and NO_PCI_BIOS\n");
@@ -1068,7 +1053,7 @@ setup_w6692(struct IsdnCard *card)
 
 	printk(KERN_INFO
 	       "HiSax: %s config irq:%d I/O:%x\n",
-	       id_list[cs->subtyp].card_name, cs->irq,
+	       id_list[id_idx].card_name, cs->irq,
 	       cs->hw.w6692.iobase);
 
 	cs->readW6692 = &ReadW6692;
--- a/drivers/isdn/hisax/w6692.h
+++ b/drivers/isdn/hisax/w6692.h
@@ -1,4 +1,4 @@
-/* $Id: w6692.h,v 1.1.4.1 2001/11/20 14:19:36 kai Exp $
+/* $Id: w6692.h,v 1.4 2001/09/24 13:22:57 kai Exp $
  *
  * Winbond W6692 specific defines
  *
--- a/drivers/isdn/hysdn/boardergo.c
+++ b/drivers/isdn/hysdn/boardergo.c
@@ -1,27 +1,41 @@
-/* $Id: boardergo.c,v 1.1.4.1 2001/11/20 14:19:37 kai Exp $
- *
+/* $Id: boardergo.c,v 1.9 2001/07/19 20:39:51 kai Exp $
+
  * Linux driver for HYSDN cards, specific routines for ergo type boards.
  *
- * Author    Werner Cornelius (werner@titro.de) for Hypercope GmbH
- * Copyright 1999 by Werner Cornelius (werner@titro.de)
- *
- * This software may be used and distributed according to the terms
- * of the GNU General Public License, incorporated herein by reference.
- *
  * 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/sched.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 <linux/vmalloc.h>
-#include <asm/io.h>
 
 #include "hysdn_defs.h"
 #include "boardergo.h"
@@ -45,11 +59,10 @@ ergo_interrupt(int intno, void *dev_id, 
 	if (!card->irq_enabled)
 		return;		/* other device interrupting or irq switched off */
 
-	save_flags(flags);
-	cli();			/* no further irqs allowed */
+	HYSDN_SPIN_LOCK(&card->irq_lock, flags);
 
 	if (!(bytein(card->iobase + PCI9050_INTR_REG) & PCI9050_INTR_REG_STAT1)) {
-		restore_flags(flags);	/* restore old state */
+		HYSDN_SPIN_UNLOCK(&card->irq_lock, flags);
 		return;		/* no interrupt requested by E1 */
 	}
 	/* clear any pending ints on the board */
@@ -63,7 +76,7 @@ ergo_interrupt(int intno, void *dev_id, 
 		queue_task(&card->irq_queue, &tq_immediate);
 		mark_bh(IMMEDIATE_BH);
 	}
-	restore_flags(flags);
+	HYSDN_SPIN_UNLOCK(&card->irq_lock, flags);
 }				/* ergo_interrupt */
 
 /******************************************************************************/
@@ -83,17 +96,15 @@ ergo_irq_bh(hysdn_card * card)
 		return;		/* invalid call */
 
 	dpr = card->dpram;	/* point to DPRAM */
+	HYSDN_SPIN_LOCK(&card->irq_lock, flags);
 
-	save_flags(flags);
-	cli();
 	if (card->hw_lock) {
-		restore_flags(flags);	/* hardware currently unavailable */
+		HYSDN_SPIN_UNLOCK(&card->irq_lock, flags);
 		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) {
@@ -113,15 +124,13 @@ ergo_irq_bh(hysdn_card * card)
 				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);
+	HYSDN_SPIN_UNLOCK(&card->irq_lock, flags);
 }				/* ergo_irq_bh */
 
 
@@ -138,8 +147,7 @@ ergo_stopcard(hysdn_card * card)
 #ifdef CONFIG_HYSDN_CAPI
 	hycapi_capi_stop(card);
 #endif /* CONFIG_HYSDN_CAPI */
-	save_flags(flags);
-	cli();
+	HYSDN_SPIN_LOCK(&card->irq_lock, flags);
 	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);
@@ -147,8 +155,7 @@ ergo_stopcard(hysdn_card * card)
 	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);
+	HYSDN_SPIN_UNLOCK(&card->irq_lock, flags);
 }				/* ergo_stopcard */
 
 /**************************************************************************/
@@ -163,20 +170,17 @@ ergo_set_errlog_state(hysdn_card * card,
 		card->err_log_state = ERRLOG_STATE_OFF;		/* must be off */
 		return;
 	}
-	save_flags(flags);
-	cli();
-
+	HYSDN_SPIN_LOCK(&card->irq_lock, flags);
 	if (((card->err_log_state == ERRLOG_STATE_OFF) && !on) ||
 	    ((card->err_log_state == ERRLOG_STATE_ON) && on)) {
-		restore_flags(flags);
+		HYSDN_SPIN_UNLOCK(&card->irq_lock, 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);
+	HYSDN_SPIN_UNLOCK(&card->irq_lock, flags);
 	queue_task(&card->irq_queue, &tq_immediate);
 	mark_bh(IMMEDIATE_BH);
 }				/* ergo_set_errlog_state */
@@ -245,9 +249,6 @@ ergo_writebootimg(struct HYSDN_CARD *car
 		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 */
 
@@ -282,7 +283,6 @@ ergo_writebootseq(struct HYSDN_CARD *car
 	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 */
@@ -358,9 +358,7 @@ ergo_waitpofready(struct HYSDN_CARD *car
 
 			if (card->debug_flags & LOG_POF_RECORD)
 				hysdn_addlog(card, "ERGO: pof boot success");
-			save_flags(flags);
-			cli();
-
+			HYSDN_SPIN_LOCK(&card->irq_lock, flags);
 			card->state = CARD_STATE_RUN;	/* now card is running */
 			/* enable the cards interrupt */
 			byteout(card->iobase + PCI9050_INTR_REG,
@@ -371,8 +369,7 @@ ergo_waitpofready(struct HYSDN_CARD *car
 			dpr->ToPcFlag = 0;	/* reset data indicator */
 			dpr->ToHyInt = 1;
 			dpr->ToPcInt = 1;	/* interrupt to E1 for all cards */
-
-			restore_flags(flags);
+			HYSDN_SPIN_UNLOCK(&card->irq_lock, flags);
 			if ((hynet_enable & (1 << card->myid)) 
 			    && (i = hysdn_net_create(card))) 
 			{
@@ -387,7 +384,6 @@ ergo_waitpofready(struct HYSDN_CARD *car
 #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 */
--- a/drivers/isdn/hysdn/boardergo.h
+++ b/drivers/isdn/hysdn/boardergo.h
@@ -1,4 +1,4 @@
-/* $Id: boardergo.h,v 1.1.4.1 2001/11/20 14:19:37 kai Exp $
+/* $Id$
  *
  * Linux driver for HYSDN cards, definitions for ergo type boards (buffers..).
  *
@@ -10,6 +10,7 @@
  *
  */
 
+#include <linux/isdn_compat.h>
 
 /************************************************/
 /* defines for the dual port memory of the card */
--- a/drivers/isdn/hysdn/hycapi.c
+++ b/drivers/isdn/hysdn/hycapi.c
@@ -1,4 +1,4 @@
-/* $Id: hycapi.c,v 1.1.4.1 2001/11/20 14:19:37 kai Exp $
+/* $Id$
  *
  * Linux driver for HYSDN cards, CAPI2.0-Interface.
  *
@@ -29,7 +29,7 @@
 #include "hysdn_defs.h"
 #include <linux/kernelcapi.h>
 
-static char hycapi_revision[]="$Revision: 1.1.4.1 $";
+static char hycapi_revision[]="$Revision$";
 
 unsigned int hycapi_enable = 0xffffffff; 
 MODULE_PARM(hycapi_enable, "i");
--- a/drivers/isdn/hysdn/hysdn_boot.c
+++ b/drivers/isdn/hysdn/hysdn_boot.c
@@ -1,4 +1,4 @@
-/* $Id: hysdn_boot.c,v 1.1.4.1 2001/11/20 14:19:37 kai Exp $
+/* $Id$
  *
  * Linux driver for HYSDN cards
  * specific routines for booting and pof handling
@@ -143,7 +143,7 @@ pof_handle_data(hysdn_card * card, int d
 					     (boot->pof_recid == TAG_CABSDATA) ? "CABSDATA" : "ABSDATA",
 					     datlen, boot->pof_recoffset);
 
-			if ((boot->last_error = card->writebootseq(card, boot->buf.BootBuf, datlen)) < 0)
+			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)
--- a/drivers/isdn/hysdn/hysdn_defs.h
+++ b/drivers/isdn/hysdn/hysdn_defs.h
@@ -1,4 +1,4 @@
-/* $Id: hysdn_defs.h,v 1.1.4.1 2001/11/20 14:19:37 kai Exp $
+/* $Id: hysdn_defs.h,v 1.10 2001/09/24 13:23:03 kai Exp $
  *
  * Linux driver for HYSDN cards
  * global definitions and exported vars and functions.
@@ -19,6 +19,11 @@
 #include <linux/interrupt.h>
 #include <linux/tqueue.h>
 #include <linux/skbuff.h>
+#include <linux/isdn_compat.h>
+#include <linux/spinlock.h>
+
+#define HYSDN_SPIN_LOCK(a,b) spin_lock(a)
+#define HYSDN_SPIN_UNLOCK(a,b) spin_unlock(a)
 
 /****************************/
 /* storage type definitions */
@@ -176,6 +181,7 @@ typedef struct HYSDN_CARD {
 	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 */
+	spinlock_t irq_lock;
 
 	/* boot process */
 	void *boot;		/* pointer to boot private data */
--- a/drivers/isdn/hysdn/hysdn_init.c
+++ b/drivers/isdn/hysdn/hysdn_init.c
@@ -1,4 +1,4 @@
-/* $Id: hysdn_init.c,v 1.1.4.1 2001/11/20 14:19:37 kai Exp $
+/* $Id$
  *
  * Linux driver for HYSDN cards, init functions.
  *
@@ -21,6 +21,7 @@
 
 #include "hysdn_defs.h"
 
+#ifndef COMPAT_HAS_2_2_PCI
 static struct pci_device_id hysdn_pci_tbl[] __initdata = {
 	{PCI_VENDOR_ID_HYPERCOPE, PCI_DEVICE_ID_HYPERCOPE_PLX, PCI_ANY_ID, PCI_SUBDEVICE_ID_HYPERCOPE_METRO},
 	{PCI_VENDOR_ID_HYPERCOPE, PCI_DEVICE_ID_HYPERCOPE_PLX, PCI_ANY_ID, PCI_SUBDEVICE_ID_HYPERCOPE_CHAMP2},
@@ -29,11 +30,12 @@ static struct pci_device_id hysdn_pci_tb
 	{ }				/* Terminating entry */
 };
 MODULE_DEVICE_TABLE(pci, hysdn_pci_tbl);
+#endif
 MODULE_DESCRIPTION("ISDN4Linux: Driver for HYSDN cards");
 MODULE_AUTHOR("Werner Cornelius");
 MODULE_LICENSE("GPL");
 
-static char *hysdn_init_revision = "$Revision: 1.1.4.1 $";
+static char *hysdn_init_revision = "$Revision$";
 int cardmax;			/* number of found cards */
 hysdn_card *card_root = NULL;	/* pointer to first card */
 
@@ -91,11 +93,11 @@ search_cards(void)
 		card->myid = cardmax;	/* set own id */
 		card->bus = akt_pcidev->bus->number;
 		card->devfn = akt_pcidev->devfn;	/* slot + function */
-		card->subsysid = akt_pcidev->subsystem_device;
+		pci_get_sub_system(akt_pcidev,card->subsysid);
 		card->irq = akt_pcidev->irq;
-		card->iobase = pci_resource_start(akt_pcidev, PCI_REG_PLX_IO_BASE);
-		card->plxbase = pci_resource_start(akt_pcidev, PCI_REG_PLX_MEM_BASE);
-		card->membase = pci_resource_start(akt_pcidev, PCI_REG_MEMORY_BASE);
+		card->iobase = pci_resource_start_io(akt_pcidev, PCI_REG_PLX_IO_BASE);
+		card->plxbase = pci_resource_start_mem(akt_pcidev, PCI_REG_PLX_MEM_BASE);
+		card->membase = pci_resource_start_mem(akt_pcidev, PCI_REG_MEMORY_BASE);
 		card->brdtype = BD_NONE;	/* unknown */
 		card->debug_flags = DEF_DEB_FLAGS;	/* set default debug */
 		card->faxchans = 0;	/* default no fax channels */
--- a/drivers/isdn/hysdn/hysdn_net.c
+++ b/drivers/isdn/hysdn/hysdn_net.c
@@ -1,4 +1,4 @@
-/* $Id: hysdn_net.c,v 1.1.4.1 2001/11/20 14:19:37 kai Exp $
+/* $Id$
  *
  * Linux driver for HYSDN cards, net (ethernet type) handling routines.
  *
@@ -29,7 +29,7 @@ unsigned int hynet_enable = 0xffffffff; 
 MODULE_PARM(hynet_enable, "i");
 
 /* store the actual version for log reporting */
-char *hysdn_net_revision = "$Revision: 1.1.4.1 $";
+char *hysdn_net_revision = "$Revision$";
 
 #define MAX_SKB_BUFFERS 20	/* number of buffers for keeping TX-data */
 
@@ -45,6 +45,10 @@ struct net_local {
 	/* additional vars may be added here */
 	char dev_name[9];	/* our own device name */
 
+#ifdef COMPAT_NO_SOFTNET
+	struct sk_buff *tx_skb;	/* buffer for tx operation */
+
+#else
 	/* Tx control lock.  This protects the transmit buffer ring
 	 * state along with the "tx full" state of the driver.  This
 	 * means all netif_queue flow control actions are protected
@@ -56,6 +60,7 @@ struct net_local {
 	int sk_count;		/* number of buffers currently in ring */
 
 	int is_open;		/* flag controlling module locking */
+#endif
 };				/* net_local */
 
 
@@ -83,11 +88,19 @@ net_open(struct net_device *dev)
 	hysdn_card *card = dev->priv;
 	int i;
 
+#ifdef COMPAT_NO_SOFTNET
+	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 */
+#else
 	if (!((struct net_local *) dev)->is_open)
 		MOD_INC_USE_COUNT;	/* increment only if interface is actually down */
 	((struct net_local *) dev)->is_open = 1;	/* device actually open */
 
 	netif_start_queue(dev);	/* start tx-queueing */
+#endif
 
 	/* Fill in the MAC-level header (if not already set) */
 	if (!card->mac_addr[0]) {
@@ -104,6 +117,7 @@ net_open(struct net_device *dev)
 	return (0);
 }				/* net_open */
 
+#ifndef COMPAT_NO_SOFTNET
 /*******************************************/
 /* flush the currently occupied tx-buffers */
 /* must only be called when device closed  */
@@ -119,6 +133,7 @@ flush_tx_buffers(struct net_local *nl)
 		nl->sk_count--;
 	}
 }				/* flush_tx_buffers */
+#endif
 
 
 /*********************************************************************/
@@ -129,6 +144,15 @@ static int
 net_close(struct net_device *dev)
 {
 
+#ifdef COMPAT_NO_SOFTNET
+	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 */
+
+#else
 	netif_stop_queue(dev);	/* disable queueing */
 
 	if (((struct net_local *) dev)->is_open)
@@ -136,9 +160,52 @@ net_close(struct net_device *dev)
 	((struct net_local *) dev)->is_open = 0;
 	flush_tx_buffers((struct net_local *) dev);
 
+#endif
 	return (0);		/* success */
 }				/* net_close */
 
+#ifdef COMPAT_NO_SOFTNET
+/************************************/
+/* send a packet on this interface. */
+/* only for kernel versions < 2.3.33 */
+/************************************/
+static int
+net_send_packet(struct sk_buff *skb, struct net_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 */
+
+#else
 /************************************/
 /* send a packet on this interface. */
 /* new style for kernel >= 2.3.33   */
@@ -176,6 +243,7 @@ net_send_packet(struct sk_buff *skb, str
 	return (0);		/* success */
 }				/* net_send_packet */
 
+#endif
 
 
 /***********************************************************************/
@@ -190,6 +258,15 @@ hysdn_tx_netack(hysdn_card * card)
 	if (!lp)
 		return;		/* non existing device */
 
+#ifdef COMPAT_NO_SOFTNET
+	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. */
+#else
 
 	if (!lp->sk_count)
 		return;		/* error condition */
@@ -203,6 +280,7 @@ hysdn_tx_netack(hysdn_card * card)
 
 	if (lp->sk_count-- == MAX_SKB_BUFFERS)	/* dec usage count */
 		netif_start_queue((struct net_device *) lp);
+#endif
 }				/* hysdn_tx_netack */
 
 /*****************************************************/
@@ -250,10 +328,15 @@ hysdn_tx_netget(hysdn_card * card)
 	if (!lp)
 		return (NULL);	/* non existing device */
 
+#ifdef COMPAT_NO_SOFTNET
+	return (lp->tx_skb);	/* return packet pointer */
+
+#else
 	if (!lp->sk_count)
 		return (NULL);	/* nothing available */
 
 	return (lp->skbs[lp->out_idx]);		/* next packet to send */
+#endif
 }				/* hysdn_tx_netget */
 
 
@@ -296,15 +379,21 @@ hysdn_net_create(hysdn_card * card)
 	}
 	memset(dev, 0, sizeof(struct net_local));	/* clean the structure */
 
+#ifndef COMPAT_NO_SOFTNET
 	spin_lock_init(&((struct net_local *) dev)->lock);
+#endif
 
 	/* 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 */
+#ifdef COMPAT_NO_SOFTNET
+	dev->name = ((struct net_local *) dev)->dev_name;	/* device name */
+#else
 	if(dev->name) {
 		strcpy(dev->name, ((struct net_local *) dev)->dev_name);
 	} 
+#endif
 	if ((i = register_netdev(dev))) {
 		printk(KERN_WARNING "HYSDN: unable to create network device\n");
 		kfree(dev);
@@ -333,7 +422,9 @@ hysdn_net_release(hysdn_card * card)
 	card->netif = NULL;	/* clear out pointer */
 	dev->stop(dev);		/* close the device */
 
+#ifndef COMPAT_NO_SOFTNET
 	flush_tx_buffers((struct net_local *) dev);	/* empty buffers */
+#endif
 
 	unregister_netdev(dev);	/* release the device */
 	kfree(dev);		/* release the memory allocated */
--- a/drivers/isdn/hysdn/hysdn_pof.h
+++ b/drivers/isdn/hysdn/hysdn_pof.h
@@ -1,4 +1,4 @@
-/* $Id: hysdn_pof.h,v 1.1.4.1 2001/11/20 14:19:37 kai Exp $
+/* $Id$
  *
  * Linux driver for HYSDN cards, definitions used for handling pof-files.
  *
--- a/drivers/isdn/hysdn/hysdn_procconf.c
+++ b/drivers/isdn/hysdn/hysdn_procconf.c
@@ -1,4 +1,4 @@
-/* $Id: hysdn_procconf.c,v 1.1.4.1 2001/11/20 14:19:37 kai Exp $
+/* $Id$
  *
  * Linux driver for HYSDN cards, /proc/net filesystem dir and conf functions.
  *
@@ -17,11 +17,13 @@
 #include <linux/poll.h>
 #include <linux/proc_fs.h>
 #include <linux/pci.h>
+#ifndef COMPAT_USE_MODCOUNT_LOCK
 #include <linux/smp_lock.h>
+#endif
 
 #include "hysdn_defs.h"
 
-static char *hysdn_procconf_revision = "$Revision: 1.1.4.1 $";
+static char *hysdn_procconf_revision = "$Revision$";
 
 #define INFO_OUT_LEN 80		/* length of info line including lf */
 
@@ -212,32 +214,29 @@ hysdn_conf_write(struct file *file, cons
 static ssize_t
 hysdn_conf_read(struct file *file, char *buf, size_t count, loff_t * off)
 {
-	loff_t pos = *off;
 	char *cp;
 	int i;
 
 	if (off != &file->f_pos)	/* fs error check */
 		return -ESPIPE;
 
-	if (!(file->f_mode & FMODE_READ))
-		return -EPERM;
-
-	if (!(cp = file->private_data))
-		return (-EFAULT);	/* should never happen */
-
-	i = strlen(cp);	/* get total string length */
-
-	if (pos != (unsigned)pos || pos >= i)
-		return 0;
-
-	/* still bytes to transfer */
-	cp += pos;	/* point to desired data offset */
-	i -= pos;	/* remaining length */
-	if (i > count)
-		i = count;	/* limit length to transfer */
-	if (copy_to_user(buf, cp, i))
-		return (-EFAULT);	/* copy error */
-	*off = pos + i;	/* adjust offset */
+	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 */
@@ -254,7 +253,11 @@ hysdn_conf_open(struct inode *ino, struc
 	char *cp, *tmp;
 
 	/* now search the addressed card */
+#ifdef COMPAT_USE_MODCOUNT_LOCK
+	MOD_INC_USE_COUNT;
+#else
 	lock_kernel();
+#endif
 	card = card_root;
 	while (card) {
 		pd = card->procconf;
@@ -263,7 +266,11 @@ hysdn_conf_open(struct inode *ino, struc
 		card = card->next;	/* search next entry */
 	}
 	if (!card) {
+#ifdef COMPAT_USE_MODCOUNT_LOCK
+		MOD_DEC_USE_COUNT;
+#else
 		unlock_kernel();
+#endif
 		return (-ENODEV);	/* device is unknown/invalid */
 	}
 	if (card->debug_flags & (LOG_PROC_OPEN | LOG_PROC_ALL))
@@ -274,7 +281,11 @@ hysdn_conf_open(struct inode *ino, struc
 		/* write only access -> write boot file or conf line */
 
 		if (!(cnf = kmalloc(sizeof(struct conf_writedata), GFP_KERNEL))) {
+#ifdef COMPAT_USE_MODCOUNT_LOCK
+			MOD_DEC_USE_COUNT;
+#else
 			unlock_kernel();
+#endif
 			return (-EFAULT);
 		}
 		cnf->card = card;
@@ -286,7 +297,11 @@ hysdn_conf_open(struct inode *ino, struc
 		/* read access -> output card info data */
 
 		if (!(tmp = (char *) kmalloc(INFO_OUT_LEN * 2 + 2, GFP_KERNEL))) {
+#ifdef COMPAT_USE_MODCOUNT_LOCK
+			MOD_DEC_USE_COUNT;
+#else
 			unlock_kernel();
+#endif
 			return (-EFAULT);	/* out of memory */
 		}
 		filep->private_data = tmp;	/* start of string */
@@ -320,10 +335,16 @@ hysdn_conf_open(struct inode *ino, struc
 		*cp++ = '\n';
 		*cp = 0;	/* end of string */
 	} else {		/* simultaneous read/write access forbidden ! */
+#ifdef COMPAT_USE_MODCOUNT_LOCK
+		MOD_DEC_USE_COUNT;
+#else
 		unlock_kernel();
+#endif
 		return (-EPERM);	/* no permission this time */
 	}
+#ifndef COMPAT_USE_MODCOUNT_LOCK
 	unlock_kernel();
+#endif
 	return (0);
 }				/* hysdn_conf_open */
 
@@ -338,7 +359,9 @@ hysdn_conf_close(struct inode *ino, stru
 	int retval = 0;
 	struct proc_dir_entry *pd;
 
+#ifndef COMPAT_USE_MODCOUNT_LOCK
 	lock_kernel();
+#endif
 	/* search the addressed card */
 	card = card_root;
 	while (card) {
@@ -348,7 +371,9 @@ hysdn_conf_close(struct inode *ino, stru
 		card = card->next;	/* search next entry */
 	}
 	if (!card) {
+#ifndef COMPAT_USE_MODCOUNT_LOCK
 		unlock_kernel();
+#endif
 		return (-ENODEV);	/* device is unknown/invalid */
 	}
 	if (card->debug_flags & (LOG_PROC_OPEN | LOG_PROC_ALL))
@@ -371,7 +396,11 @@ hysdn_conf_close(struct inode *ino, stru
 		if (filep->private_data)
 			kfree(filep->private_data);	/* release memory */
 	}
+#ifdef COMPAT_USE_MODCOUNT_LOCK
+	MOD_DEC_USE_COUNT;
+#else
 	unlock_kernel();
+#endif
 	return (retval);
 }				/* hysdn_conf_close */
 
@@ -387,6 +416,9 @@ static struct file_operations conf_fops 
 	release:        hysdn_conf_close,                                       
 };
 
+#ifdef COMPAT_NO_SOFTNET
+static struct inode_operations conf_inode_operations;
+#endif
 /*****************************/
 /* hysdn subdir in /proc/net */
 /*****************************/
@@ -415,8 +447,17 @@ hysdn_procconf_init(void)
 		if ((card->procconf = (void *) create_proc_entry(conf_name,
 					     S_IFREG | S_IRUGO | S_IWUSR,
 					    hysdn_proc_entry)) != NULL) {
+#ifdef COMPAT_NO_SOFTNET
+			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;
+#else
 			((struct proc_dir_entry *) card->procconf)->proc_fops = &conf_fops;
+#ifdef COMPAT_HAS_FILEOP_OWNER
 			((struct proc_dir_entry *) card->procconf)->owner = THIS_MODULE;
+#endif
+#endif
 			hysdn_proclog_init(card);	/* init the log file entry */
 		}
 		card = card->next;	/* next entry */
--- a/drivers/isdn/hysdn/hysdn_proclog.c
+++ b/drivers/isdn/hysdn/hysdn_proclog.c
@@ -1,4 +1,4 @@
-/* $Id: hysdn_proclog.c,v 1.1.4.1 2001/11/20 14:19:37 kai Exp $
+/* $Id$
  *
  * Linux driver for HYSDN cards, /proc/net filesystem log functions.
  *
@@ -16,7 +16,9 @@
 #include <linux/poll.h>
 #include <linux/proc_fs.h>
 #include <linux/pci.h>
+#ifndef COMPAT_USE_MODCOUNT_LOCK
 #include <linux/smp_lock.h>
+#endif
 
 #include "hysdn_defs.h"
 
@@ -115,8 +117,7 @@ put_log_buffer(hysdn_card * card, char *
 	strcpy(ib->log_start, cp);	/* set output string */
 	ib->next = NULL;
 	ib->proc_ctrl = pd;	/* point to own control structure */
-	save_flags(flags);
-	cli();
+	HYSDN_SPIN_LOCK(&card->irq_lock, flags);
 	ib->usage_cnt = pd->if_used;
 	if (!pd->log_head)
 		pd->log_head = ib;	/* new head */
@@ -124,7 +125,7 @@ put_log_buffer(hysdn_card * card, char *
 		pd->log_tail->next = ib;	/* follows existing messages */
 	pd->log_tail = ib;	/* new tail */
 	i = pd->del_lock++;	/* get lock state */
-	restore_flags(flags);
+	HYSDN_SPIN_UNLOCK(&card->irq_lock, flags);
 
 	/* delete old entrys */
 	if (!i)
@@ -210,7 +211,6 @@ hysdn_log_read(struct file *file, char *
 	word ino;
 	struct procdata *pd = NULL;
 	hysdn_card *card;
-	loff_t pos = *off;
 
 	if (!*((struct log_data **) file->private_data)) {
 		if (file->f_flags & O_NONBLOCK)
@@ -235,11 +235,11 @@ hysdn_log_read(struct file *file, char *
 		return (0);
 
 	inf->usage_cnt--;	/* new usage count */
-	file->private_data = &inf->next;	/* next structure */
+	(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;
-		*off = pos + len;
+		file->f_pos += len;
 		return (len);
 	}
 	return (0);
@@ -255,7 +255,11 @@ hysdn_log_open(struct inode *ino, struct
 	struct procdata *pd = NULL;
 	ulong flags;
 
+#ifdef COMPAT_USE_MODCOUNT_LOCK
+	MOD_INC_USE_COUNT;
+#else
 	lock_kernel();
+#endif
 	card = card_root;
 	while (card) {
 		pd = card->proclog;
@@ -264,7 +268,11 @@ hysdn_log_open(struct inode *ino, struct
 		card = card->next;	/* search next entry */
 	}
 	if (!card) {
+#ifdef COMPAT_USE_MODCOUNT_LOCK
+		MOD_DEC_USE_COUNT;
+#else
 		unlock_kernel();
+#endif
 		return (-ENODEV);	/* device is unknown/invalid */
 	}
 	filep->private_data = card;	/* remember our own card */
@@ -274,19 +282,24 @@ hysdn_log_open(struct inode *ino, struct
 	} else if ((filep->f_mode & (FMODE_READ | FMODE_WRITE)) == FMODE_READ) {
 
 		/* read access -> log/debug read */
-		save_flags(flags);
-		cli();
+		HYSDN_SPIN_LOCK(&card->irq_lock, flags);
 		pd->if_used++;
 		if (pd->log_head)
-			filep->private_data = &(pd->log_tail->next);
+			(struct log_data **) filep->private_data = &(pd->log_tail->next);
 		else
-			filep->private_data = &(pd->log_head);
-		restore_flags(flags);
+			(struct log_data **) filep->private_data = &(pd->log_head);
+		HYSDN_SPIN_UNLOCK(&card->irq_lock, flags);
 	} else {		/* simultaneous read/write access forbidden ! */
+#ifdef COMPAT_USE_MODCOUNT_LOCK
+		MOD_DEC_USE_COUNT;
+#else
 		unlock_kernel();
+#endif
 		return (-EPERM);	/* no permission this time */
 	}
+#ifndef COMPAT_USE_MODCOUNT_LOCK
 	unlock_kernel();
+#endif
 	return (0);
 }				/* hysdn_log_open */
 
@@ -306,7 +319,9 @@ hysdn_log_close(struct inode *ino, struc
 	int flags, retval = 0;
 
 
+#ifndef COMPAT_USE_MODCOUNT_LOCK
 	lock_kernel();
+#endif
 	if ((filep->f_mode & (FMODE_READ | FMODE_WRITE)) == FMODE_WRITE) {
 		/* write only access -> write debug level written */
 		retval = 0;	/* success */
@@ -314,8 +329,7 @@ hysdn_log_close(struct inode *ino, struc
 		/* read access -> log/debug read, mark one further file as closed */
 
 		pd = NULL;
-		save_flags(flags);
-		cli();
+		HYSDN_SPIN_LOCK(&card->irq_lock, flags);
 		inf = *((struct log_data **) filep->private_data);	/* get first log entry */
 		if (inf)
 			pd = (struct procdata *) inf->proc_ctrl;	/* still entries there */
@@ -338,7 +352,7 @@ hysdn_log_close(struct inode *ino, struc
 			inf->usage_cnt--;	/* decrement usage count for buffers */
 			inf = inf->next;
 		}
-		restore_flags(flags);
+		HYSDN_SPIN_UNLOCK(&card->irq_lock, flags);
 
 		if (pd)
 			if (pd->if_used <= 0)	/* delete buffers if last file closed */
@@ -348,7 +362,11 @@ hysdn_log_close(struct inode *ino, struc
 					kfree(inf);
 				}
 	}			/* read access */
+#ifdef COMPAT_USE_MODCOUNT_LOCK
+	MOD_DEC_USE_COUNT;
+#else
 	unlock_kernel();
+#endif
 
 	return (retval);
 }				/* hysdn_log_close */
@@ -400,6 +418,9 @@ static struct file_operations log_fops =
 	release:        hysdn_log_close,                                        
 };
 
+#ifdef COMPAT_NO_SOFTNET
+struct inode_operations log_inode_operations;
+#endif
 
 /***********************************************************************************/
 /* hysdn_proclog_init is called when the module is loaded after creating the cards */
@@ -414,10 +435,20 @@ hysdn_proclog_init(hysdn_card * card)
 
 	if ((pd = (struct procdata *) kmalloc(sizeof(struct procdata), GFP_KERNEL)) != NULL) {
 		memset(pd, 0, sizeof(struct procdata));
+#ifdef COMPAT_NO_SOFTNET
+		memset(&log_inode_operations, 0, sizeof(struct inode_operations));
+		log_inode_operations.default_file_ops = &log_fops;
+#endif
 		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) {
+#ifdef COMPAT_NO_SOFTNET
+			pd->log->ops = &log_inode_operations;	/* set new operations table */
+#else
 		        pd->log->proc_fops = &log_fops; 
+#ifdef COMPAT_HAS_FILEOP_OWNER
 		        pd->log->owner = THIS_MODULE;
+#endif
+#endif
 		}
 
 		init_waitqueue_head(&(pd->rd_queue));
--- a/drivers/isdn/hysdn/hysdn_sched.c
+++ b/drivers/isdn/hysdn/hysdn_sched.c
@@ -1,4 +1,4 @@
-/* $Id: hysdn_sched.c,v 1.1.4.1 2001/11/20 14:19:37 kai Exp $
+/* $Id: hysdn_sched.c,v 1.9 2001/09/24 13:23:03 kai Exp $
  *
  * Linux driver for HYSDN cards
  * scheduler routines for handling exchange card <-> pc.
@@ -12,11 +12,9 @@
  */
 
 #include <linux/config.h>
-#include <linux/sched.h>
 #include <linux/signal.h>
 #include <linux/kernel.h>
 #include <linux/ioport.h>
-#include <linux/interrupt.h>
 #include <asm/io.h>
 
 #include "hysdn_defs.h"
@@ -151,22 +149,19 @@ hysdn_tx_cfgline(hysdn_card * card, ucha
 
 	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();
+	HYSDN_SPIN_LOCK(&card->irq_lock, flags);
 	while (card->async_busy) {
-		sti();
-
+		HYSDN_SPIN_UNLOCK(&card->irq_lock, flags);
 		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);
+			HYSDN_SPIN_UNLOCK(&card->irq_lock, flags);
 			return (-ERR_ASYNC_TIME);	/* timed out */
 		}
-		cli();
+		HYSDN_SPIN_LOCK(&card->irq_lock, flags);
 	}			/* wait for buffer to become free */
 
 	strcpy(card->async_data, line);
@@ -177,31 +172,26 @@ hysdn_tx_cfgline(hysdn_card * card, ucha
 	/* now queue the task */
 	queue_task(&card->irq_queue, &tq_immediate);
 	mark_bh(IMMEDIATE_BH);
-	sti();
-
+	HYSDN_SPIN_UNLOCK(&card->irq_lock, flags);
 	if (card->debug_flags & LOG_SCHED_ASYN)
 		hysdn_addlog(card, "async tx-cfg data queued");
 
 	cnt++;			/* short delay */
-	cli();
-
+	HYSDN_SPIN_LOCK(&card->irq_lock, flags);
 	while (card->async_busy) {
-		sti();
-
+		HYSDN_SPIN_UNLOCK(&card->irq_lock, flags);
 		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);
+			HYSDN_SPIN_UNLOCK(&card->irq_lock, flags);
 			return (-ERR_ASYNC_TIME);	/* timed out */
 		}
-		cli();
+		HYSDN_SPIN_LOCK(&card->irq_lock, flags);
 	}			/* wait for buffer to become free again */
-
-	restore_flags(flags);
-
+	HYSDN_SPIN_UNLOCK(&card->irq_lock, flags);
 	if (card->debug_flags & LOG_SCHED_ASYN)
 		hysdn_addlog(card, "async tx-cfg data send");
 
--- a/drivers/isdn/icn/icn.c
+++ b/drivers/isdn/icn/icn.c
@@ -1,4 +1,4 @@
-/* $Id: icn.c,v 1.1.4.1 2001/11/20 14:19:37 kai Exp $
+/* $Id$
  *
  * ISDN low-level module for the ICN active ISDN-Card.
  *
@@ -41,7 +41,7 @@ MODULE_PARM_DESC(icn_id2, "ID-String of 
 #undef MAP_DEBUG
 
 static char
-*revision = "$Revision: 1.1.4.1 $";
+*revision = "$Revision$";
 
 static int icn_addcard(int, char *, char *);
 
@@ -1634,6 +1634,7 @@ icn_addcard(int port, char *id1, char *i
 }
 
 #ifndef MODULE
+#ifdef COMPAT_HAS_NEW_SETUP
 static int __init
 icn_setup(char *line)
 {
@@ -1643,6 +1644,14 @@ icn_setup(char *line)
 	static char sid2[20];
 
 	str = get_options(line, 2, ints);
+#else
+void
+icn_setup(char *str, int *ints)
+{
+	char *p;
+	static char sid[20];
+	static char sid2[20];
+#endif
 	if (ints[0])
 		portbase = ints[1];
 	if (ints[0] > 1)
@@ -1656,9 +1665,13 @@ icn_setup(char *line)
 			icn_id2 = sid2;
 		}
 	}
+#ifdef COMPAT_HAS_NEW_SETUP
 	return(1);
 }
 __setup("icn=", icn_setup);
+#else
+}
+#endif
 #endif /* MODULE */
 
 static int __init icn_init(void)
--- a/drivers/isdn/icn/icn.h
+++ b/drivers/isdn/icn/icn.h
@@ -1,4 +1,4 @@
-/* $Id: icn.h,v 1.1.4.1 2001/11/20 14:19:37 kai Exp $
+/* $Id$
  *
  * ISDN lowlevel-module for the ICN active ISDN-Card.
  *
--- a/drivers/isdn/isdn_audio.c
+++ b/drivers/isdn/isdn_audio.c
@@ -1,9 +1,9 @@
-/* $Id: isdn_audio.c,v 1.1.4.1 2001/11/20 14:19:33 kai Exp $
+/* $Id: isdn_audio.c,v 1.24 2002/08/13 09:57:26 keil Exp $
  *
  * Linux ISDN subsystem, audio conversion and compression (linklevel).
  *
  * Copyright 1994-1999 by Fritz Elfert (fritz@isdn4linux.de)
- * DTMF code (c) 1996 by Christian Mock (cm@kukuruz.ping.at)
+ * DTMF code (c) 1996 by Christian Mock (cm@tahina.priv.at)
  * Silence detection (c) 1998 by Armin Schindler (mac@gismo.telekom.de)
  *
  * This software may be used and distributed according to the terms
@@ -15,7 +15,7 @@
 #include "isdn_audio.h"
 #include "isdn_common.h"
 
-char *isdn_audio_revision = "$Revision: 1.1.4.1 $";
+char *isdn_audio_revision = "$Revision: 1.24 $";
 
 /*
  * Misc. lookup-tables.
@@ -169,19 +169,39 @@ static char isdn_audio_ulaw_to_alaw[] =
 	0x8a, 0x8a, 0x6a, 0x6a, 0xea, 0xea, 0x2a, 0x2a
 };
 
-#define NCOEFF            8     /* number of frequencies to be analyzed       */
-#define DTMF_TRESH     4000     /* above this is dtmf                         */
+#define NCOEFF           16     /* number of frequencies to be analyzed       */
+#define DTMF_TRESH    25000     /* above this is dtmf                         */
 #define SILENCE_TRESH   200     /* below this is silence                      */
+#define H2_TRESH      20000     /* 2nd harmonic                               */
 #define AMP_BITS          9     /* bits per sample, reduced to avoid overflow */
 #define LOGRP             0
 #define HIGRP             1
 
+typedef struct {
+	int grp;                /* low/high group     */
+	int k;                  /* k                  */
+	int k2;                 /* k fuer 2. harmonic */
+} dtmf_t;
+
 /* For DTMF recognition:
  * 2 * cos(2 * PI * k / N) precalculated for all k
  */
 static int cos2pik[NCOEFF] =
 {
-	55813, 53604, 51193, 48591, 38114, 33057, 25889, 18332
+	55812, 29528, 53603, 24032, 51193, 14443, 48590, 6517,
+	38113, -21204, 33057, -32186, 25889, -45081, 18332, -55279
+};
+
+static dtmf_t dtmf_tones[8] =
+{
+	{LOGRP, 0, 1},          /*  697 Hz */
+	{LOGRP, 2, 3},          /*  770 Hz */
+	{LOGRP, 4, 5},          /*  852 Hz */
+	{LOGRP, 6, 7},          /*  941 Hz */
+	{HIGRP, 8, 9},          /* 1209 Hz */
+	{HIGRP, 10, 11},        /* 1336 Hz */
+	{HIGRP, 12, 13},        /* 1477 Hz */
+	{HIGRP, 14, 15}         /* 1633 Hz */
 };
 
 static char dtmf_matrix[4][4] =
@@ -208,7 +228,7 @@ isdn_audio_tlookup(const u_char *table, 
 	:	"memory", "ax");
 #else
 	while (n--)
-		*buff = table[*(unsigned char *)buff], buff++;
+		*buff++ = table[*(unsigned char *)buff];
 #endif
 }
 
@@ -479,18 +499,6 @@ isdn_audio_goertzel(int *sample, modem_i
 			sk2 = sk1;
 			sk1 = sk;
 		}
-		/* Avoid overflows */
-		sk >>= 1;
-		sk2 >>= 1;
-		/* compute |X(k)|**2 */
-		/* report overflows. This should not happen. */
-		/* Comment this out if desired */
-		if (sk < -32768 || sk > 32767)
-			printk(KERN_DEBUG
-			       "isdn_audio: dtmf goertzel overflow, sk=%d\n", sk);
-		if (sk2 < -32768 || sk2 > 32767)
-			printk(KERN_DEBUG
-			       "isdn_audio: dtmf goertzel overflow, sk2=%d\n", sk2);
 		result[k] =
 		    ((sk * sk) >> AMP_BITS) -
 		    ((((cos2pik[k] * sk) >> 15) * sk2) >> AMP_BITS) +
@@ -514,58 +522,28 @@ isdn_audio_eval_dtmf(modem_info * info)
 	int grp[2];
 	char what;
 	char *p;
-	int thresh;
 
 	while ((skb = skb_dequeue(&info->dtmf_queue))) {
 		result = (int *) skb->data;
 		s = info->dtmf_state;
-		grp[LOGRP] = grp[HIGRP] = -1;
+		grp[LOGRP] = grp[HIGRP] = -2;
 		silence = 0;
-		thresh = 0;
-		for (i = 0; i < NCOEFF; i++) {
-			if (result[i] > DTMF_TRESH) {
-				if (result[i] > thresh)
-					thresh = result[i];
-			}
-			else if (result[i] < SILENCE_TRESH)
+		for (i = 0; i < 8; i++) {
+			if ((result[dtmf_tones[i].k] > DTMF_TRESH) &&
+			    (result[dtmf_tones[i].k2] < H2_TRESH))
+				grp[dtmf_tones[i].grp] = (grp[dtmf_tones[i].grp] == -2) ? i : -1;
+			else if ((result[dtmf_tones[i].k] < SILENCE_TRESH) &&
+			      (result[dtmf_tones[i].k2] < SILENCE_TRESH))
 				silence++;
 		}
-		if (silence == NCOEFF)
+		if (silence == 8)
 			what = ' ';
 		else {
-			if (thresh > 0)	{
-				thresh = thresh >> 4;  /* touchtones must match within 12 dB */
-				for (i = 0; i < NCOEFF; i++) {
-					if (result[i] < thresh)
-						continue;  /* ignore */
-					/* good level found. This is allowed only one time per group */
-					if (i < NCOEFF / 2) {
-						/* lowgroup*/
-						if (grp[LOGRP] >= 0) {
-							// Bad. Another tone found. */
-							grp[LOGRP] = -1;
-							break;
-						}
-						else
-							grp[LOGRP] = i;
-					}
-					else { /* higroup */
-						if (grp[HIGRP] >= 0) { // Bad. Another tone found. */
-							grp[HIGRP] = -1;
-							break;
-						}
-						else
-							grp[HIGRP] = i - NCOEFF/2;
-					}
-				}
-				if ((grp[LOGRP] >= 0) && (grp[HIGRP] >= 0)) {
-					what = dtmf_matrix[grp[LOGRP]][grp[HIGRP]];
-					if (s->last != ' ' && s->last != '.')
-						s->last = what;	/* min. 1 non-DTMF between DTMF */
-				} else
-					what = '.';
-			}
-			else
+			if ((grp[LOGRP] >= 0) && (grp[HIGRP] >= 0)) {
+				what = dtmf_matrix[grp[LOGRP]][grp[HIGRP] - 4];
+				if (s->last != ' ' && s->last != '.')
+					s->last = what;	/* min. 1 non-DTMF between DTMF */
+			} else
 				what = '.';
 		}
 		if ((what != s->last) && (what != ' ') && (what != '.')) {
--- a/drivers/isdn/isdn_audio.h
+++ b/drivers/isdn/isdn_audio.h
@@ -1,4 +1,4 @@
-/* $Id: isdn_audio.h,v 1.1.4.1 2001/11/20 14:19:34 kai Exp $
+/* $Id: isdn_audio.h,v 1.10 2001/09/24 13:22:42 kai Exp $
  *
  * Linux ISDN subsystem, audio conversion and compression (linklevel).
  *
@@ -20,7 +20,6 @@ typedef struct adpcm_state {
 
 typedef struct dtmf_state {
 	char last;
-	char llast;
 	int idx;
 	int buf[DTMF_NPOINTS];
 } dtmf_state;
--- a/drivers/isdn/isdn_bsdcomp.c
+++ b/drivers/isdn/isdn_bsdcomp.c
@@ -105,6 +105,14 @@ MODULE_LICENSE("Dual BSD/GPL");
 
 #define DEBUG 1
 
+#ifdef CONFIG_ISDN_WITH_ABC
+#define BSD_C_MALLOC(x)     kmalloc((x),GFP_ATOMIC)
+#define BSD_C_FREE(x)       kfree(x)
+#else
+#define BSD_C_MALLOC(x)     vmalloc(x)
+#define BSD_C_FREE(x)       vfree(x)
+#endif
+
 /*
  * A dictionary for doing BSD compress.
  */
@@ -285,7 +293,7 @@ static void bsd_free (void *state)
 		 * Release the dictionary
 		 */
 		if (db->dict) {
-			vfree (db->dict);
+			BSD_C_FREE (db->dict);
 			db->dict = NULL;
 		}
 
@@ -293,7 +301,7 @@ static void bsd_free (void *state)
 		 * Release the string buffer
 		 */
 		if (db->lens) {
-			vfree (db->lens);
+			BSD_C_FREE (db->lens);
 			db->lens = NULL;
 		}
 
@@ -350,14 +358,19 @@ static void *bsd_alloc (struct isdn_ppp_
 	 * Allocate space for the dictionary. This may be more than one page in
 	 * length.
 	 */
-	db->dict = (struct bsd_dict *) vmalloc (hsize * sizeof (struct bsd_dict));
+	db->dict = (struct bsd_dict *) BSD_C_MALLOC (hsize * sizeof (struct bsd_dict));
+
+	MOD_INC_USE_COUNT;
+	/*
+	** MOD_INC_USE_COUNT must be before bsd_free
+	** bsd_free make MOD_DEC_USE_COUNT if db != NULL
+	*/
+
 	if (!db->dict) {
 		bsd_free (db);
 		return NULL;
 	}
 
-	MOD_INC_USE_COUNT;
-
 	/*
 	 * If this is the compression buffer then there is no length data.
 	 * For decompression, the length information is needed as well.
@@ -365,7 +378,7 @@ static void *bsd_alloc (struct isdn_ppp_
 	if (!decomp)
 		db->lens = NULL;
 	else {
-		db->lens = (unsigned short *) vmalloc ((maxmaxcode + 1) *
+		db->lens = (unsigned short *) BSD_C_MALLOC ((maxmaxcode + 1) *
 			sizeof (db->lens[0]));
 		if (!db->lens) {
 			bsd_free (db); /* calls MOD_DEC_USE_COUNT; */
@@ -478,7 +491,11 @@ static int bsd_compress (void *state, st
 	int hval,disp,ilen,mxcode;
 	unsigned char *rptr = skb_in->data;
 	int isize = skb_in->len;
+#ifdef CONFIG_ISDN_WITH_ABC
+	long secure = 0;
+#endif
 
+#ifndef CONFIG_ISDN_WITH_ABC
 #define OUTPUT(ent)			\
   {					\
     bitno -= n_bits;			\
@@ -490,17 +507,45 @@ static int bsd_compress (void *state, st
 	bitno += 8;			\
     } while (bitno <= 24);		\
   }
+#else
+#define OUTPUT(ent)			\
+  {					\
+  	secure = 0;					\
+    bitno -= n_bits;			\
+    accm |= ((ent) << bitno);		\
+    do	{				\
+        if(skb_out && skb_tailroom(skb_out) > 0) 	\
+      		*(skb_put(skb_out,1)) = (unsigned char) (accm>>24); \
+	accm <<= 8;			\
+	bitno += 8;			\
+	} while (bitno <= 24 && ++secure < 10000);		\
+	if(secure >= 10000) {							\
+		printk(KERN_DEBUG "BSD in OUTPUT secure counter reached\n");	\
+		return 0;									\
+	}												\
+  }
+#endif
 
 	/*
 	 * If the protocol is not in the range we're interested in,
 	 * just return without compressing the packet.  If it is,
 	 * the protocol becomes the first byte to compress.
 	 */
+#ifdef CONFIG_ISDN_WITH_ABC
+	ent = proto;
+
+	if (proto < 0x21 || proto > 0xf9 || !(proto & 0x1) ) {
+
+		printk(KERN_DEBUG "bsd_compress called with %x\n",proto);
+		return 0;
+	}
+#else
 	printk(KERN_DEBUG "bsd_compress called with %x\n",proto);
 	
 	ent = proto;
 	if (proto < 0x21 || proto > 0xf9 || !(proto & 0x1) )
 		return 0;
+#endif
 
 	db      = (struct bsd_db *) state;
 	hshift  = db->hshift;
@@ -538,6 +583,9 @@ static int bsd_compress (void *state, st
 	
 		/* continue probing until a match or invalid entry */
 		disp = (hval == 0) ? 1 : hval;
+#ifdef CONFIG_ISDN_WITH_ABC
+		secure = 0;
+#endif
 
 		do {
 			hval += disp;
@@ -546,7 +594,15 @@ static int bsd_compress (void *state, st
 			dictp = dict_ptr (db, hval);
 			if (dictp->codem1 >= max_ent)
 				goto nomatch;
+#ifndef CONFIG_ISDN_WITH_ABC
 		} while (dictp->fcode != fcode);
+#else
+		} while (dictp->fcode != fcode && ++secure < 100000);
+		if(secure >= 100000) {
+			printk(KERN_DEBUG "BSD: compress while dictp->fcode != fcode secure-counter reached\n");
+			return 0;
+		}
+#endif
 
 		ent = dictp->codem1 + 1;	/* finally found (prefix,suffix) */
 		continue;
@@ -669,6 +725,9 @@ static int bsd_decompress (void *state, 
 	int ilen;
 	int codelen;
 	int extra;
+#ifdef CONFIG_ISDN_WITH_ABC
+	unsigned long secure = 0;
+#endif
 
 	db       = (struct bsd_db *) state;
 	max_ent  = db->max_ent;
@@ -677,7 +736,9 @@ static int bsd_decompress (void *state, 
 	n_bits   = db->n_bits;
 	tgtbitno = 32 - n_bits;	/* bitno when we have a code */
 
+#ifndef CONFIG_ISDN_WITH_ABC
 	printk(KERN_DEBUG "bsd_decompress called\n");
+#endif
 
 	if(!skb_in || !skb_out) {
 		printk(KERN_ERR "bsd_decompress called with NULL parameter\n");
@@ -795,7 +856,11 @@ static int bsd_decompress (void *state, 
 
 		p     = skb_put(skb_out,codelen);
 		p += codelen;
+#ifdef CONFIG_ISDN_WITH_ABC
+		for(secure = 0; finchar > LAST && secure < 50000;secure++) {
+#else
 		while (finchar > LAST) {
+#endif
 			struct bsd_dict *dictp2 = dict_ptr (db, finchar);
 	    
 			dictp = dict_ptr (db, dictp2->cptr);
@@ -822,6 +887,12 @@ static int bsd_decompress (void *state, 
 			}
 		}
 		*--p = finchar;
+#ifdef CONFIG_ISDN_WITH_ABC
+		if(secure >= 50000) {
+			printk(KERN_DEBUG "BSD: decompress secure-counter reached\n");
+			return DECOMP_FATALERROR;
+		}
+#endif
 	
 #ifdef DEBUG
 		if (--codelen != 0)
@@ -851,12 +922,23 @@ static int bsd_decompress (void *state, 
 			/* look for a free hash table entry */
 			if (dictp->codem1 < max_ent) {
 				disp = (hval == 0) ? 1 : hval;
+#ifdef CONFIG_ISDN_WITH_ABC
+				secure = 0;
+#endif
 				do {
 					hval += disp;
 					if (hval >= db->hsize)
 						hval -= db->hsize;
 					dictp = dict_ptr (db, hval);
+#ifndef CONFIG_ISDN_WITH_ABC
 				} while (dictp->codem1 < max_ent);
+#else
+				} while (dictp->codem1 < max_ent && ++secure < 50000);
+				if(secure >= 50000) {
+					printk(KERN_DEBUG "BSD: decomp while (dictp->codem1 < max_ent) secure-counter reached\n");
+					return DECOMP_FATALERROR;
+				}
+#endif
 			}
 	    
 			/*
@@ -895,11 +977,21 @@ static int bsd_decompress (void *state, 
 	db->comp_bytes   += skb_in->len - BSD_OVHD;
 	db->uncomp_bytes += skb_out->len;
 
+#ifdef CONFIG_ISDN_WITH_ABC
+	/*
+	** bsd_check will call bsd_clear 
+	** and so on the internal tables will be cleared.
+	**
+	** I think that's not what we will at this point ?????
+	** For me at works without bsd_check.
+	*/
+#else
 	if (bsd_check(db)) {
 		if (db->debug)
 			printk(KERN_DEBUG "bsd_decomp%d: peer should have cleared dictionary on %d\n",
 				db->unit, db->seqno - 1);
 	}
+#endif
 	return skb_out->len;
 }
 
--- a/drivers/isdn/isdn_common.c
+++ b/drivers/isdn/isdn_common.c
@@ -1,4 +1,4 @@
-/* $Id: isdn_common.c,v 1.1.4.1 2001/11/20 14:19:34 kai Exp $
+/* $Id: isdn_common.c,v 1.137 2002/02/09 21:19:11 keil Exp $
  *
  * Linux ISDN subsystem, common used functions (linklevel).
  *
@@ -19,6 +19,7 @@
 #include <linux/vmalloc.h>
 #include <linux/isdn.h>
 #include <linux/smp_lock.h>
+#include <linux/list.h>
 #include "isdn_common.h"
 #include "isdn_tty.h"
 #include "isdn_net.h"
@@ -33,7 +34,9 @@
 #include <linux/isdn_divertif.h>
 #endif /* CONFIG_ISDN_DIVERSION */
 #include "isdn_v110.h"
+#ifdef HAVE_DEVFS_FS
 #include <linux/devfs_fs_kernel.h>
+#endif /* HAVE_DEVFS_FS */
 
 /* Debugflags */
 #undef ISDN_DEBUG_STATCALLB
@@ -44,7 +47,7 @@ MODULE_LICENSE("GPL");
 
 isdn_dev *dev;
 
-static char *isdn_revision = "$Revision: 1.1.4.1 $";
+static char *isdn_revision = "$Revision: 1.137 $";
 
 extern char *isdn_net_revision;
 extern char *isdn_tty_revision;
@@ -67,19 +70,19 @@ static isdn_divert_if *divert_if; /* = N
 
 static int isdn_writebuf_stub(int, int, const u_char *, int, int);
 static void set_global_features(void);
+#ifdef HAVE_DEVFS_FS
 static void isdn_register_devfs(int);
 static void isdn_unregister_devfs(int);
+#endif /* HAVE_DEVFS_FS */
 static int isdn_wildmat(char *s, char *p);
 
 void
 isdn_lock_drivers(void)
 {
 	int i;
-	isdn_ctrl cmd;
 
-	for (i = 0; i < ISDN_MAX_DRIVERS; i++) {
-		if (!dev->drv[i])
-			continue;
+	for (i = 0; i < dev->drivers; i++) {
+		isdn_ctrl cmd;
 
 		cmd.driver = i;
 		cmd.arg = 0;
@@ -101,10 +104,7 @@ isdn_unlock_drivers(void)
 {
 	int i;
 
-	for (i = 0; i < ISDN_MAX_DRIVERS; i++) {
-		if (!dev->drv[i])
-			continue;
-
+	for (i = 0; i < dev->drivers; i++)
 		if (dev->drv[i]->locks > 0) {
 			isdn_ctrl cmd;
 
@@ -114,7 +114,6 @@ isdn_unlock_drivers(void)
 			isdn_command(&cmd);
 			dev->drv[i]->locks--;
 		}
-	}
 }
 
 void
@@ -473,6 +472,7 @@ isdn_status_callback(isdn_ctrl * c)
 			dev->drv[di]->flags &= ~DRV_FLAG_RUNNING;
 			break;
 		case ISDN_STAT_ICALL:
+		case ISDN_STAT_ICALLW:
 			if (i < 0)
 				return -1;
 #ifdef ISDN_DEBUG_STATCALLB
@@ -718,7 +718,9 @@ isdn_status_callback(isdn_ctrl * c)
 					dev->drvmap[i] = -1;
 					dev->chanmap[i] = -1;
 					dev->usage[i] &= ~ISDN_USAGE_DISABLED;
+#ifdef HAVE_DEVFS_FS
 					isdn_unregister_devfs(i);
+#endif /* HAVE_DEVFS_FS */
 				}
 			dev->drivers--;
 			dev->channels -= dev->drv[di]->channels;
@@ -755,6 +757,10 @@ isdn_status_callback(isdn_ctrl * c)
                         if (divert_if)
                           return(divert_if->stat_callback(c));
 #endif /* CONFIG_ISDN_DIVERSION */
+		case ISDN_STAT_ALERT:
+		case ISDN_STAT_PROCEED:
+			isdn_tty_stat_callback(i, c);
+			break;
 		default:
 			return -1;
 	}
@@ -900,72 +906,239 @@ isdn_minor2chan(int minor)
 	return (dev->chanmap[minor]);
 }
 
-static char *
-isdn_statstr(void)
+// ----------------------------------------------------------------------
+// /dev/isdninfo
+// 
+// This device has somewhat insane semantics, but we need to support
+// them for the sake of compatibility.
+//
+// After opening, the first read will succeed and return the current state
+// Then, unless O_NONBLOCK is set, it will block until a state change happens
+// and then return the new state.
+// Also, if the buffer size for the read is too small, we'll just return
+// EOF
+
+struct isdnstatus_dev {
+	struct list_head list;
+	int update;
+};
+
+static DECLARE_WAIT_QUEUE_HEAD(isdnstatus_waitq);
+static LIST_HEAD(isdnstatus_devs);
+static spinlock_t isdnstatus_devs_lock = SPIN_LOCK_UNLOCKED;
+
+void
+isdn_info_update(void)
+{
+	struct list_head *p;
+	struct isdnstatus_dev *idev;
+
+	spin_lock(&isdnstatus_devs_lock);
+	list_for_each(p, &isdnstatus_devs) {
+		idev = list_entry(p, struct isdnstatus_dev, list);
+		idev->update = 1;
+	}
+	spin_unlock(&isdnstatus_devs_lock);
+	wake_up_interruptible(&isdnstatus_waitq);
+}
+
+static int
+isdnstatus_open(struct inode *ino, struct file *filep)
+{
+	struct isdnstatus_dev *p;
+
+	p = kmalloc(sizeof(struct isdnstatus_dev), GFP_USER);
+	if (!p)
+		return -ENOMEM;
+
+	/* At opening time we allow a single update */
+	p->update = 1;
+	spin_lock(&isdnstatus_devs_lock);
+	list_add(&p->list, &isdnstatus_devs);
+	spin_unlock(&isdnstatus_devs_lock);
+	filep->private_data = p;
+
+	return 0;
+}
+
+static void
+isdnstatus_close(struct inode *ino, struct file *filep)
+{
+	struct isdnstatus_dev *p = filep->private_data;
+
+	spin_lock(&isdnstatus_devs_lock);
+	list_del(&p->list);
+	spin_unlock(&isdnstatus_devs_lock);
+	kfree(p);
+}
+
+// FIXME we don't lock against the state changing whilst being
+// printed
+
+void
+isdn_statstr(char *buf)
 {
-	static char istatbuf[2048];
 	char *p;
 	int i;
 
-	sprintf(istatbuf, "idmap:\t");
-	p = istatbuf + strlen(istatbuf);
+	p = buf;
+	p += sprintf(p, "idmap:\t");
 	for (i = 0; i < ISDN_MAX_CHANNELS; i++) {
-		sprintf(p, "%s ", (dev->drvmap[i] < 0) ? "-" : dev->drvid[dev->drvmap[i]]);
-		p = istatbuf + strlen(istatbuf);
+		p += sprintf(p, "%s ", (dev->drvmap[i] < 0) ? "-" : dev->drvid[dev->drvmap[i]]);
 	}
-	sprintf(p, "\nchmap:\t");
-	p = istatbuf + strlen(istatbuf);
+	p += sprintf(p, "\nchmap:\t");
 	for (i = 0; i < ISDN_MAX_CHANNELS; i++) {
-		sprintf(p, "%d ", dev->chanmap[i]);
-		p = istatbuf + strlen(istatbuf);
+		p += sprintf(p, "%d ", dev->chanmap[i]);
 	}
-	sprintf(p, "\ndrmap:\t");
-	p = istatbuf + strlen(istatbuf);
+	p += sprintf(p, "\ndrmap:\t");
 	for (i = 0; i < ISDN_MAX_CHANNELS; i++) {
-		sprintf(p, "%d ", dev->drvmap[i]);
-		p = istatbuf + strlen(istatbuf);
+		p += sprintf(p, "%d ", dev->drvmap[i]);
 	}
-	sprintf(p, "\nusage:\t");
-	p = istatbuf + strlen(istatbuf);
+	p += sprintf(p, "\nusage:\t");
 	for (i = 0; i < ISDN_MAX_CHANNELS; i++) {
-		sprintf(p, "%d ", dev->usage[i]);
-		p = istatbuf + strlen(istatbuf);
+		p += sprintf(p, "%d ", dev->usage[i]);
 	}
-	sprintf(p, "\nflags:\t");
-	p = istatbuf + strlen(istatbuf);
+	p += sprintf(p, "\nflags:\t");
 	for (i = 0; i < ISDN_MAX_DRIVERS; i++) {
 		if (dev->drv[i]) {
-			sprintf(p, "%ld ", dev->drv[i]->online);
-			p = istatbuf + strlen(istatbuf);
+			p += sprintf(p, "%ld ", dev->drv[i]->online);
 		} else {
-			sprintf(p, "? ");
-			p = istatbuf + strlen(istatbuf);
+			p += sprintf(p, "? ");
 		}
 	}
-	sprintf(p, "\nphone:\t");
-	p = istatbuf + strlen(istatbuf);
+	p += sprintf(p, "\nphone:\t");
 	for (i = 0; i < ISDN_MAX_CHANNELS; i++) {
-		sprintf(p, "%s ", dev->num[i]);
-		p = istatbuf + strlen(istatbuf);
+		p += sprintf(p, "%s ", dev->num[i]);
 	}
-	sprintf(p, "\n");
-	return istatbuf;
+	p += sprintf(p, "\n");
 }
 
-/* Module interface-code */
+static ssize_t
+isdnstatus_read(struct file *file, char *buf, size_t count, loff_t * off)
+{
+	static DECLARE_MUTEX(istatbuf_mutex);
+	static char istatbuf[2048];
 
-void
-isdn_info_update(void)
+        DECLARE_WAITQUEUE(wait, current);
+	struct isdnstatus_dev *idev;
+	int retval = 0;
+	unsigned int len;
+
+	idev = file->private_data;
+
+	if (off != &file->f_pos)
+		return -ESPIPE;
+
+        add_wait_queue(&isdnstatus_waitq, &wait);
+        for (;;) {
+                set_current_state(TASK_INTERRUPTIBLE);
+                
+		if (idev->update)
+                        break;
+
+                retval = -EAGAIN;
+                if (file->f_flags & O_NONBLOCK)
+                        break;
+
+                retval = -ERESTARTSYS;
+                if (signal_pending(current))
+                        break;
+
+                schedule();
+        }
+        __set_current_state(TASK_RUNNING);
+        remove_wait_queue(&isdnstatus_waitq, &wait);
+
+	if (!idev->update)
+		goto out;
+
+	idev->update = 0;
+	down(&istatbuf_mutex);
+	isdn_statstr(istatbuf);
+	len = strlen(istatbuf);
+	if (len > count) {
+		retval = 0;
+		goto out_unlock;
+	}
+	if (copy_to_user(buf, istatbuf, len)) {
+		retval = -EFAULT;
+		goto out_unlock;
+	}
+	*off += len;
+	retval = len;
+
+ out_unlock:
+	up(&istatbuf_mutex);
+ out:
+	return retval;
+}
+
+static ssize_t
+isdnstatus_write(struct file *file, const char *buf, size_t count, loff_t * off)
 {
-	infostruct *p = dev->infochain;
+	return -EINVAL;
+}
+
+static unsigned int
+isdnstatus_poll(struct file *file, poll_table * wait)
+{
+	struct isdnstatus_dev *idev;
+	unsigned int mask = 0;
+
+	idev = file->private_data;
 
-	while (p) {
-		*(p->private) = 1;
-		p = (infostruct *) p->next;
+	poll_wait(file, &isdnstatus_waitq, wait);
+	if (idev->update) {
+		mask |= POLLIN | POLLRDNORM;
 	}
-	wake_up_interruptible(&(dev->info_waitq));
+	return mask;
 }
 
+static int
+isdnstatus_ioctl(struct inode *inode, struct file *file, uint cmd, ulong arg)
+{
+	int retval;
+	isdn_net_ioctl_phone phone;
+
+	switch (cmd) {
+	case IIOCGETDVR:
+		return (TTY_DV +
+			(NET_DV << 8) +
+			(INF_DV << 16));
+	case IIOCGETCPS:
+		if (arg) {
+			ulong *p = (ulong *) arg;
+			int i;
+			if ((retval = verify_area(VERIFY_WRITE, (void *) arg,
+					       sizeof(ulong) * ISDN_MAX_CHANNELS * 2)))
+				return retval;
+			for (i = 0; i < ISDN_MAX_CHANNELS; i++) {
+				put_user(dev->ibytes[i], p++);
+				put_user(dev->obytes[i], p++);
+			}
+			return 0;
+		} else
+			return -EINVAL;
+		break;
+#ifdef CONFIG_NETDEVICES
+	case IIOCNETGPN:
+		/* Get peer phone number of a connected 
+		 * isdn network interface */
+		if (arg) {
+			if (copy_from_user((char *) &phone, (char *) arg, sizeof(phone)))
+				return -EFAULT;
+			return isdn_net_getpeer(&phone, (isdn_net_ioctl_phone *) arg);
+		} else
+			return -EINVAL;
+#endif
+	default:
+		return -EINVAL;
+	}
+}
+
+// ----------------------------------------------------------------------
+
+
 static ssize_t
 isdn_read(struct file *file, char *buf, size_t count, loff_t * off)
 {
@@ -976,37 +1149,16 @@ isdn_read(struct file *file, char *buf, 
 	int chidx;
 	int retval;
 	char *p;
-	loff_t pos = *off;
 
 	if (off != &file->f_pos)
 		return -ESPIPE;
 
-	if (pos != (unsigned) pos)
-		return -EINVAL;
-
+#ifndef COMPAT_HAVE_READ_LOCK_KERNEL
 	lock_kernel();
-	if (minor == ISDN_MINOR_STATUS) {
-		if (!file->private_data) {
-			if (file->f_flags & O_NONBLOCK) {
-				retval = -EAGAIN;
-				goto out;
-			}
-			interruptible_sleep_on(&(dev->info_waitq));
-		}
-		p = isdn_statstr();
-		file->private_data = 0;
-		if ((len = strlen(p)) <= count) {
-			if (copy_to_user(buf, p, len)) {
-				retval = -EFAULT;
-				goto out;
-			}
-			*off = pos + len;
-			retval = len;
-			goto out;
-		}
-		retval = 0;
-		goto out;
-	}
+#endif
+	if (minor == ISDN_MINOR_STATUS)
+		return isdnstatus_read(file, buf, count, off);
+	  
 	if (!dev->drivers) {
 		retval = -ENODEV;
 		goto out;
@@ -1031,7 +1183,7 @@ isdn_read(struct file *file, char *buf, 
 		cli();
 		len = isdn_readbchan(drvidx, chidx, p, 0, count,
 				     &dev->drv[drvidx]->rcv_waitq[chidx]);
-		*off = pos + len;
+		*off += len;
 		restore_flags(flags);
 		if (copy_to_user(buf,p,len)) 
 			len = -EFAULT;
@@ -1052,6 +1204,9 @@ isdn_read(struct file *file, char *buf, 
 			}
 			interruptible_sleep_on(&(dev->drv[drvidx]->st_waitq));
 		}
+#ifdef CONFIG_ISDN_WITH_ABC_LCR_SUPPORT
+		if(drvidx || (len = isdn_dw_abc_lcr_readstat(buf,count)) < 1) {
+#endif
 		if (dev->drv[drvidx]->interface->readstat) {
 			if (count > dev->drv[drvidx]->stavail)
 				count = dev->drv[drvidx]->stavail;
@@ -1065,6 +1220,9 @@ isdn_read(struct file *file, char *buf, 
 		} else {
 			len = 0;
 		}
+#ifdef CONFIG_ISDN_WITH_ABC_LCR_SUPPORT
+		}
+#endif
 		save_flags(flags);
 		cli();
 		if (len)
@@ -1072,7 +1230,7 @@ isdn_read(struct file *file, char *buf, 
 		else
 			dev->drv[drvidx]->stavail = 0;
 		restore_flags(flags);
-		*off = pos + len;
+		*off += len;
 		retval = len;
 		goto out;
 	}
@@ -1084,7 +1242,9 @@ isdn_read(struct file *file, char *buf, 
 #endif
 	retval = -ENODEV;
  out:
+#ifndef COMPAT_HAVE_READ_LOCK_KERNEL
 	unlock_kernel();
+#endif
 	return retval;
 }
 
@@ -1096,15 +1256,18 @@ isdn_write(struct file *file, const char
 	int chidx;
 	int retval;
 
+	if (minor == ISDN_MINOR_STATUS)
+		return isdnstatus_write(file, buf, count, off);
+
 	if (off != &file->f_pos)
 		return -ESPIPE;
 
-	if (minor == ISDN_MINOR_STATUS)
-		return -EPERM;
 	if (!dev->drivers)
 		return -ENODEV;
 
+#ifndef COMPAT_HAVE_WRITE_LOCK_KERNEL
 	lock_kernel();
+#endif
 	if (minor <= ISDN_MINOR_BMAX) {
 		printk(KERN_WARNING "isdn_write minor %d obsolete!\n", minor);
 		drvidx = isdn_minor2drv(minor);
@@ -1149,7 +1312,9 @@ isdn_write(struct file *file, const char
 #endif
 	retval = -ENODEV;
  out:
+#ifndef COMPAT_HAVE_WRITE_LOCK_KERNEL
 	unlock_kernel();
+#endif
 	return retval;
 }
 
@@ -1160,15 +1325,12 @@ isdn_poll(struct file *file, poll_table 
 	unsigned int minor = MINOR(file->f_dentry->d_inode->i_rdev);
 	int drvidx = isdn_minor2drv(minor - ISDN_MINOR_CTRL);
 
+#ifndef COMPAT_HAVE_POLL_LOCK_KERNEL
 	lock_kernel();
-	if (minor == ISDN_MINOR_STATUS) {
-		poll_wait(file, &(dev->info_waitq), wait);
-		/* mask = POLLOUT | POLLWRNORM; */
-		if (file->private_data) {
-			mask |= POLLIN | POLLRDNORM;
-		}
-		goto out;
-	}
+#endif
+	if (minor == ISDN_MINOR_STATUS)
+ 		return isdnstatus_poll(file, wait);
+
 	if (minor >= ISDN_MINOR_CTRL && minor <= ISDN_MINOR_CTRLMAX) {
 		if (drvidx < 0) {
 			/* driver deregistered while file open */
@@ -1190,7 +1352,9 @@ isdn_poll(struct file *file, poll_table 
 #endif
 	mask = POLLERR;
  out:
+#ifndef COMPAT_HAVE_POLL_LOCK_KERNEL
 	unlock_kernel();
+#endif
 	return mask;
 }
 
@@ -1220,42 +1384,9 @@ isdn_ioctl(struct inode *inode, struct f
 #define phone iocpar.phone
 #define cfg   iocpar.cfg
 
-	if (minor == ISDN_MINOR_STATUS) {
-		switch (cmd) {
-			case IIOCGETDVR:
-				return (TTY_DV +
-					(NET_DV << 8) +
-					(INF_DV << 16));
-			case IIOCGETCPS:
-				if (arg) {
-					ulong *p = (ulong *) arg;
-					int i;
-					if ((ret = verify_area(VERIFY_WRITE, (void *) arg,
-							       sizeof(ulong) * ISDN_MAX_CHANNELS * 2)))
-						return ret;
-					for (i = 0; i < ISDN_MAX_CHANNELS; i++) {
-						put_user(dev->ibytes[i], p++);
-						put_user(dev->obytes[i], p++);
-					}
-					return 0;
-				} else
-					return -EINVAL;
-				break;
-#ifdef CONFIG_NETDEVICES
-			case IIOCNETGPN:
-				/* Get peer phone number of a connected 
-				 * isdn network interface */
-				if (arg) {
-					if (copy_from_user((char *) &phone, (char *) arg, sizeof(phone)))
-						return -EFAULT;
-					return isdn_net_getpeer(&phone, (isdn_net_ioctl_phone *) arg);
-				} else
-					return -EINVAL;
-#endif
-			default:
-				return -EINVAL;
-		}
-	}
+	if (minor == ISDN_MINOR_STATUS)
+		return isdnstatus_ioctl(inode, file, cmd, arg);
+
 	if (!dev->drivers)
 		return -ENODEV;
 	if (minor <= ISDN_MINOR_BMAX) {
@@ -1277,11 +1408,34 @@ isdn_ioctl(struct inode *inode, struct f
  */
 		switch (cmd) {
 			case IIOCNETDWRSET:
+#ifdef CONFIG_ISDN_WITH_ABC
+				if (arg) {
+
+					if (copy_from_user(name, (char *) arg, sizeof(name))) {
+
+						return(-EFAULT);
+
+					} else {
+
+						isdn_net_dev *p = isdn_net_findif(name);
+
+						if(p == NULL)
+							return(-EINVAL);
+
+						return(isdn_dw_abc_reset_interface(p->local,1));
+					}
+				} 
+#else
 				printk(KERN_INFO "INFO: ISDN_DW_ABC_EXTENSION not enabled\n");
+#endif
 				return(-EINVAL);
 			case IIOCNETLCR:
+#ifdef CONFIG_ISDN_WITH_ABC_LCR_SUPPORT
+				return(isdn_dw_abc_lcr_ioctl(arg));
+#else
 				printk(KERN_INFO "INFO: ISDN_ABC_LCR_SUPPORT not enabled\n");
 				return -ENODEV;
+#endif
 #ifdef CONFIG_NETDEVICES
 			case IIOCNETAIF:
 				/* Add a network-interface */
@@ -1657,22 +1811,12 @@ isdn_open(struct inode *ino, struct file
 	int chidx;
 	int retval = -ENODEV;
 
+#ifdef COMPAT_USE_MODCOUNT_LOCK
+	MOD_INC_USE_COUNT;
+#endif
 
 	if (minor == ISDN_MINOR_STATUS) {
-		infostruct *p;
-
-		if ((p = kmalloc(sizeof(infostruct), GFP_KERNEL))) {
-			p->next = (char *) dev->infochain;
-			p->private = (char *) &(filep->private_data);
-			dev->infochain = p;
-			/* At opening we allow a single update */
-			filep->private_data = (char *) 1;
-			retval = 0;
-			goto out;
-		} else {
-			retval = -ENOMEM;
-			goto out;
-		}
+		return isdnstatus_open(ino, filep);
 	}
 	if (!dev->channels)
 		goto out;
@@ -1695,6 +1839,9 @@ isdn_open(struct inode *ino, struct file
 		if (drvidx < 0)
 			goto out;
 		isdn_lock_drivers();
+#ifdef CONFIG_ISDN_WITH_ABC_LCR_SUPPORT
+		if(!drvidx) isdn_dw_abc_lcr_open();
+#endif
 		retval = 0;
 		goto out;
 	}
@@ -1707,6 +1854,10 @@ isdn_open(struct inode *ino, struct file
 	}
 #endif
  out:
+#ifdef COMPAT_USE_MODCOUNT_LOCK
+	if (retval)
+		MOD_DEC_USE_COUNT;
+#endif
 	return retval;
 }
 
@@ -1715,25 +1866,11 @@ isdn_close(struct inode *ino, struct fil
 {
 	uint minor = MINOR(ino->i_rdev);
 
+#ifndef COMPAT_USE_MODCOUNT_LOCK
 	lock_kernel();
+#endif
 	if (minor == ISDN_MINOR_STATUS) {
-		infostruct *p = dev->infochain;
-		infostruct *q = NULL;
-
-		while (p) {
-			if (p->private == (char *) &(filep->private_data)) {
-				if (q)
-					q->next = p->next;
-				else
-					dev->infochain = (infostruct *) (p->next);
-				kfree(p);
-				goto out;
-			}
-			q = p;
-			p = (infostruct *) (p->next);
-		}
-		printk(KERN_WARNING "isdn: No private data while closing isdnctrl\n");
-		goto out;
+		isdnstatus_close(ino, filep);
 	}
 	isdn_unlock_drivers();
 	if (minor <= ISDN_MINOR_BMAX)
@@ -1741,6 +1878,12 @@ isdn_close(struct inode *ino, struct fil
 	if (minor <= ISDN_MINOR_CTRLMAX) {
 		if (dev->profd == current)
 			dev->profd = NULL;
+#ifdef CONFIG_ISDN_WITH_ABC_LCR_SUPPORT
+		{
+			int drvidx = isdn_minor2drv(minor - ISDN_MINOR_CTRL);
+			if(!drvidx) isdn_dw_abc_lcr_close();
+		}
+#endif
 		goto out;
 	}
 #ifdef CONFIG_ISDN_PPP
@@ -1749,13 +1892,19 @@ isdn_close(struct inode *ino, struct fil
 #endif
 
  out:
+#ifdef COMPAT_USE_MODCOUNT_LOCK
+	MOD_DEC_USE_COUNT;
+#else
 	unlock_kernel();
+#endif
 	return 0;
 }
 
 static struct file_operations isdn_fops =
 {
+#ifdef COMPAT_HAS_FILEOP_OWNER
 	owner:		THIS_MODULE,
+#endif
 	llseek:		no_llseek,
 	read:		isdn_read,
 	write:		isdn_write,
@@ -1808,6 +1957,15 @@ isdn_get_free_channel(int usage, int l2_
 		if (USG_NONE(dev->usage[i]) &&
 		    (dev->drvmap[i] != -1)) {
 			int d = dev->drvmap[i];
+#ifdef CONFIG_ISDN_WITH_ABC_CH_EXTINUSE
+			if(jiffies < dev->dwabc_chan_external_inuse[i]) {
+
+				if((dev->dwabc_chan_external_inuse[i] - jiffies) > (HZ * 120))
+					dev->dwabc_chan_external_inuse[i] = 0;
+				else 
+					continue;
+			}
+#endif
 			if ((dev->usage[i] & ISDN_USAGE_EXCLUSIVE) &&
 			((pre_dev != d) || (pre_chan != dev->chanmap[i])))
 				continue;
@@ -1826,7 +1984,11 @@ isdn_get_free_channel(int usage, int l2_
 						restore_flags(flags);
 						return i;
 					} else {
+#ifdef CONFIG_ISDN_WITH_ABC
+						if ((pre_dev == d) && ((pre_chan == dev->chanmap[i]) || pre_chan > 1000)) {
+#else
 						if ((pre_dev == d) && (pre_chan == dev->chanmap[i])) {
+#endif
 							dev->usage[i] &= ISDN_USAGE_EXCLUSIVE;
 							dev->usage[i] |= usage;
 							isdn_info_update();
@@ -2013,7 +2175,7 @@ isdn_add_channels(driver *d, int drvidx,
 
 	if ((adding) && (d->rcverr))
 		kfree(d->rcverr);
-	if (!(d->rcverr = kmalloc(sizeof(int) * m, GFP_KERNEL))) {
+	if (!(d->rcverr = (int *) kmalloc(sizeof(int) * m, GFP_KERNEL))) {
 		printk(KERN_WARNING "register_isdn: Could not alloc rcverr\n");
 		return -1;
 	}
@@ -2021,7 +2183,7 @@ isdn_add_channels(driver *d, int drvidx,
 
 	if ((adding) && (d->rcvcount))
 		kfree(d->rcvcount);
-	if (!(d->rcvcount = kmalloc(sizeof(int) * m, GFP_KERNEL))) {
+	if (!(d->rcvcount = (int *) kmalloc(sizeof(int) * m, GFP_KERNEL))) {
 		printk(KERN_WARNING "register_isdn: Could not alloc rcvcount\n");
 		if (!adding) kfree(d->rcverr);
 		return -1;
@@ -2033,7 +2195,8 @@ isdn_add_channels(driver *d, int drvidx,
 			skb_queue_purge(&d->rpqueue[j]);
 		kfree(d->rpqueue);
 	}
-	if (!(d->rpqueue = kmalloc(sizeof(struct sk_buff_head) * m, GFP_KERNEL))) {
+	if (!(d->rpqueue =
+	      (struct sk_buff_head *) kmalloc(sizeof(struct sk_buff_head) * m, GFP_KERNEL))) {
 		printk(KERN_WARNING "register_isdn: Could not alloc rpqueue\n");
 		if (!adding) {
 			kfree(d->rcvcount);
@@ -2047,7 +2210,8 @@ isdn_add_channels(driver *d, int drvidx,
 
 	if ((adding) && (d->rcv_waitq))
 		kfree(d->rcv_waitq);
-	d->rcv_waitq = kmalloc(sizeof(wait_queue_head_t) * 2 * m, GFP_KERNEL);
+	d->rcv_waitq = (wait_queue_head_t *)
+		kmalloc(sizeof(wait_queue_head_t) * 2 * m, GFP_KERNEL);
 	if (!d->rcv_waitq) {
 		printk(KERN_WARNING "register_isdn: Could not alloc rcv_waitq\n");
 		if (!adding) {
@@ -2071,7 +2235,9 @@ isdn_add_channels(driver *d, int drvidx,
 			if (dev->chanmap[k] < 0) {
 				dev->chanmap[k] = j;
 				dev->drvmap[k] = drvidx;
+#ifdef HAVE_DEVFS_FS
 				isdn_register_devfs(k);
+#endif /* HAVE_DEVFS_FS */
 				break;
 			}
 	restore_flags(flags);
@@ -2135,6 +2301,7 @@ int DIVERT_REG_NAME(isdn_divert_if *i_di
         i_div->ll_cmd = isdn_command; /* set command function */
         i_div->drv_to_name = map_drvname; 
         i_div->name_to_drv = map_namedrv; 
+        i_div->dial_net_name = isdn_net_force_dial; 
         MOD_INC_USE_COUNT;
         divert_if = i_div; /* remember interface */
         return(DIVERT_NO_ERR);
@@ -2172,7 +2339,7 @@ register_isdn(isdn_if * i)
 		printk(KERN_WARNING "register_isdn: No write routine given.\n");
 		return 0;
 	}
-	if (!(d = kmalloc(sizeof(driver), GFP_KERNEL))) {
+	if (!(d = (driver *) kmalloc(sizeof(driver), GFP_KERNEL))) {
 		printk(KERN_WARNING "register_isdn: Could not alloc driver-struct\n");
 		return 0;
 	}
@@ -2232,6 +2399,7 @@ isdn_getrev(const char *revision)
 	return rev;
 }
 
+#ifdef HAVE_DEVFS_FS
 #ifdef CONFIG_DEVFS_FS
 
 static devfs_handle_t devfs_handle;
@@ -2321,6 +2489,7 @@ static void isdn_cleanup_devfs(void)
 }
 
 #endif  /* CONFIG_DEVFS_FS */
+#endif /* HAVE_DEVFS_FS */
 
 /*
  * Allocate and initialize all data, register modem-devices
@@ -2338,7 +2507,6 @@ static int __init isdn_init(void)
 	init_timer(&dev->timer);
 	dev->timer.function = isdn_timer_funct;
 	init_MUTEX(&dev->sem);
-	init_waitqueue_head(&dev->info_waitq);
 	for (i = 0; i < ISDN_MAX_CHANNELS; i++) {
 		dev->drvmap[i] = -1;
 		dev->chanmap[i] = -1;
@@ -2352,7 +2520,9 @@ static int __init isdn_init(void)
 		vfree(dev);
 		return -EIO;
 	}
+#ifdef HAVE_DEVFS_FS
 	isdn_init_devfs();
+#endif /* HAVE_DEVFS_FS */
 	if ((i = isdn_tty_modem_init()) < 0) {
 		printk(KERN_WARNING "isdn: Could not register tty devices\n");
 		if (i == -3)
@@ -2360,7 +2530,9 @@ static int __init isdn_init(void)
 		if (i <= -2)
 			tty_unregister_driver(&dev->mdm.tty_modem);
 		vfree(dev);
+#ifdef HAVE_DEVFS_FS
 		isdn_cleanup_devfs();
+#endif /* HAVE_DEVFS_FS */
 		devfs_unregister_chrdev(ISDN_MAJOR, "isdn");
 		return -EIO;
 	}
@@ -2371,7 +2543,9 @@ static int __init isdn_init(void)
 		tty_unregister_driver(&dev->mdm.cua_modem);
 		for (i = 0; i < ISDN_MAX_CHANNELS; i++)
 			kfree(dev->mdm.info[i].xmit_buf - 4);
+#ifdef HAVE_DEVFS_FS
 		isdn_cleanup_devfs();
+#endif /* HAVE_DEVFS_FS */
 		devfs_unregister_chrdev(ISDN_MAJOR, "isdn");
 		vfree(dev);
 		return -EIO;
@@ -2397,6 +2571,9 @@ static int __init isdn_init(void)
 	printk("\n");
 #endif
 	isdn_info_update();
+#ifdef CONFIG_ISDN_WITH_ABC
+	isdn_dw_abc_init_func();
+#endif
 	return 0;
 }
 
@@ -2405,7 +2582,7 @@ static int __init isdn_init(void)
  */
 static void __exit isdn_exit(void)
 {
-	unsigned long flags;
+	int flags;
 	int i;
 
 #ifdef CONFIG_ISDN_PPP
@@ -2439,13 +2616,18 @@ static void __exit isdn_exit(void)
 		printk(KERN_WARNING "isdn: controldevice busy, remove cancelled\n");
 		restore_flags(flags);
 	} else {
+#ifdef HAVE_DEVFS_FS
 		isdn_cleanup_devfs();
+#endif /* HAVE_DEVFS_FS */
 		del_timer(&dev->timer);
 		restore_flags(flags);
 		/* call vfree with interrupts enabled, else it will hang */
 		vfree(dev);
 		printk(KERN_NOTICE "ISDN-subsystem unloaded\n");
 	}
+#ifdef CONFIG_ISDN_WITH_ABC
+	isdn_dw_abc_release_func();
+#endif
 }
 
 module_init(isdn_init);
--- a/drivers/isdn/isdn_common.h
+++ b/drivers/isdn/isdn_common.h
@@ -1,4 +1,4 @@
-/* $Id: isdn_common.h,v 1.1.4.1 2001/11/20 14:19:34 kai Exp $
+/* $Id: isdn_common.h,v 1.22 2001/09/24 13:22:42 kai Exp $
  *
  * header for Linux ISDN subsystem
  * common used functions and debugging-switches (linklevel).
@@ -24,6 +24,9 @@
 #undef  ISDN_DEBUG_NET_DIAL
 #undef  ISDN_DEBUG_NET_ICALL
 
+#ifdef CONFIG_ISDN_WITH_ABC
+int isdn_net_force_dial_lp(isdn_net_local *);
+#endif
 /* Prototypes */
 extern void isdn_MOD_INC_USE_COUNT(void);
 extern void isdn_MOD_DEC_USE_COUNT(void);
--- a/drivers/isdn/isdn_concap.c
+++ b/drivers/isdn/isdn_concap.c
@@ -1,4 +1,4 @@
-/* $Id: isdn_concap.c,v 1.1.4.1 2001/11/20 14:19:34 kai Exp $
+/* $Id: isdn_concap.c,v 1.9 2001/09/24 13:22:42 kai Exp $
  * 
  * Linux ISDN subsystem, protocol encapsulation
  *
--- a/drivers/isdn/isdn_concap.h
+++ b/drivers/isdn/isdn_concap.h
@@ -1,4 +1,4 @@
-/* $Id: isdn_concap.h,v 1.1.4.1 2001/11/20 14:19:34 kai Exp $
+/* $Id: isdn_concap.h,v 1.4 2001/09/24 13:22:42 kai Exp $
  *
  * Linux ISDN subsystem, protocol encapsulation
  *
--- /dev/null
+++ b/drivers/isdn/isdn_dwabc.c
@@ -0,0 +1,1053 @@
+
+/* $Id: isdn_dwabc.c,v 1.27 2001/12/01 23:18:21 detabc Exp $
+
+ * Linux ISDN subsystem, abc-extension releated funktions.
+ *
+ * Copyright           by abc GmbH
+ *                     written by Detlef Wengorz <detlefw@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.
+ *
+ */
+
+#include <linux/config.h>
+#define __NO_VERSION__
+
+#ifdef CONFIG_ISDN_WITH_ABC
+
+static char *dwabcrevison = "$Revision: 1.27 $";
+
+#include <asm/semaphore.h>
+#define CONFIG_ISDN_WITH_ABC_NEED_DWSJIFFIES 	1
+#include <linux/list.h>
+#include <linux/isdn.h>
+#include "isdn_common.h"
+#include "isdn_net.h"
+
+#include <linux/skbuff.h>
+
+#include <net/udp.h>
+#include <net/checksum.h>
+#include <linux/isdn_dwabc.h>
+
+
+#if CONFIG_ISDN_WITH_ABC_RAWIPCOMPRESS && CONFIG_ISDN_PPP
+#include <linux/isdn_ppp.h>
+extern struct isdn_ppp_compressor *isdn_ippp_comp_head;
+#define ipc_head isdn_ippp_comp_head
+#ifndef CI_BSD_COMPRESS
+#define CI_BSD_COMPRESS 21
+#endif
+#endif
+
+#define NBYTEORDER_30BYTES      0x1e00 
+#define DWABC_TMRES (HZ / 10)
+
+#define VERBLEVEL (dev->net_verbose > 2)
+
+static struct timer_list dw_abc_timer;
+
+
+#ifdef CONFIG_ISDN_WITH_ABC_LCR_SUPPORT
+static ISDN_DWSPINLOCK lcr_spin = ISDN_DWSPIN_UNLOCKED;
+#define LCR_LOCK() isdn_dwspin_trylock(&lcr_spin)
+#define LCR_ULOCK() isdn_dwspin_unlock(&lcr_spin)
+
+typedef struct ISDN_DW_ABC_LCR {
+
+	struct list_head dll;
+	char lcr_printbuf[64 + ISDN_MSNLEN + ISDN_MSNLEN];
+	char *lcr_poin;
+	char *lcr_epoin;
+
+} ISDN_DW_ABC_LCR;
+
+static LIST_HEAD(lcr_dll);
+static atomic_t lcr_open_count		=	ATOMIC_INIT(0);
+static volatile  ulong lcr_call_counter	= 0;
+
+
+static int myjiftime(char *p,u_long nj)
+{
+	sprintf(p,"%02ld:%02ld.%02ld",
+		((nj / 100) / 60) % 100, (nj / 100) % 60,nj % 100);
+
+	return(8);
+}
+
+
+static void dw_lcr_clear_all(void)
+{
+	struct list_head *lh;
+
+	if(!LCR_LOCK()) {
+
+		while((lh = lcr_dll.next) != &lcr_dll) {
+
+			ISDN_DW_ABC_LCR *p = list_entry(lh,ISDN_DW_ABC_LCR,dll);
+			list_del(&p->dll);
+			kfree(p);
+		}
+
+		LCR_ULOCK();
+	}
+}
+
+void isdn_dw_abc_lcr_open(void) 
+{ atomic_inc(&lcr_open_count); }
+
+void isdn_dw_abc_lcr_close(void) 
+{ 
+	if(atomic_dec_and_test(&lcr_open_count))
+		dw_lcr_clear_all();
+}
+
+int isdn_dw_abc_lcr_lock(void) 
+{ return(LCR_LOCK()); }
+
+void isdn_dw_abc_lcr_ulock(void) 
+{ LCR_ULOCK(); }
+
+
+size_t isdn_dw_abc_lcr_readstat(char *buf,size_t count) 
+{
+	size_t  retw = 0;
+
+	while(buf != NULL && count > 0) {
+
+		struct list_head *lh = NULL;
+		ISDN_DW_ABC_LCR *p = NULL;
+		char *dp = NULL;
+		size_t  n;
+
+		if((n = LCR_LOCK())) {
+
+			if(!retw)
+				retw = n;
+
+			break;
+		}
+
+
+		while((lh = lcr_dll.next) != &lcr_dll) {
+
+			p = list_entry(lh,ISDN_DW_ABC_LCR,dll);
+
+			if(p->lcr_poin >= p->lcr_epoin) {
+
+				list_del(&p->dll);
+				kfree(p);
+				p = NULL;
+
+			} else break;
+		}
+
+		if(p == NULL) {
+				
+			LCR_ULOCK();
+			break;
+		}
+
+		n = p->lcr_epoin - p->lcr_poin;
+
+		if(n > count)
+			n = count;
+
+		dp = p->lcr_poin;
+		p->lcr_poin += n;
+		retw += n;
+		LCR_ULOCK();
+		copy_to_user(buf,dp,n);
+		buf += n;
+	}
+
+	return(retw);
+}
+
+
+static void isdn_dw_abc_lcr_clear_helper(isdn_net_local *lp)
+{
+	if(lp != NULL) {
+
+		void *a,*b;
+
+		a = lp->dw_abc_lcr_cmd;  
+		b = lp->dw_abc_lcr_io;
+		lp->dw_abc_lcr_io = NULL;
+		lp->dw_abc_lcr_cmd = NULL;
+		lp->dw_abc_lcr_callid = 
+		lp->dw_abc_lcr_start_request =
+		lp->dw_abc_lcr_end_request = 0;
+		
+		if(a) kfree(a);
+		if(b) kfree(b);
+	}
+}
+
+void isdn_dw_abc_lcr_clear(isdn_net_local *lp)
+{
+	if(!LCR_LOCK()) {
+		isdn_dw_abc_lcr_clear_helper(lp);
+		LCR_ULOCK();
+	}
+}
+
+
+u_long isdn_dw_abc_lcr_call_number( isdn_net_local *lp,isdn_ctrl *call_cmd)
+{
+	u_long mid = 0;
+
+	if(LCR_LOCK())
+		return(0);
+
+	isdn_dw_abc_lcr_clear_helper(lp);
+
+	if( atomic_read(&lcr_open_count) > 0 && 
+		lp != NULL 						&& 
+		call_cmd != NULL) {
+
+		ISDN_DW_ABC_LCR  *lc = NULL;
+		int ab = 0;
+
+		if((lp->dw_abc_lcr_cmd = 
+			( isdn_ctrl *)kmalloc(sizeof(isdn_ctrl),GFP_ATOMIC)) == NULL) {
+
+no_mem_out:;
+			isdn_dw_abc_lcr_clear_helper(lp);
+			LCR_ULOCK();
+			printk(KERN_DEBUG "%s %d : LCR no memory\n",__FILE__,__LINE__);
+			return(0);
+		}
+
+		memcpy(lp->dw_abc_lcr_cmd,call_cmd,sizeof(*call_cmd));
+		while(!(lp->dw_abc_lcr_callid = mid = lcr_call_counter++));
+		
+		lp->dw_abc_lcr_end_request = lp->dw_abc_lcr_start_request = jiffies;
+		lp->dw_abc_lcr_end_request += HZ * 3;
+
+		if((lc = (ISDN_DW_ABC_LCR  *)kmalloc(sizeof(*lc),GFP_KERNEL)) == NULL)
+			goto no_mem_out;
+
+		lc->lcr_poin = lc->lcr_epoin = lc->lcr_printbuf;
+		lc->lcr_epoin += myjiftime(lc->lcr_epoin,jiffies);
+
+		sprintf(lc->lcr_epoin," DW_ABC_LCR\t%lu\t%.*s\t%.*s\n",
+			mid,
+			(int)ISDN_MSNLEN,
+			call_cmd->parm.setup.eazmsn,
+			(int)ISDN_MSNLEN,
+			call_cmd->parm.setup.phone);
+
+		lc->lcr_epoin += strlen(lc->lcr_epoin);
+		ab = lc->lcr_epoin - lc->lcr_poin;
+
+		list_add_tail(&lc->dll,&lcr_dll);
+		LCR_ULOCK();
+
+		if(ab > 0) {
+
+			if(dev->drv[0] != NULL ) {
+
+				dev->drv[0]->stavail += ab;
+				wake_up_interruptible(&dev->drv[0]->st_waitq);
+			}
+		}
+
+	} else LCR_ULOCK();
+
+	return(mid);
+}
+
+
+int isdn_dw_abc_lcr_ioctl(u_long arg)
+{
+	struct ISDN_DWABC_LCR_IOCTL	i;
+	int need = sizeof(struct ISDN_DWABC_LCR_IOCTL); 
+	isdn_net_dev *p; 
+
+	memset(&i,0,sizeof(struct ISDN_DWABC_LCR_IOCTL));
+	copy_from_user(&i,(char *)arg,sizeof(int));
+
+	if(i.lcr_ioctl_sizeof < need)
+		need = i.lcr_ioctl_sizeof;
+
+	if(need > 0) 
+		copy_from_user(&i,(char *)arg,need);
+
+	 if(LCR_LOCK())
+	 	return(-EAGAIN);
+
+	 p = dev->netdev; 
+
+	 for(;p ; p = p->next) {
+
+	 	isdn_net_local *lp = p->local;
+
+	 	if(	lp->dw_abc_lcr_callid != i.lcr_ioctl_callid)
+			continue;
+
+		if(lp->dw_abc_lcr_cmd == NULL) 
+			continue;
+
+		if(lp->dw_abc_lcr_io == NULL)
+			lp->dw_abc_lcr_io = (struct ISDN_DWABC_LCR_IOCTL *)
+				kmalloc(sizeof(struct ISDN_DWABC_LCR_IOCTL),GFP_ATOMIC);
+
+		if(lp->dw_abc_lcr_io == NULL) {
+
+			printk(KERN_DEBUG "%s %d : no memory\n",__FILE__,__LINE__);
+			continue;
+		}
+
+		memcpy(lp->dw_abc_lcr_io,&i,sizeof(struct ISDN_DWABC_LCR_IOCTL));
+
+		if(i.lcr_ioctl_flags & DWABC_LCR_FLG_NEWNUMBER) {
+
+			char *xx = i.lcr_ioctl_nr;
+			char *exx = xx + sizeof(i.lcr_ioctl_nr);
+			char *d = lp->dw_abc_lcr_cmd->parm.setup.phone;
+			char *ed = d + sizeof(lp->dw_abc_lcr_cmd->parm.setup.phone) - 1;
+
+			while(d < ed && xx < exx && *xx) *(d++) = *(xx++);
+			while(d < ed) *(d++) = 0;
+			*d = 0;
+		}
+	 }
+
+	 LCR_ULOCK();
+	 return(0);
+}
+
+#endif
+
+
+#ifdef CONFIG_ISDN_WITH_ABC_UDP_CHECK
+int dw_abc_udp_test(struct sk_buff *skb,struct net_device *ndev)
+{
+	if(ndev != NULL && skb != NULL && skb->protocol == htons(ETH_P_IP)) {
+
+		struct iphdr *iph = (struct iphdr *)skb->data;
+		isdn_net_local *lp = (isdn_net_local *) ndev->priv;
+		int rklen = skb->len;
+
+		if (skb->nh.raw > skb->data && skb->nh.raw < skb->tail) {
+
+			rklen -= (char *)skb->nh.raw - (char *)skb->data;
+			iph = (struct iphdr *)skb->nh.raw;
+		}
+
+		if(rklen >= 20 && iph->version == 4 && 
+			!(lp->dw_abc_flags & ISDN_DW_ABC_FLAG_NO_UDP_CHECK)) {
+
+			if(	iph->tot_len == NBYTEORDER_30BYTES	&& 
+				iph->protocol == IPPROTO_UDP) {
+
+				struct udphdr *udp = 
+					(struct udphdr *)((char *)iph + (iph->ihl << 2));
+
+				ushort usrc = ntohs(udp->source);
+
+				if(	udp->dest == htons(25001) && 
+					usrc >= 20000 && usrc < 25000) {
+
+					char *p = (char *)(udp + 1);
+
+					if(p[0] == p[1]) {
+
+						char mc = 0;
+
+						switch(*p) {
+						case 0x30:
+
+							mc = *p;
+
+							if((lp->flags & ISDN_NET_CONNECTED) && (!lp->dialstate))
+								mc++;
+
+							break;
+
+						case 0x32:
+
+							mc = *p;
+#ifdef CONFIG_ISDN_WITH_ABC_UDP_CHECK_DIAL
+							if((lp->flags & ISDN_NET_CONNECTED) && (!lp->dialstate)) {
+
+								mc++;
+								break;
+							}
+
+							if(!isdn_net_force_dial_lp(lp)) mc++;
+#endif
+							break;
+
+						case 0x11:
+							mc = *p + 1;
+							isdn_dw_abc_reset_interface(lp,1);
+							break;
+
+						case 0x28:	mc = *p + 1;	break;
+						case 0x2a:
+						case 0x2c:
+
+							mc = *p;
+#ifdef CONFIG_ISDN_WITH_ABC_UDP_CHECK_HANGUP
+							if(!(lp->dw_abc_flags & ISDN_DW_ABC_FLAG_NO_UDP_HANGUP)) {
+
+								if(lp->isdn_device >= 0) {
+
+									isdn_net_hangup(ndev);
+									mc = *p + 1;
+								}
+							}
+#endif
+							break;
+						}
+
+						if(mc) {
+
+							struct sk_buff *nskb;
+							int need = 2+sizeof(struct iphdr)+sizeof(struct udphdr);
+							int hneed = need + ndev->hard_header_len;
+
+							if((nskb = (struct sk_buff *)dev_alloc_skb(hneed)) != NULL) {
+
+								ushort n = sizeof(struct udphdr) + 2;
+								struct iphdr *niph;
+								struct udphdr *nup;
+								skb_reserve(nskb,ndev->hard_header_len);
+
+								if((niph = (struct iphdr *)skb_put(nskb,need))==NULL){
+
+									printk(KERN_DEBUG "%s: skb_put failt (%d bytes)\n", lp->name,hneed);
+									dev_kfree_skb(nskb);
+									return(0);
+								}
+
+								nup = (struct udphdr *)(niph + 1);
+								((char *)(nup + 1))[0] = mc;
+								((char *)(nup + 1))[1] = mc;
+								nup->source=udp->dest;
+								nup->dest=udp->source;
+								nup->len=htons(n);
+								nup->check=0; /* dont need checksum */
+								memset((void *)niph,0,sizeof(*niph));
+								niph->version=4;
+								niph->ihl=5;
+								niph->tot_len=NBYTEORDER_30BYTES;
+								niph->ttl = 32;
+								niph->protocol = IPPROTO_UDP;
+								niph->saddr=iph->daddr;
+								niph->daddr=iph->saddr;
+								niph->id=iph->id;
+								niph->check=ip_fast_csum((unsigned char *)niph,niph->ihl);
+								nskb->dev = ndev;
+								nskb->pkt_type = PACKET_HOST;
+								nskb->protocol = htons(ETH_P_IP);
+								nskb->mac.raw = nskb->data;
+								netif_rx(nskb);
+							}
+
+							return(1);
+						}
+					}
+				}
+			}
+		}
+	}
+
+	return(0);
+}
+#endif
+
+
+void isdn_dw_clear_if(ulong pm,isdn_net_local *lp)
+{
+	if(lp != NULL) {
+#ifdef CONFIG_ISDN_WITH_ABC_LCR_SUPPORT
+		isdn_dw_abc_lcr_clear(lp);
+#endif
+	}
+}
+
+
+
+static void dw_abc_timer_func(u_long dont_need_yet)
+{
+	register u_long t;
+
+	if(!((t = ++isdn_dwabc_jiffies.msec_100) & 1))
+		if(isdn_dwabc_jiffies.msec_200++ & 1)
+			isdn_dwabc_jiffies.msec_400++;
+	
+	if(!(t % 5)) 
+		if(isdn_dwabc_jiffies.msec_500++ & 1)
+			isdn_dwabc_jiffies.msec_1000++;
+
+	dw_abc_timer.expires = jiffies + DWABC_TMRES;
+	add_timer(&dw_abc_timer);
+}
+
+
+void isdn_dw_abc_init_func(void)
+{
+
+	init_timer(&dw_abc_timer);
+	dw_abc_timer.function = dw_abc_timer_func;
+
+
+	printk( KERN_INFO
+		"abc-extension %s Kernel 0x%06X\n"
+		"written by\nDetlef Wengorz <detlefw@isdn4linux.de>\n"
+		"Installed options:\n"
+#ifdef CONFIG_ISDN_WITH_ABC_CALLB
+		"CONFIG_ISDN_WITH_ABC_CALLB\n"
+#endif
+#ifdef CONFIG_ISDN_WITH_ABC_UDP_CHECK
+		"CONFIG_ISDN_WITH_ABC_UDP_CHECK\n"
+#endif
+#ifdef CONFIG_ISDN_WITH_ABC_UDP_CHECK_HANGUP
+		"CONFIG_ISDN_WITH_ABC_UDP_CHECK_HANGUP\n"
+#endif
+#ifdef CONFIG_ISDN_WITH_ABC_UDP_CHECK_DIAL
+		"CONFIG_ISDN_WITH_ABC_UDP_CHECK_DIAL\n"
+#endif
+#ifdef CONFIG_ISDN_WITH_ABC_OUTGOING_EAZ
+		"CONFIG_ISDN_WITH_ABC_OUTGOING_EAZ\n"
+#endif
+#ifdef CONFIG_ISDN_WITH_ABC_LCR_SUPPORT
+		"CONFIG_ISDN_WITH_ABC_LCR_SUPPORT\n"
+#endif
+#ifdef CONFIG_ISDN_WITH_ABC_RCV_NO_HUPTIMER
+		"CONFIG_ISDN_WITH_ABC_RCV_NO_HUPTIMER\n"
+#endif
+#ifdef CONFIG_ISDN_WITH_ABC_CH_EXTINUSE
+		"CONFIG_ISDN_WITH_ABC_CH_EXTINUSE\n"
+#endif
+#ifdef CONFIG_ISDN_WITH_ABC_CONN_ERROR
+		"CONFIG_ISDN_WITH_ABC_CONN_ERROR\n"
+#endif
+#ifdef CONFIG_ISDN_WITH_ABC_RAWIPCOMPRESS
+		"CONFIG_ISDN_WITH_ABC_RAWIPCOMPRESS\n"
+#endif
+		"loaded\n",
+		dwabcrevison,LINUX_VERSION_CODE);
+		dwsjiffies = 0;
+		dw_abc_timer.expires = jiffies + DWABC_TMRES;
+		add_timer(&dw_abc_timer);
+}
+
+void isdn_dw_abc_release_func(void)
+{
+	del_timer(&dw_abc_timer);
+#ifdef CONFIG_ISDN_WITH_ABC_LCR_SUPPORT
+	dw_lcr_clear_all();
+#endif
+	printk( KERN_INFO
+		"abc-extension %s  Kernel 0x%06X\n"
+		"written by\n"
+		"Detlef Wengorz <detlefw@isdn4linux.de>\n"
+		"unloaded\n",
+		dwabcrevison,LINUX_VERSION_CODE);
+}
+
+
+void isdn_dwabc_test_phone(isdn_net_local *lp) 
+{
+	if(lp != NULL) {
+
+		isdn_net_phone *h = lp->phone[0];
+		ulong oflags = lp->dw_abc_flags;
+		int secure = 0;
+
+		lp->dw_abc_flags = 0;
+#ifdef CONFIG_ISDN_WITH_ABC_OUTGOING_EAZ
+		*lp->dw_out_msn = 0;
+#endif
+
+		for(;h != NULL && secure < 1000;secure++,h = h->next) {
+
+			char *p 	= 	h->num;
+			char *ep 	= 	p + ISDN_MSNLEN;
+
+			for(;p < ep && *p && (*p <= ' ' || *p == '"' || *p == '\'');p++);
+
+			if(p >= ep)
+				continue;
+
+#ifdef CONFIG_ISDN_WITH_ABC_OUTGOING_EAZ
+			if(*p == '>') {
+
+				if(++p < ep && *p != '<' && *p != '>') {
+
+					char *d = lp->dw_out_msn;
+
+					for(;*p && (p < ep) && (*p == ' ' || *p == '\t');p++);
+					for(ep--;*p && (p < ep);) *(d++) = *(p++);
+					*d = 0;
+					continue;
+				}
+			}
+#endif
+
+			if(*p == '~') {
+
+				/* abc switch's */
+
+				for(p++;p < ep && *p;p++) switch(*p) {
+				case 'u':	lp->dw_abc_flags |= ISDN_DW_ABC_FLAG_NO_UDP_CHECK;			break;
+				case 'h':	lp->dw_abc_flags |= ISDN_DW_ABC_FLAG_NO_UDP_HANGUP;			break;
+				case 'd':	lp->dw_abc_flags |= ISDN_DW_ABC_FLAG_NO_UDP_DIAL;			break;
+				case 'c':	lp->dw_abc_flags |= ISDN_DW_ABC_FLAG_NO_CH_EXTINUSE;		break;
+				case 'e':   lp->dw_abc_flags |= ISDN_DW_ABC_FLAG_NO_CONN_ERROR;			break;
+				case 'l':   lp->dw_abc_flags |= ISDN_DW_ABC_FLAG_NO_LCR;				break;
+
+				case 'x':
+				case 'X':	lp->dw_abc_flags |= ISDN_DW_ABC_FLAG_RCV_NO_HUPTIMER;		break;
+
+				case 'B':	lp->dw_abc_flags |= ISDN_DW_ABC_FLAG_BSD_COMPRESS;			break;
+				case 'L': 	lp->dw_abc_flags |= ISDN_DW_ABC_FLAG_LEASED_LINE;			break;
+
+				case '"':
+				case ' ':
+				case '\t':
+				case '\'':	break;
+
+				default:	
+					printk(KERN_DEBUG"isdn_net: %s abc-switch <~%c> unknown\n",lp->name,*p);
+					break;
+				}
+			}
+		}
+
+		if(lp->dw_abc_flags & ISDN_DW_ABC_FLAG_LEASED_LINE) {
+
+			lp->dw_abc_flags |= 
+					ISDN_DW_ABC_FLAG_NO_UDP_CHECK		|
+					ISDN_DW_ABC_FLAG_NO_UDP_HANGUP		|
+					ISDN_DW_ABC_FLAG_NO_UDP_DIAL		|
+					ISDN_DW_ABC_FLAG_NO_CH_EXTINUSE		|
+					ISDN_DW_ABC_FLAG_NO_CONN_ERROR		|
+					ISDN_DW_ABC_FLAG_NO_LCR;
+		}
+
+		if(dev->net_verbose  && (lp->dw_abc_flags != oflags || dev->net_verbose > 4))
+			printk(KERN_DEBUG "isdn_net %s abc-flags 0x%lx\n",lp->name,lp->dw_abc_flags);
+
+	}
+}
+
+
+int isdn_dw_abc_reset_interface(isdn_net_local *lp,int with_message)
+{
+	int r = -EINVAL;
+
+	if(lp != NULL) {
+
+		r = 0;
+
+		lp->dw_abc_bchan_last_connect = 0;
+		lp->dw_abc_dialstart = 0;
+		lp->dw_abc_inuse_secure = 0;
+#ifdef CONFIG_ISDN_WITH_ABC_CONN_ERROR
+		lp->dw_abc_bchan_errcnt = 0;
+#endif
+
+		if(with_message && dev->net_verbose > 0)
+			printk(KERN_INFO
+				"%s: NOTE: reset (clear) abc-interface-secure-counter\n",
+				lp->name);
+	}
+
+	return(r);
+}
+
+	
+#if CONFIG_ISDN_WITH_ABC_RAWIPCOMPRESS && CONFIG_ISDN_PPP
+
+#define DWBSD_PKT_FIRST_LEN 16
+#define DWBSD_PKT_SWITCH	165
+#define DWBSD_PKT_BSD		189
+
+#define DWBSD_VERSION 		0x2
+
+void dwabc_bsd_first_gen(isdn_net_local *lp)
+{
+	if(lp != NULL && lp->p_encap == ISDN_NET_ENCAP_RAWIP && 
+		(lp->dw_abc_flags & ISDN_DW_ABC_FLAG_BSD_COMPRESS)) { 
+		
+		struct sk_buff *skb = NULL;
+		char *p = NULL;
+		char *ep = NULL;
+
+		if((skb =(struct sk_buff *)dev_alloc_skb(128)) == NULL) {
+
+			printk(KERN_INFO "%s: dwabc: alloc-skb failed for 128 bytes\n",lp->name);
+			return;
+		}
+
+		skb_reserve(skb,64);
+		p = skb_put(skb,DWBSD_PKT_FIRST_LEN);
+		ep = p + DWBSD_PKT_FIRST_LEN;
+
+		*(p++) = DWBSD_PKT_SWITCH;
+		*(p++) = DWBSD_VERSION;
+		for(;p < ep;p++)	*(p++) = 0;
+
+		isdn_net_write_super(lp, skb);
+
+		if(dev->net_verbose > 2)
+			printk(KERN_INFO "%s: dwabc: sending comm-header version 0x%x\n",lp->name,DWBSD_VERSION);
+	}
+}
+
+
+void dwabc_bsd_free(isdn_net_local *lp)
+{
+	if(lp != NULL) {
+
+		if(lp->dw_abc_bsd_stat_rx || lp->dw_abc_bsd_stat_tx) {
+
+			struct isdn_ppp_compressor *c = NULL;
+
+			if(!(c = (struct isdn_ppp_compressor *)lp->dw_abc_bsd_compressor)) {
+
+				printk(KERN_WARNING
+				"%s: PANIC: freeing bsd compressmemory without compressor\n",
+					lp->name);
+
+			} else {
+
+				if(lp->dw_abc_bsd_stat_rx) (*c->free)(lp->dw_abc_bsd_stat_rx);
+				if(lp->dw_abc_bsd_stat_tx) (*c->free)(lp->dw_abc_bsd_stat_tx);
+
+				if(dev->net_verbose > 2)
+					printk(KERN_INFO
+						"%s: free bsd compress-memory\n",
+						lp->name);
+			}
+		}
+
+		lp->dw_abc_bsd_compressor = NULL;
+		lp->dw_abc_bsd_stat_rx = NULL;
+		lp->dw_abc_bsd_stat_tx = NULL;
+		lp->dw_abc_if_flags &= ~ISDN_DW_ABC_IFFLAG_BSDAKTIV;
+
+		if(dev->net_verbose > 0) {
+
+			if(lp->dw_abc_bsd_rcv != lp->dw_abc_bsd_bsd_rcv) {
+
+				printk(KERN_INFO "%s: Receive %lu<-%lu kb\n",lp->name,
+					lp->dw_abc_bsd_rcv >> 10 , lp->dw_abc_bsd_bsd_rcv >> 10);
+			}
+
+
+			if(lp->dw_abc_bsd_snd != lp->dw_abc_bsd_bsd_snd) {
+
+				printk(KERN_INFO "%s: Send  %lu->%lu kb\n",lp->name,
+					lp->dw_abc_bsd_snd >> 10 , lp->dw_abc_bsd_bsd_snd >> 10);
+			}
+		}
+
+		lp->dw_abc_bsd_rcv 		=
+		lp->dw_abc_bsd_bsd_rcv	=
+		lp->dw_abc_bsd_snd 		=
+		lp->dw_abc_bsd_bsd_snd 	= 0;
+	}
+}
+
+
+int dwabc_bsd_init(isdn_net_local *lp)
+{
+	int r = 1;
+
+	if(lp != NULL) {
+
+		dwabc_bsd_free(lp);
+
+		if(lp->p_encap == ISDN_NET_ENCAP_RAWIP) {
+
+			void *rx = NULL;
+			void *tx = NULL;
+			struct isdn_ppp_comp_data *cp = NULL;
+			struct isdn_ppp_compressor *c = NULL;
+
+			if(lp->dw_abc_flags & ISDN_DW_ABC_FLAG_BSD_COMPRESS) do {
+
+				for(c = ipc_head ;
+					c != NULL && c->num != CI_BSD_COMPRESS; c = c->next);
+
+				if(c == NULL) {
+
+					printk(KERN_INFO
+						"%s: Module isdn_bsdcompress not loaded\n",
+						lp->name);
+
+					break;
+				}
+
+				cp = (struct isdn_ppp_comp_data *)
+					kmalloc(sizeof(struct isdn_ppp_comp_data),GFP_ATOMIC);
+
+				if(cp == NULL) {
+
+					printk(KERN_INFO
+						"%s: allocation of isdn_ppp_comp_data failed\n",
+						lp->name);
+
+					break;
+				}
+
+				memset(cp,0,sizeof(*cp));
+				cp->num = CI_BSD_COMPRESS;
+				cp->optlen = 1;
+					
+				/*
+				** set BSD_VERSION 1 and 12 bits compressmode
+				*/
+				*cp->options = (1 << 5) | 12;
+
+				if((rx = (*c->alloc)(cp)) == NULL) {
+
+					printk(KERN_INFO
+						"%s: allocation of bsd rx-memory failed\n",
+						lp->name);
+
+					break;
+				}
+					
+				if(!(*c->init)(rx,cp,0,1)) {
+
+					printk(KERN_INFO 
+						"%s: init of bsd rx-stream  failed\n",lp->name);
+
+					break;
+				}
+
+				cp->flags = IPPP_COMP_FLAG_XMIT;
+						
+				if((tx = (*c->alloc)(cp)) == NULL) {
+
+					printk(KERN_INFO
+						"%s: allocation of bsd tx-memory failed\n",
+						lp->name);
+
+					break;
+				}
+
+				if(!(*c->init)(tx,cp,0,1)) {
+
+					printk(KERN_INFO
+						"%s: init of bsd tx-stream  failed\n",
+						lp->name);
+
+					break;
+				}
+
+				lp->dw_abc_bsd_compressor = (void *)c;
+				lp->dw_abc_bsd_stat_rx = rx;
+				lp->dw_abc_bsd_stat_tx = tx;
+				rx = tx = NULL;
+				r = 0;
+
+				if(dev->net_verbose > 2)
+					printk(KERN_INFO
+						"%s: bsd compress-memory and init ok\n",
+						lp->name);
+
+			} while(0);
+
+			if(cp != NULL)
+				kfree(cp);
+
+			if(c != NULL) {
+
+				if(tx != NULL) (*c->free)(tx);
+				if(rx != NULL) (*c->free)(rx);
+			}
+
+		} else if(lp->dw_abc_flags & ISDN_DW_ABC_FLAG_BSD_COMPRESS) {
+		
+			printk(KERN_INFO
+				"%s: bsd-compress only with encapsulation rawip allowed\n",
+				lp->name);
+		}
+	}
+
+	return(r);
+}
+
+struct sk_buff *dwabc_bsd_compress(	isdn_net_local *lp,
+									struct sk_buff *skb,
+									struct net_device *ndev)
+{
+	if(lp != NULL && lp->p_encap == ISDN_NET_ENCAP_RAWIP 	&& 
+		(lp->dw_abc_flags & ISDN_DW_ABC_FLAG_BSD_COMPRESS)	&&
+		(lp->dw_abc_if_flags & ISDN_DW_ABC_IFFLAG_BSDAKTIV)) {
+
+		if(lp->dw_abc_bsd_stat_tx != NULL && lp->dw_abc_bsd_compressor) {
+
+			struct isdn_ppp_compressor *cp = 
+				(struct isdn_ppp_compressor *)lp->dw_abc_bsd_compressor;
+
+			struct sk_buff *nskb = (struct sk_buff *)
+				dev_alloc_skb(skb->len * 2 + ndev->hard_header_len);
+
+			int l = 0;
+
+			if(nskb == NULL) {
+
+				(void)(*cp->reset)(lp->dw_abc_bsd_stat_tx,0,0,NULL,0,NULL);
+				printk(KERN_INFO "%s: dwabc-compress no memory\n",lp->name);
+
+			} else {
+
+				skb_reserve(nskb,ndev->hard_header_len);
+				*(unsigned char *)skb_put(nskb,1) = DWBSD_PKT_BSD;
+				l = (*cp->compress)(lp->dw_abc_bsd_stat_tx,skb,nskb,0x21);
+
+				if(l < 1 || l > skb->len) {
+
+					(void)(*cp->reset)(lp->dw_abc_bsd_stat_tx,0,0,NULL,0,NULL);
+					dev_kfree_skb(nskb);
+
+				} else {
+
+					u_short sqnr;
+
+					dev_kfree_skb(skb);
+					skb = nskb;
+					sqnr = ((*(u_char *)skb->data) << 8) + 
+							((u_char)skb->data[1]);
+
+					if(sqnr > 65500)
+						(void)(*cp->reset)
+							(lp->dw_abc_bsd_stat_tx,0,0,NULL,0,NULL);
+				}
+			}
+		}
+	}
+
+	return(skb);
+}
+
+struct sk_buff *dwabc_bsd_rx_pkt(	isdn_net_local *lp,
+									struct sk_buff *skb,
+									struct net_device *ndev)
+{
+	struct sk_buff *r = skb;
+
+	if(lp != NULL && lp->p_encap == ISDN_NET_ENCAP_RAWIP && 
+		(lp->dw_abc_flags & ISDN_DW_ABC_FLAG_BSD_COMPRESS)) { 
+
+		unsigned char *p = (unsigned char *)skb->data;
+		struct isdn_ppp_compressor *cp = 
+			(struct isdn_ppp_compressor *)lp->dw_abc_bsd_compressor;
+
+		if(*p == DWBSD_PKT_SWITCH) {
+
+			if(skb->len == DWBSD_PKT_FIRST_LEN) {
+
+				if((lp->dw_abc_remote_version = p[1]) < 0x2) {
+
+					printk(KERN_INFO 
+						"%s: I can't really talk with remote version 0x%x\n"
+						"Please upgrade remote or disable rawip-compression\n",
+						lp->name,
+						p[1]);
+				}
+
+				lp->dw_abc_if_flags |= ISDN_DW_ABC_IFFLAG_BSDAKTIV;
+				dev_kfree_skb(skb);
+
+				if(cp && lp->dw_abc_bsd_stat_tx) 
+					(void)(*cp->reset)(lp->dw_abc_bsd_stat_tx,0,0,NULL,0,NULL);
+
+				if(dev->net_verbose > 2)
+					printk(KERN_INFO 
+						"%s: receive comm-header rem-version 0x%02x\n",
+						lp->name,
+						lp->dw_abc_remote_version);
+
+				return(NULL);
+			}
+
+		} else if(*p == DWBSD_PKT_BSD && lp->dw_abc_bsd_stat_rx != NULL && cp) {
+
+			struct sk_buff *nskb = NULL;
+
+			if(test_and_set_bit(ISDN_DW_ABC_BITLOCK_RECEIVE,
+				&lp->dw_abc_bitlocks)) {
+
+				printk(KERN_INFO "%s: bsd-decomp called recursivly\n",lp->name);
+				dev_kfree_skb(skb);
+				dwabc_bsd_first_gen(lp);
+				return(NULL);
+			} 
+			
+			nskb = (struct sk_buff *)
+				dev_alloc_skb(2048 + ndev->hard_header_len);
+
+			if(nskb != NULL) {
+
+				int l = 0;
+				u_short sqnr;
+
+				skb_reserve(nskb,ndev->hard_header_len);
+				skb_pull(skb, 1);
+				sqnr = ((*(u_char *)skb->data) << 8) | ((u_char)skb->data[1]);
+
+				if(!sqnr && cp && lp->dw_abc_bsd_stat_rx)
+					(void)(*cp->reset)(lp->dw_abc_bsd_stat_rx,0,0,NULL,0,NULL);
+
+				if((l = (*cp->decompress)
+					(lp->dw_abc_bsd_stat_rx,skb,nskb,NULL)) < 1 || l>8000) {
+
+					printk(KERN_INFO "%s: abc-decomp failed\n",lp->name);
+					dev_kfree_skb(nskb);
+					dev_kfree_skb(skb);
+					nskb = NULL;
+					dwabc_bsd_first_gen(lp);
+
+				} else {
+
+					if (nskb->data[0] & 0x1)
+						skb_pull(nskb, 1);   /* protocol ID is only 8 bit */
+					else
+						skb_pull(nskb, 2);
+
+					nskb->dev = skb->dev;
+					nskb->pkt_type = skb->pkt_type;
+					nskb->mac.raw = nskb->data;
+					dev_kfree_skb(skb);
+				}
+
+			} else {
+
+				printk(KERN_INFO "%s: PANIC abc-decomp no memory\n",lp->name);
+				dev_kfree_skb(skb);
+				dwabc_bsd_first_gen(lp);
+			}
+
+			clear_bit(ISDN_DW_ABC_BITLOCK_RECEIVE,&lp->dw_abc_bitlocks);
+			r = nskb;
+		}
+	}
+
+	return(r);
+}
+
+#else
+int dwabc_bsd_init(isdn_net_local *lp) { return(1); }
+void dwabc_bsd_free(isdn_net_local *lp) { return; }
+void dwabc_bsd_first_gen(isdn_net_local *lp) { return ; }
+
+struct sk_buff *dwabc_bsd_compress(isdn_net_local *lp,struct sk_buff *skb,struct net_device *ndev)
+{ return(skb); }
+
+struct sk_buff *dwabc_bsd_rx_pkt(isdn_net_local *lp,struct sk_buff *skb,struct net_device *ndev)
+{ return(skb); }
+#endif
+#endif
--- a/drivers/isdn/isdn_net.c
+++ b/drivers/isdn/isdn_net.c
@@ -1,4 +1,4 @@
-/* $Id: isdn_net.c,v 1.1.4.1 2001/11/20 14:19:34 kai Exp $
+/* $Id: isdn_net.c,v 1.153 2002/08/17 18:35:23 detabc Exp $
  *
  * Linux ISDN subsystem, network interfaces and related functions (linklevel).
  *
@@ -9,14 +9,6 @@
  * This software may be used and distributed according to the terms
  * of the GNU General Public License, incorporated herein by reference.
  *
- * Data Over Voice (DOV) support added - Guy Ellis 23-Mar-02 
- *                                       guy@traverse.com.au
- * Outgoing calls - looks for a 'V' in first char of dialed number
- * Incoming calls - checks first character of eaz as follows:
- *   Numeric - accept DATA only - original functionality
- *   'V'     - accept VOICE (DOV) only
- *   'B'     - accept BOTH DATA and DOV types
- *
  * Jan 2001: fix CISCO HDLC      Bjoern A. Zeeb <i4l@zabbadoz.net>
  *           for info on the protocol, see 
  *           http://i4l.zabbadoz.net/i4l/cisco-hdlc.txt
@@ -38,6 +30,10 @@
 #include "isdn_concap.h"
 #endif
 
+#ifdef CONFIG_ISDN_WITH_ABC
+#include <linux/isdn_dwabc.h>
+#define isdn_net_log_skb(skb,lp) isdn_net_log_skb_dwabc(skb,lp,NULL)
+#endif
 
 /*
  * Outline of new tbusy handling: 
@@ -79,7 +75,11 @@ static __inline__ int isdn_net_device_st
 		dev = lp->master;
 	else
 		dev = &n->dev;
+#ifdef COMPAT_NO_SOFTNET
+	return dev->start;
+#else
 	return netif_running(dev);
+#endif
 }
 
 /*
@@ -143,6 +143,10 @@ static __inline__ void isdn_net_inc_fram
 	atomic_inc(&lp->frame_cnt);
 	if (isdn_net_device_busy(lp))
 		isdn_net_device_stop_queue(lp);
+#if 0
+	printk(KERN_DEBUG "%s: inc_frame_cnt now %d\n", lp->name, 
+	      atomic_read(&lp->frame_cnt));
+#endif
 }
 
 static __inline__ void isdn_net_dec_frame_cnt(isdn_net_local *lp)
@@ -157,11 +161,19 @@ static __inline__ void isdn_net_dec_fram
 			isdn_net_device_wake_queue(lp);
 		}
        }                                                                      
+#if 0
+	printk(KERN_DEBUG "%s: dec_frame_cnt now %d\n", lp->name, 
+	       atomic_read(&lp->frame_cnt));
+#endif
 }
 
 static __inline__ void isdn_net_zero_frame_cnt(isdn_net_local *lp)
 {
 	atomic_set(&lp->frame_cnt, 0);
+#if 0
+	printk(KERN_DEBUG "%s: zero_frame_cnt now %d\n", lp->name,
+	       atomic_read(&lp->frame_cnt));
+#endif
 }
 
 /* For 2.2.x we leave the transmitter busy timeout at 2 secs, just 
@@ -173,23 +185,101 @@ static __inline__ void isdn_net_zero_fra
  * which might rely on the tx timeout. If so, we'll find out this way...
  */
 
+#ifdef COMPAT_NO_SOFTNET
+#define ISDN_NET_TX_TIMEOUT (2*HZ)
+#else
 #define ISDN_NET_TX_TIMEOUT (20*HZ) 
+#endif
 
 /* Prototypes */
 
+#ifndef CONFIG_ISDN_WITH_ABC
 int isdn_net_force_dial_lp(isdn_net_local *);
+#endif
 static int isdn_net_start_xmit(struct sk_buff *, struct net_device *);
 
 static void isdn_net_ciscohdlck_connected(isdn_net_local *lp);
 static void isdn_net_ciscohdlck_disconnected(isdn_net_local *lp);
 
-char *isdn_net_revision = "$Revision: 1.1.4.1 $";
+char *isdn_net_revision = "$Revision: 1.153 $";
 
  /*
   * Code for raw-networking over ISDN
   */
+#ifdef CONFIG_ISDN_WITH_ABC
+#ifdef CONFIG_ISDN_WITH_ABC_CONN_ERROR
+static int isdn_dwabc_encap_with_conerr(isdn_net_local *lp)
+{
+	if(lp->dw_abc_flags & ISDN_DW_ABC_FLAG_NO_CONN_ERROR)
+		return(0);
+
+	return( 
+		lp->p_encap == ISDN_NET_ENCAP_SYNCPPP			||
+		lp->p_encap == ISDN_NET_ENCAP_RAWIP 			||
+		lp->p_encap == ISDN_NET_ENCAP_CISCOHDLCK		||
+		lp->p_encap == ISDN_NET_ENCAP_UIHDLC			);
+}
+
+static int isdn_dwabc_conerr_ippktok(struct sk_buff *skb)
+{
+		struct iphdr *iph = (struct iphdr *)skb->data;
+		return(iph->version == 6 || (skb->len >= 20 && iph->version == 4));
+}
+
+#endif
+
+static int isdn_dwabc_is_interface_disabled(isdn_net_local *lp)
+{
+	if(lp == NULL)
+		return(0);
+
+	lp->dw_abc_inuse_secure = 0;
+	lp->dw_abc_dialstart = 0;
+
+	/*
+	** check for jiffies overflow
+	*/
+	if(lp->dw_abc_bchan_last_connect > jiffies) {
+
+#ifdef CONFIG_ISDN_WITH_ABC_CONN_ERROR
+		lp->dw_abc_bchan_errcnt = 0;
+#endif
+		lp->dw_abc_bchan_last_connect = 0;
+	}
+
+#ifdef CONFIG_ISDN_WITH_ABC_CONN_ERROR
+	if(!(lp->dw_abc_flags & ISDN_DW_ABC_FLAG_NO_CONN_ERROR) && isdn_dwabc_encap_with_conerr(lp)) {
+
+		if(lp->dw_abc_bchan_errcnt > 3 && !(lp->dw_abc_bchan_errcnt & 3)) {
 
+			ulong nj = jiffies;
+			ulong delay = 	lp->dw_abc_bchan_errcnt * 
+							lp->dw_abc_bchan_errcnt * 
+							lp->dw_abc_bchan_errcnt;
+
+			if(delay > 86400) delay = 86400;
+			delay = (lp->dw_abc_bchan_last_connect + delay * HZ);
+
+			if(delay > nj) {
+
+				printk(KERN_INFO 
+					"%s: interface auto-disabled (bchannel connect-error %lu seconds left)\n",
+					lp->name,(delay - nj) / HZ);
+
+				return(1);
+			}
+		}
+	}
+#endif
+	return(0);
+}
+#endif
+
+#ifdef CONFIG_ISDN_WITH_ABC
+void
+#else
 static void
+#endif
 isdn_net_unreachable(struct net_device *dev, struct sk_buff *skb, char *reason)
 {
 	if(skb) {
@@ -297,6 +387,12 @@ isdn_net_unbind_channel(isdn_net_local *
 
 	save_flags(flags);
 	cli();
+#ifdef CONFIG_ISDN_WITH_ABC
+	isdn_dw_clear_if(0l,lp);
+	lp->dw_abc_if_flags &= ~ISDN_DW_ABC_IFFLAG_NODCHAN;
+	lp->dw_abc_inuse_secure = 0;
+	dwabc_bsd_free(lp);
+#endif
 	skb_queue_purge(&lp->super_tx_queue);
 
 	if (!lp->master) {	/* reset only master device */
@@ -351,6 +447,26 @@ isdn_net_autohup()
 		if ((l->flags & ISDN_NET_CONNECTED) && (!l->dialstate)) {
 			anymore = 1;
 			l->huptimer++;
+#ifdef CONFIG_ISDN_WITH_ABC
+#ifdef CONFIG_ISDN_WITH_ABC_CONN_ERROR
+			if(	isdn_dwabc_encap_with_conerr(l)	&& l->dw_abc_bchan_errcnt > 0) {
+
+				int n = 180;
+
+				if(l->dw_abc_bchan_errcnt > 3) n = 120;
+				if(l->dw_abc_bchan_errcnt > 6) n = 90;
+				if(l->dw_abc_bchan_errcnt > 9) n = 60;
+
+				if(l->huptimer > n) {
+
+					printk(KERN_INFO "%s: bchan conf-error auto-secure-hangup\n",l->name);
+					isdn_net_hangup(&p->dev);
+					p = (isdn_net_dev *) p->next;
+					continue;
+				}
+			}
+#endif
+#endif
 			/*
 			 * if there is some dialmode where timeout-hangup
 			 * should _not_ be done, check for that here
@@ -465,8 +581,32 @@ isdn_net_stat_callback(int idx, isdn_ctr
 					printk(KERN_INFO "%s: Chargesum is %d\n", lp->name,
 					       lp->charge);
 					isdn_net_unbind_channel(lp);
+#ifdef CONFIG_ISDN_WITH_ABC_CONN_ERROR
+					if(lp->dw_abc_bchan_errcnt) {
+
+						printk(KERN_INFO
+							"%s: Note: bchannel-error-counter is %hd\n",
+							lp->name,
+							lp->dw_abc_bchan_errcnt);
+					}
+#endif
 					return 1;
 				}
+#ifdef CONFIG_ISDN_WITH_ABC_CH_EXTINUSE
+				if(!(lp->dw_abc_flags & ISDN_DW_ABC_FLAG_NO_CH_EXTINUSE)) {
+					if((lp->dialstate == 4 || lp->dialstate == 12) && 
+						lp->dw_abc_dialstart && (idx < ISDN_MAX_CHANNELS)) {
+					
+						if((jiffies - lp->dw_abc_dialstart) < (HZ >>2)) {
+
+							lp->dw_abc_if_flags |= ISDN_DW_ABC_IFFLAG_NODCHAN;
+							lp->dialstate = 1;
+							dev->dwabc_chan_external_inuse[idx] = jiffies + HZ * 30;
+							printk(KERN_INFO "%s: Channel %d look like external in use\n",lp->name,idx);
+						}
+					}
+				}
+#endif
 				break;
 #ifdef CONFIG_ISDN_X25
 			case ISDN_STAT_BHUP:
@@ -507,6 +647,19 @@ isdn_net_stat_callback(int idx, isdn_ctr
 							}
 						}
 						printk(KERN_INFO "isdn_net: %s connected\n", lp->name);
+#ifdef CONFIG_ISDN_WITH_ABC
+						if(!dwabc_bsd_init(lp)) dwabc_bsd_first_gen(lp);
+						lp->dw_abc_bchan_last_connect = jiffies;
+#ifdef CONFIG_ISDN_WITH_ABC_CONN_ERROR
+						if(!(lp->dw_abc_flags & ISDN_DW_ABC_FLAG_NO_CONN_ERROR)) {
+
+							lp->dw_abc_bchan_errcnt += isdn_dwabc_encap_with_conerr(lp);
+							
+							if(lp->dw_abc_bchan_errcnt > 32000)
+								lp->dw_abc_bchan_errcnt = 32000;
+						}
+#endif
+#endif
 						/* If first Chargeinfo comes before B-Channel connect,
 						 * we correct the timestamp here.
 						 */
@@ -578,7 +731,6 @@ isdn_net_dial(void)
 	int i;
 	unsigned long flags;
 	isdn_ctrl cmd;
-        u_char *phone_number;
 
 	while (p) {
 		isdn_net_local *lp = p->local;
@@ -597,6 +749,47 @@ isdn_net_dial(void)
 				 */
 				save_flags(flags);
 				cli();
+#ifdef CONFIG_ISDN_WITH_ABC_CH_EXTINUSE
+				if(!(lp->dw_abc_flags & ISDN_DW_ABC_FLAG_NO_CH_EXTINUSE) &&
+					(lp->dw_abc_if_flags & ISDN_DW_ABC_IFFLAG_NODCHAN)) {
+
+					int chi = 0;
+					short lsecure = 0;
+
+					lsecure = lp->dw_abc_inuse_secure;
+					isdn_net_unbind_channel(lp);
+					lp->dw_abc_inuse_secure = lsecure + 1;
+
+					/* Grab a free ISDN-Channel */
+					if ((lsecure >= ISDN_MAX_CHANNELS ) || (chi = 
+						isdn_get_free_channel(
+							ISDN_USAGE_NET,
+							lp->l2_proto,
+							lp->l3_proto,
+							lp->pre_device,
+						 	lp->pre_channel,
+#ifdef CONFIG_ISDN_WITH_ABC_OUTGOING_EAZ
+							(*lp->dw_out_msn) ? lp->dw_out_msn : lp->msn)
+#else
+							lp->msn)
+#endif
+							) < 0) {
+
+						restore_flags(flags);
+						isdn_net_unreachable(&p->dev, NULL,
+							"DWABC: redial-external-inuse NO FREE CHANNEL\n");
+						isdn_net_hangup(&p->dev);
+						break;
+					}
+
+					isdn_net_bind_channel(lp, chi);
+					lp->dialstate = 1;
+					lp->dialstarted = 0;
+					lp->dialwait_timer = 0;
+				}
+
+				lp->dw_abc_if_flags &= ~ISDN_DW_ABC_IFFLAG_NODCHAN;
+#endif
 				lp->dial = lp->phone[1];
 				restore_flags(flags);
 				if (!lp->dial) {
@@ -621,18 +814,69 @@ isdn_net_dial(void)
 				cmd.arg = lp->isdn_channel;
 				cmd.command = ISDN_CMD_CLREAZ;
 				isdn_command(&cmd);
+#ifdef CONFIG_ISDN_WITH_ABC_OUTGOING_EAZ
+				sprintf(cmd.parm.num, "%s",
+					isdn_map_eaz2msn((*lp->dw_out_msn) ? lp->dw_out_msn : lp->msn, cmd.driver));
+#else
 				sprintf(cmd.parm.num, "%s", isdn_map_eaz2msn(lp->msn, cmd.driver));
+#endif
 				cmd.command = ISDN_CMD_SETEAZ;
 				isdn_command(&cmd);
 				lp->dialretry = 0;
 				anymore = 1;
 				lp->dialstate++;
+#ifdef CONFIG_ISDN_WITH_ABC
+				lp->onhtime = lp->dw_abc_old_onhtime;
+#ifdef CONFIG_ISDN_WITH_ABC_LCR_SUPPORT
+				isdn_dw_abc_lcr_clear(lp);
+#endif
+#endif
 				/* Fall through */
 			case 3:
 				/* Setup interface, dial current phone-number, switch to next number.
 				 * If list of phone-numbers is exhausted, increment
 				 * retry-counter.
 				 */
+#ifdef CONFIG_ISDN_WITH_ABC_LCR_SUPPORT
+				if(!isdn_dw_abc_lcr_lock()) {
+
+					if(	lp->dw_abc_lcr_cmd != NULL 		&&
+						lp->dw_abc_lcr_start_request 	!= 
+						lp->dw_abc_lcr_end_request) {
+
+						if(	lp->dw_abc_lcr_io == NULL 				&& 
+							lp->dw_abc_lcr_start_request <= jiffies &&
+							lp->dw_abc_lcr_end_request > jiffies) {
+							
+							isdn_dw_abc_lcr_ulock();
+							anymore = 1;
+							break;
+						}
+
+						if(lp->dw_abc_lcr_io != NULL) {
+
+							if(lp->dw_abc_lcr_io->lcr_ioctl_flags & 
+								DWABC_LCR_FLG_DISABLE) {
+
+								isdn_dw_abc_lcr_ulock();
+								isdn_net_hangup(&p->dev);
+								break;
+							}
+
+							if(lp->dw_abc_lcr_io->lcr_ioctl_flags & 
+								DWABC_LCR_FLG_NEWHUPTIME) {
+								lp->onhtime = lp->dw_abc_lcr_io->lcr_ioctl_onhtime;
+							}
+						}
+
+						memcpy(&cmd,lp->dw_abc_lcr_cmd,sizeof(cmd));
+						isdn_dw_abc_lcr_ulock();
+						goto dw_abc_lcr_next_click;
+					}
+
+					isdn_dw_abc_lcr_ulock();
+				}
+#endif
 				if(dev->global_flags & ISDN_GLOBAL_STOPPED || (ISDN_NET_DIALMODE(*lp) == ISDN_NET_DM_OFF)) {
 					char *s;
 					if (dev->global_flags & ISDN_GLOBAL_STOPPED)
@@ -677,20 +921,7 @@ isdn_net_dial(void)
 							break;
 						}
 
-					cmd.driver = lp->isdn_device;
-					cmd.command = ISDN_CMD_DIAL;
-					cmd.parm.setup.si2 = 0;
-
-                                        /* check for DOV */
-                                        phone_number = lp->dial->num;
-                                        if ((*phone_number == 'v') ||
-					    (*phone_number == 'V')) { /* DOV call */
-                                                cmd.parm.setup.si1 = 1;
-                                        } else { /* DATA call */
-                                                cmd.parm.setup.si1 = 7;
-					}
-
-					strcpy(cmd.parm.setup.phone, phone_number);
+					sprintf(cmd.parm.setup.phone, "%s", lp->dial->num);
 					/*
 					 * Switch to next number or back to start if at end of list.
 					 */
@@ -710,17 +941,70 @@ isdn_net_dial(void)
 						}
 					}
 					restore_flags(flags);
+					cmd.driver = lp->isdn_device;
+					cmd.command = ISDN_CMD_DIAL;
+					cmd.parm.setup.si1 = 7;
+					cmd.parm.setup.si2 = 0;
+#ifdef CONFIG_ISDN_WITH_ABC_OUTGOING_EAZ 
+					sprintf(cmd.parm.setup.eazmsn, "%s",
+						isdn_map_eaz2msn((*lp->dw_out_msn) ? lp->dw_out_msn : lp->msn, cmd.driver));
+#else
 					sprintf(cmd.parm.setup.eazmsn, "%s",
 						isdn_map_eaz2msn(lp->msn, cmd.driver));
+#endif
+#ifdef CONFIG_ISDN_WITH_ABC_LCR_SUPPORT
+					/*
+					** if callback-out we dont need 
+					** low-cost-routing LCR
+					*/
+				    if(!(lp->flags & ISDN_NET_CBOUT) &&
+						!(lp->dw_abc_flags & ISDN_DW_ABC_FLAG_NO_LCR)) {
+
+						isdn_dw_abc_lcr_call_number(lp,&cmd);
+						
+						if(lp->dw_abc_lcr_start_request != lp->dw_abc_lcr_end_request) {
+
+							if(dev->net_verbose > 2) {
+
+								printk(KERN_INFO 
+					"%s: Waiting for LCR-response from isdnlog %s -> %s...\n",
+									lp->name,
+						   			cmd.parm.setup.eazmsn,
+						   			cmd.parm.setup.phone);
+							}
+								
+							anymore = 1;
+							break;
+						}
+					} 
+
+dw_abc_lcr_next_click:;
+					isdn_dw_abc_lcr_clear(lp);
+#endif
 					i = isdn_dc2minor(lp->isdn_device, lp->isdn_channel);
 					if (i >= 0) {
 						strcpy(dev->num[i], cmd.parm.setup.phone);
 						dev->usage[i] |= ISDN_USAGE_OUTGOING;
 						isdn_info_update();
 					}
-					printk(KERN_INFO "%s: dialing %d %s... %s\n", lp->name,
-					       lp->dialretry, cmd.parm.setup.phone,
-					       (cmd.parm.setup.si1 == 1) ? "DOV" : "");
+#ifdef CONFIG_ISDN_WITH_ABC
+					printk(KERN_INFO "%s: dialing %d %s -> %s...\n", lp->name,
+					       lp->dialretry, 
+						   cmd.parm.setup.eazmsn,
+						   cmd.parm.setup.phone);
+#ifdef CONFIG_ISDN_WITH_ABC_CONN_ERROR
+					if(lp->dw_abc_bchan_errcnt) {
+
+						printk(KERN_INFO
+							"%s: Note: bchannel-error-counter is %hd\n",
+							lp->name,
+							lp->dw_abc_bchan_errcnt);
+					}
+#endif
+#else
+					printk(KERN_INFO "%s: dialing %d %s...\n", lp->name,
+					       lp->dialretry, cmd.parm.setup.phone);
+#endif
 					lp->dtimer = 0;
 #ifdef ISDN_DEBUG_NET_DIAL
 					printk(KERN_DEBUG "dial: d=%d c=%d\n", lp->isdn_device,
@@ -741,6 +1025,10 @@ isdn_net_dial(void)
 				lp->dialstate =
 				    (lp->cbdelay &&
 				     (lp->flags & ISDN_NET_CBOUT)) ? 12 : 4;
+#ifdef CONFIG_ISDN_WITH_ABC
+				lp->dw_abc_if_flags &= ~ISDN_DW_ABC_IFFLAG_NODCHAN;
+				lp->dw_abc_dialstart = jiffies;
+#endif
 				break;
 			case 4:
 				/* Wait for D-Channel-connect.
@@ -890,6 +1178,15 @@ isdn_net_hangup(struct net_device *d)
 		isdn_command(&cmd);
 		printk(KERN_INFO "%s: Chargesum is %d\n", lp->name, lp->charge);
 		isdn_all_eaz(lp->isdn_device, lp->isdn_channel);
+#ifdef CONFIG_ISDN_WITH_ABC_CONN_ERROR
+		if(lp->dw_abc_bchan_errcnt) {
+
+			printk(KERN_INFO
+				"%s: Note: bchannel-error-counter is %hd\n",
+				lp->name,
+				lp->dw_abc_bchan_errcnt);
+		}
+#endif
 	}
 	isdn_net_unbind_channel(lp);
 }
@@ -899,8 +1196,13 @@ typedef struct {
 	unsigned short dest;
 } ip_ports;
 
+#ifdef CONFIG_ISDN_WITH_ABC
+void
+isdn_net_log_skb_dwabc(struct sk_buff * skb, isdn_net_local * lp,char *reason)
+#else
 static void
 isdn_net_log_skb(struct sk_buff * skb, isdn_net_local * lp)
+#endif
 {
 	u_char *p = skb->nh.raw; /* hopefully, this was set correctly */
 	unsigned short proto = ntohs(skb->protocol);
@@ -972,7 +1274,13 @@ isdn_net_log_skb(struct sk_buff * skb, i
 					break;
 			}
 			printk(KERN_INFO
+#ifdef CONFIG_ISDN_WITH_ABC
+				"%s %s: %d.%d.%d.%d -> %d.%d.%d.%d%s\n",
+				(reason == NULL) ? "OPEN" : reason,
+				(lp != NULL) ? lp->name : "",
+#else
 				"OPEN: %d.%d.%d.%d -> %d.%d.%d.%d%s\n",
+#endif
 
 			       p[12], p[13], p[14], p[15],
 			       p[16], p[17], p[18], p[19],
@@ -980,7 +1288,13 @@ isdn_net_log_skb(struct sk_buff * skb, i
 			break;
 		case ETH_P_ARP:
 			printk(KERN_INFO
+#ifdef CONFIG_ISDN_WITH_ABC
+				"%s %s: ARP %d.%d.%d.%d -> *.*.*.* ?%d.%d.%d.%d\n",
+				(reason == NULL) ? "OPEN" : reason,
+				(lp != NULL) ? lp->name : "",
+#else
 				"OPEN: ARP %d.%d.%d.%d -> *.*.*.* ?%d.%d.%d.%d\n",
+#endif
 			       p[14], p[15], p[16], p[17],
 			       p[24], p[25], p[26], p[27]);
 			break;
@@ -1004,11 +1318,22 @@ void isdn_net_write_super(isdn_net_local
 	}
 
 	spin_lock_bh(&lp->xmit_lock);
+
 	if (!isdn_net_lp_busy(lp)) {
+#ifdef CONFIG_ISDN_WITH_ABC
+		if(!skb_queue_empty(&lp->super_tx_queue)) {
+			/*
+			** don't reverse the frame flow
+			** compression need frames in order and maybe other's too
+			*/
+			skb_queue_tail(&lp->super_tx_queue, skb); 
+			skb = skb_dequeue(&lp->super_tx_queue);
+		}
+#endif
 		isdn_net_writebuf_skb(lp, skb);
-	} else {
-		skb_queue_tail(&lp->super_tx_queue, skb);
-	}
+
+	} else skb_queue_tail(&lp->super_tx_queue, skb);
+
 	spin_unlock_bh(&lp->xmit_lock);
 }
 
@@ -1056,7 +1381,6 @@ void isdn_net_writebuf_skb(isdn_net_loca
 		printk(KERN_WARNING "%s: HL driver queue full\n", lp->name);
 		goto error;
 	}
-	
 	lp->transcount += len;
 	isdn_net_inc_frame_cnt(lp);
 	return;
@@ -1064,9 +1388,19 @@ void isdn_net_writebuf_skb(isdn_net_loca
  error:
 	dev_kfree_skb(skb);
 	lp->stats.tx_errors++;
-
 }
 
+#if 0
+int isdn_net_send_skb(struct net_device *ndev, isdn_net_local * lp,struct sk_buff *skb)
+{
+	if (isdn_net_lp_busy(lp)) {
+		printk(KERN_WARNING "isdn_net_send_skb: HL channel busy\n");
+		return 1;
+	}
+	isdn_net_writebuf_skb(lp, skb);
+	return 0;
+}
+#endif
 
 /*
  *  Helper function for isdn_net_start_xmit.
@@ -1109,7 +1443,54 @@ isdn_net_xmit(struct net_device *ndev, s
 
 	/* Reset hangup-timeout */
 	lp->huptimer = 0; // FIXME?
+#ifdef CONFIG_ISDN_WITH_ABC
+
+	if(test_and_set_bit(ISDN_DW_ABC_BITLOCK_SEND,&lp->dw_abc_bitlocks)) {
+
+		if(dev->net_verbose > 2)
+			printk(KERN_INFO "%s: isdn_net_xmit  called recursivly\n",lp->name);
+
+		spin_unlock_bh(&lp->xmit_lock);
+		return(1);
+	}
+
+	if(skb != NULL) {
+
+		int l = skb->len;
+		int nl = l;
+
+		if(	lp->p_encap == ISDN_NET_ENCAP_RAWIP &&
+				(lp->dw_abc_if_flags & ISDN_DW_ABC_IFFLAG_BSDAKTIV)) {
+
+			if((skb = dwabc_bsd_compress(lp,skb,ndev)) != NULL) {
+
+				int r = 0;
+				nl = skb->len;
+				skb_queue_tail(&lp->super_tx_queue,skb);
+
+				if(l != nl && (r = isdn_dc2minor(lp->isdn_device,lp->isdn_channel)) >= 0) {
+
+					dev->obytes[r] += l - nl;
+					lp->stats.tx_bytes += l - nl;
+				}
+			}
+
+		} else skb_queue_tail(&lp->super_tx_queue,skb);
+
+		if(lp->p_encap == ISDN_NET_ENCAP_RAWIP) {
+
+			lp->dw_abc_bsd_snd += l;
+			lp->dw_abc_bsd_bsd_snd += nl;
+		}
+	}
+	clear_bit(ISDN_DW_ABC_BITLOCK_SEND,&lp->dw_abc_bitlocks);
+
+	while(!isdn_net_lp_busy(lp) && (skb = skb_dequeue(&lp->super_tx_queue)))
+		isdn_net_writebuf_skb(lp, skb);
+
+#else
 	isdn_net_writebuf_skb(lp, skb);
+#endif
 	spin_unlock_bh(&lp->xmit_lock);
 
 	/* the following stuff is here for backwards compatibility.
@@ -1143,6 +1524,69 @@ isdn_net_xmit(struct net_device *ndev, s
 
 	return retv;
 
+#if 0
+	if (lp->cps > lp->triggercps) {
+		/* Device overloaded */
+
+		/*
+		 * Packet-delivery via round-robin over master
+		 * and all connected slaves.
+		 */
+		if (lp->master) {
+			/* Slaves always deliver themselves */
+			spin_lock_bh(&lp->xmit_lock);
+			if (!isdn_net_lp_busy(lp)) {
+				isdn_net_writebuf_skb(lp, skb);
+				ret = 0;
+			} else {
+				isdn_net_device_stop_queue(lp);
+				ret = 1;
+			}
+			ret = isdn_net_send_skb(ndev, lp, skb);
+			spin_unlock_bh(&lp->xmit_lock);
+		} else {
+			isdn_net_local *slp = (isdn_net_local *) (lp->srobin->priv);
+			/* Master delivers via srobin and maintains srobin */
+			if (lp->srobin == ndev) {
+				spin_lock_bh(&lp->xmit_lock);
+				ret = isdn_net_send_skb(ndev, lp, skb);
+				spin_unlock_bh(&lp->xmit_lock);
+			} else {
+				ret = isdn_net_start_xmit(skb, lp->srobin);
+			}
+			lp->srobin = (slp->slave) ? slp->slave : ndev;
+			slp = (isdn_net_local *) (lp->srobin->priv);
+			if (!((slp->flags & ISDN_NET_CONNECTED) && (slp->dialstate == 0)))
+				lp->srobin = ndev;
+		}
+		/* Slave-startup using delay-variable */
+		if (lp->slave) {
+			if (!lp->sqfull) {
+				/* First time overload: set timestamp only */
+				lp->sqfull = 1;
+				lp->sqfull_stamp = jiffies;
+			} else {
+				/* subsequent overload: if slavedelay exceeded, start dialing */
+				if ((jiffies - lp->sqfull_stamp) > lp->slavedelay)
+					isdn_net_force_dial_lp((isdn_net_local *) lp->slave->priv);
+			}
+		}
+	} else {
+		/* Not overloaded, deliver locally */
+		spin_lock_bh(&lp->xmit_lock);
+		if (!isdn_net_lp_busy(lp)) {
+			isdn_net_writebuf_skb(lp, skb);
+			ret = 0;
+		} else {
+			isdn_net_device_stop_queue(lp);
+			ret = 1;
+		}
+		spin_unlock_bh(&lp->xmit_lock);
+		if (lp->sqfull && ((jiffies - lp->sqfull_stamp) > (lp->slavedelay + (10 * HZ))))
+			lp->sqfull = 0;
+	}
+	return ret;
+#endif
 }
 
 static void
@@ -1161,6 +1605,7 @@ isdn_net_adjust_hdr(struct sk_buff *skb,
 }
 
 
+#ifndef COMPAT_NO_SOFTNET
 void isdn_net_tx_timeout(struct net_device * ndev)
 {
 	isdn_net_local *lp = (isdn_net_local *) ndev->priv;
@@ -1188,19 +1633,206 @@ void isdn_net_tx_timeout(struct net_devi
 	ndev->trans_start = jiffies;
 	netif_wake_queue(ndev);
 }
+#endif
 
 /*
  * Try sending a packet.
  * If this interface isn't connected to a ISDN-Channel, find a free channel,
  * and start dialing.
  */
+#ifdef CONFIG_ISDN_WITH_ABC
+static int dwabc_isdn_net_start_xmit(struct sk_buff *,struct net_device *);
+
+static int isdn_net_start_xmit(struct sk_buff *skb, struct net_device *ndev)
+{
+	if(skb == NULL || ndev == NULL)
+		return(dwabc_isdn_net_start_xmit(skb,ndev));
+#ifdef CONFIG_ISDN_WITH_ABC_UDP_CHECK
+	if(!(((isdn_net_local *)ndev->priv)->dw_abc_flags & 
+		ISDN_DW_ABC_FLAG_NO_UDP_CHECK)) {
+
+		if(dw_abc_udp_test(skb,ndev)) {
+			dev_kfree_skb(skb);
+			return(0);
+		}
+	}
+#endif
+	return(dwabc_isdn_net_start_xmit(skb,ndev));
+}
+
+
+#ifdef CONFIG_ISDN_WITH_ABC
+int isdn_auto_dial_helper(	isdn_net_local *lp,
+							struct sk_buff *skb,
+							int dm_manual_allowed)
+/**********************************************************************
+	return's:
+		-1		dial not allowed or impossible
+		0		interface is connected
+		1		dial is started
+***********************************************************************/
+{
+	int retw = -1;
+	int chi;
+	ulong flags;
+	char *errmsg = NULL;
+
+#ifdef ISDN_DEBUG_NET_DUMP
+	{
+		char *buf = skb->data;
+		isdn_dumppkt("S:", buf, skb->len, 40);
+	}
+#endif
+	if (lp->flags & ISDN_NET_CONNECTED) 
+		return(0);
+
+	save_flags(flags);
+	cli();
+
+	do {
+
+		/* Log packet, which triggered dialing */
+		if (dev->net_verbose)
+			isdn_net_log_skb(skb, lp);
+		/* only do autodial if allowed by config */
+		if (!(ISDN_NET_DIALMODE(*lp) == ISDN_NET_DM_AUTO)) {
+			errmsg = "dial rejected: interface not in dialmode `auto'";
+
+			if(dm_manual_allowed &&
+				!(ISDN_NET_DIALMODE(*lp) == ISDN_NET_DM_MANUAL)) {
+
+				errmsg = 
+				"dial rejected: interface not in dialmode `auto or manual'";
+			}
+			break;
+		}
+
+		if (!lp->phone[1]) {
+
+			errmsg = "No phone number";
+			break;
+		}
+
+		if(lp->dialwait_timer <= 0) {
+
+			if(	lp->dialstarted > 0 &&
+				lp->dialtimeout > 0 && 
+				jiffies < (lp->dialstarted + lp->dialtimeout + lp->dialwait)) {
+
+				lp->dialwait_timer = 
+					lp->dialstarted + lp->dialtimeout + lp->dialwait;
+			}
+		}
+
+		if(lp->dialwait_timer > 0) {
+
+			if(jiffies < lp->dialwait_timer) {
+
+				errmsg = "dial rejected: retry-time not reached";
+				break;
+
+			} else lp->dialwait_timer = 0;
+		}
+#ifdef CONFIG_ISDN_WITH_ABC
+		if(isdn_dwabc_is_interface_disabled(lp))
+			break;
+#endif
+		/* Grab a free ISDN-Channel */
+		if (((chi =
+				isdn_get_free_channel(
+					ISDN_USAGE_NET,
+					lp->l2_proto,
+					lp->l3_proto,
+					lp->pre_device,
+					lp->pre_channel,
+#ifdef CONFIG_ISDN_WITH_ABC_OUTGOING_EAZ
+					(*lp->dw_out_msn) ? lp->dw_out_msn :
+#endif
+					lp->msn)
+			) < 0) &&
+			((chi =
+				isdn_get_free_channel(
+					ISDN_USAGE_NET,
+					lp->l2_proto,
+					lp->l3_proto,
+					lp->pre_device,
+					lp->pre_channel^1,
+#ifdef CONFIG_ISDN_WITH_ABC_OUTGOING_EAZ
+					(*lp->dw_out_msn) ? lp->dw_out_msn :
+#endif
+					lp->msn)
+			) < 0)) {
+
+				errmsg = "No channel";
+				break;
+		}
+
+		lp->dialstate = 1;
+		/* Connect interface with channel */
+		isdn_net_bind_channel(lp, chi);
+#ifdef CONFIG_ISDN_PPP
+		if (lp->p_encap == ISDN_NET_ENCAP_SYNCPPP) {
+			/* no 'first_skb' handling for syncPPP */
+			if (isdn_ppp_bind(lp) < 0) {
+				isdn_net_unbind_channel(lp);
+				break;
+			}
+
+			isdn_net_dial();	/* Initiate dialing */
+			netif_stop_queue(&lp->netdev->dev);
+			retw = 1;
+			break;
+			/* let upper layer requeue skb packet */
+		}
+#endif
+		/* Initiate dialing */
+		isdn_net_dial();
+		isdn_net_device_stop_queue(lp);
+		retw = 1;
+
+	} while(0);
+
+	if(retw < 0 && errmsg != NULL)
+		isdn_net_unreachable(&lp->netdev->dev, skb, errmsg);
+
+	restore_flags(flags);
+	return(retw);
+}
+#endif
+
+
+
+static int
+dwabc_isdn_net_start_xmit(struct sk_buff *skb, struct net_device *ndev)
+#else
 static int
 isdn_net_start_xmit(struct sk_buff *skb, struct net_device *ndev)
+#endif
 {
 	isdn_net_local *lp = (isdn_net_local *) ndev->priv;
 #ifdef CONFIG_ISDN_X25
 	struct concap_proto * cprot = lp -> netdev -> cprot;
 #endif
+#ifdef COMPAT_NO_SOFTNET 
+	/* some comment as with the softnet TX timeout
+	   when this happens, it's a bug in the HL card driver
+	   and should be fixed there, so we can supposedly get rid of 
+	   this here at all. 
+	   I added a debugging message to find out if it ever occurs --KG
+	*/
+
+	if (ndev->tbusy) {
+		if (jiffies - ndev->trans_start < ISDN_NET_TX_TIMEOUT)
+			return 1;
+		if (!lp->dialstate){
+			lp->stats.tx_errors++;
+			printk(KERN_WARNING "isdn_tx_timeout dev %s dialstate %d\n",
+				ndev->name, lp->dialstate);
+		}
+		ndev->trans_start = jiffies;
+		netif_wake_queue(ndev);
+	}
+#endif
 #ifdef CONFIG_ISDN_X25
 /* At this point hard_start_xmit() passes control to the encapsulation
    protocol (if present).
@@ -1220,6 +1852,40 @@ isdn_net_start_xmit(struct sk_buff *skb,
 	} else
 #endif
 	/* auto-dialing xmit function */
+#ifdef CONFIG_ISDN_WITH_ABC
+	{
+		int r;
+
+		isdn_net_adjust_hdr(skb, ndev);
+
+		if(!(r = isdn_auto_dial_helper(lp,skb,0))) {
+
+			/* 
+			** Device is connected to an ISDN channel
+			*/ 
+			ndev->trans_start = jiffies;
+
+			if (!lp->dialstate) {
+
+				/* 
+				** ISDN connection is established, try sending 
+				*/
+				r = isdn_net_xmit(ndev, skb);
+
+			} else r = 1;
+
+			if(r)
+				netif_stop_queue(ndev);
+
+		} else if(r < 0) {
+
+			dev_kfree_skb(skb);
+			r = 0;
+		}
+
+		return(r);
+	}
+#else
 	{
 #ifdef ISDN_DEBUG_NET_DUMP
 		u_char *buf;
@@ -1256,6 +1922,14 @@ isdn_net_start_xmit(struct sk_buff *skb,
 					} else
 						lp->dialwait_timer = 0;
 				}
+#ifdef CONFIG_ISDN_WITH_ABC
+				if(isdn_dwabc_is_interface_disabled(lp)) {
+
+					dev_kfree_skb(skb);
+					restore_flags(flags);
+					return(0);
+				}
+#endif
 				/* Grab a free ISDN-Channel */
 				if (((chi =
 				     isdn_get_free_channel(
@@ -1264,6 +1938,9 @@ isdn_net_start_xmit(struct sk_buff *skb,
 							lp->l3_proto,
 							lp->pre_device,
 						 	lp->pre_channel,
+#ifdef CONFIG_ISDN_WITH_ABC_OUTGOING_EAZ
+							(*lp->dw_out_msn) ? lp->dw_out_msn : 
+#endif
 							lp->msn)
 							) < 0) &&
 					((chi =
@@ -1273,6 +1950,9 @@ isdn_net_start_xmit(struct sk_buff *skb,
 							lp->l3_proto,
 							lp->pre_device,
 							lp->pre_channel^1,
+#ifdef CONFIG_ISDN_WITH_ABC_OUTGOING_EAZ
+							(*lp->dw_out_msn) ? lp->dw_out_msn :
+#endif
 							lp->msn)
 							) < 0)) {
 					restore_flags(flags);
@@ -1296,16 +1976,6 @@ isdn_net_start_xmit(struct sk_buff *skb,
 						restore_flags(flags);
 						return 0;	/* STN (skb to nirvana) ;) */
 					}
-#ifdef CONFIG_IPPP_FILTER
-					if (isdn_ppp_autodial_filter(skb, lp)) {
-						isdn_ppp_free(lp);
-						isdn_net_unbind_channel(lp);
-						restore_flags(flags);
-						isdn_net_unreachable(ndev, skb, "dial rejected: packet filtered");
-						dev_kfree_skb(skb);
-						return 0;
-					}
-#endif
 					restore_flags(flags);
 					isdn_net_dial();	/* Initiate dialing */
 					netif_stop_queue(ndev);
@@ -1337,6 +2007,7 @@ isdn_net_start_xmit(struct sk_buff *skb,
 		}
 	}
 	return 1;
+#endif
 }
 
 /*
@@ -1356,6 +2027,9 @@ isdn_net_close(struct net_device *dev)
 	if( cprot && cprot -> pops ) cprot -> pops -> close( cprot );
 #endif
 	netif_stop_queue(dev);
+#ifdef COMPAT_NO_SOFTNET
+	dev->start = 0;
+#endif
 	if ((p = (((isdn_net_local *) dev->priv)->slave))) {
 		/* If this interface has slaves, stop them also */
 		while (p) {
@@ -1776,6 +2450,10 @@ isdn_net_ciscohdlck_receive(isdn_net_loc
 	}
 
 	switch (type) {
+	case CISCO_TYPE_INET:
+		skb->protocol = htons(ETH_P_IP);
+		netif_rx(skb);
+		break;
 	case CISCO_TYPE_SLARP:
 		isdn_net_ciscohdlck_slarp_in(lp, skb);
 		goto out_free;
@@ -1785,11 +2463,11 @@ isdn_net_ciscohdlck_receive(isdn_net_loc
 				"\"no cdp enable\" on cisco.\n", lp->name);
 		goto out_free;
 	default:
-		/* no special cisco protocol */
-		skb->protocol = htons(type);
-		netif_rx(skb);
-		return;
+		printk(KERN_WARNING "%s: Unknown Cisco type 0x%04x\n",
+		       lp->name, type);
+		goto out_free;
 	}
+	return;
 
  out_free:
 	kfree_skb(skb);
@@ -1803,9 +2481,19 @@ isdn_net_receive(struct net_device *ndev
 {
 	isdn_net_local *lp = (isdn_net_local *) ndev->priv;
 	isdn_net_local *olp = lp;	/* original 'lp' */
+#ifdef CONFIG_ISDN_PPP
+	int proto = PPP_PROTOCOL(skb->data);
+#endif
 #ifdef CONFIG_ISDN_X25
 	struct concap_proto *cprot = lp -> netdev -> cprot;
 #endif
+#ifdef CONFIG_ISDN_WITH_ABC
+	struct net_device *ondev = ndev;
+#ifdef CONFIG_ISDN_WITH_ABC_RCV_NO_HUPTIMER
+	ulong lp_huptimer  = 0;
+	ulong olp_huptimer = 0;
+#endif
+#endif
 	lp->transcount += skb->len;
 
 	lp->stats.rx_packets++;
@@ -1819,6 +2507,10 @@ isdn_net_receive(struct net_device *ndev
 		lp->stats.rx_packets++;
 		lp->stats.rx_bytes += skb->len;
 	}
+#ifdef CONFIG_ISDN_WITH_ABC_RCV_NO_HUPTIMER
+	lp_huptimer  = lp->huptimer;
+	olp_huptimer = olp->huptimer;
+#endif
 	skb->dev = ndev;
 	skb->pkt_type = PACKET_HOST;
 	skb->mac.raw = skb->data;
@@ -1840,9 +2532,40 @@ isdn_net_receive(struct net_device *ndev
 			/* Fall through */
 		case ISDN_NET_ENCAP_RAWIP:
 			/* RAW-IP without MAC-Header */
+#ifdef CONFIG_ISDN_WITH_ABC
+			if(olp->p_encap == ISDN_NET_ENCAP_RAWIP) {
+
+				ushort l = skb->len;
+				short r = 0;
+
+				olp->dw_abc_bsd_bsd_rcv += l;
+
+				if((skb = dwabc_bsd_rx_pkt(olp,skb,ondev)) == NULL) {
+
+					olp->dw_abc_bsd_rcv += l;
+					return;
+				}
+
+				olp->dw_abc_bsd_rcv += skb->len;
+
+				if(	l != skb->len && 
+					(r=isdn_dc2minor(olp->isdn_device,olp->isdn_channel))>=0) {
+
+					dev->ibytes[r] += skb->len - l;
+					olp->stats.rx_bytes += skb->len - l;
+
+					if(olp != lp)
+						lp->stats.rx_bytes += skb->len - l;
+				}
+			}
+#endif
 			olp->huptimer = 0;
 			lp->huptimer = 0;
 			skb->protocol = htons(ETH_P_IP);
+#ifdef CONFIG_ISDN_WITH_ABC_CONN_ERROR
+			if(isdn_dwabc_conerr_ippktok(skb))
+				lp->dw_abc_bchan_errcnt = 0;
+#endif
 			break;
 		case ISDN_NET_ENCAP_CISCOHDLCK:
 			isdn_net_ciscohdlck_receive(lp, skb);
@@ -1862,8 +2585,22 @@ isdn_net_receive(struct net_device *ndev
 			break;
 #ifdef CONFIG_ISDN_PPP
 		case ISDN_NET_ENCAP_SYNCPPP:
-			/* huptimer is done in isdn_ppp_push_higher */
+			/*
+			 * If encapsulation is syncppp, don't reset
+			 * huptimer on LCP packets.
+			 */
+			if (proto != PPP_LCP) {
+				olp->huptimer = 0;
+				lp->huptimer = 0;
+			}
 			isdn_ppp_receive(lp->netdev, olp, skb);
+#ifdef CONFIG_ISDN_WITH_ABC_RCV_NO_HUPTIMER
+			if(olp->dw_abc_flags & ISDN_DW_ABC_FLAG_RCV_NO_HUPTIMER) {
+
+				lp->huptimer = lp_huptimer + 1;
+				olp->huptimer = olp_huptimer+ 1;
+			}
+#endif
 			return;
 #endif
 
@@ -1873,6 +2610,15 @@ isdn_net_receive(struct net_device *ndev
 			if(cprot) if(cprot -> pops)
 				if( cprot -> pops -> data_ind){
 					cprot -> pops -> data_ind(cprot,skb);
+#ifdef CONFIG_ISDN_WITH_ABC_CONN_ERROR
+					lp->dw_abc_bchan_errcnt = 0;
+#ifdef CONFIG_ISDN_WITH_ABC_RCV_NO_HUPTIMER
+					if(olp->dw_abc_flags & ISDN_DW_ABC_FLAG_RCV_NO_HUPTIMER) {
+						lp->huptimer = lp_huptimer;
+						olp->huptimer = olp_huptimer;
+					}
+#endif
+#endif
 					return;
 				};
 #endif /* CONFIG_ISDN_X25 */
@@ -1882,6 +2628,15 @@ isdn_net_receive(struct net_device *ndev
 			return;
 	}
 
+#ifdef CONFIG_ISDN_WITH_ABC
+#ifdef CONFIG_ISDN_WITH_ABC_RCV_NO_HUPTIMER
+	if(olp->dw_abc_flags & ISDN_DW_ABC_FLAG_RCV_NO_HUPTIMER) {
+
+		lp->huptimer = lp_huptimer;
+		olp->huptimer = olp_huptimer;
+	}
+#endif
+#endif
 	netif_rx(skb);
 	return;
 }
@@ -2160,7 +2915,10 @@ isdn_net_find_icall(int di, int ch, int 
 	isdn_net_phone *n;
 	ulong flags;
 	char nr[ISDN_MSNLEN];
-	char *my_eaz;
+#ifdef CONFIG_ISDN_WITH_ABC
+	if(dev->net_verbose > 2)
+		printk(KERN_DEBUG "n_fi: di=%d ch=%d idx=%d usg=0x%04X\n", di, ch, idx,dev->usage[idx]);
+#endif
 
 	/* Search name in netdev-chain */
 	save_flags(flags);
@@ -2182,17 +2940,15 @@ isdn_net_find_icall(int di, int ch, int 
 		eaz = setup->eazmsn;
 	if (dev->net_verbose > 1)
 		printk(KERN_INFO "isdn_net: call from %s,%d,%d -> %s\n", nr, si1, si2, eaz);
-        /* Accept DATA and VOICE calls at this stage
-        local eaz is checked later for allowed call types */
-        if ((si1 != 7) && (si1 != 1)) {
-                restore_flags(flags);
-                if (dev->net_verbose > 1)
-                        printk(KERN_INFO "isdn_net: Service-Indicator not 1 or 7, ignored\n");
-                return 0;
-        }
-
-n = (isdn_net_phone *) 0;
-p = dev->netdev;
+	/* Accept only calls with Si1 = 7 (Data-Transmission) */
+	if (si1 != 7) {
+		restore_flags(flags);
+		if (dev->net_verbose > 1)
+			printk(KERN_INFO "isdn_net: Service-Indicator not 7, ignored\n");
+		return 0;
+	}
+	n = (isdn_net_phone *) 0;
+	p = dev->netdev;
 	ematch = wret = swapped = 0;
 #ifdef ISDN_DEBUG_NET_ICALL
 	printk(KERN_DEBUG "n_fi: di=%d ch=%d idx=%d usg=%d\n", di, ch, idx,
@@ -2212,25 +2968,8 @@ p = dev->netdev;
 				break;
 		}
 		swapped = 0;
-                /* check acceptable call types for DOV */
-                my_eaz = isdn_map_eaz2msn(lp->msn, di);
-                if (si1 == 1) { /* it's a DOV call, check if we allow it */
-                        if (*my_eaz == 'v' || *my_eaz == 'V' ||
-			    *my_eaz == 'b' || *my_eaz == 'B')
-                                my_eaz++; /* skip to allow a match */
-                        else
-                                my_eaz = 0; /* force non match */
-                } else { /* it's a DATA call, check if we allow it */
-                        if (*my_eaz == 'b' || *my_eaz == 'B')
-                                my_eaz++; /* skip to allow a match */
-                }
-                if (my_eaz)
-                        matchret = isdn_msncmp(eaz, my_eaz);
-                else
-                        matchret = 1;
-                if (!matchret)
-                        ematch = 1;
-
+		if (!(matchret = isdn_msncmp(eaz, isdn_map_eaz2msn(lp->msn, di))))
+			ematch = 1;
 		/* Remember if more numbers eventually can match */
 		if (matchret > wret)
 			wret = matchret;
@@ -2238,17 +2977,122 @@ p = dev->netdev;
 		printk(KERN_DEBUG "n_fi: if='%s', l.msn=%s, l.flags=%d, l.dstate=%d\n",
 		       lp->name, lp->msn, lp->flags, lp->dialstate);
 #endif
+#ifdef CONFIG_ISDN_WITH_ABC_CALLB
+		if ((!matchret) &&                                        /* EAZ is matching   */
+		    (((!(lp->flags & ISDN_NET_CONNECTED)) &&              /* but not connected */
+		      (USG_NONE(dev->usage[idx]))) ||                     /* and ch. unused or */
+		     (lp->dialstate == 4) || (lp->dialstate == 12) ||		/* if dialing        */
+			  ((lp->flags & ISDN_NET_CBOUT) != 0 &&		  		/* init a callback	*/
+			  lp->outgoing != 0 )))
+
+		/*
+		** we dont stop call's anymore (both sides call's syncron)
+		** it will be problem in any case.
+		** both sides will make the same.
+		** i try later to make a switch (check the phon-numbers)
+		** to detect with side must be stop the call.
+		*/
+#else
 		if ((!matchret) &&                                        /* EAZ is matching   */
 		    (((!(lp->flags & ISDN_NET_CONNECTED)) &&              /* but not connected */
 		      (USG_NONE(dev->usage[idx]))) ||                     /* and ch. unused or */
 		     ((((lp->dialstate == 4) || (lp->dialstate == 12)) && /* if dialing        */
 		       (!(lp->flags & ISDN_NET_CALLBACK)))                /* but no callback   */
 		     )))
+#endif
 			 {
 #ifdef ISDN_DEBUG_NET_ICALL
 			printk(KERN_DEBUG "n_fi: match1, pdev=%d pch=%d\n",
 			       lp->pre_device, lp->pre_channel);
 #endif
+#ifdef CONFIG_ISDN_WITH_ABC
+#ifdef CONFIG_ISDN_WITH_ABC_CALLB
+			{
+				int use_this_call = 0;
+
+				if(!(lp->flags & ISDN_NET_CBOUT) && ((lp->dialstate == 4) || (lp->dialstate == 12))) {
+
+					/*
+					** searching for a diff. in the calling-number and the EAZ
+					** the remote will make the same
+					*/
+
+					char *pnr = nr;
+					char *pea = eaz;
+
+					for(;*pnr;pnr++);
+					for(;*pea;pea++);
+					for(pnr--,pea--;pnr >= nr && pea >= eaz && *pea != *pnr;pnr--,pea--);
+
+					if(pnr < nr || pea < eaz || *pea > *pnr) {
+
+						p = (isdn_net_dev *) p->next;
+						continue;
+					}
+
+					use_this_call = 1;
+				}
+				
+				if( use_this_call || 
+					((lp->flags & ISDN_NET_CBOUT) && (lp->flags & ISDN_NET_CONNECTED))) {
+
+					/*
+					** the incoming call was to quick.
+					** the callback-delay-time ist not reached.
+					** in that case we can stop the call
+					*/
+
+					if(lp->isdn_device > -1 && lp->isdn_channel > -1) {
+
+						int minor = isdn_dc2minor(lp->isdn_device,lp->isdn_channel);
+
+						if(lp->isdn_device != di || lp->isdn_channel != ch) {
+
+							isdn_ctrl cmd;
+
+							memset((void *)&cmd,0,sizeof(cmd));
+							cmd.driver = lp->isdn_device;
+							cmd.command = ISDN_CMD_HANGUP;
+							cmd.arg = lp->isdn_channel;
+							(void) dev->drv[cmd.driver]->interface->command(&cmd);
+							isdn_all_eaz(lp->isdn_device, lp->isdn_channel);
+
+							if(dev->net_verbose > 1) {
+
+								printk(KERN_INFO 
+				"%s: found outgoing call hangup old call on di %d ch %d\n",
+									lp->name,lp->isdn_device,lp->isdn_channel);
+							}
+
+						} else if (dev->net_verbose > 1) {
+
+							printk(KERN_INFO "%s: found outgoing call on same di %d ch %d\n",
+								lp->name,lp->isdn_device,lp->isdn_channel);
+						}
+
+						if(minor >= 0) {
+
+							dev->rx_netdev[minor] = NULL;
+							dev->st_netdev[minor] = NULL;
+						}
+
+						isdn_free_channel(lp->isdn_device,
+							lp->isdn_channel, ISDN_USAGE_NET);
+
+					} else if (dev->net_verbose > 1) {
+
+						printk(KERN_INFO "%s: found outgoing call reset callstate \n",lp->name);
+					}
+
+					lp->flags &= ~ISDN_NET_CONNECTED;
+					lp->isdn_device = -1;
+					lp->isdn_channel = -1;
+					lp->dtimer = 0;
+					lp->dialstate = 0;
+				}
+			}
+#endif
+#endif
 			if (dev->usage[idx] & ISDN_USAGE_EXCLUSIVE) {
 				if ((lp->pre_channel != ch) ||
 				    (lp->pre_device != di)) {
@@ -2377,6 +3221,12 @@ p = dev->netdev;
 						continue;
 					}
 				} 
+#ifdef CONFIG_ISDN_WITH_ABC_CONN_ERROR
+				if(isdn_dwabc_is_interface_disabled(lp)) {
+					restore_flags(flags);
+					return 3;
+				}
+#endif
 				if (lp->flags & ISDN_NET_CALLBACK) {
 					int chi;
 					/*
@@ -2429,6 +3279,47 @@ p = dev->netdev;
 					restore_flags(flags);
 					return 0;
 				} else {
+#ifdef CONFIG_ISDN_WITH_ABC_CALLB
+					{
+					/*
+					** this is a sanity-check.
+					** check for double use (device and channel)
+					** will be very near to a kernel-crash in that case
+					*/
+					isdn_net_dev *sp = dev->netdev;
+					int s_shl;
+					isdn_net_local *ml;
+
+					for(s_shl=0; s_shl < 2048 && sp != NULL; sp = (isdn_net_dev *)sp->next, s_shl++) {
+
+						if(sp == p || (ml = sp->local) == NULL)
+							continue;
+
+						if(ml->isdn_device != di || ml->isdn_channel != ch)
+							continue;
+
+						if(ml->dialstate != 4 && ml->dialstate != 12) {
+
+							/*
+							** wrong situation
+							*/
+							break;
+						}
+
+						isdn_net_unbind_channel(ml);
+					}
+
+					if(sp != NULL) {
+
+						printk(KERN_DEBUG
+"%s: call from %s -> %s (drv %d chan %d duplicated with %s) \n",
+							lp->name, nr, eaz,di,ch,
+							sp->local->name	);
+
+						restore_flags(flags);
+						return 3;
+					}}
+#endif
 					printk(KERN_DEBUG "%s: call from %s -> %s accepted\n", lp->name, nr,
 					       eaz);
 					/* if this interface is dialing, it does it probably on a different
@@ -2518,7 +3409,11 @@ isdn_net_force_dial_lp(isdn_net_local * 
 							lp->l3_proto,
 							lp->pre_device,
 						 	lp->pre_channel,
+#ifdef CONFIG_ISDN_WITH_ABC_OUTGOING_EAZ
+							(*lp->dw_out_msn) ? lp->dw_out_msn : lp->msn)
+#else
 							lp->msn)
+#endif
 							) < 0) {
 				printk(KERN_WARNING "isdn_net_force_dial: No channel for %s\n", lp->name);
 				restore_flags(flags);
@@ -2601,7 +3496,11 @@ isdn_net_new(char *name, struct net_devi
 		strcpy(netdev->local->name, "         ");
 	else
 		strcpy(netdev->local->name, name);
+#ifdef COMPAT_NO_SOFTNET
+	netdev->dev.name = netdev->local->name;
+#else
 	strcpy(netdev->dev.name, netdev->local->name);
+#endif
 	netdev->dev.priv = netdev->local;
 	netdev->dev.init = isdn_net_init;
 	netdev->local->p_encap = ISDN_NET_ENCAP_RAWIP;
@@ -2619,11 +3518,13 @@ isdn_net_new(char *name, struct net_devi
 		((isdn_net_local *) q->priv)->slave = &(netdev->dev);
 	} else {
 		/* Device shall be a master */
+#ifndef COMPAT_NO_SOFTNET
 		/*
 		 * Watchdog timer (currently) for master only.
 		 */
 		netdev->dev.tx_timeout = isdn_net_tx_timeout;
 		netdev->dev.watchdog_timeo = ISDN_NET_TX_TIMEOUT;
+#endif
 		if (register_netdev(&netdev->dev) != 0) {
 			printk(KERN_WARNING "isdn_net: Could not register net-device\n");
 			kfree(netdev->local);
@@ -2660,6 +3561,9 @@ isdn_net_new(char *name, struct net_devi
 	netdev->local->hupflags = ISDN_INHUP;	/* Do hangup even on incoming calls */
 	netdev->local->onhtime = 10;	/* Default hangup-time for saving costs
 	   of those who forget configuring this */
+#ifdef CONFIG_ISDN_WITH_ABC 
+	netdev->local->dw_abc_old_onhtime = netdev->local->onhtime;
+#endif
 	netdev->local->dialmax = 1;
 	netdev->local->flags = ISDN_NET_CBHUP | ISDN_NET_DM_MANUAL;	/* Hangup before Callback, manual dial */
 	netdev->local->cbdelay = 25;	/* Wait 5 secs before Callback */
@@ -2833,7 +3737,6 @@ isdn_net_setcfg(isdn_net_ioctl_cfg * cfg
 
 			/* If binding is exclusive, try to grab the channel */
 			save_flags(flags);
-			cli();
 			if ((i = isdn_get_free_channel(ISDN_USAGE_NET,
 				lp->l2_proto, lp->l3_proto, drvidx,
 				chidx, lp->msn)) < 0) {
@@ -2862,6 +3765,9 @@ isdn_net_setcfg(isdn_net_ioctl_cfg * cfg
 		lp->pre_device = drvidx;
 		lp->pre_channel = chidx;
 		lp->onhtime = cfg->onhtime;
+#ifdef CONFIG_ISDN_WITH_ABC 
+		lp->dw_abc_old_onhtime = lp->onhtime;
+#endif
 		lp->charge = cfg->charge;
 		lp->l2_proto = cfg->l2_proto;
 		lp->l3_proto = cfg->l3_proto;
@@ -2935,6 +3841,9 @@ isdn_net_setcfg(isdn_net_ioctl_cfg * cfg
 			}
 		}
 		lp->p_encap = cfg->p_encap;
+#ifdef CONFIG_ISDN_WITH_ABC 
+		isdn_dw_abc_reset_interface(lp,0);
+#endif
 		return 0;
 	}
 	return -ENODEV;
@@ -3011,6 +3920,9 @@ isdn_net_addphone(isdn_net_ioctl_phone *
 		n->num[sizeof(n->num) - 1] = 0;
 		n->next = p->local->phone[phone->outgoing & 1];
 		p->local->phone[phone->outgoing & 1] = n;
+#ifdef CONFIG_ISDN_WITH_ABC
+		isdn_dwabc_test_phone(p->local);
+#endif
 		return 0;
 	}
 	return -ENODEV;
@@ -3104,6 +4016,9 @@ isdn_net_delphone(isdn_net_ioctl_phone *
 				else
 					p->local->phone[inout] = n->next;
 				kfree(n);
+#ifdef CONFIG_ISDN_WITH_ABC
+				isdn_dwabc_test_phone(p->local);
+#endif
 				restore_flags(flags);
 				return 0;
 			}
@@ -3139,6 +4054,9 @@ isdn_net_rmallphone(isdn_net_dev * p)
 		p->local->phone[i] = NULL;
 	}
 	p->local->dial = NULL;
+#ifdef CONFIG_ISDN_WITH_ABC
+	isdn_dwabc_test_phone(p->local);
+#endif
 	restore_flags(flags);
 	return 0;
 }
@@ -3222,6 +4140,10 @@ isdn_net_realrm(isdn_net_dev * p, isdn_n
 	/* If no more net-devices remain, disable auto-hangup timer */
 	if (dev->netdev == NULL)
 		isdn_timer_ctrl(ISDN_TIMER_NETHANGUP, 0);
+#ifdef CONFIG_ISDN_WITH_ABC
+	isdn_dw_clear_if(~0l,p->local);
+	dwabc_bsd_free(p->local);
+#endif
 	restore_flags(flags);
 	kfree(p->local);
 	kfree(p);
--- a/drivers/isdn/isdn_net.h
+++ b/drivers/isdn/isdn_net.h
@@ -1,4 +1,4 @@
-/* $Id: isdn_net.h,v 1.1.4.1 2001/11/20 14:19:34 kai Exp $
+/* $Id: isdn_net.h,v 1.23 2001/11/07 22:35:48 kai Exp $
  *
  * header for Linux ISDN subsystem, network related functions (linklevel).
  *
@@ -26,6 +26,7 @@
 #define CISCO_ADDR_BROADCAST  0x8f
 #define CISCO_CTRL            0x00
 #define CISCO_TYPE_CDP        0x2000
+#define CISCO_TYPE_INET       0x0800
 #define CISCO_TYPE_SLARP      0x8035
 #define CISCO_SLARP_REQUEST   0
 #define CISCO_SLARP_REPLY     1
@@ -106,8 +107,6 @@ static __inline__ void isdn_net_add_to_b
 	spin_lock_irqsave(&nd->queue_lock, flags);
 
 	lp = nd->queue;
-//	printk(KERN_DEBUG __FUNCTION__": lp:%s(%p) nlp:%s(%p) last(%p)\n",
-//		lp->name, lp, nlp->name, nlp, lp->last); 
 	nlp->last = lp->last;
 	lp->last->next = nlp;
 	lp->last = nlp;
@@ -127,20 +126,12 @@ static __inline__ void isdn_net_rm_from_
 	if (lp->master)
 		master_lp = (isdn_net_local *) lp->master->priv;
 
-//	printk(KERN_DEBUG __FUNCTION__": lp:%s(%p) mlp:%s(%p) last(%p) next(%p) mndq(%p)\n",
-//		lp->name, lp, master_lp->name, master_lp, lp->last, lp->next, master_lp->netdev->queue); 
 	spin_lock_irqsave(&master_lp->netdev->queue_lock, flags);
 	lp->last->next = lp->next;
 	lp->next->last = lp->last;
-	if (master_lp->netdev->queue == lp) {
+	if (master_lp->netdev->queue == lp)
 		master_lp->netdev->queue = lp->next;
-		if (lp->next == lp) { /* last in queue */
-			master_lp->netdev->queue = master_lp->netdev->local;
-		}
-	}
 	lp->next = lp->last = lp;	/* (re)set own pointers */
-//	printk(KERN_DEBUG __FUNCTION__": mndq(%p)\n",
-//		master_lp->netdev->queue); 
 	spin_unlock_irqrestore(&master_lp->netdev->queue_lock, flags);
 }
 
--- a/drivers/isdn/isdn_ppp.c
+++ b/drivers/isdn/isdn_ppp.c
@@ -1,4 +1,4 @@
-/* $Id: isdn_ppp.c,v 1.1.4.1 2001/11/20 14:19:34 kai Exp $
+/* $Id: isdn_ppp.c,v 1.94 2001/11/07 22:35:48 kai Exp $
  *
  * Linux ISDN subsystem, functions for synchronous PPP (linklevel).
  *
@@ -13,9 +13,6 @@
 #include <linux/isdn.h>
 #include <linux/poll.h>
 #include <linux/ppp-comp.h>
-#ifdef CONFIG_IPPP_FILTER
-#include <linux/filter.h>
-#endif
 
 #include "isdn_common.h"
 #include "isdn_ppp.h"
@@ -72,11 +69,19 @@ static void isdn_ppp_mp_cleanup( isdn_ne
 static int isdn_ppp_bundle(struct ippp_struct *, int unit);
 #endif	/* CONFIG_ISDN_MPP */
   
-char *isdn_ppp_revision = "$Revision: 1.1.4.1 $";
+char *isdn_ppp_revision = "$Revision: 1.94 $";
 
 static struct ippp_struct *ippp_table[ISDN_MAX_CHANNELS];
 
+#ifndef CONFIG_ISDN_WITH_ABC
 static struct isdn_ppp_compressor *ipc_head = NULL;
+#else
+	/*
+	** make compressor's common usable
+	*/
+struct isdn_ppp_compressor *isdn_ippp_comp_head = NULL;
+#define ipc_head isdn_ippp_comp_head
+#endif
 
 /*
  * frame log (debug)
@@ -110,11 +115,8 @@ isdn_ppp_free(isdn_net_local * lp)
 	unsigned long flags;
 	struct ippp_struct *is;
 
-	if (lp->ppp_slot < 0 || lp->ppp_slot > ISDN_MAX_CHANNELS) {
-		printk(KERN_ERR "%s: ppp_slot(%d) out of range\n",
-			__FUNCTION__, lp->ppp_slot);
+	if (lp->ppp_slot < 0 || lp->ppp_slot > ISDN_MAX_CHANNELS)
 		return 0;
-	}
 
 	save_flags(flags);
 	cli();
@@ -130,12 +132,7 @@ isdn_ppp_free(isdn_net_local * lp)
 	lp->netdev->pb->ref_ct--;
 	spin_unlock(&lp->netdev->pb->lock);
 #endif /* CONFIG_ISDN_MPP */
-	if (lp->ppp_slot < 0 || lp->ppp_slot > ISDN_MAX_CHANNELS) {
-		printk(KERN_ERR "%s: ppp_slot(%d) now invalid\n",
-			__FUNCTION__, lp->ppp_slot);
-		restore_flags(flags);
-		return 0;
-	}
+
 	is = ippp_table[lp->ppp_slot];
 	if ((is->state & IPPP_CONNECT))
 		isdn_ppp_closewait(lp->ppp_slot);	/* force wakeup on ippp device */
@@ -231,13 +228,12 @@ isdn_ppp_bind(isdn_net_local * lp)
 void
 isdn_ppp_wakeup_daemon(isdn_net_local * lp)
 {
-	if (lp->ppp_slot < 0 || lp->ppp_slot >= ISDN_MAX_CHANNELS) {
-		printk(KERN_ERR "%s: ppp_slot(%d) out of range\n",
-			__FUNCTION__, lp->ppp_slot);
+	if (lp->ppp_slot < 0 || lp->ppp_slot >= ISDN_MAX_CHANNELS)
 		return;
-	}
+
 	ippp_table[lp->ppp_slot]->state = IPPP_OPEN | IPPP_CONNECT | IPPP_NOBLOCK;
-	wake_up_interruptible(&ippp_table[lp->ppp_slot]->wq);
+
+		wake_up_interruptible(&ippp_table[lp->ppp_slot]->wq);
 }
 
 /*
@@ -250,14 +246,13 @@ isdn_ppp_closewait(int slot)
 {
 	struct ippp_struct *is;
 
-	if (slot < 0 || slot >= ISDN_MAX_CHANNELS) {
-		printk(KERN_ERR "%s: slot(%d) out of range\n",
-			__FUNCTION__, slot);
+	if (slot < 0 || slot >= ISDN_MAX_CHANNELS)
 		return 0;
-	}
 	is = ippp_table[slot];
+
 	if (is->state)
 		wake_up_interruptible(&is->wq);
+
 	is->state = IPPP_CLOSEWAIT;
 	return 1;
 }
@@ -295,9 +290,11 @@ isdn_ppp_open(int min, struct file *file
 		return -EBUSY;
 	}
 	is = file->private_data = ippp_table[slot];
-	
-	printk(KERN_DEBUG "ippp, open, slot: %d, minor: %d, state: %04x\n",
-	       slot, min, is->state);
+
+#if 0
+	if (is->debug & 0x1)
+#endif
+		printk(KERN_DEBUG "ippp, open, slot: %d, minor: %d, state: %04x\n", slot, min, is->state);
 
 	/* compression stuff */
 	is->link_compressor   = is->compressor = NULL;
@@ -327,10 +324,7 @@ isdn_ppp_open(int min, struct file *file
 	 */
 	is->slcomp = slhc_init(16, 16);	/* not necessary for 2. link in bundle */
 #endif
-#ifdef CONFIG_IPPP_FILTER
-	is->pass_filter.filter = NULL;
-	is->active_filter.filter = NULL;
-#endif
+
 	is->state = IPPP_OPEN;
 
 	return 0;
@@ -349,20 +343,12 @@ isdn_ppp_release(int min, struct file *f
 		return;
 	is = file->private_data;
 
-	if (!is) {
-		printk(KERN_ERR "%s: no file->private_data\n", __FUNCTION__);
-		return;
-	}
 	if (is->debug & 0x1)
 		printk(KERN_DEBUG "ippp: release, minor: %d %lx\n", min, (long) is->lp);
 
 	if (is->lp) {           /* a lp address says: this link is still up */
 		isdn_net_dev *p = is->lp->netdev;
 
-		if (!p) {
-			printk(KERN_ERR "%s: no lp->netdev\n", __FUNCTION__);
-			return;
-		}
 		is->state &= ~IPPP_CONNECT;	/* -> effect: no call of wakeup */
 		/*
 		 * isdn_net_hangup() calls isdn_ppp_free()
@@ -385,18 +371,8 @@ isdn_ppp_release(int min, struct file *f
 	slhc_free(is->slcomp);
 	is->slcomp = NULL;
 #endif
-#ifdef CONFIG_IPPP_FILTER
-	if (is->pass_filter.filter) {
-		kfree(is->pass_filter.filter);
-		is->pass_filter.filter = NULL;
-	}
-	if (is->active_filter.filter) {
-		kfree(is->active_filter.filter);
-		is->active_filter.filter = NULL;
-	}
-#endif
 
-/* TODO: if this was the previous master: link the stuff to the new master */
+/* TODO: if this was the previous master: link the the stuff to the new master */
 	if(is->comp_stat)
 		is->compressor->free(is->comp_stat);
 	if(is->link_comp_stat)
@@ -509,13 +485,15 @@ isdn_ppp_ioctl(int min, struct file *fil
 			if (val & SC_ENABLE_IP && !(is->pppcfg & SC_ENABLE_IP) && (is->state & IPPP_CONNECT)) {
 				if (lp) {
 					/* OK .. we are ready to send buffers */
-					is->pppcfg = val; /* isdn_ppp_xmit test for SC_ENABLE_IP !!! */
 					netif_wake_queue(&lp->netdev->dev);
-					break;
 				}
 			}
 			is->pppcfg = val;
 			break;
+#if 0
+		case PPPIOCGSTAT:	/* read PPP statistic information */
+			break;
+#endif
 		case PPPIOCGIDLE:	/* get idle time information */
 			if (lp) {
 				struct ppp_idle pidle;
@@ -604,39 +582,6 @@ isdn_ppp_ioctl(int min, struct file *fil
 				}
 				return set_arg((void *)arg,&pci,sizeof(struct pppcallinfo));
 			}
-#ifdef CONFIG_IPPP_FILTER
-		case PPPIOCSPASS:
-		case PPPIOCSACTIVE:
-			{
-				struct sock_fprog uprog, *filtp;
-				struct sock_filter *code = NULL;
-				int len, err;
-
-				if (copy_from_user(&uprog, (void *) arg, sizeof(uprog)))
-					return -EFAULT;
-				if (uprog.len > 0 && uprog.len < 65536) {
-					len = uprog.len * sizeof(struct sock_filter);
-					code = kmalloc(len, GFP_KERNEL);
-					if (code == NULL)
-						return -ENOMEM;
-					if (copy_from_user(code, uprog.filter, len)) {
-						kfree(code);
-						return -EFAULT;
-					}
-					err = sk_chk_filter(code, uprog.len);
-					if (err) {
-						kfree(code);
-						return err;
-					}
-				}
-				filtp = (cmd == PPPIOCSPASS) ? &is->pass_filter : &is->active_filter;
-				if (filtp->filter)
-					kfree(filtp->filter);
-				filtp->filter = code;
-				filtp->len = uprog.len;
-				break;
-			}
-#endif /* CONFIG_IPPP_FILTER */
 		default:
 			break;
 	}
@@ -699,7 +644,7 @@ isdn_ppp_fill_rq(unsigned char *buf, int
 	struct ippp_struct *is;
 
 	if (slot < 0 || slot >= ISDN_MAX_CHANNELS) {
-		printk(KERN_WARNING "ippp: illegal slot(%d).\n", slot);
+		printk(KERN_WARNING "ippp: illegal slot.\n");
 		return 0;
 	}
 	is = ippp_table[slot];
@@ -976,8 +921,7 @@ void isdn_ppp_receive(isdn_net_dev * net
 
 	slot = lp->ppp_slot;
 	if (slot < 0 || slot > ISDN_MAX_CHANNELS) {
-		printk(KERN_ERR "isdn_ppp_receive: lp->ppp_slot(%d)\n",
-			lp->ppp_slot);
+		printk(KERN_ERR "isdn_ppp_receive: lp->ppp_slot %d\n", lp->ppp_slot);
 		kfree_skb(skb);
 		return;
 	}
@@ -1026,23 +970,19 @@ isdn_ppp_push_higher(isdn_net_dev * net_
 {
 	struct net_device *dev = &net_dev->dev;
  	struct ippp_struct *is, *mis;
-	isdn_net_local *mlp = NULL;
 	int slot;
 
 	slot = lp->ppp_slot;
 	if (slot < 0 || slot > ISDN_MAX_CHANNELS) {
-		printk(KERN_ERR "isdn_ppp_push_higher: lp->ppp_slot(%d)\n",
-			lp->ppp_slot);
+		printk(KERN_ERR "isdn_ppp_push_higher: lp->ppp_slot %d\n", lp->ppp_slot);
 		goto drop_packet;
 	}
 	is = ippp_table[slot];
  	
  	if (lp->master) { // FIXME?
-		mlp = (isdn_net_local *) lp->master->priv;
- 		slot = mlp->ppp_slot;
+ 		slot = ((isdn_net_local *) (lp->master->priv))->ppp_slot;
  		if (slot < 0 || slot > ISDN_MAX_CHANNELS) {
- 			printk(KERN_ERR "isdn_ppp_push_higher: master->ppp_slot(%d)\n",
- 				lp->ppp_slot);
+ 			printk(KERN_ERR "isdn_ppp_push_higher: master->ppp_slot %d\n", lp->ppp_slot);
 			goto drop_packet;
  		}
  	}
@@ -1076,11 +1016,6 @@ isdn_ppp_push_higher(isdn_net_dev * net_
 		case PPP_VJC_UNCOMP:
 			if (is->debug & 0x20)
 				printk(KERN_DEBUG "isdn_ppp: VJC_UNCOMP\n");
-			if (net_dev->local->ppp_slot < 0) {
-				printk(KERN_ERR "%s: net_dev->local->ppp_slot(%d) out of range\n",
-					__FUNCTION__, net_dev->local->ppp_slot);
-				goto drop_packet;
-			}
 			if (slhc_remember(ippp_table[net_dev->local->ppp_slot]->slcomp, skb->data, skb->len) <= 0) {
 				printk(KERN_WARNING "isdn_ppp: received illegal VJC_UNCOMP frame!\n");
 				goto drop_packet;
@@ -1102,11 +1037,6 @@ isdn_ppp_push_higher(isdn_net_dev * net_
 				}
 				skb_put(skb, skb_old->len + 128);
 				memcpy(skb->data, skb_old->data, skb_old->len);
-				if (net_dev->local->ppp_slot < 0) {
-					printk(KERN_ERR "%s: net_dev->local->ppp_slot(%d) out of range\n",
-						__FUNCTION__, net_dev->local->ppp_slot);
-					goto drop_packet;
-				}
 				pkt_len = slhc_uncompress(ippp_table[net_dev->local->ppp_slot]->slcomp,
 						skb->data, skb_old->len);
 				kfree_skb(skb_old);
@@ -1133,36 +1063,12 @@ isdn_ppp_push_higher(isdn_net_dev * net_
 			return;
 	}
 
-#ifdef CONFIG_IPPP_FILTER
-	/* check if the packet passes the pass and active filters
-	 * the filter instructions are constructed assuming
-	 * a four-byte PPP header on each packet (which is still present) */
-	skb_push(skb, 4);
-	skb->data[0] = 0;	/* indicate inbound */
-
-	if (is->pass_filter.filter
-	    && sk_run_filter(skb, is->pass_filter.filter,
-	                    is->pass_filter.len) == 0) {
-		if (is->debug & 0x2)
-			printk(KERN_DEBUG "IPPP: inbound frame filtered.\n");
-		kfree_skb(skb);
-		return;
-	}
-	if (!(is->active_filter.filter
-	      && sk_run_filter(skb, is->active_filter.filter,
-	                       is->active_filter.len) == 0)) {
-		if (is->debug & 0x2)
-			printk(KERN_DEBUG "IPPP: link-active filter: reseting huptimer.\n");
-		lp->huptimer = 0;
-		if (mlp)
-			mlp->huptimer = 0;
-	}
-	skb_pull(skb, 4);
-#else /* CONFIG_IPPP_FILTER */
-	lp->huptimer = 0;
-	if (mlp)
-		mlp->huptimer = 0;
-#endif /* CONFIG_IPPP_FILTER */
+ 	/* Reset hangup-timer */
+ 	lp->huptimer = 0;
+#ifdef CONFIG_ISDN_WITH_ABC_CONN_ERROR
+	lp->dw_abc_bchan_errcnt = 0;
+#endif
+
 	skb->dev = dev;
 	skb->mac.raw = skb->data;
 	netif_rx(skb);
@@ -1199,6 +1105,7 @@ static unsigned char *isdn_ppp_skb_push(
 	return skb_push(skb,len);
 }
 
+
 /*
  * send ppp frame .. we expect a PIDCOMPressable proto --
  *  (here: currently always PPP_IP,PPP_VJC_COMP,PPP_VJC_UNCOMP)
@@ -1214,25 +1121,23 @@ isdn_ppp_xmit(struct sk_buff *skb, struc
 	isdn_net_dev *nd;
 	unsigned int proto = PPP_IP;     /* 0x21 */
 	struct ippp_struct *ipt,*ipts;
-	int slot, retval = 0;
+	int slot;
 
 	mlp = (isdn_net_local *) (netdev->priv);
 	nd = mlp->netdev;       /* get master lp */
 
 	slot = mlp->ppp_slot;
 	if (slot < 0 || slot > ISDN_MAX_CHANNELS) {
-		printk(KERN_ERR "isdn_ppp_xmit: lp->ppp_slot(%d)\n",
-			mlp->ppp_slot);
+		printk(KERN_ERR "isdn_ppp_xmit: lp->ppp_slot %d\n", mlp->ppp_slot);
 		kfree_skb(skb);
-		goto out;
+		return 0;
 	}
 	ipts = ippp_table[slot];
 
 	if (!(ipts->pppcfg & SC_ENABLE_IP)) {	/* PPP connected ? */
 		if (ipts->debug & 0x1)
 			printk(KERN_INFO "%s: IP frame delayed.\n", netdev->name);
-		retval = 1;
-		goto out;
+		return 1;
 	}
 
 	switch (ntohs(skb->protocol)) {
@@ -1246,25 +1151,24 @@ isdn_ppp_xmit(struct sk_buff *skb, struc
 			printk(KERN_ERR "isdn_ppp: skipped unsupported protocol: %#x.\n", 
 			       skb->protocol);
 			dev_kfree_skb(skb);
-			goto out;
+			return 0;
 	}
 
 	lp = isdn_net_get_locked_lp(nd);
 	if (!lp) {
 		printk(KERN_WARNING "%s: all channels busy - requeuing!\n", netdev->name);
-		retval = 1;
-		goto out;
+		return 1;
 	}
 	/* we have our lp locked from now on */
 
 	slot = lp->ppp_slot;
 	if (slot < 0 || slot > ISDN_MAX_CHANNELS) {
-		printk(KERN_ERR "isdn_ppp_xmit: lp->ppp_slot(%d)\n",
-			lp->ppp_slot);
+		printk(KERN_ERR "isdn_ppp_xmit: lp->ppp_slot %d\n", lp->ppp_slot);
 		kfree_skb(skb);
-		goto unlock;
+		return 0;
 	}
 	ipt = ippp_table[slot];
+	lp->huptimer = 0;
 
 	/*
 	 * after this line .. requeueing in the device queue is no longer allowed!!!
@@ -1275,34 +1179,6 @@ isdn_ppp_xmit(struct sk_buff *skb, struc
 	 */
 	skb_pull(skb,IPPP_MAX_HEADER);
 
-#ifdef CONFIG_IPPP_FILTER
-	/* check if we should pass this packet
-	 * the filter instructions are constructed assuming
-	 * a four-byte PPP header on each packet */
-	skb_push(skb, 4);
-	skb->data[0] = 1;	/* indicate outbound */
-	*(u_int16_t *)(skb->data + 2) = htons(proto);
-
-	if (ipt->pass_filter.filter 
-	    && sk_run_filter(skb, ipt->pass_filter.filter,
-		             ipt->pass_filter.len) == 0) {
-		if (ipt->debug & 0x4)
-			printk(KERN_DEBUG "IPPP: outbound frame filtered.\n");
-		kfree_skb(skb);
-		goto unlock;
-	}
-	if (!(ipt->active_filter.filter
-	      && sk_run_filter(skb, ipt->active_filter.filter,
-		               ipt->active_filter.len) == 0)) {
-		if (ipt->debug & 0x4)
-			printk(KERN_DEBUG "IPPP: link-active filter: reseting huptimer.\n");
-		lp->huptimer = 0;
-	}
-	skb_pull(skb, 4);
-#else /* CONFIG_IPPP_FILTER */
-	lp->huptimer = 0;
-#endif /* CONFIG_IPPP_FILTER */
-
 	if (ipt->debug & 0x4)
 		printk(KERN_DEBUG "xmit skb, len %d\n", (int) skb->len);
         if (ipts->debug & 0x40)
@@ -1440,54 +1316,9 @@ isdn_ppp_xmit(struct sk_buff *skb, struc
 
  unlock:
 	spin_unlock_bh(&lp->xmit_lock);
- out:
-	return retval;
+	return 0;
 }
 
-#ifdef CONFIG_IPPP_FILTER
-/*
- * check if this packet may trigger auto-dial.
- */
-
-int isdn_ppp_autodial_filter(struct sk_buff *skb, isdn_net_local *lp)
-{
-	struct ippp_struct *is = ippp_table[lp->ppp_slot];
-	u_int16_t proto;
-	int drop = 0;
-
-	switch (ntohs(skb->protocol)) {
-	case ETH_P_IP:
-		proto = PPP_IP;
-		break;
-	case ETH_P_IPX:
-		proto = PPP_IPX;
-		break;
-	default:
-		printk(KERN_ERR "isdn_ppp_autodial_filter: unsupported protocol 0x%x.\n",
-		       skb->protocol);
-		return 1;
-	}
-
-	/* the filter instructions are constructed assuming
-	 * a four-byte PPP header on each packet. we have to
-	 * temporarily remove part of the fake header stuck on
-	 * earlier.
-	 */
-	skb_pull(skb, IPPP_MAX_HEADER - 4);
-	skb->data[0] = 1;	/* indicate outbound */
-	*(u_int16_t *)(skb->data + 2) = htons(proto);
-	
-	drop |= is->pass_filter.filter
-	        && sk_run_filter(skb, is->pass_filter.filter,
-	                         is->pass_filter.len) == 0;
-	drop |= is->active_filter.filter
-	        && sk_run_filter(skb, is->active_filter.filter,
-	                         is->active_filter.len) == 0;
-	
-	skb_push(skb, IPPP_MAX_HEADER - 4);
-	return drop;
-}
-#endif
 #ifdef CONFIG_ISDN_MPP
 
 /* this is _not_ rfc1990 header, but something we convert both short and long
@@ -1537,15 +1368,8 @@ static ippp_bundle * isdn_ppp_mp_bundle_
 
 static int isdn_ppp_mp_init( isdn_net_local * lp, ippp_bundle * add_to )
 {
-	struct ippp_struct * is;
-
-	if (lp->ppp_slot < 0) {
-		printk(KERN_ERR "%s: lp->ppp_slot(%d) out of range\n",
-			__FUNCTION__, lp->ppp_slot);
-		return(-EINVAL);
-	}
-
-	is = ippp_table[lp->ppp_slot];
+	struct ippp_struct * is = ippp_table[lp->ppp_slot];
+   
 	if (add_to) {
 		if( lp->netdev->pb )
 			lp->netdev->pb->ref_ct--;
@@ -1591,8 +1415,7 @@ static void isdn_ppp_mp_receive(isdn_net
         stats = &mp->stats;
 	slot = lp->ppp_slot;
 	if (slot < 0 || slot > ISDN_MAX_CHANNELS) {
-		printk(KERN_ERR "%s: lp->ppp_slot(%d)\n",
-			__FUNCTION__, lp->ppp_slot);
+		printk(KERN_ERR "isdn_ppp_mp_receive: lp->ppp_slot %d\n", lp->ppp_slot);
 		stats->frame_drops++;
 		dev_kfree_skb(skb);
 		spin_unlock_irqrestore(&mp->lock, flags);
@@ -1628,8 +1451,7 @@ static void isdn_ppp_mp_receive(isdn_net
 	for (lpq = net_dev->queue;;) {
 		slot = lpq->ppp_slot;
 		if (slot < 0 || slot > ISDN_MAX_CHANNELS) {
-			printk(KERN_ERR "%s: lpq->ppp_slot(%d)\n",
-				__FUNCTION__, lpq->ppp_slot);
+			printk(KERN_ERR "isdn_ppp_mp_receive: lpq->ppp_slot %d\n", lpq->ppp_slot);
 		} else {
 			u32 lls = ippp_table[slot]->last_link_seqno;
 			if (MP_LT(lls, minseq))
@@ -1861,14 +1683,9 @@ void isdn_ppp_mp_reassembly( isdn_net_de
 	struct sk_buff * skb;
 	unsigned int tot_len;
 
-	if (lp->ppp_slot < 0 || lp->ppp_slot > ISDN_MAX_CHANNELS) {
-		printk(KERN_ERR "%s: lp->ppp_slot(%d) out of range\n",
-			__FUNCTION__, lp->ppp_slot);
-		return;
-	}
 	if( MP_FLAGS(from) == (MP_BEGIN_FRAG | MP_END_FRAG) ) {
 		if( ippp_table[lp->ppp_slot]->debug & 0x40 )
-			printk(KERN_DEBUG "isdn_mppp: reassembly: frame %d, "
+			printk(KERN_DEBUG"isdn_mppp: reassembly: frame %d, "
 					"len %d\n", MP_SEQ(from), from->len );
 		skb = from;
 		skb_pull(skb, MP_HEADER_LEN);
@@ -1987,10 +1804,8 @@ isdn_ppp_dev_ioctl_stats(int slot, struc
 	memset(&t, 0, sizeof(struct ppp_stats));
 	if (dev->flags & IFF_UP) {
 		t.p.ppp_ipackets = lp->stats.rx_packets;
-		t.p.ppp_ibytes = lp->stats.rx_bytes;
 		t.p.ppp_ierrors = lp->stats.rx_errors;
 		t.p.ppp_opackets = lp->stats.tx_packets;
-		t.p.ppp_obytes = lp->stats.tx_bytes;
 		t.p.ppp_oerrors = lp->stats.tx_errors;
 #ifdef CONFIG_ISDN_PPP_VJ
 		if (slot >= 0 && ippp_table[slot]->slcomp) {
@@ -2018,6 +1833,9 @@ isdn_ppp_dev_ioctl(struct net_device *de
 	int len;
 	isdn_net_local *lp = (isdn_net_local *) dev->priv;
 
+#if 0
+	printk(KERN_DEBUG "ippp, dev_ioctl: cmd %#08x , %d \n", cmd, lp->ppp_slot);
+#endif
 
 	if (lp->p_encap != ISDN_NET_ENCAP_SYNCPPP)
 		return -EINVAL;
@@ -2432,7 +2250,7 @@ static void isdn_ppp_ccp_reset_trans(str
 				return;
 			}
 			rs->state = CCPResetSentReq;
-			/* We always expect an Ack if the decompressor doesn't
+			/* We always expect an Ack if the decompressor doesnt
 			   know	better */
 			rs->expra = 1;
 			rs->dlen = 0;
@@ -2583,7 +2401,13 @@ static struct sk_buff *isdn_ppp_compress
     }
 
 	if(type) { /* type=1 => Link compression */
+#if 0
+		compressor = is->link_compressor;
+		stat = is->link_comp_stat;
+		new_proto = PPP_LINK_COMP;
+#else
 		return skb_in;
+#endif
 	}
 	else {
 		if(!master) {
@@ -2631,31 +2455,18 @@ static struct sk_buff *isdn_ppp_compress
 static void isdn_ppp_receive_ccp(isdn_net_dev *net_dev, isdn_net_local *lp,
 	 struct sk_buff *skb,int proto)
 {
-	struct ippp_struct *is;
+	struct ippp_struct *is = ippp_table[lp->ppp_slot];
 	struct ippp_struct *mis;
 	int len;
 	struct isdn_ppp_resetparams rsparm;
 	unsigned char rsdata[IPPP_RESET_MAXDATABYTES];	
 
-	printk(KERN_DEBUG "Received CCP frame from peer slot(%d)\n",
-		lp->ppp_slot);
-	if (lp->ppp_slot < 0 || lp->ppp_slot > ISDN_MAX_CHANNELS) {
-		printk(KERN_ERR "%s: lp->ppp_slot(%d) out of range\n",
-			__FUNCTION__, lp->ppp_slot);
-		return;
-	}
-	is = ippp_table[lp->ppp_slot];
+	printk(KERN_DEBUG "Received CCP frame from peer\n");
 	isdn_ppp_frame_log("ccp-rcv", skb->data, skb->len, 32, is->unit,lp->ppp_slot);
 
-	if(lp->master) {
-		int slot = ((isdn_net_local *) (lp->master->priv))->ppp_slot;
-		if (slot < 0 || slot > ISDN_MAX_CHANNELS) {
-			printk(KERN_ERR "%s: slot(%d) out of range\n",
-				__FUNCTION__, slot);
-			return;
-		}	
-		mis = ippp_table[slot];
-	} else
+	if(lp->master)
+		mis = ippp_table[((isdn_net_local *) (lp->master->priv))->ppp_slot];
+	else
 		mis = is;
 
 	switch(skb->data[0]) {
@@ -2807,18 +2618,13 @@ static void isdn_ppp_receive_ccp(isdn_ne
 
 static void isdn_ppp_send_ccp(isdn_net_dev *net_dev, isdn_net_local *lp, struct sk_buff *skb)
 {
-	struct ippp_struct *mis,*is;
-	int proto, slot = lp->ppp_slot;
+	struct ippp_struct *mis,*is = ippp_table[lp->ppp_slot];
+	int proto;
 	unsigned char *data;
 
 	if(!skb || skb->len < 3)
 		return;
-	if (slot < 0 || slot > ISDN_MAX_CHANNELS) {
-		printk(KERN_ERR "%s: lp->ppp_slot(%d) out of range\n",
-			__FUNCTION__, slot);
-		return;
-	}	
-	is = ippp_table[slot];
+
 	/* Daemon may send with or without address and control field comp */
 	data = skb->data;
 	if(!(is->pppcfg & SC_COMP_AC) && data[0] == 0xff && data[1] == 0x03) {
@@ -2834,17 +2640,12 @@ static void isdn_ppp_send_ccp(isdn_net_d
 	printk(KERN_DEBUG "Received CCP frame from daemon:\n");
 	isdn_ppp_frame_log("ccp-xmit", skb->data, skb->len, 32, is->unit,lp->ppp_slot);
 
-	if (lp->master) {
-		slot = ((isdn_net_local *) (lp->master->priv))->ppp_slot;
-		if (slot < 0 || slot > ISDN_MAX_CHANNELS) {
-			printk(KERN_ERR "%s: slot(%d) out of range\n",
-				__FUNCTION__, slot);
-			return;
-		}	
-		mis = ippp_table[slot];
-	} else
-		mis = is;
-	if (mis != is)
+        if(lp->master)
+                mis = ippp_table[((isdn_net_local *) (lp->master->priv))->ppp_slot];
+        else
+                mis = is;
+	
+	if(mis != is)
 		printk(KERN_DEBUG "isdn_ppp: Ouch! Master CCP sends on slave slot!\n");
 	
         switch(data[2]) {
--- a/drivers/isdn/isdn_ppp.h
+++ b/drivers/isdn/isdn_ppp.h
@@ -1,4 +1,4 @@
-/* $Id: isdn_ppp.h,v 1.1.4.1 2001/11/20 14:19:34 kai Exp $
+/* $Id: isdn_ppp.h,v 1.18 2001/09/24 13:22:42 kai Exp $
  *
  * header for Linux ISDN subsystem, functions for synchronous PPP (linklevel).
  *
@@ -19,7 +19,6 @@ extern int isdn_ppp_init(void);
 extern void isdn_ppp_cleanup(void);
 extern int isdn_ppp_free(isdn_net_local *);
 extern int isdn_ppp_bind(isdn_net_local *);
-extern int isdn_ppp_autodial_filter(struct sk_buff *, isdn_net_local *);
 extern int isdn_ppp_xmit(struct sk_buff *, struct net_device *);
 extern void isdn_ppp_receive(isdn_net_dev *, isdn_net_local *, struct sk_buff *);
 extern int isdn_ppp_dev_ioctl(struct net_device *, struct ifreq *, int);
--- a/drivers/isdn/isdn_tty.c
+++ b/drivers/isdn/isdn_tty.c
@@ -1,4 +1,4 @@
-/* $Id: isdn_tty.c,v 1.1.4.1 2001/11/20 14:19:34 kai Exp $
+/* $Id: isdn_tty.c,v 1.104 2002/02/09 21:19:11 keil Exp $
  *
  * Linux ISDN subsystem, tty functions and AT-command emulator (linklevel).
  *
@@ -53,7 +53,7 @@ static int bit2si[8] =
 static int si2bit[8] =
 {4, 1, 4, 4, 4, 4, 4, 4};
 
-char *isdn_tty_revision = "$Revision: 1.1.4.1 $";
+char *isdn_tty_revision = "$Revision: 1.104 $";
 
 
 /* isdn_tty_try_read() is called from within isdn_tty_rcv_skb()
@@ -321,7 +321,10 @@ isdn_tty_tint(modem_info * info)
 		info->send_outstanding++;
 		info->msr &= ~UART_MSR_CTS;
 		info->lsr &= ~UART_LSR_TEMT;
-		tty_wakeup(tty);
+		if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
+		    tty->ldisc.write_wakeup)
+			(tty->ldisc.write_wakeup) (tty);
+		wake_up_interruptible(&tty->write_wait);
 		return;
 	}
 	if (slen < 0) {
@@ -1211,7 +1214,10 @@ isdn_tty_write(struct tty_struct *tty, i
 						/* If DLE decoding results in zero-transmit, but
 						 * c originally was non-zero, do a wakeup.
 						 */
-						tty_wakeup(tty);
+						if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
+						 tty->ldisc.write_wakeup)
+							(tty->ldisc.write_wakeup) (tty);
+						wake_up_interruptible(&tty->write_wait);
 						info->msr |= UART_MSR_CTS;
 						info->lsr |= UART_LSR_TEMT;
 					}
@@ -1232,6 +1238,7 @@ isdn_tty_write(struct tty_struct *tty, i
 					}
 				}
 			} else
+#ifdef ISDN_TTY_FCLASS1
 			if (TTY_IS_FCLASS1(info)) {
 				int cc = isdn_tty_handleDLEdown(info, m, c);
 				
@@ -1252,6 +1259,7 @@ isdn_tty_write(struct tty_struct *tty, i
 				info->xmit_count += cc;
 			} else
 #endif
+#endif
 				info->xmit_count += c;
 		} else {
 			info->msr |= UART_MSR_CTS;
@@ -1329,7 +1337,10 @@ isdn_tty_flush_buffer(struct tty_struct 
 	isdn_tty_cleanup_xmit(info);
 	info->xmit_count = 0;
 	restore_flags(flags);
-	tty_wakeup(tty);
+	wake_up_interruptible(&tty->write_wait);
+	if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
+	    tty->ldisc.write_wakeup)
+		(tty->ldisc.write_wakeup) (tty);
 }
 
 static void
@@ -1858,7 +1869,8 @@ isdn_tty_close(struct tty_struct *tty, s
 	isdn_tty_shutdown(info);
 	if (tty->driver.flush_buffer)
 		tty->driver.flush_buffer(tty);
-	tty_ldisc_flush(tty);
+	if (tty->ldisc.flush_buffer)
+		tty->ldisc.flush_buffer(tty);
 	info->tty = 0;
 	info->ncarrier = 0;
 	tty->closing = 0;
@@ -2306,6 +2318,22 @@ isdn_tty_stat_callback(int i, isdn_ctrl 
 				  isdn_tty_at_cout("\r\n", info);
 				}
 				return 1;
+			case ISDN_STAT_ALERT:
+#ifdef ISDN_TTY_STAT_DEBUG
+				printk(KERN_DEBUG "tty_STAT_ALERT ttyI%d\n", info->line);
+#endif
+				/* Signal RINGING to tty-device if requested */
+				if (info->emu.mdmreg[REG_ALERT] & BIT_ALERT)
+					isdn_tty_modem_result(RESULT_RINGING, info);
+				return 1;
+			case ISDN_STAT_PROCEED:
+#ifdef ISDN_TTY_STAT_DEBUG
+				printk(KERN_DEBUG "tty_STAT_PROCEED ttyI%d\n", info->line);
+#endif
+				/* Signal PROCEEDING to tty-device if requested */
+				if (info->emu.mdmreg[REG_PROCEED] & BIT_PROCEED)
+					isdn_tty_modem_result(RESULT_PROCEEDING, info);
+				return 1;
 			case ISDN_STAT_DCONN:
 #ifdef ISDN_TTY_STAT_DEBUG
 				printk(KERN_DEBUG "tty_STAT_DCONN ttyI%d\n", info->line);
@@ -2618,7 +2646,7 @@ isdn_tty_modem_result(int code, modem_in
 	static char *msg[] =
 	{"OK", "CONNECT", "RING", "NO CARRIER", "ERROR",
 	 "CONNECT 64000", "NO DIALTONE", "BUSY", "NO ANSWER",
-	 "RINGING", "NO MSN/EAZ", "VCON", "RUNG"};
+	 "RINGING", "NO MSN/EAZ", "VCON", "RUNG", "PROCEEDING"};
 	ulong flags;
 	char s[ISDN_MSNLEN+10];
 
@@ -2781,7 +2809,8 @@ isdn_tty_modem_result(int code, modem_in
 			restore_flags(flags);
 			return;
 		}
-		tty_ldisc_flush(info->tty);
+		if (info->tty->ldisc.flush_buffer)
+			info->tty->ldisc.flush_buffer(info->tty);
 		if ((info->flags & ISDN_ASYNC_CHECK_CD) &&
 		    (!((info->flags & ISDN_ASYNC_CALLOUT_ACTIVE) &&
 		       (info->flags & ISDN_ASYNC_CALLOUT_NOHUP)))) {
@@ -3296,9 +3325,11 @@ isdn_tty_cmd_PLUSF(char **p, modem_info 
 #ifdef CONFIG_ISDN_TTY_FAX
 				if (TTY_IS_FCLASS2(info))
 						sprintf(rs, "\r\n2");
+#ifdef ISDN_TTY_FCLASS1
 				else if (TTY_IS_FCLASS1(info))
 						sprintf(rs, "\r\n1");
 #endif
+#endif
 				isdn_tty_at_cout(rs, info);
 				break;
 			case '=':
@@ -3313,6 +3344,7 @@ isdn_tty_cmd_PLUSF(char **p, modem_info 
 						    m->mdmreg[REG_PSIZE] * 16;
 						break;
 #ifdef CONFIG_ISDN_TTY_FAX
+#ifdef ISDN_TTY_FCLASS1
 					case '1':
 						p[0]++;
 						if (!(dev->global_features &
@@ -3324,6 +3356,7 @@ isdn_tty_cmd_PLUSF(char **p, modem_info 
 						info->xmit_size =
 						    m->mdmreg[REG_PSIZE] * 16;
 						break;
+#endif
 					case '2':
 						p[0]++;
 						if (!(dev->global_features &
@@ -3348,9 +3381,11 @@ isdn_tty_cmd_PLUSF(char **p, modem_info 
 						p[0]++;
 						strcpy(rs, "\r\n0,");
 #ifdef CONFIG_ISDN_TTY_FAX
+#ifdef ISDN_TTY_FCLASS1
 						if (dev->global_features &
 							ISDN_FEATURE_L3_FCLASS1)
 							strcat(rs, "1,");
+#endif
 						if (dev->global_features &
 							ISDN_FEATURE_L3_FCLASS2)
 							strcat(rs, "2,");
--- a/drivers/isdn/isdn_tty.h
+++ b/drivers/isdn/isdn_tty.h
@@ -1,4 +1,4 @@
-/* $Id: isdn_tty.h,v 1.1.4.1 2001/11/20 14:19:34 kai Exp $
+/* $Id: isdn_tty.h,v 1.25 2002/02/09 21:19:11 keil Exp $
  *
  * header for Linux ISDN subsystem, tty related functions (linklevel).
  *
@@ -78,6 +78,10 @@
 #define BIT_CPNFCON   2
 #define REG_CDN      23
 #define BIT_CDN       4
+#define REG_ALERT    23
+#define BIT_ALERT     8
+#define REG_PROCEED  23
+#define BIT_PROCEED  16
 
 /* defines for result codes */
 #define RESULT_OK		0
@@ -93,10 +97,13 @@
 #define RESULT_NO_MSN_EAZ	10
 #define RESULT_VCON		11
 #define RESULT_RUNG		12
+#define RESULT_PROCEEDING	13
 
+#ifdef ISDN_TTY_FCLASS1
 #define TTY_IS_FCLASS1(info) \
 	((info->emu.mdmreg[REG_L2PROT] == ISDN_PROTO_L2_FAX) && \
 	 (info->emu.mdmreg[REG_L3PROT] == ISDN_PROTO_L3_FCLASS1))
+#endif
 #define TTY_IS_FCLASS2(info) \
 	((info->emu.mdmreg[REG_L2PROT] == ISDN_PROTO_L2_FAX) && \
 	 (info->emu.mdmreg[REG_L3PROT] == ISDN_PROTO_L3_FCLASS2))
--- a/drivers/isdn/isdn_ttyfax.c
+++ b/drivers/isdn/isdn_ttyfax.c
@@ -1,4 +1,4 @@
-/* $Id: isdn_ttyfax.c,v 1.1.4.1 2001/11/20 14:19:34 kai Exp $
+/* $Id: isdn_ttyfax.c,v 1.9 2001/09/24 13:22:43 kai Exp $
  *
  * Linux ISDN subsystem, tty_fax AT-command emulator (linklevel).
  *
@@ -20,7 +20,7 @@
 #include "isdn_ttyfax.h"
 
 
-static char *isdn_tty_fax_revision = "$Revision: 1.1.4.1 $";
+static char *isdn_tty_fax_revision = "$Revision: 1.9 $";
 
 #define PARSE_ERROR1 { isdn_tty_fax_modem_result(1, info); return 1; }
 
@@ -148,6 +148,7 @@ isdn_tty_fax_modem_result(int code, mode
 	}
 }
 
+#ifdef ISDN_TTY_FCLASS1
 int
 isdn_tty_fax_command1(modem_info * info, isdn_ctrl * c)
 {
@@ -186,6 +187,7 @@ isdn_tty_fax_command1(modem_info * info,
 	}
 	return (0);
 }
+#endif
 
 int
 isdn_tty_fax_command(modem_info * info, isdn_ctrl * c)
@@ -193,8 +195,10 @@ isdn_tty_fax_command(modem_info * info, 
 	T30_s *f = info->fax;
 	char rs[10];
 
+#ifdef ISDN_TTY_FCLASS1
 	if (TTY_IS_FCLASS1(info))
 		return (isdn_tty_fax_command1(info, c));
+#endif
 
 #ifdef ISDN_TTY_FAX_CMD_DEBUG
 	printk(KERN_DEBUG "isdn_tty: Fax cmd %d on ttyI%d\n",
@@ -312,6 +316,7 @@ isdn_tty_fax_bitorder(modem_info * info,
 	}
 }
 
+#ifdef ISDN_TTY_FCLASS1
 /*
  * Parse AT+F.. FAX class 1 commands
  */
@@ -403,6 +408,7 @@ isdn_tty_cmd_FCLASS1(char **p, modem_inf
 	}
 	return 1;
 }
+#endif
 
 /*
  * Parse AT+F.. FAX class 2 commands
@@ -970,6 +976,70 @@ isdn_tty_cmd_FCLASS2(char **p, modem_inf
 		}
 		return 0;
 	}
+#if 0
+	/* LO=n - Flow control opts */
+	if (!strncmp(p[0], "LO", 2)) {	/* TODO */
+		p[0] += 2;
+		switch (*p[0]) {
+			case '?':
+				p[0]++;
+				sprintf(rs, "\r\n%d", f->lo);
+				isdn_tty_at_cout(rs, info);
+				break;
+			case '=':
+				p[0]++;
+				if (*p[0] == '?') {
+					p[0]++;
+					sprintf(rs, "\r\n0,1,2");
+					isdn_tty_at_cout(rs, info);
+				} else {
+					par = isdn_getnum(p);
+					if ((par < 0) || (par > 2))
+						PARSE_ERROR1;
+					f->lo = par;
+#ifdef ISDN_TTY_FAX_STAT_DEBUG
+					printk(KERN_DEBUG "isdn_tty: Fax FLO=%d\n", par);
+#endif
+				}
+				break;
+			default:
+				PARSE_ERROR1;
+		}
+		return 0;
+	}
+#endif
+#if 0
+	/* LPL=n - Doc for polling cmd  */
+	if (!strncmp(p[0], "LPL", 3)) {		/* TODO */
+		p[0] += 3;
+		switch (*p[0]) {
+			case '?':
+				p[0]++;
+				sprintf(rs, "\r\n%d", f->lpl);
+				isdn_tty_at_cout(rs, info);
+				break;
+			case '=':
+				p[0]++;
+				if (*p[0] == '?') {
+					p[0]++;
+					sprintf(rs, "\r\n0,1");
+					isdn_tty_at_cout(rs, info);
+				} else {
+					par = isdn_getnum(p);
+					if ((par < 0) || (par > 1))
+						PARSE_ERROR1;
+					f->lpl = par;
+#ifdef ISDN_TTY_FAX_STAT_DEBUG
+					printk(KERN_DEBUG "isdn_tty: Fax FLPL=%d\n", par);
+#endif
+				}
+				break;
+			default:
+				PARSE_ERROR1;
+		}
+		return 0;
+	}
+#endif
 
 	/* MDL? - DCE Model       */
 	if (!strncmp(p[0], "MDL?", 4)) {
@@ -1049,6 +1119,38 @@ isdn_tty_cmd_FCLASS2(char **p, modem_inf
 		}
 		return 0;
 	}
+#if 0
+	/* PTS=n - Page transfer status       */
+	if (!strncmp(p[0], "PTS", 3)) {		/* TODO */
+		p[0] += 3;
+		switch (*p[0]) {
+			case '?':
+				p[0]++;
+				sprintf(rs, "\r\n%d", f->pts);
+				isdn_tty_at_cout(rs, info);
+				break;
+			case '=':
+				p[0]++;
+				if (*p[0] == '?') {
+					p[0]++;
+					sprintf(rs, "\r\n0-5");
+					isdn_tty_at_cout(rs, info);
+				} else {
+					par = isdn_getnum(p);
+					if ((par < 0) || (par > 5))
+						PARSE_ERROR1;
+					f->pts = par;
+#ifdef ISDN_TTY_FAX_STAT_DEBUG
+					printk(KERN_DEBUG "isdn_tty: Fax FPTS=%d\n", par);
+#endif
+				}
+				break;
+			default:
+				PARSE_ERROR1;
+		}
+		return 0;
+	}
+#endif
 
 	/* REL=n - Phase C received EOL alignment */
 	if (!strncmp(p[0], "REL", 3)) {
@@ -1091,6 +1193,38 @@ isdn_tty_cmd_FCLASS2(char **p, modem_inf
 		isdn_tty_at_cout(rs, info);
 		return 0;
 	}
+#if 0
+	/* SPL=n - Enable polling */
+	if (!strncmp(p[0], "SPL", 3)) {		/* TODO */
+		p[0] += 3;
+		switch (*p[0]) {
+			case '?':
+				p[0]++;
+				sprintf(rs, "\r\n%d", f->spl);
+				isdn_tty_at_cout(rs, info);
+				break;
+			case '=':
+				p[0]++;
+				if (*p[0] == '?') {
+					p[0]++;
+					sprintf(rs, "\r\n0,1");
+					isdn_tty_at_cout(rs, info);
+				} else {
+					par = isdn_getnum(p);
+					if ((par < 0) || (par > 1))
+						PARSE_ERROR1;
+					f->spl = par;
+#ifdef ISDN_TTY_FAX_STAT_DEBUG
+					printk(KERN_DEBUG "isdn_tty: Fax FSPL=%d\n", par);
+#endif
+				}
+				break;
+			default:
+				PARSE_ERROR1;
+		}
+		return 0;
+	}
+#endif
 
 	/* Phase C Transmit Data Block Size */
 	if (!strncmp(p[0], "TBC=", 4)) {	/* dummy, not used */
@@ -1116,7 +1250,9 @@ isdn_tty_cmd_PLUSF_FAX(char **p, modem_i
 {
 	if (TTY_IS_FCLASS2(info))
 		return (isdn_tty_cmd_FCLASS2(p, info));
+#ifdef ISDN_TTY_FCLASS1
 	else if (TTY_IS_FCLASS1(info))
 		return (isdn_tty_cmd_FCLASS1(p, info));
+#endif
 	PARSE_ERROR1;
 }
--- a/drivers/isdn/isdn_ttyfax.h
+++ b/drivers/isdn/isdn_ttyfax.h
@@ -1,4 +1,4 @@
-/* $Id: isdn_ttyfax.h,v 1.1.4.1 2001/11/20 14:19:34 kai Exp $
+/* $Id: isdn_ttyfax.h,v 1.3 2001/09/24 13:22:43 kai Exp $
  *
  * header for Linux ISDN subsystem, tty_fax related functions (linklevel).
  *
--- a/drivers/isdn/isdn_v110.c
+++ b/drivers/isdn/isdn_v110.c
@@ -1,4 +1,4 @@
-/* $Id: isdn_v110.c,v 1.1.4.1 2001/11/20 14:19:34 kai Exp $
+/* $Id: isdn_v110.c,v 1.8 2001/09/24 13:22:43 kai Exp $
  *
  * Linux ISDN subsystem, V.110 related functions (linklevel).
  *
@@ -19,7 +19,7 @@
 
 #undef ISDN_V110_DEBUG
 
-char *isdn_v110_revision = "$Revision: 1.1.4.1 $";
+char *isdn_v110_revision = "$Revision: 1.8 $";
 
 #define V110_38400 255
 #define V110_19200  15
@@ -138,6 +138,14 @@ isdn_v110_close(isdn_v110_stream * v)
 		return;
 #ifdef ISDN_V110_DEBUG
 	printk(KERN_DEBUG "v110 close\n");
+#if 0
+	printk(KERN_DEBUG "isdn_v110_close: nbytes=%d\n", v->nbytes);
+	printk(KERN_DEBUG "isdn_v110_close: nbits=%d\n", v->nbits);
+	printk(KERN_DEBUG "isdn_v110_close: key=%d\n", v->key);
+	printk(KERN_DEBUG "isdn_v110_close: SyncInit=%d\n", v->SyncInit);
+	printk(KERN_DEBUG "isdn_v110:close: decodelen=%d\n", v->decodelen);
+	printk(KERN_DEBUG "isdn_v110_close: framelen=%d\n", v->framelen);
+#endif
 #endif
 	kfree(v->encodebuf);
 	kfree(v);
--- a/drivers/isdn/isdn_v110.h
+++ b/drivers/isdn/isdn_v110.h
@@ -1,4 +1,4 @@
-/* $Id: isdn_v110.h,v 1.1.4.1 2001/11/20 14:19:34 kai Exp $
+/* $Id: isdn_v110.h,v 1.5 2001/09/24 13:22:43 kai Exp $
  *
  * Linux ISDN subsystem, V.110 related functions (linklevel).
  *
--- a/drivers/isdn/isdn_x25iface.c
+++ b/drivers/isdn/isdn_x25iface.c
@@ -1,4 +1,4 @@
-/* $Id: isdn_x25iface.c,v 1.1.4.1 2001/11/20 14:19:34 kai Exp $
+/* $Id: isdn_x25iface.c,v 1.10 2001/09/24 13:22:43 kai Exp $
  *
  * Linux ISDN subsystem, X.25 related functions
  *
--- a/drivers/isdn/isdn_x25iface.h
+++ b/drivers/isdn/isdn_x25iface.h
@@ -1,4 +1,4 @@
-/* $Id: isdn_x25iface.h,v 1.1.4.1 2001/11/20 14:19:34 kai Exp $
+/* $Id: isdn_x25iface.h,v 1.4 2001/09/24 13:22:43 kai Exp $
  *
  * header for Linux ISDN subsystem, x.25 related functions
  *
--- a/drivers/isdn/isdnloop/isdnloop.c
+++ b/drivers/isdn/isdnloop/isdnloop.c
@@ -1,4 +1,4 @@
-/* $Id: isdnloop.c,v 1.1.4.1 2001/11/20 14:19:37 kai Exp $
+/* $Id: isdnloop.c,v 1.17 2001/08/30 10:45:42 kai Exp $
  *
  * ISDN low-level module implementing a dummy loop driver.
  *
@@ -14,7 +14,7 @@
 #include <linux/init.h>
 #include "isdnloop.h"
 
-static char *revision = "$Revision: 1.1.4.1 $";
+static char *revision = "$Revision$";
 static char *isdnloop_id;
 
 MODULE_DESCRIPTION("ISDN4Linux: Pseudo Driver that simulates an ISDN card");
@@ -22,8 +22,8 @@ MODULE_AUTHOR("Fritz Elfert");
 MODULE_LICENSE("GPL");
 MODULE_PARM(isdnloop_id, "s");
 MODULE_PARM_DESC(isdnloop_id, "ID-String of first card");
-
-static int isdnloop_addcard(char *);
+  
+  static int isdnloop_addcard(char *);
 
 /*
  * Free queue completely.
@@ -1542,11 +1542,7 @@ isdnloop_init(void)
 	} else
 		strcpy(rev, " ??? ");
 	printk(KERN_NOTICE "isdnloop-ISDN-driver Rev%s\n", rev);
-
-	if (isdnloop_id)
-		return (isdnloop_addcard(isdnloop_id));
-
-	return 0;
+	return (isdnloop_addcard(isdnloop_id));
 }
 
 static void __exit
--- a/drivers/isdn/isdnloop/isdnloop.h
+++ b/drivers/isdn/isdnloop/isdnloop.h
@@ -1,4 +1,4 @@
-/* $Id: isdnloop.h,v 1.1.4.1 2001/11/20 14:19:37 kai Exp $
+/* $Id$
  *
  * Loopback lowlevel module for testing of linklevel.
  *
--- a/drivers/isdn/pcbit/callbacks.c
+++ b/drivers/isdn/pcbit/callbacks.c
@@ -3,7 +3,7 @@
  *
  * Copyright (C) 1996 Universidade de Lisboa
  * 
- * Written by Pedro Roque Marques (pedro_m@yahoo.com)
+ * Written by Pedro Roque Marques (roque@di.fc.ul.pt)
  *
  * This software may be used and distributed according to the terms of 
  * the GNU General Public License, incorporated herein by reference.
--- a/drivers/isdn/pcbit/callbacks.h
+++ b/drivers/isdn/pcbit/callbacks.h
@@ -3,7 +3,7 @@
  *
  * Copyright (C) 1996 Universidade de Lisboa
  * 
- * Written by Pedro Roque Marques (pedro_m@yahoo.com)
+ * Written by Pedro Roque Marques (roque@di.fc.ul.pt)
  *
  * This software may be used and distributed according to the terms of 
  * the GNU General Public License, incorporated herein by reference.
--- a/drivers/isdn/pcbit/capi.c
+++ b/drivers/isdn/pcbit/capi.c
@@ -4,7 +4,7 @@
  *
  * Copyright (C) 1996 Universidade de Lisboa
  * 
- * Written by Pedro Roque Marques (pedro_m@yahoo.com)
+ * Written by Pedro Roque Marques (roque@di.fc.ul.pt)
  *
  * This software may be used and distributed according to the terms of 
  * the GNU General Public License, incorporated herein by reference.
--- a/drivers/isdn/pcbit/capi.h
+++ b/drivers/isdn/pcbit/capi.h
@@ -3,7 +3,7 @@
  *
  * Copyright (C) 1996 Universidade de Lisboa
  * 
- * Written by Pedro Roque Marques (pedro_m@yahoo.com)
+ * Written by Pedro Roque Marques (roque@di.fc.ul.pt)
  *
  * This software may be used and distributed according to the terms of 
  * the GNU General Public License, incorporated herein by reference.
@@ -63,7 +63,8 @@ extern int capi_disc_resp(struct pcbit_c
 extern int capi_decode_debug_188(u_char *hdr, ushort hdrlen);
 #endif
 
-static inline struct pcbit_chan * 
+extern __inline__ 
+struct pcbit_chan * 
 capi_channel(struct pcbit_dev *dev, struct sk_buff *skb)
 {
 	ushort callref;
--- a/drivers/isdn/pcbit/drv.c
+++ b/drivers/isdn/pcbit/drv.c
@@ -3,7 +3,7 @@
  *
  * Copyright (C) 1996 Universidade de Lisboa
  * 
- * Written by Pedro Roque Marques (pedro_m@yahoo.com)
+ * Written by Pedro Roque Marques (roque@di.fc.ul.pt)
  *
  * This software may be used and distributed according to the terms of 
  * the GNU General Public License, incorporated herein by reference.
@@ -35,7 +35,9 @@
 #include <linux/isdnif.h>
 #include <asm/string.h>
 #include <asm/io.h>
+#ifdef COMPAT_HAS_ISA_IOREMAP
 #include <linux/ioport.h>
+#endif
 
 #include "pcbit.h"
 #include "edss1.h"
@@ -89,6 +91,7 @@ int pcbit_init_dev(int board, int mem_ba
 
 	if (mem_base >= 0xA0000 && mem_base <= 0xFFFFF ) {
 		dev->ph_mem = mem_base;
+#ifdef COMPAT_HAS_ISA_IOREMAP
 		if (check_mem_region(dev->ph_mem, 4096)) {
 			printk(KERN_WARNING
 				"PCBIT: memory region %lx-%lx already in use\n",
@@ -100,6 +103,9 @@ int pcbit_init_dev(int board, int mem_ba
 			request_mem_region(dev->ph_mem, 4096, "PCBIT mem");
 		}
 		dev->sh_mem = (unsigned char*)ioremap(dev->ph_mem, 4096);
+#else
+		dev->sh_mem = (unsigned char*) mem_base;
+#endif
 	}
 	else 
 	{
@@ -112,8 +118,10 @@ int pcbit_init_dev(int board, int mem_ba
 	dev->b1 = kmalloc(sizeof(struct pcbit_chan), GFP_KERNEL);
 	if (!dev->b1) {
 		printk("pcbit_init: couldn't malloc pcbit_chan struct\n");
+#ifdef COMPAT_HAS_ISA_IOREMAP
 		iounmap((unsigned char*)dev->sh_mem);
 		release_mem_region(dev->ph_mem, 4096);
+#endif
 		kfree(dev);
 		return -ENOMEM;
 	}
@@ -122,8 +130,10 @@ int pcbit_init_dev(int board, int mem_ba
 	if (!dev->b2) {
 		printk("pcbit_init: couldn't malloc pcbit_chan struct\n");
 		kfree(dev->b1);
+#ifdef COMPAT_HAS_ISA_IOREMAP
 		iounmap((unsigned char*)dev->sh_mem);
 		release_mem_region(dev->ph_mem, 4096);
+#endif
 		kfree(dev);
 		return -ENOMEM;
 	}
@@ -144,8 +154,10 @@ int pcbit_init_dev(int board, int mem_ba
 	{
 		kfree(dev->b1);
 		kfree(dev->b2);
+#ifdef COMPAT_HAS_ISA_IOREMAP
 		iounmap((unsigned char*)dev->sh_mem);
 		release_mem_region(dev->ph_mem, 4096);
+#endif
 		kfree(dev);
 		dev_pcbit[board] = NULL;
 		return -EIO;
@@ -166,8 +178,10 @@ int pcbit_init_dev(int board, int mem_ba
 		free_irq(irq, dev);
 		kfree(dev->b1);
 		kfree(dev->b2);
+#ifdef COMPAT_HAS_ISA_IOREMAP
 		iounmap((unsigned char*)dev->sh_mem);
 		release_mem_region(dev->ph_mem, 4096);
+#endif
 		kfree(dev);
 		dev_pcbit[board] = NULL;
 		return -EIO;
@@ -197,8 +211,10 @@ int pcbit_init_dev(int board, int mem_ba
 		free_irq(irq, dev);
 		kfree(dev->b1);
 		kfree(dev->b2);
+#ifdef COMPAT_HAS_ISA_IOREMAP
 		iounmap((unsigned char*)dev->sh_mem);
 		release_mem_region(dev->ph_mem, 4096);
+#endif
 		kfree(dev);
 		dev_pcbit[board] = NULL;
 		return -EIO;
@@ -235,8 +251,10 @@ void pcbit_terminate(int board)
 			del_timer(&dev->b2->fsm_timer);
 		kfree(dev->b1);
 		kfree(dev->b2);
+#ifdef COMPAT_HAS_ISA_IOREMAP
 		iounmap((unsigned char*)dev->sh_mem);
 		release_mem_region(dev->ph_mem, 4096);
+#endif
 		kfree(dev);
 	}
 }
@@ -430,7 +448,7 @@ int pcbit_writecmd(const u_char* buf, in
 	switch(dev->l2_state) {
 	case L2_LWMODE:
 		/* check (size <= rdp_size); write buf into board */
-		if (len < 0 || len > BANK4 + 1)
+		if (len > BANK4 + 1)
 		{
 			printk("pcbit_writecmd: invalid length %d\n", len);
 			return -EINVAL;
@@ -609,6 +627,20 @@ void pcbit_l3_receive(struct pcbit_dev *
 		       dev->b1->s_refnum, 
 		       dev->b2->s_refnum);
 #endif
+#if 0	
+		if (dev->b1->s_refnum == refnum)
+			chan = dev->b1;
+		else { 
+		   
+			if (dev->b2->s_refnum == refnum)
+				chan = dev->b2;
+			else {
+				chan = NULL;
+				printk(KERN_WARNING "Connection Confirm - refnum doesn't match chan\n");
+				break;
+			}
+		}
+#else
 		/* We just try to find a channel in the right state */
 
 		if (dev->b1->fsm_state == ST_CALL_INIT)
@@ -622,6 +654,7 @@ void pcbit_l3_receive(struct pcbit_dev *
 				break;
 			}
 		}
+#endif
 		if (capi_decode_conn_conf(chan, skb, &complete)) {
 			printk(KERN_DEBUG "conn_conf indicates error\n");
 			pcbit_fsm_event(dev, chan, EV_ERROR, NULL);
--- a/drivers/isdn/pcbit/edss1.c
+++ b/drivers/isdn/pcbit/edss1.c
@@ -4,7 +4,7 @@
  *
  * Copyright (C) 1996 Universidade de Lisboa
  * 
- * Written by Pedro Roque Marques (pedro_m@yahoo.com)
+ * Written by Pedro Roque Marques (roque@di.fc.ul.pt)
  *
  * This software may be used and distributed according to the terms of 
  * the GNU General Public License, incorporated herein by reference.
--- a/drivers/isdn/pcbit/edss1.h
+++ b/drivers/isdn/pcbit/edss1.h
@@ -3,7 +3,7 @@
  *
  * Copyright (C) 1996 Universidade de Lisboa
  * 
- * Written by Pedro Roque Marques (pedro_m@yahoo.com)
+ * Written by Pedro Roque Marques (roque@di.fc.ul.pt)
  *
  * This software may be used and distributed according to the terms of 
  * the GNU General Public License, incorporated herein by reference.
--- a/drivers/isdn/pcbit/layer2.c
+++ b/drivers/isdn/pcbit/layer2.c
@@ -3,7 +3,7 @@
  *
  * Copyright (C) 1996 Universidade de Lisboa
  *
- * Written by Pedro Roque Marques (pedro_m@yahoo.com)
+ * Written by Pedro Roque Marques (roque@di.fc.ul.pt)
  *
  * This software may be used and distributed according to the terms of
  * the GNU General Public License, incorporated herein by reference.
@@ -369,11 +369,16 @@ pcbit_receive(struct pcbit_dev *dev)
 
 		if (dev->read_frame) {
 			printk(KERN_DEBUG "pcbit_receive: Type 0 frame and read_frame != NULL\n");
+#if 0
+			pcbit_l2_error(dev);
+			return;
+#else
 			/* discard previous queued frame */
 			if (dev->read_frame->skb)
 				kfree_skb(dev->read_frame->skb);
 			kfree(dev->read_frame);
 			dev->read_frame = NULL;
+#endif
 		}
 		frame = kmalloc(sizeof(struct frame_buf), GFP_ATOMIC);
 
@@ -449,10 +454,14 @@ pcbit_receive(struct pcbit_dev *dev)
 
 		if (!(frame = dev->read_frame)) {
 			printk("Type 1 frame and no frame queued\n");
+#if 1
 			/* usually after an error: toss frame */
 			dev->readptr += tt;
 			if (dev->readptr > dev->sh_mem + BANK2 + BANKLEN)
 				dev->readptr -= BANKLEN;
+#else
+			pcbit_l2_error(dev);
+#endif
 			return;
 
 		}
--- a/drivers/isdn/pcbit/layer2.h
+++ b/drivers/isdn/pcbit/layer2.h
@@ -3,7 +3,7 @@
  *
  * Copyright (C) 1996 Universidade de Lisboa
  * 
- * Written by Pedro Roque Marques (pedro_m@yahoo.com)
+ * Written by Pedro Roque Marques (roque@di.fc.ul.pt)
  *
  * This software may be used and distributed according to the terms of 
  * the GNU General Public License, incorporated herein by reference.
--- a/drivers/isdn/pcbit/module.c
+++ b/drivers/isdn/pcbit/module.c
@@ -3,7 +3,7 @@
  *
  * Copyright (C) 1996 Universidade de Lisboa
  * 
- * Written by Pedro Roque Marques (pedro_m@yahoo.com)
+ * Written by Pedro Roque Marques (roque@di.fc.ul.pt)
  *
  * This software may be used and distributed according to the terms of 
  * the GNU General Public License, incorporated herein by reference.
@@ -92,6 +92,7 @@ static void __exit pcbit_exit(void)
 }
 
 #ifndef MODULE
+#ifdef COMPAT_HAS_NEW_SETUP
 #define MAX_PARA	(MAX_PCBIT_CARDS * 2)
 static int __init pcbit_setup(char *line)
 {
@@ -100,6 +101,11 @@ static int __init pcbit_setup(char *line
 	int ints[MAX_PARA+1];
 
 	str = get_options(line, MAX_PARA, ints);
+#else
+void pcbit_setup(char *str, int *ints)
+{
+	int i, j, argc;
+#endif
 	argc = ints[0];
 	i = 0;
 	j = 1;
@@ -118,9 +124,13 @@ static int __init pcbit_setup(char *line
 
 		i++;
 	}
+#ifdef COMPAT_HAS_NEW_SETUP
 	return(1);
 }
 __setup("pcbit=", pcbit_setup);
+#else
+}
+#endif
 #endif
 
 module_init(pcbit_init);
--- a/drivers/isdn/pcbit/pcbit.h
+++ b/drivers/isdn/pcbit/pcbit.h
@@ -3,7 +3,7 @@
  *
  * Copyright (C) 1996 Universidade de Lisboa
  * 
- * Written by Pedro Roque Marques (pedro_m@yahoo.com)
+ * Written by Pedro Roque Marques (roque@di.fc.ul.pt)
  *
  * This software may be used and distributed according to the terms of 
  * the GNU General Public License, incorporated herein by reference.
--- a/drivers/isdn/sc/card.h
+++ b/drivers/isdn/sc/card.h
@@ -1,4 +1,4 @@
-/* $Id: card.h,v 1.1.4.1 2001/11/20 14:19:37 kai Exp $
+/* $Id$
  *
  * Driver parameters for SpellCaster ISA ISDN adapters
  *
--- a/drivers/isdn/sc/command.c
+++ b/drivers/isdn/sc/command.c
@@ -1,4 +1,4 @@
-/* $Id: command.c,v 1.1.4.1 2001/11/20 14:19:37 kai Exp $
+/* $Id$
  *
  * Copyright (C) 1996  SpellCaster Telecommunications Inc.
  *
@@ -95,7 +95,7 @@ int get_card_from_id(int driver)
 		if(adapter[i]->driverId == driver)
 			return i;
 	}
-	return -ENODEV;
+	return -NODEV;
 }
 
 /* 
--- a/drivers/isdn/sc/debug.c
+++ b/drivers/isdn/sc/debug.c
@@ -1,4 +1,4 @@
-/* $Id: debug.c,v 1.1.4.1 2001/11/20 14:19:37 kai Exp $
+/* $Id$
  *
  * Copyright (C) 1996  SpellCaster Telecommunications Inc.
  *
--- a/drivers/isdn/sc/debug.h
+++ b/drivers/isdn/sc/debug.h
@@ -1,4 +1,4 @@
-/* $Id: debug.h,v 1.1.4.1 2001/11/20 14:19:37 kai Exp $
+/* $Id$
  *
  * Copyright (C) 1996  SpellCaster Telecommunications Inc.
  *
--- a/drivers/isdn/sc/event.c
+++ b/drivers/isdn/sc/event.c
@@ -1,4 +1,4 @@
-/* $Id: event.c,v 1.1.4.1 2001/11/20 14:19:37 kai Exp $
+/* $Id$
  *
  * Copyright (C) 1996  SpellCaster Telecommunications Inc.
  *
--- a/drivers/isdn/sc/init.c
+++ b/drivers/isdn/sc/init.c
@@ -514,6 +514,15 @@ int identify_board(unsigned long rambase
 	schedule_timeout(HZ);
 	sig = readl(rambase + SIG_OFFSET);
 	pr_debug("Looking for a signature, got 0x%x\n", sig);
+#if 0
+/*
+ * For Gary: 
+ * If it's a timing problem, it should be gone with the above schedule()
+ * Another possible reason may be the missing volatile in the original
+ * code. readl() does this for us.
+ */
+	printk("");	/* Hack! Doesn't work without this !!!??? */
+#endif
 	if(sig == SIGNATURE)
 		return PRI_BOARD;
 
@@ -525,6 +534,9 @@ int identify_board(unsigned long rambase
 	schedule_timeout(HZ);
 	sig = readl(rambase + SIG_OFFSET);
 	pr_debug("Looking for a signature, got 0x%x\n", sig);
+#if 0
+	printk("");	/* Hack! Doesn't work without this !!!??? */
+#endif
 	if(sig == SIGNATURE)
 		return BRI_BOARD;
 
--- a/drivers/isdn/sc/interrupt.c
+++ b/drivers/isdn/sc/interrupt.c
@@ -1,4 +1,4 @@
-/* $Id: interrupt.c,v 1.1.4.1 2001/11/20 14:19:37 kai Exp $
+/* $Id$
  *
  * Copyright (C) 1996  SpellCaster Telecommunications Inc.
  *
--- a/drivers/isdn/sc/ioctl.c
+++ b/drivers/isdn/sc/ioctl.c
@@ -23,6 +23,9 @@ extern int send_and_receive(int, unsigne
 
 extern board *adapter[];
 
+#if 0
+static char *ChannelStates[] = { "Idle", "Ready", "Connecting", "Connected", "Disconnecting" };
+#endif
 
 int GetStatus(int card, boardInfo *);
 
--- a/drivers/isdn/sc/message.c
+++ b/drivers/isdn/sc/message.c
@@ -1,4 +1,4 @@
-/* $Id: message.c,v 1.1.4.1 2001/11/20 14:19:37 kai Exp $
+/* $Id$
  *
  * functions for sending and receiving control messages
  *
--- a/drivers/isdn/sc/message.h
+++ b/drivers/isdn/sc/message.h
@@ -1,4 +1,4 @@
-/* $Id: message.h,v 1.1.4.1 2001/11/20 14:19:37 kai Exp $
+/* $Id$
  *
  * Copyright (C) 1996  SpellCaster Telecommunications Inc.
  *
--- a/drivers/isdn/sc/packet.c
+++ b/drivers/isdn/sc/packet.c
@@ -1,4 +1,4 @@
-/* $Id: packet.c,v 1.1.4.1 2001/11/20 14:19:37 kai Exp $
+/* $Id$
  *
  * Copyright (C) 1996  SpellCaster Telecommunications Inc.
  *
--- a/drivers/isdn/sc/shmem.c
+++ b/drivers/isdn/sc/shmem.c
@@ -1,4 +1,4 @@
-/* $Id: shmem.c,v 1.1.4.1 2001/11/20 14:19:37 kai Exp $
+/* $Id$
  *
  * Copyright (C) 1996  SpellCaster Telecommunications Inc.
  *
--- a/drivers/isdn/sc/timer.c
+++ b/drivers/isdn/sc/timer.c
@@ -1,4 +1,4 @@
-/* $Id: timer.c,v 1.1.4.1 2001/11/20 14:19:37 kai Exp $
+/* $Id$
  *
  * Copyright (C) 1996  SpellCaster Telecommunications Inc.
  *
--- a/drivers/isdn/tpam/tpam.h
+++ b/drivers/isdn/tpam/tpam.h
@@ -1,4 +1,4 @@
-/* $Id: tpam.h,v 1.1.2.1 2001/11/20 14:19:37 kai Exp $
+/* $Id: tpam.h,v 1.3 2001/09/24 13:23:12 kai Exp $
  *
  * Turbo PAM ISDN driver for Linux. (Kernel Driver)
  *
--- a/drivers/isdn/tpam/tpam_commands.c
+++ b/drivers/isdn/tpam/tpam_commands.c
@@ -1,4 +1,4 @@
-/* $Id: tpam_commands.c,v 1.1.2.1 2001/11/20 14:19:37 kai Exp $
+/* $Id: tpam_commands.c,v 1.3 2001/09/24 13:23:12 kai Exp $
  *
  * Turbo PAM ISDN driver for Linux. (Kernel Driver - ISDN commands)
  *
--- a/drivers/isdn/tpam/tpam_crcpc.c
+++ b/drivers/isdn/tpam/tpam_crcpc.c
@@ -1,4 +1,4 @@
-/* $Id: tpam_crcpc.c,v 1.1.2.1 2001/11/20 14:19:37 kai Exp $
+/* $Id$
  *
  * Turbo PAM ISDN driver for Linux. (Kernel Driver - CRC encoding)
  *
--- a/drivers/isdn/tpam/tpam_hdlc.c
+++ b/drivers/isdn/tpam/tpam_hdlc.c
@@ -1,4 +1,4 @@
-/* $Id: tpam_hdlc.c,v 1.1.2.1 2001/11/20 14:19:37 kai Exp $
+/* $Id: tpam_hdlc.c,v 1.3 2001/09/24 13:23:12 kai Exp $
  *
  * Turbo PAM ISDN driver for Linux. (Kernel Driver - HDLC encoding)
  *
--- a/drivers/isdn/tpam/tpam_main.c
+++ b/drivers/isdn/tpam/tpam_main.c
@@ -1,4 +1,4 @@
-/* $Id: tpam_main.c,v 1.1.2.2 2001/12/09 18:45:14 kai Exp $
+/* $Id$
  *
  * Turbo PAM ISDN driver for Linux. (Kernel Driver - main routines)
  *
@@ -254,7 +254,7 @@ static struct pci_driver tpam_driver = {
 	name:		"tpam",
 	id_table:	tpam_pci_tbl,
 	probe:		tpam_probe,
-	remove:		__devexit_p(tpam_remove),
+	remove:		tpam_remove,
 };
 
 static int __init tpam_init(void) {
--- a/drivers/isdn/tpam/tpam_memory.c
+++ b/drivers/isdn/tpam/tpam_memory.c
@@ -1,4 +1,4 @@
-/* $Id: tpam_memory.c,v 1.1.2.1 2001/11/20 14:19:37 kai Exp $
+/* $Id$
  *
  * Turbo PAM ISDN driver for Linux. (Kernel Driver - Board Memory Access)
  *
--- a/drivers/isdn/tpam/tpam_nco.c
+++ b/drivers/isdn/tpam/tpam_nco.c
@@ -1,4 +1,4 @@
-/* $Id: tpam_nco.c,v 1.1.2.1 2001/11/20 14:19:37 kai Exp $
+/* $Id$
  *
  * Turbo PAM ISDN driver for Linux. 
  * (Kernel Driver - Low Level NCO Manipulation)
--- a/drivers/isdn/tpam/tpam_queues.c
+++ b/drivers/isdn/tpam/tpam_queues.c
@@ -1,4 +1,4 @@
-/* $Id: tpam_queues.c,v 1.1.2.1 2001/11/20 14:19:37 kai Exp $
+/* $Id$
  *
  * Turbo PAM ISDN driver for Linux. (Kernel Driver)
  *
@@ -146,7 +146,6 @@ void tpam_irq(int irq, void *dev_id, str
 		do {
 			hpic = readl(card->bar0 + TPAM_HPIC_REGISTER);
 			if (waiting_too_long++ > 0xfffffff) {
-				kfree_skb(skb); 
 				spin_unlock(&card->lock);
 				printk(KERN_ERR "TurboPAM(tpam_irq): "
 						"waiting too long...\n");
--- a/include/linux/b1lli.h
+++ b/include/linux/b1lli.h
@@ -1,4 +1,4 @@
-/* $Id: b1lli.h,v 1.8.8.3 2001/09/23 22:25:05 kai Exp $
+/* $Id$
  *
  * ISDN lowlevel-module for AVM B1-card.
  *
--- a/include/linux/b1pcmcia.h
+++ b/include/linux/b1pcmcia.h
@@ -1,4 +1,4 @@
-/* $Id: b1pcmcia.h,v 1.1.8.2 2001/09/23 22:25:05 kai Exp $
+/* $Id$
  *
  * Exported functions of module b1pcmcia to be called by
  * avm_cs card services module.
--- a/include/linux/capi.h
+++ b/include/linux/capi.h
@@ -1,4 +1,4 @@
-/* $Id: capi.h,v 1.1.4.1 2001/11/20 14:19:38 kai Exp $
+/* $Id$
  * 
  * CAPI 2.0 Interface for Linux
  * 
--- a/include/linux/concap.h
+++ b/include/linux/concap.h
@@ -1,4 +1,4 @@
-/* $Id: concap.h,v 1.2.8.1 2001/09/23 22:25:05 kai Exp $
+/* $Id: concap.h,v 1.3 2001/09/24 13:23:13 kai Exp $
  *
  * Copyright 1997 by Henner Eisen <eis@baty.hanse.de>
  *
@@ -11,6 +11,7 @@
 #ifdef __KERNEL__
 #include <linux/skbuff.h>
 #include <linux/netdevice.h>
+#include <linux/isdn_compat.h>
 
 /* Stuff to support encapsulation protocols genericly. The encapsulation
    protocol is processed at the uppermost layer of the network interface.
--- a/include/linux/hysdn_if.h
+++ b/include/linux/hysdn_if.h
@@ -1,4 +1,4 @@
-/* $Id: hysdn_if.h,v 1.1.8.3 2001/09/23 22:25:05 kai Exp $
+/* $Id$
  *
  * Linux driver for HYSDN cards
  * ioctl definitions shared by hynetmgr and driver.
--- a/include/linux/isdn/tpam.h
+++ b/include/linux/isdn/tpam.h
@@ -1,4 +1,4 @@
-/* $Id: tpam.h,v 1.1.2.1 2001/11/20 14:19:38 kai Exp $
+/* $Id$
  *
  * Turbo PAM ISDN driver for Linux. (Kernel Driver)
  *
--- a/include/linux/isdn.h
+++ b/include/linux/isdn.h
@@ -1,4 +1,4 @@
-/* $Id: isdn.h,v 1.1.4.1 2001/11/20 14:19:38 kai Exp $
+/* $Id: isdn.h,v 1.125 2001/12/01 23:18:21 detabc Exp $
  *
  * Main header for the Linux ISDN subsystem (linklevel).
  *
@@ -14,6 +14,7 @@
 #ifndef __ISDN_H__
 #define __ISDN_H__
 
+#include <linux/isdn_compat.h>
 #include <linux/ioctl.h>
 
 #ifdef CONFIG_COBALT_MICRO_SERVER
@@ -93,9 +94,15 @@
 #define ISDN_LMSNLEN         255 /* Length of tty's Listen-MSN string */
 #define ISDN_CMSGLEN	     50	 /* Length of CONNECT-Message to add for Modem */
 
+#ifdef BIG_PHONE_NUMBERS
 #define ISDN_MSNLEN          32
 #define NET_DV 0x06  /* Data version for isdn_net_ioctl_cfg   */
 #define TTY_DV 0x06  /* Data version for iprofd etc.          */
+#else
+#define ISDN_MSNLEN          20
+#define NET_DV 0x05  /* Data version for isdn_net_ioctl_cfg   */
+#define TTY_DV 0x05  /* Data version for iprofd etc.          */
+#endif
 
 #define INF_DV 0x01  /* Data version for /dev/isdninfo        */
 
@@ -187,6 +194,61 @@ typedef struct {
 #define ISDN_MINOR_PPPMAX   (128 + (ISDN_MAX_CHANNELS-1))
 #define ISDN_MINOR_STATUS   255
 
+#ifndef CONFIG_ISDN_WITH_ABC
+#undef CONFIG_ISDN_WITH_ABC_CALLB
+#undef CONFIG_ISDN_WITH_ABC_UDP_CHECK
+#undef CONFIG_ISDN_WITH_ABC_UDP_CHECK_HANGUP
+#undef CONFIG_ISDN_WITH_ABC_UDP_CHECK_DIAL
+#undef CONFIG_ISDN_WITH_ABC_OUTGOING_EAZ
+#undef CONFIG_ISDN_WITH_ABC_LCR_SUPPORT
+#undef CONFIG_ISDN_WITH_ABC_RCV_NO_HUPTIMER
+#undef CONFIG_ISDN_WITH_ABC_CH_EXTINUSE
+#undef CONFIG_ISDN_WITH_ABC_CONN_ERROR
+#undef CONFIG_ISDN_WITH_ABC_RAWIPCOMPRESS
+#else /* CONFIG_ISDN_WITH_ABC */
+#include <linux/isdn_dwabc.h>
+
+
+typedef struct DWABCJIFFIES {
+
+	u_long	msec_1000;
+	u_long  msec_500;
+	u_long	msec_400;
+	u_long	msec_200;
+	u_long	msec_100;
+
+} DWABCJIFFIES;
+
+
+#ifdef CONFIG_ISDN_WITH_ABC_NEED_DWSJIFFIES
+DWABCJIFFIES isdn_dwabc_jiffies;
+#else
+extern DWABCJIFFIES isdn_dwabc_jiffies;
+#endif
+#define dwsjiffies (isdn_dwabc_jiffies.msec_1000)
+
+#define ISDN_DW_ABC_FLAG_UNUSED00001		0x00000001L
+#define ISDN_DW_ABC_FLAG_NO_UDP_CHECK		0x00000002L
+#define ISDN_DW_ABC_FLAG_NO_UDP_HANGUP		0x00000004L
+#define ISDN_DW_ABC_FLAG_NO_UDP_DIAL		0x00000008L
+#define ISDN_DW_ABC_FLAG_UNUSED00010		0x00000010L
+#define ISDN_DW_ABC_FLAG_RCV_NO_HUPTIMER	0x00000020L
+#define ISDN_DW_ABC_FLAG_NO_CH_EXTINUSE		0x00000040L
+#define ISDN_DW_ABC_FLAG_NO_CONN_ERROR		0x00000080L
+#define ISDN_DW_ABC_FLAG_BSD_COMPRESS		0x00000100L
+#define ISDN_DW_ABC_FLAG_NO_LCR				0x00000200L
+#define ISDN_DW_ABC_FLAG_LEASED_LINE		0x00001000L
+
+#define ISDN_DW_ABC_IFFLAG_NODCHAN			0x00000001L
+#define ISDN_DW_ABC_IFFLAG_BSDAKTIV			0x00000002L
+
+#define ISDN_DW_ABC_BITLOCK_SEND			0
+#define ISDN_DW_ABC_BITLOCK_RECEIVE			1
+
+#endif /* CONFIG_ISDN_WITH_ABC */
+
+
+
 #ifdef CONFIG_ISDN_PPP
 
 #ifdef CONFIG_ISDN_PPP_VJ
@@ -204,9 +266,11 @@ typedef struct {
 #  include <linux/concap.h>
 #endif
 
+#ifdef HAVE_DEVFS_FS
 #ifdef CONFIG_DEVFS_FS
 #  include <linux/devfs_fs_kernel.h>
 #endif
+#endif /* HAVE_DEVFS_FS */
 
 #include <linux/isdnif.h>
 
@@ -272,6 +336,12 @@ typedef struct {
 #define ISDN_NET_CALLBACK   0x04       /* activate callback                 */
 #define ISDN_NET_CBHUP      0x08       /* hangup before callback            */
 #define ISDN_NET_CBOUT      0x10       /* remote machine does callback      */
+#if 0
+/* Unused??? */
+#define ISDN_NET_CLONE      0x08       /* clone a tmp interface when called */
+#define ISDN_NET_TMP        0x10       /* tmp interface until getting an IP */
+#define ISDN_NET_DYNAMIC    0x20       /* this link is dynamically allocated */
+#endif
 
 #define ISDN_NET_MAGIC      0x49344C02 /* for paranoia-checking             */
 
@@ -386,6 +456,38 @@ typedef struct isdn_net_local_s {
   char cisco_debserint;			/* debugging flag of cisco hdlc with slarp */
   struct timer_list cisco_timer;
   struct tq_struct tqueue;
+#ifdef CONFIG_ISDN_WITH_ABC
+  ulong 	dw_abc_flags;
+  ulong 	dw_abc_if_flags;
+  int   	dw_abc_inuse_secure;
+  ulong 	dw_abc_dialstart;
+  int   	dw_abc_old_onhtime;
+  int 		dw_abc_remote_version;
+  int		dw_abc_bitlocks;
+#ifdef CONFIG_ISDN_WITH_ABC_OUTGOING_EAZ
+  char	dw_out_msn[ISDN_MSNLEN]; /* eaz for outgoing call if *out_msn != 0 */
+#endif
+#ifdef CONFIG_ISDN_WITH_ABC_LCR_SUPPORT
+  ulong 				dw_abc_lcr_callid;
+  ulong 				dw_abc_lcr_start_request;
+  ulong 				dw_abc_lcr_end_request;
+  isdn_ctrl 			*dw_abc_lcr_cmd;
+  struct ISDN_DWABC_LCR_IOCTL	*dw_abc_lcr_io;
+#endif
+  ulong dw_abc_bchan_last_connect;
+#ifdef CONFIG_ISDN_WITH_ABC_CONN_ERROR
+  short dw_abc_bchan_errcnt;
+#endif
+#ifdef CONFIG_ISDN_WITH_ABC_RAWIPCOMPRESS
+  void *dw_abc_bsd_compressor;
+  void *dw_abc_bsd_stat_rx;
+  void *dw_abc_bsd_stat_tx;
+#endif
+  ulong	dw_abc_bsd_snd;
+  ulong	dw_abc_bsd_bsd_snd;
+  ulong	dw_abc_bsd_rcv;
+  ulong	dw_abc_bsd_bsd_rcv;
+#endif
 } isdn_net_local;
 
 /* the interface itself */
@@ -608,12 +710,13 @@ typedef struct isdn_devt {
 	int               tflags;                    /* Timer-Flags:               */
 	/*  see ISDN_TIMER_..defines  */
 	int               global_flags;
-	infostruct        *infochain;                /* List of open info-devs.    */
-	wait_queue_head_t info_waitq;               /* Wait-Queue for isdninfo    */
 	struct timer_list timer;		       /* Misc.-function Timer       */
 	int               chanmap[ISDN_MAX_CHANNELS];/* Map minor->device-channel  */
 	int               drvmap[ISDN_MAX_CHANNELS]; /* Map minor->driver-index    */
 	int               usage[ISDN_MAX_CHANNELS];  /* Used by tty/ip/voice       */
+#ifdef CONFIG_ISDN_WITH_ABC_CH_EXTINUSE
+	ulong			  dwabc_chan_external_inuse[ISDN_MAX_CHANNELS];
+#endif
 	char              num[ISDN_MAX_CHANNELS][ISDN_MSNLEN];
 	/* Remote number of active ch.*/
 	int               m_idx[ISDN_MAX_CHANNELS];  /* Index for mdm....          */
@@ -631,6 +734,7 @@ typedef struct isdn_devt {
 	isdn_v110_stream  *v110[ISDN_MAX_CHANNELS];  /* V.110 private data         */
 	struct semaphore  sem;                       /* serialize list access*/
 	unsigned long     global_features;
+#ifdef HAVE_DEVFS_FS
 #ifdef CONFIG_DEVFS_FS
 	devfs_handle_t devfs_handle_isdninfo;
 	devfs_handle_t devfs_handle_isdnctrl;
@@ -640,10 +744,41 @@ typedef struct isdn_devt {
 	devfs_handle_t devfs_handle_ipppX[ISDN_MAX_CHANNELS];
 #endif
 #endif /* CONFIG_DEVFS_FS */
+#endif /* HAVE_DEVFS_FS */
 } isdn_dev;
 
 extern isdn_dev *dev;
 
+#ifdef CONFIG_ISDN_WITH_ABC
+extern int isdn_auto_dial_helper(isdn_net_local *,struct sk_buff *,int);
+extern void dwisdn_nfw_send(isdn_net_local *lp,int drop_only);
+extern void isdn_net_unreachable(struct net_device *,struct sk_buff *,char *);
+extern void isdn_net_log_skb_dwabc(struct sk_buff *,isdn_net_local *,char *);
+extern void isdn_net_hangup(struct net_device *d);
+extern void isdn_dw_clear_if(ulong pm,isdn_net_local *);
+extern void isdn_dwabc_test_phone(isdn_net_local *);
+extern void isdn_dw_abc_init_func(void);
+extern void isdn_dw_abc_release_func(void);
+extern int isdn_dw_abc_reset_interface(isdn_net_local *,int);
+extern int dwabc_bsd_init(isdn_net_local *lp);
+extern void dwabc_bsd_free(isdn_net_local *lp);
+extern struct sk_buff *dwabc_bsd_compress(isdn_net_local *,struct sk_buff *,struct net_device *);
+extern void dwabc_bsd_first_gen(isdn_net_local *);
+extern struct sk_buff *dwabc_bsd_rx_pkt(isdn_net_local *,struct sk_buff *,struct net_device *);
+#ifdef CONFIG_ISDN_WITH_ABC_LCR_SUPPORT
+extern size_t isdn_dw_abc_lcr_readstat(char *,size_t);
+extern ulong isdn_dw_abc_lcr_call_number(isdn_net_local *,isdn_ctrl *);
+extern void isdn_dw_abc_lcr_open(void);
+extern void isdn_dw_abc_lcr_close(void);
+extern int isdn_dw_abc_lcr_ioctl(ulong);
+extern void isdn_dw_abc_lcr_clear(isdn_net_local *);
+extern int isdn_dw_abc_lcr_lock(void);
+extern void isdn_dw_abc_lcr_ulock(void);
+#endif
+#ifdef CONFIG_ISDN_WITH_ABC_UDP_CHECK
+extern int dw_abc_udp_test(struct sk_buff *skb,struct net_device *ndev); 
+#endif
+#endif
 
 #endif /* __KERNEL__ */
 
--- /dev/null
+++ b/include/linux/isdn_compat.h
@@ -0,0 +1,261 @@
+/* $Id: isdn_compat.h,v 1.53 2001/09/24 13:23:13 kai Exp $
+ *
+ * Linux ISDN subsystem
+ * Compatibility for various Linux kernel versions
+ *
+ * This software may be used and distributed according to the terms
+ * of the GNU General Public License, incorporated herein by reference.
+ *
+ */
+
+#ifndef _LINUX_ISDN_COMPAT_H
+#define _LINUX_ISDN_COMPAT_H
+
+#ifdef __KERNEL__
+
+#ifndef ISDN_COMPAT_NOT_GENERIC
+/* when using std2kern -u, this part is left out and instead provided
+   by the .ctrl files */
+
+#include <linux/version.h>
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,2,18)
+
+#define set_current_state(sta) (current->state = sta)
+#define module_init(x)	int init_module(void) { return x(); }
+#define module_exit(x)	void cleanup_module(void) { x(); }
+#define BUG() do { printk("kernel BUG at %s:%d!\n", __FILE__, __LINE__); *(int *)0 = 0; } while (0)
+#define init_MUTEX(x)				*(x)=MUTEX
+#define init_MUTEX_LOCKED(x)			*(x)=MUTEX_LOCKED
+#define __devinit
+#define __devinitdata
+
+#else /* 2.2.18 and later */
+
+#define COMPAT_HAS_NEW_SETUP
+#define COMPAT_HAS_NEW_WAITQ
+
+#endif
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0)
+
+#define dev_kfree_skb_irq(a) dev_kfree_skb(a)
+#define dev_kfree_skb_any(a) dev_kfree_skb(a)
+#define COMPAT_HAS_2_2_PCI
+#define get_pcibase(ps, nr) ps->base_address[nr]
+#define pci_resource_start_io(pdev, nr) ((pdev)->base_address[nr] & PCI_BASE_ADDRESS_IO_MASK)
+#define pci_resource_start_mem(pdev, nr) ((pdev)->base_address[nr] & PCI_BASE_ADDRESS_MEM_MASK)
+#define pci_get_sub_vendor(pdev, id)	pci_read_config_word(pdev, PCI_SUBSYSTEM_VENDOR_ID, &id)
+#define pci_get_sub_system(pdev, id)	pci_read_config_word(pdev, PCI_SUBSYSTEM_ID, &id)
+
+#define __exit
+#define __devinit
+#define __devinitdata
+
+#define net_device device
+#define COMPAT_NO_SOFTNET
+#define netif_running(d) test_bit(LINK_STATE_START, &d->state)
+#define COMPAT_NEED_MPPP_DEFS
+#define spin_lock_bh(lock)
+#define spin_unlock_bh(lock)
+#define COMPAT_NEED_SPIN_LOCK_BH
+#define i_count_read(ic) ic
+#define i_count_inc(ic)  ic++
+#define COMPAT_USE_MODCOUNT_LOCK
+#define devfs_register_chrdev(m,n,f) register_chrdev(m,n,f)
+#define devfs_unregister_chrdev(m,n) unregister_chrdev(m,n)
+#define COMPAT_NEED_PCI_IDS
+#define in_irq() (local_irq_count[smp_processor_id()] != 0)
+
+#else /* 2.4.0 and later */
+
+#define pci_resource_start_io(pdev, nr) pci_resource_start(pdev, nr)
+#define pci_resource_start_mem(pdev, nr) pci_resource_start(pdev, nr)
+#define get_pcibase(ps, nr) ps->resource[nr].start
+#define pci_get_sub_system(pdev, id)	id = pdev->subsystem_device
+#define pci_get_sub_vendor(pdev, id)	id = pdev->subsystem_vendor
+
+#define BIG_PHONE_NUMBERS
+#define COMPAT_HAS_ISA_IOREMAP
+#define i_count_read(ic) atomic_read(&ic)
+#define i_count_inc(ic)  atomic_inc(&ic)
+#define COMPAT_HAS_FILEOP_OWNER
+#define COMPAT_HAVE_NEW_FILLDIR
+#define COMPAT_has_fileops_in_inode
+#define COMPAT_HAS_init_special_inode
+#define COMPAT_d_alloc_root_one_parameter
+#define HAVE_DEVFS_FS
+#define COMPAT_HAS_SCHEDULE_TASK
+#define COMPAT_HAS_USB_IDTAB
+
+#endif
+
+#endif /* ISDN_COMPAT_GENERIC */
+
+#ifdef COMPAT_HAS_2_2_PCI 
+#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
+
+#ifdef COMPAT_NO_SOFTNET
+#include <linux/netdevice.h>
+
+/*
+ * Tell upper layers that the network device is ready to xmit more frames.
+ */
+static void __inline__ netif_wake_queue(struct net_device * dev)
+{
+	dev->tbusy = 0;
+	mark_bh(NET_BH);
+}
+
+/*
+ * called during net_device open()
+ */
+static void __inline__ netif_start_queue(struct net_device * dev)
+{
+	dev->tbusy = 0;
+	/* actually, we never use the interrupt flag at all */
+	dev->interrupt = 0;
+	dev->start = 1;
+}
+
+/*
+ * Ask upper layers to temporarily cease passing us more xmit frames.
+ */
+static void __inline__ netif_stop_queue(struct net_device * dev)
+{
+	dev->tbusy = 1;
+}
+
+#endif /* COMPAT_NO_SOFTNET */
+
+#ifndef COMPAT_HAS_NEW_WAITQ
+typedef struct wait_queue wait_queue_t;
+typedef struct wait_queue *wait_queue_head_t;
+
+#define DECLARE_WAITQUEUE(wait, current)	struct wait_queue wait = { current, NULL }
+#define DECLARE_WAIT_QUEUE_HEAD(wait)		wait_queue_head_t wait
+#define init_waitqueue_head(x)			*(x)=NULL
+#define init_waitqueue_entry(q,p)		((q)->task)=(p)
+#endif /* COMPAT_HAS_NEW_WAITQ */
+
+#ifdef COMPAT_NEED_PCI_IDS
+
+#define PCI_ANY_ID (~0)
+
+#define PCI_VENDOR_ID_DYNALINK          0x0675
+#define PCI_DEVICE_ID_DYNALINK_IS64PH   0x1702
+
+#define PCI_DEVICE_ID_WINBOND2_6692	0x6692
+
+#define PCI_DEVICE_ID_PLX_R685		0x1030
+#define PCI_DEVICE_ID_PLX_DJINN_ITOO    0x1151
+#define PCI_DEVICE_ID_PLX_R753          0x1152
+
+#define PCI_VENDOR_ID_ELSA		0x1048
+#define PCI_DEVICE_ID_ELSA_MICROLINK	0x1000
+#define PCI_DEVICE_ID_ELSA_QS3000	0x3000
+
+#define PCI_VENDOR_ID_EICON		0x1133
+#define PCI_DEVICE_ID_EICON_DIVA20PRO	0xe001
+#define PCI_DEVICE_ID_EICON_DIVA20	0xe002
+#define PCI_DEVICE_ID_EICON_DIVA20PRO_U	0xe003
+#define PCI_DEVICE_ID_EICON_DIVA20_U	0xe004
+#define PCI_DEVICE_ID_EICON_DIVA201	0xe005
+#define PCI_DEVICE_ID_EICON_MAESTRA	0xe010
+#define PCI_DEVICE_ID_EICON_MAESTRAQ	0xe012
+#define PCI_DEVICE_ID_EICON_MAESTRAQ_U	0xe013
+#define PCI_DEVICE_ID_EICON_MAESTRAP	0xe014
+ 
+#define PCI_VENDOR_ID_CCD		0x1397
+#define PCI_DEVICE_ID_CCD_2BD0	        0x2BD0
+#define PCI_DEVICE_ID_CCD_B000	        0xB000
+#define PCI_DEVICE_ID_CCD_B006	        0xB006
+#define PCI_DEVICE_ID_CCD_B007	        0xB007
+#define PCI_DEVICE_ID_CCD_B008	        0xB008
+#define PCI_DEVICE_ID_CCD_B009	        0xB009
+#define PCI_DEVICE_ID_CCD_B00A	        0xB00A
+#define PCI_DEVICE_ID_CCD_B00B	        0xB00B
+#define PCI_DEVICE_ID_CCD_B00C	        0xB00C
+#define PCI_DEVICE_ID_CCD_B100	        0xB100
+
+#define PCI_VENDOR_ID_ASUSTEK           0x1043   
+#define PCI_DEVICE_ID_ASUSTEK_0675      0x0675
+
+#define PCI_VENDOR_ID_BERKOM		        0x0871
+#define PCI_DEVICE_ID_BERKOM_A1T	        0xFFA1
+#define PCI_DEVICE_ID_BERKOM_T_CONCEPT          0xFFA2
+#define PCI_DEVICE_ID_BERKOM_A4T	        0xFFA4
+#define PCI_DEVICE_ID_BERKOM_SCITEL_QUADRO      0xFFA8
+
+#define PCI_DEVICE_ID_SATSAGEM_NICCY	0x1016
+
+#define PCI_DEVICE_ID_TIGERJET_100	0x0002
+
+#define PCI_VENDOR_ID_ANIGMA		0x1051
+#define PCI_DEVICE_ID_ANIGMA_MC145575	0x0100
+
+#define PCI_VENDOR_ID_ZOLTRIX		0x15b0
+#define PCI_DEVICE_ID_ZOLTRIX_2BD0	0x2BD0
+
+#define PCI_DEVICE_ID_DIGI_DF_M_IOM2_E	0x0070
+#define PCI_DEVICE_ID_DIGI_DF_M_E	0x0071
+#define PCI_DEVICE_ID_DIGI_DF_M_IOM2_A	0x0072
+#define PCI_DEVICE_ID_DIGI_DF_M_A	0x0073
+
+#define PCI_DEVICE_ID_AVM_B1		0x0700
+#define PCI_DEVICE_ID_AVM_C4		0x0800
+#define PCI_DEVICE_ID_AVM_C2		0x1100
+#define PCI_DEVICE_ID_AVM_T1		0x1200
+
+#define PCI_VENDOR_ID_HYPERCOPE		0x1365
+#define PCI_DEVICE_ID_HYPERCOPE_PLX	0x9050
+#define PCI_SUBDEVICE_ID_HYPERCOPE_OLD_ERGO     0x0104
+#define PCI_SUBDEVICE_ID_HYPERCOPE_ERGO         0x0106
+#define PCI_SUBDEVICE_ID_HYPERCOPE_METRO        0x0107
+#define PCI_SUBDEVICE_ID_HYPERCOPE_CHAMP2       0x0108
+#define PCI_SUBDEVICE_ID_HYPERCOPE_PLEXUS       0x0109
+
+#define PCI_VENDOR_ID_ABOCOM            0x13D1
+#define PCI_DEVICE_ID_ABOCOM_2BD1       0x2BD1
+
+#endif /* COMPAT_NEED_PCI_IDS */
+
+#endif /* __KERNEL__ */
+#endif /* _LINUX_ISDN_COMPAT_H */
--- a/include/linux/isdn_divertif.h
+++ b/include/linux/isdn_divertif.h
@@ -1,4 +1,4 @@
-/* $Id: isdn_divertif.h,v 1.1.4.1 2001/11/20 14:19:38 kai Exp $
+/* $Id$
  *
  * Header for the diversion supplementary interface for i4l.
  *
@@ -14,7 +14,7 @@
 /***********************************************************/
 /* magic value is also used to control version information */
 /***********************************************************/
-#define DIVERT_IF_MAGIC 0x25873401
+#define DIVERT_IF_MAGIC 0x25873402
 #define DIVERT_CMD_REG  0x00  /* register command */
 #define DIVERT_CMD_REL  0x01  /* release command */
 #define DIVERT_NO_ERR   0x00  /* return value no error */
@@ -34,6 +34,7 @@ typedef struct
     int (*ll_cmd)(isdn_ctrl *); /* supplied by hl on return */
     char * (*drv_to_name)(int); /* map a driver id to name, supplied by hl */
     int (*name_to_drv)(char *); /* map a driver id to name, supplied by hl */
+    int (*dial_net_name)(char *); /* force dial of a ll net interface  */
   } isdn_divert_if;
 
 /*********************/
--- /dev/null
+++ b/include/linux/isdn_dwabc.h
@@ -0,0 +1,84 @@
+/* $Id: isdn_dwabc.h,v 1.9 2001/09/26 20:32:08 detabc Exp $
+ *
+ * Header for the Linux ISDN abc-extension.
+ *
+ * Copyright           by abc GmbH
+ *                     written by Detlef Wengorz <detlefw@isdn4linux.de>
+ * 
+ * This software may be used and distributed according to the terms
+ * of the GNU General Public License, incorporated herein by reference.
+ *
+ */
+
+#ifndef ISDN_DWABC_H
+#define ISDN_DWABC_H
+
+#ifdef __KERNEL__
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/smp.h>
+#include <linux/spinlock.h>
+#include <linux/errno.h>
+
+
+typedef struct ISDN_DWSPINLOCK {
+
+	spinlock_t 	spin;
+	short  		owner;
+	short		my_flags;
+	ulong 		irq_flags;
+
+} ISDN_DWSPINLOCK;
+
+#define ISDN_DWSPIN_UNLOCKED				\
+	(ISDN_DWSPINLOCK) {						\
+		spin: 		SPIN_LOCK_UNLOCKED,		\
+		owner:		-1,						\
+		my_flags:	0,						\
+		irq_flags:	0,						\
+	}
+
+#define ISDN_DWSPIN_INIT(x)			\
+			do { *(x) = ISDN_DWSPIN_UNLOCKED; } while(0);
+
+static __inline__ int isdn_dwspin_trylock(ISDN_DWSPINLOCK *spin)
+{
+	if(!spin_trylock(&spin->spin)) {
+
+		if(spin->owner == smp_processor_id())
+			return(-EAGAIN);
+
+		spin_lock(&spin->spin);
+	}
+
+	spin->owner = smp_processor_id();
+	return(0);
+}
+
+static __inline__ void isdn_dwspin_unlock(ISDN_DWSPINLOCK *spin)
+{
+	spin->owner = -1;
+	spin_unlock(&spin->spin);
+}
+
+
+#else
+#include <sys/types.h>
+#endif
+
+#define DWABC_LCR_FLG_NEWNUMBER		0x00000001L
+#define DWABC_LCR_FLG_DISABLE		0x00000002L
+#define DWABC_LCR_FLG_NEWHUPTIME	0x00000004L
+
+
+struct ISDN_DWABC_LCR_IOCTL {
+
+	int 	lcr_ioctl_sizeof;	/* mustbe sizeof(ISDN_DWABC_LCR_IOCTL)	*/
+	u_short lcr_ioctl_onhtime;	/* new hanguptime						*/
+	u_long 	lcr_ioctl_callid;	/* callid from lcr-subsystem			*/
+	u_long 	lcr_ioctl_flags;	/* see above							*/
+	char 	lcr_ioctl_nr[32];	/* new destination phonenumber			*/
+};
+
+#endif
--- a/include/linux/isdn_lzscomp.h
+++ b/include/linux/isdn_lzscomp.h
@@ -1,4 +1,4 @@
-/* $Id: isdn_lzscomp.h,v 1.1.4.1 2001/11/20 14:19:38 kai Exp $
+/* $Id$
  *
  * Header for isdn_lzscomp.c
  * Concentrated here to not mess up half a dozen kernel headers with code
--- a/include/linux/isdn_ppp.h
+++ b/include/linux/isdn_ppp.h
@@ -8,6 +8,7 @@
 #ifndef _LINUX_ISDN_PPP_H
 #define _LINUX_ISDN_PPP_H
 
+#include <linux/isdn_compat.h>
 
 #define CALLTYPE_INCOMING 0x1
 #define CALLTYPE_OUTGOING 0x2
@@ -33,6 +34,11 @@ struct pppcallinfo
 #define PPPIOCSCOMPRESSOR _IOW('t',135,int)
 #define PPPIOCGIFNAME      _IOR('t',136, char [IFNAMSIZ] )
 
+#ifdef COMPAT_NEED_MPPP_DEFS
+#define PPP_MP          0x003d
+#define PPP_COMPFRAG    0x00fb
+#define PPP_CCPFRAG     0x80fb
+#endif
 
 #define SC_MP_PROT       0x00000200
 #define SC_REJ_MP_PROT   0x00000400
@@ -65,9 +71,6 @@ struct isdn_ppp_comp_data {
 
 #include <linux/config.h>
 
-#ifdef CONFIG_IPPP_FILTER
-#include <linux/filter.h>
-#endif
 
 #define DECOMP_ERR_NOMEM	(-10)
 
@@ -226,10 +229,6 @@ struct ippp_struct {
   unsigned char *cbuf;
   struct slcompress *slcomp;
 #endif
-#ifdef CONFIG_IPPP_FILTER
-  struct sock_fprog pass_filter;	/* filter for packets to pass */
-  struct sock_fprog active_filter;	/* filter for pkts to reset idle */
-#endif
   unsigned long debug;
   struct isdn_ppp_compressor *compressor,*decompressor;
   struct isdn_ppp_compressor *link_compressor,*link_decompressor;
--- a/include/linux/isdnif.h
+++ b/include/linux/isdnif.h
@@ -1,4 +1,4 @@
-/* $Id: isdnif.h,v 1.1.4.1 2001/11/20 14:19:38 kai Exp $
+/* $Id: isdnif.h,v 1.43 2002/02/09 21:19:11 keil Exp $
  *
  * Linux ISDN subsystem
  * Definition of the interface between the subsystem and its low-level drivers.
@@ -14,6 +14,7 @@
 #ifndef __ISDNIF_H__
 #define __ISDNIF_H__
 
+#include <linux/isdn_compat.h>
 
 /*
  * Values for general protocol-selection
@@ -213,6 +214,8 @@ typedef struct
 #define ISDN_STAT_FAXIND  276    /* FAX indications from HL-driver        */
 #define ISDN_STAT_AUDIO   277    /* DTMF, DSP indications                 */
 #define ISDN_STAT_DISCH   278    /* Disable/Enable channel usage          */
+#define ISDN_STAT_ALERT   279    /* Signal alerting                       */
+#define ISDN_STAT_PROCEED 280    /* Signal proceeding                     */
 
 /*
  * Audio commands
--- a/include/linux/kernelcapi.h
+++ b/include/linux/kernelcapi.h
@@ -1,12 +1,10 @@
-/* $Id: kernelcapi.h,v 1.1.4.2 2002/01/28 18:25:10 kai Exp $
+/*
+ * $Id: kernelcapi.h,v 1.9 2000/11/28 09:34:02 kai Exp $
  * 
  * Kernel CAPI 2.0 Interface for Linux
  * 
  * (c) Copyright 1997 by Carsten Paeth (calle@calle.in-berlin.de)
  * 
- * This software may be used and distributed according to the terms
- * of the GNU General Public License, incorporated herein by reference.
- *
  */
 
 #ifndef __KERNELCAPI_H__
