]> git.neil.brown.name Git - history.git/commitdiff
Linux 2.0.36pre13 2.0.36pre13
authorAlan Cox <alan@lxorguk.ukuu.org.uk>
Fri, 23 Nov 2007 20:12:01 +0000 (15:12 -0500)
committerAlan Cox <alan@lxorguk.ukuu.org.uk>
Fri, 23 Nov 2007 20:12:01 +0000 (15:12 -0500)
This won't be the last. I'm told the final 5.1 revision super save the universe
adaptec driver will be out in a few days. I'm going to do a pre14 when that
occurs. No point having 2.0.36 appear the day before the new adaptec driver
passes its final testing.

Anyway.. the changes

2.0.36pre13 changes

o lxdialog handles differences between Ncurses versions nicely
[Thomas Dickey]
o Bridging might actually compile and work right now [me]
o A quota hanging bug has been killed [c/o DaveM]
o New EEPro10 driver update [Bao]
o SMP deadlock possibility fixed [Leonard]
o SYSV define and shm swap off now work right [me]
o ISDN update [Karsten Keil]
o make xconfig bug fixes [Andrew Veliath]
o Incorrect definition of one of the IP options fixed [ANK]
o paride update [Grant Guenther]
o Ensoniq known in PCI vendor data [Bill Nottingham]
o Alpha returns -ENOSYS not -EPERM for invalid syscalls
o TCP/IP accounting now doesnt account packets with invalid headers

40 files changed:
Documentation/Configure.help
Documentation/isdn/README.HiSax
drivers/isdn/Config.in
drivers/isdn/hisax/Makefile
drivers/isdn/hisax/arcofi.c
drivers/isdn/hisax/avm_a1.c
drivers/isdn/hisax/avm_a1p.c [new file with mode: 0644]
drivers/isdn/hisax/avm_pci.c [new file with mode: 0644]
drivers/isdn/hisax/callc.c
drivers/isdn/hisax/config.c
drivers/isdn/hisax/elsa.c
drivers/isdn/hisax/elsa_ser.c
drivers/isdn/hisax/hfc_2bds0.c
drivers/isdn/hisax/hfc_2bs0.c
drivers/isdn/hisax/hisax.h
drivers/isdn/hisax/hscx.c
drivers/isdn/hisax/hscx_irq.c
drivers/isdn/hisax/isac.c
drivers/isdn/hisax/isdnl1.c
drivers/isdn/hisax/isdnl1.h
drivers/isdn/hisax/isdnl2.c
drivers/isdn/hisax/isdnl3.c
drivers/isdn/hisax/l3_1tr6.c
drivers/isdn/hisax/l3_1tr6.h
drivers/isdn/hisax/l3dss1.c
drivers/isdn/hisax/netjet.c
drivers/isdn/hisax/sedlbauer.c
drivers/net/eepro.c
fs/ext2/ialloc.c
include/asm-i386/irq.h
include/linux/ip.h
mm/swapfile.c
net/bridge/br.c
net/ipv4/ip_input.c
net/netrom/af_netrom.c
net/netrom/nr_loopback.c
scripts/lxdialog/dialog.h
scripts/lxdialog/lxdialog.c
scripts/lxdialog/menubox.c
scripts/lxdialog/textbox.c

index 49c6d23091d7bfef85b1afba1d65905101748176..0481e8009153437d06950308ec01e7c95d09f411 100644 (file)
@@ -4488,11 +4488,33 @@ CONFIG_ISDN_DRV_HISAX
   chipset in a more general way. This chipset is used on various
   ISDN-cards (like AVM A1, Elsa ISDN cards, Teles S0-16.0,
   Teles S0-16.3, Teles S0-8, Teles/Creatix PnP, ITK micro ix1 and
-  many compatibles). It's a complete rewrite of the original Teles
-  driver.
+  many compatibles). It supports other chipsets too.
   See Documentation/isdn/README.HiSax for further informations on
   using this driver.
 
+HiSax Support for EURO/DSS1
+CONFIG_HISAX_EURO
+  Enable this if you have a EURO ISDN line.
+
+Support for german chargeinfo
+CONFIG_DE_AOC
+If you have german AOC, you can enable this to get the charginfo.
+
+Disable sending complete
+CONFIG_HISAX_NO_SENDCOMPLETE
+If you have trouble with some ugly exchanges or you live in Australia
+select this option.
+
+Disable sending low layer compatibility
+CONFIG_HISAX_NO_LLC
+If you have trouble with some ugly exchanges try to select this
+option.
+
+HiSax Support for german 1TR6
+CONFIG_HISAX_1TR6
+Enable this if you have a old german 1TR6 line.
+Note: Many older local switches are using 1TR6 on internal S0.
+
 HiSax Support for Teles 16.0/8.0
 CONFIG_HISAX_16_0
   This enables HiSax support for the Teles ISDN-cards S0-16.0,
@@ -4507,64 +4529,95 @@ CONFIG_HISAX_16_3
   the Teles/Creatix PnP and the Teles PCMCIA.
   See Documentation/isdn/README.HiSax on how to configure it
   using the different cards, a different D-channel protocol, or
-  non-standard IRQ/port/shmem settings.
+  non-standard IRQ/port settings.
+
+HiSax Support for Teles 16.3c
+CONFIG_HISAX_TELES3C
+  This enables HiSax support for the Teles 16.3c PnP.
+  See Documentation/isdn/README.HiSax on how to configure it.
+
+HiSax Support for Teles PCI
+CONFIG_HISAX_TELESPCI
+  This enables HiSax support for the Teles PCI.
+  See Documentation/isdn/README.HiSax on how to configure it.
+
+HiSax Support for Teles S0Box
+CONFIG_HISAX_S0BOX
+  This enables HiSax support for the Teles/Creatix parallel port S0BOX.
+  See Documentation/isdn/README.HiSax on how to configure it.
 
 HiSax Support for AVM A1 (Fritz)
 CONFIG_HISAX_AVM_A1
-  This enables HiSax support for the AVM A1 (aka "Fritz").
+  This enables HiSax support for the AVM A1 (aka "Fritz!").
   See Documentation/isdn/README.HiSax on how to configure it
   using the different cards, a different D-channel protocol, or
-  non-standard IRQ/port/shmem settings.
+  non-standard IRQ/port settings.
 
-HiSax Support for Elsa ISA cards
-CONFIG_HISAX_ELSA_PCC
-  This enables HiSax support for the Elsa Mircolink cards and
-  for the Elsa Quickstep series cards for the ISA bus.
-  You don't have to select "HiSax Support for Elsa PCMCIA card"
-  at the same time.
-  See Documentation/isdn/README.HiSax on how to configure it
-  using the different cards, a different D-channel protocol, or
-  non-standard IRQ/port/shmem settings.
+HiSax Support for AVM PCI (Fritz!PCI)
+CONFIG_HISAX_FRITZPCI
+  This enables HiSax support for the AVM "Fritz!PCI").
+  See Documentation/isdn/README.HiSax on how to configure it.
+
+HiSax Support for AVM A1 PCMCIA (Fritz)
+CONFIG_HISAX_AVM_A1_PCMCIA
+  This enables HiSax support for the AVM A1 "Fritz!PCMCIA").
+  See Documentation/isdn/README.HiSax on how to configure it.
 
-HiSax Support for Elsa PCMCIA card
-CONFIG_HISAX_ELSA_PCMCIA
-  This enables HiSax support for the Elsa PCMCIA card.
-  You don't have to select "HiSax Support for Elsa ISA cards" at
-  the same time.
+HiSax Support for Elsa ISA cards
+CONFIG_HISAX_ELSA
+  This enables HiSax support for all Elsa cards.
   See Documentation/isdn/README.HiSax on how to configure it
   using the different cards, a different D-channel protocol, or
-  non-standard IRQ/port/shmem settings.
+  non-standard IRQ/port settings.
 
 HiSax Support for ITK ix1-micro Revision 2
 CONFIG_HISAX_IX1MICROR2
   This enables HiSax support for the ITK ix1-micro Revision 2 card.
-  See Documentation/isdn/README.HiSax on how to configure it
-  using the different cards, a different D-channel protocol, or
-  non-standard IRQ/port/shmem settings.
-
-HiSax Support for EURO/DSS1
-CONFIG_HISAX_EURO
-  You should choose your D-channel protocol your local
-  telephone service provider uses here by saying Y or N.
-  NOTE: This is mutually exclusive with HiSax Support for
-  german 1TR6 and US/NI-1 if you have only one ISDN card
-  installed.
-
-HiSax Support for US/NI-1
-CONFIG_HISAX_NI1
-  You should choose your D-channel protocol your local
-  telephone service provider uses here by saying Y or N.
-  NOTE: This is mutually exclusive with HiSax Support for
-  german 1TR6 and EURO/DSS1 if you have only one ISDN card
-  installed. (not working yet, under developement)
-
-HiSax Support for german 1TR6
-CONFIG_HISAX_1TR6
-  You should choose your D-channel protocol your local
-  telephone service provider uses here by saying Y or N.
-  NOTE: This is mutually exclusive with HiSax Support for
-  EURO/DSS1 and US/NI-1 if you have only one ISDN card
-  installed.
+  See Documentation/isdn/README.HiSax on how to configure it.
+
+HiSax Support for Eicon.Diehl Diva cards
+CONFIG_HISAX_DIEHLDIVA
+  This enables HiSax support for all none Pro versions of Eicon.Diehl's 
+  Diva series passiv cards.
+  See Documentation/isdn/README.HiSax on how to configure it.
+
+HiSax Support for ASUSCOM cards
+CONFIG_HISAX_ASUSCOM
+  This enables HiSax support for all AsusCom passiv cards.
+  See Documentation/isdn/README.HiSax on how to configure it.
+
+HiSax Support for TELEINT cards
+CONFIG_HISAX_TELEINT
+  This enables HiSax support for TeleInts semi-activ card and for other
+  HFC-2BS0 based cards
+  See Documentation/isdn/README.HiSax on how to configure it.
+
+HiSax Support for Sedlbauer speed card/win/star/PC104/fax
+CONFIG_HISAX_SEDLBAUER
+  This enables HiSax support for all Sedlbauer passiv cards.
+  See Documentation/isdn/README.HiSax on how to configure it.
+
+HiSax Support for USR Sportster internal TA
+CONFIG_HISAX_SPORTSTER
+  This enables HiSax support for the USR (3Com) Sportster internal TA passiv card.
+  See Documentation/isdn/README.HiSax on how to configure it.
+
+HiSax Support for MIC card
+CONFIG_HISAX_MIC
+  This enables HiSax support for the MIC passiv card.
+  See Documentation/isdn/README.HiSax on how to configure it.
+
+HiSax Support for NETjet card
+CONFIG_HISAX_NETJET
+  This enables HiSax support for the NetJet PCI and maybe for other 
+  Tiger300 based passiv cards.
+  See Documentation/isdn/README.HiSax on how to configure it.
+
+HiSax Support for Niccy PnP/PCI card
+CONFIG_HISAX_NICCY
+  This enables HiSax support for Dr. Neuhaus (Sagem) Niccy series
+  passiv cards.
+  See Documentation/isdn/README.HiSax on how to configure it.
 
 PCBIT-D support
 CONFIG_ISDN_DRV_PCBIT
index 593994f1767a83e0fd5156705a2c22c89f356ee2..53f8de99472e661a5f166e43a8b4c93e10f5967e 100644 (file)
@@ -31,6 +31,8 @@ Creatix S0Box
 Creatix PnP S0 
 Compaq ISDN S0 ISA card
 AVM A1 (Fritz, Teledat 150)
+AVM Fritz PCMCIA
+AVM Fritz PCI
 ELSA Microlink PCC-16, PCF, PCF-Pro, PCC-8
 ELSA Quickstep 1000
 ELSA Quickstep 1000PCI
@@ -45,6 +47,7 @@ Dynalink IS64PH (OEM version of ASUSCOM NETWORK INC. ISDNLink 128K adapter)
 HFC-2BS0 based cards (TeleInt SA1)
 Sedlbauer Speed Card (Speed Win, Teledat 100)
 Sedlbauer Speed Star (PCMCIA)
+Sedlbauer ISDN-Controller PC/104
 USR Sportster internal TA (compatible Stollmann tina-pp V3)
 ith Kommunikationstechnik GmbH MIC 16 ISA card 
 Traverse Technologie NETjet PCI S0 card
@@ -72,7 +75,7 @@ It can be configured using the command line feature while loading the kernel
 with LILO or LOADLIN or, if built as a module, using insmod/modprobe with
 parameters.
 There is also some config needed before you compile the kernel and/or
-modules. It is enclose in the normal "make [menu]config" target at the
+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: All PnP cards need to be configured with isapnp and will work
@@ -154,12 +157,12 @@ Card types:
    24   Dr. Neuhaus Niccy PnP    irq, io0, io1 (from isapnp setup)
    24   Dr. Neuhaus Niccy PCI    no parameter
    25   Teles S0Box              irq, io (of the used lpt port)
+   26   AVM A1 PCMCIA (Fritz!)   irq, io (set with card manager)
+   27   AVM PCI (Fritz!PCI)      no parameter
 
         
 At the moment IRQ sharing is only possible with PCI cards. Please make sure
 that your IRQ is free and enabled for ISA use.
-Note: For using the ELSA PCMCIA you need the cardmanager under MSDOS for
-enabling in the moment, then boot linux with loadlin.
 
 
 Examples for module loading
@@ -243,8 +246,10 @@ Card types:
    21   Teles PCI               no parameter
    22   Sedlbauer Speed Star (PCMCIA)  pa=irq, pb=io  (set with card manager)
    24   Dr. Neuhaus Niccy PnP   ONLY WORKS AS A MODULE !
-   24   Dr. Neuhaus Niccy PCI    no parameter
-   25   Teles S0Box              irq, io (of the used lpt port)
+   24   Dr. Neuhaus Niccy PCI   no parameter
+   25   Teles S0Box             irq, io (of the used lpt port)
+   26   AVM A1 PCMCIA (Fritz!)  irq, io (set with card manager)
+   27   AVM PCI (Fritz!PCI)     no parameter
 
 Running the driver
 ------------------
@@ -283,7 +288,7 @@ At the moment, debugging messages are enabled with the hisaxctrl tool:
 
     hisaxctrl <DriverId> DebugCmd <debugging_flags>
 
-<DriverId> default is HiSax, if you didn't specified one.
+<DriverId> default is HiSax, if you didn't specify one.
 
 DebugCmd is  1  for generic debugging
             11  for layer 1 development debugging
@@ -320,18 +325,18 @@ With DebugCmd set to 11:
 With DebugCmd set to 13:
 
          1  Warnings (default: on)
-         2  l3 protocol discriptor errors
+         2  l3 protocol descriptor errors
          4  l3 state machine
          8  charge info debugging (1TR6)
 
 For example, 'hisaxctrl HiSax 1 0x3ff' enables full generic debugging.
 
 Because of some obscure problems with some switch equipment, the delay
-between CONNECT message and sending the first data on th B-channel is now
+between the CONNECT message and sending the first data on the B-channel is now
 configurable with 
 
 hisaxctrl <DriverId> 2 <delay>
-<delay> in ms Value between 50 an 800 ms are recommended.
+<delay> in ms Value between 50 and 800 ms is recommended.
 
 
 Warning
@@ -377,7 +382,9 @@ Special thanks to:
        Firma S.u.S.E
        Firma ith Kommunikationstechnik GmbH
        Firma Traverse Technologie Australia
-        
+       Firma Medusa GmbH  (www.medusa.de).
+       Firma Quant-X Austria for sponsoring a DEC Alpha board+CPU
+         
         My girl friend and partner in life Ute for her patience with me.
 
 
@@ -402,7 +409,7 @@ Original from Juergen Quade, new version KKe.
 Attention NEW VERSION, the old leased line syntax won't work !!!
 
 You can use HiSax to connect your Linux-Box via an ISDN leased line
-to i.e. the internet:
+to e.g. the Internet:
 
 1. Build a kernel which includes the HiSax driver either as a module
    or as part of the kernel.
@@ -420,7 +427,7 @@ to i.e. the internet:
      vi /etc/lilo.conf
      <add HiSax driver parameter in the global section (see below)>
      lilo
-   Your lilo.conf _might_ look as the following:
+   Your lilo.conf _might_ look like the following:
 
        # LILO configuration-file
        # global section
@@ -462,7 +469,7 @@ to i.e. the internet:
       /sbin/isdnctrl secure isdn0 on
       /sbin/isdnctrl huptimeout isdn0 0
       /sbin/isdnctrl l2_prot isdn0 hdlc
-      # Attention you must not set a outgoing number !!! This won't work !!!
+      # Attention you must not set an outgoing number !!! This won't work !!!
       # The incomming number is LEASED0 for the first card, LEASED1 for the
       # second and so on. 
       /sbin/isdnctrl addphone isdn0 in LEASED0
@@ -478,7 +485,8 @@ to i.e. the internet:
       /sbin/hisaxctrl HiSax 5 1
  
 Remarks:
-a) If you have a CISCO don´t forget to switch off the KEEP ALIVE option!
+a) If you have a CISCO don't forget to switch off the KEEP ALIVE option!
+b) Use state of the art isdn4k-utils
 
 Here an example script:
 #!/bin/sh
@@ -530,6 +538,7 @@ case "$1" in
                        /sbin/isdnctrl encap isdn0s cisco-h
                fi
        fi
+       /sbin/isdnctrl status isdn0 on
        # configure tcp/ip
        /sbin/ifconfig isdn0 ${LOCAL_IP} pointopoint ${REMOTE_IP}
        /sbin/route add -host ${REMOTE_IP} isdn0
index 64e2a6974e311b7526a9a379903711fb6e5d1689..0e8ca1edc85dcfd8a219f9a5e8c888d567099a69 100644 (file)
@@ -22,7 +22,8 @@ if [ "$CONFIG_ISDN_DRV_HISAX" != "n" ]; then
     bool 'HiSax Support for EURO/DSS1' CONFIG_HISAX_EURO
     if [ "$CONFIG_HISAX_EURO" != "n" ]; then
            bool 'Support for german chargeinfo' CONFIG_DE_AOC
-           bool 'Support for australian Microlink service (not for std. EURO)' CONFIG_HISAX_ML
+           bool 'Disable sending complete' CONFIG_HISAX_NO_SENDCOMPLETE
+           bool 'Disable sending low layer compatibility' CONFIG_HISAX_NO_LLC
     fi
     bool 'HiSax Support for german 1TR6' CONFIG_HISAX_1TR6
     bool 'HiSax Support for Teles 16.0/8.0' CONFIG_HISAX_16_0
@@ -31,12 +32,14 @@ if [ "$CONFIG_ISDN_DRV_HISAX" != "n" ]; then
     bool 'HiSax Support for Teles PCI' CONFIG_HISAX_TELESPCI 
     bool 'HiSax Support for Teles S0Box' CONFIG_HISAX_S0BOX 
     bool 'HiSax Support for AVM A1 (Fritz)' CONFIG_HISAX_AVM_A1
+    bool 'HiSax Support for AVM PCI (Fritz!PCI)' CONFIG_HISAX_FRITZPCI
+    bool 'HiSax Support for AVM A1 PCMCIA (Fritz)' CONFIG_HISAX_AVM_A1_PCMCIA
     bool 'HiSax Support for Elsa cards' CONFIG_HISAX_ELSA
     bool 'HiSax Support for ITK ix1-micro Revision 2' CONFIG_HISAX_IX1MICROR2
     bool 'HiSax Support for Eicon.Diehl Diva cards' CONFIG_HISAX_DIEHLDIVA
     bool 'HiSax Support for ASUSCOM cards' CONFIG_HISAX_ASUSCOM
     bool 'HiSax Support for TELEINT cards' CONFIG_HISAX_TELEINT
-    bool 'HiSax Support for Sedlbauer speed card/win/star' CONFIG_HISAX_SEDLBAUER
+    bool 'HiSax Support for Sedlbauer speed card/win/star/PC104/fax' CONFIG_HISAX_SEDLBAUER
     bool 'HiSax Support for USR Sportster internal TA' CONFIG_HISAX_SPORTSTER
     bool 'HiSax Support for MIC card' CONFIG_HISAX_MIC
     bool 'HiSax Support for NETjet card' CONFIG_HISAX_NETJET
index 65e1341ee18711bf578fa2f563689a6795e83333..179b4e6a0093421917985d5709bd5cc44b08fb6f 100644 (file)
@@ -1,5 +1,12 @@
 L_OBJS :=
 M_OBJS :=
+LX_OBJS :=
+MX_OBJS :=
+O_OBJS :=
+OX_OBJS :=
+L_TARGET :=
+O_TARGET :=
+
 O_OBJS := isdnl1.o tei.o isdnl2.o isdnl3.o \
           lmgr.o q931.o callc.o fsm.o
 
@@ -53,6 +60,18 @@ ifeq ($(CONFIG_HISAX_AVM_A1),y)
         HSCX_OBJ := hscx.o
 endif
 
+ifeq ($(CONFIG_HISAX_AVM_A1_PCMCIA),y)
+        O_OBJS += avm_a1p.o
+        ISAC_OBJ := isac.o
+        HSCX_OBJ := hscx.o
+endif
+ifeq ($(CONFIG_HISAX_FRITZPCI),y)
+        O_OBJS += avm_pci.o
+        ISAC_OBJ := isac.o
+endif
+
+
 ifeq ($(CONFIG_HISAX_ELSA),y)
         O_OBJS += elsa.o
         ISAC_OBJ := isac.o
@@ -118,7 +137,8 @@ ifeq ($(CONFIG_HISAX_NICCY),y)
         HSCX_OBJ := hscx.o
 endif
 
-O_OBJS += $(ISAC_OBJ) $(HSCX_OBJ) $(HFC_OBJ) $(HFC_2BDS0) $(ARCOFI_OBJ)
+O_OBJS += $(ISAC_OBJ) $(HSCX_OBJ) $(ARCOFI_OBJ) 
+O_OBJS += $(HFC_OBJ) $(HFC_2BDS0)
 OX_OBJS += config.o
 
 O_TARGET :=
index 29c43ddcb892c80dcf64a298254d82a16aa8922c..e38fefab47f4d708019146bc7572e366b2ecfe50 100644 (file)
@@ -1,12 +1,18 @@
-/* $Id: arcofi.c,v 1.1.2.3 1998/05/27 18:04:48 keil Exp $
+/* $Id: arcofi.c,v 1.1.2.5 1998/09/30 22:20:03 keil Exp $
 
- * arcofi.h   Ansteuerung ARCOFI 2165
+ * arcofi.c   Ansteuerung ARCOFI 2165
  *
  * Author     Karsten Keil (keil@temic-ech.spacenet.de)
  *
  *
  *
  * $Log: arcofi.c,v $
+ * Revision 1.1.2.5  1998/09/30 22:20:03  keil
+ * Cosmetics
+ *
+ * Revision 1.1.2.4  1998/09/27 13:05:29  keil
+ * Apply most changes from 2.1.X (HiSax 3.1)
+ *
  * Revision 1.1.2.3  1998/05/27 18:04:48  keil
  * HiSax 3.0
  *
@@ -27,9 +33,8 @@
 int
 send_arcofi(struct IsdnCardState *cs, const u_char *msg, int bc, int receive) {
        u_char val;
-       char tmp[32];
        long flags;
-       int cnt=50;
+       int cnt=30;
        
        cs->mon_txp = 0;
        cs->mon_txc = msg[0];
@@ -55,11 +60,6 @@ send_arcofi(struct IsdnCardState *cs, const u_char *msg, int bc, int receive) {
        while (cnt && !test_bit(HW_MON1_TX_END, &cs->HW_Flags)) {
                cnt--;
                udelay(500);
-#if 0
-               current->state = TASK_INTERRUPTIBLE;
-               current->timeout = jiffies + (10 * HZ) / 1000;  /* Timeout 10ms */
-               schedule();
-#endif
        }
        if (receive) {
                while (cnt && !test_bit(HW_MON1_RX_END, &cs->HW_Flags)) {
@@ -68,8 +68,9 @@ send_arcofi(struct IsdnCardState *cs, const u_char *msg, int bc, int receive) {
                }
        }
        restore_flags(flags);
-       sprintf(tmp, "arcofi tout %d", cnt);
-       debugl1(cs, tmp);
+       if (cnt <= 0) {
+               printk(KERN_WARNING"HiSax arcofi monitor timed out\n");
+               debugl1(cs, "HiSax arcofi monitor timed out");
+       }
        return(cnt);    
 }
-
index 42434c789308e15824a0ebfac9a3c2eb1c62c862..d911ab254b587083ff484518abe22a4e7ecd8173 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: avm_a1.c,v 1.6.2.10 1998/05/27 18:04:50 keil Exp $
+/* $Id: avm_a1.c,v 1.6.2.11 1998/09/27 13:05:30 keil Exp $
 
  * avm_a1.c     low level stuff for AVM A1 (Fritz) isdn cards
  *
@@ -6,6 +6,9 @@
  *
  *
  * $Log: avm_a1.c,v $
+ * Revision 1.6.2.11  1998/09/27 13:05:30  keil
+ * Apply most changes from 2.1.X (HiSax 3.1)
+ *
  * Revision 1.6.2.10  1998/05/27 18:04:50  keil
  * HiSax 3.0
  *
@@ -60,7 +63,7 @@
 #include "isdnl1.h"
 
 extern const char *CardType[];
-const char *avm_revision = "$Revision: 1.6.2.10 $";
+static const char *avm_revision = "$Revision: 1.6.2.11 $";
 
 #define         AVM_A1_STAT_ISAC       0x01
 #define         AVM_A1_STAT_HSCX       0x02
diff --git a/drivers/isdn/hisax/avm_a1p.c b/drivers/isdn/hisax/avm_a1p.c
new file mode 100644 (file)
index 0000000..24ad589
--- /dev/null
@@ -0,0 +1,330 @@
+/* $Id: avm_a1p.c,v 1.1.2.2 1998/09/27 13:05:33 keil Exp $
+ *
+ * avm_a1p.c    low level stuff for the following AVM cards:
+ *              A1 PCMCIA
+ *             FRITZ!Card PCMCIA
+ *             FRITZ!Card PCMCIA 2.0
+ *
+ * Author       Carsten Paeth (calle@calle.in-berlin.de)
+ *
+ * $Log: avm_a1p.c,v $
+ * Revision 1.1.2.2  1998/09/27 13:05:33  keil
+ * Apply most changes from 2.1.X (HiSax 3.1)
+ *
+ * Revision 1.1.2.1  1998/07/15 14:43:26  calle
+ * Support for AVM passive PCMCIA cards:
+ *    A1 PCMCIA, FRITZ!Card PCMCIA and FRITZ!Card PCMCIA 2.0
+ *
+ *
+ */
+#define __NO_VERSION__
+#include "hisax.h"
+#include "isac.h"
+#include "hscx.h"
+#include "isdnl1.h"
+
+/* register offsets */
+#define ADDRREG_OFFSET         0x02
+#define DATAREG_OFFSET         0x03
+#define ASL0_OFFSET            0x04
+#define ASL1_OFFSET            0x05
+#define MODREG_OFFSET          0x06
+#define VERREG_OFFSET          0x07
+
+/* address offsets */
+#define ISAC_FIFO_OFFSET       0x00
+#define ISAC_REG_OFFSET                0x20
+#define HSCX_CH_DIFF           0x40
+#define HSCX_FIFO_OFFSET       0x80
+#define HSCX_REG_OFFSET                0xa0
+
+/* read bits ASL0 */
+#define         ASL0_R_TIMER           0x10 /* active low */
+#define         ASL0_R_ISAC            0x20 /* active low */
+#define         ASL0_R_HSCX            0x40 /* active low */
+#define         ASL0_R_TESTBIT         0x80
+#define  ASL0_R_IRQPENDING     (ASL0_R_ISAC|ASL0_R_HSCX|ASL0_R_TIMER)
+
+/* write bits ASL0 */
+#define         ASL0_W_RESET           0x01
+#define         ASL0_W_TDISABLE        0x02
+#define         ASL0_W_TRESET          0x04
+#define         ASL0_W_IRQENABLE       0x08
+#define         ASL0_W_TESTBIT         0x80
+
+/* write bits ASL1 */
+#define         ASL1_W_LED0            0x10
+#define         ASL1_W_LED1            0x20
+#define         ASL1_W_ENABLE_S0       0xC0
+#define byteout(addr,val) outb(val,addr)
+#define bytein(addr) inb(addr)
+
+static const char *avm_revision = "$Revision: 1.1.2.2 $";
+
+static inline u_char
+ReadISAC(struct IsdnCardState *cs, u_char offset)
+{
+       long flags;
+        u_char ret;
+
+        offset -= 0x20;
+       save_flags(flags);
+       cli();
+        byteout(cs->hw.avm.cfg_reg+ADDRREG_OFFSET,ISAC_REG_OFFSET+offset);
+       ret = bytein(cs->hw.avm.cfg_reg+DATAREG_OFFSET);
+       restore_flags(flags);
+       return ret;
+}
+
+static inline void
+WriteISAC(struct IsdnCardState *cs, u_char offset, u_char value)
+{
+       long flags;
+
+        offset -= 0x20;
+
+       save_flags(flags);
+       cli();
+        byteout(cs->hw.avm.cfg_reg+ADDRREG_OFFSET,ISAC_REG_OFFSET+offset);
+       byteout(cs->hw.avm.cfg_reg+DATAREG_OFFSET, value);
+       restore_flags(flags);
+}
+
+static inline void
+ReadISACfifo(struct IsdnCardState *cs, u_char * data, int size)
+{
+       long flags;
+
+       save_flags(flags);
+       cli();
+       byteout(cs->hw.avm.cfg_reg+ADDRREG_OFFSET,ISAC_FIFO_OFFSET);
+       insb(cs->hw.avm.cfg_reg+DATAREG_OFFSET, data, size);
+       restore_flags(flags);
+}
+
+static inline void
+WriteISACfifo(struct IsdnCardState *cs, u_char * data, int size)
+{
+       long flags;
+
+       save_flags(flags);
+       cli();
+       byteout(cs->hw.avm.cfg_reg+ADDRREG_OFFSET,ISAC_FIFO_OFFSET);
+       outsb(cs->hw.avm.cfg_reg+DATAREG_OFFSET, data, size);
+       restore_flags(flags);
+}
+
+static inline u_char
+ReadHSCX(struct IsdnCardState *cs, int hscx, u_char offset)
+{
+       u_char ret;
+       long flags;
+
+        offset -= 0x20;
+
+       save_flags(flags);
+       cli();
+       byteout(cs->hw.avm.cfg_reg+ADDRREG_OFFSET,
+                       HSCX_REG_OFFSET+hscx*HSCX_CH_DIFF+offset);
+       ret = bytein(cs->hw.avm.cfg_reg+DATAREG_OFFSET);
+       restore_flags(flags);
+       return ret;
+}
+
+static inline void
+WriteHSCX(struct IsdnCardState *cs, int hscx, u_char offset, u_char value)
+{
+       long flags;
+
+        offset -= 0x20;
+
+       save_flags(flags);
+       cli();
+       byteout(cs->hw.avm.cfg_reg+ADDRREG_OFFSET,
+                       HSCX_REG_OFFSET+hscx*HSCX_CH_DIFF+offset);
+       byteout(cs->hw.avm.cfg_reg+DATAREG_OFFSET, value);
+       restore_flags(flags);
+}
+
+static inline void
+ReadHSCXfifo(struct IsdnCardState *cs, int hscx, u_char * data, int size)
+{
+       long flags;
+
+       save_flags(flags);
+       cli();
+       byteout(cs->hw.avm.cfg_reg+ADDRREG_OFFSET,
+                       HSCX_FIFO_OFFSET+hscx*HSCX_CH_DIFF);
+       insb(cs->hw.avm.cfg_reg+DATAREG_OFFSET, data, size);
+       restore_flags(flags);
+}
+
+static inline void
+WriteHSCXfifo(struct IsdnCardState *cs, int hscx, u_char * data, int size)
+{
+       long flags;
+
+       save_flags(flags);
+       cli();
+       byteout(cs->hw.avm.cfg_reg+ADDRREG_OFFSET,
+                       HSCX_FIFO_OFFSET+hscx*HSCX_CH_DIFF);
+       outsb(cs->hw.avm.cfg_reg+DATAREG_OFFSET, data, size);
+       restore_flags(flags);
+}
+
+/*
+ * fast interrupt HSCX stuff goes here
+ */
+
+#define READHSCX(cs, nr, reg) ReadHSCX(cs, nr, reg)
+#define WRITEHSCX(cs, nr, reg, data) WriteHSCX(cs, nr, reg, data)
+#define READHSCXFIFO(cs, nr, ptr, cnt) ReadHSCXfifo(cs, nr, ptr, cnt) 
+#define WRITEHSCXFIFO(cs, nr, ptr, cnt) WriteHSCXfifo(cs, nr, ptr, cnt)
+
+#include "hscx_irq.c"
+
+static void
+avm_a1p_interrupt(int intno, void *dev_id, struct pt_regs *regs)
+{
+       struct IsdnCardState *cs = dev_id;
+       u_char val, sval, stat = 0;
+       char tmp[32];
+
+       if (!cs) {
+               printk(KERN_WARNING "AVM A1 PCMCIA: Spurious interrupt!\n");
+               return;
+       }
+       while ((sval = (~bytein(cs->hw.avm.cfg_reg+ASL0_OFFSET) & ASL0_R_IRQPENDING))) {
+               if (cs->debug & L1_DEB_INTSTAT) {
+                       sprintf(tmp, "avm IntStatus %x", sval);
+                       debugl1(cs, tmp);
+               }
+               if (sval & ASL0_R_HSCX) {
+                        val = ReadHSCX(cs, 1, HSCX_ISTA);
+                       if (val) {
+                               hscx_int_main(cs, val);
+                               stat |= 1;
+                       }
+               }
+               if (sval & ASL0_R_ISAC) {
+                       val = ReadISAC(cs, ISAC_ISTA);
+                       if (val) {
+                               isac_interrupt(cs, val);
+                               stat |= 2;
+                       }
+               }
+       }
+       if (stat & 1) {
+               WriteHSCX(cs, 0, HSCX_MASK, 0xff);
+               WriteHSCX(cs, 1, HSCX_MASK, 0xff);
+               WriteHSCX(cs, 0, HSCX_MASK, 0x00);
+               WriteHSCX(cs, 1, HSCX_MASK, 0x00);
+       }
+       if (stat & 2) {
+               WriteISAC(cs, ISAC_MASK, 0xff);
+               WriteISAC(cs, ISAC_MASK, 0x00);
+       }
+}
+
+static int
+AVM_card_msg(struct IsdnCardState *cs, int mt, void *arg)
+{
+       int ret;
+       switch (mt) {
+               case CARD_RESET:
+                       byteout(cs->hw.avm.cfg_reg+ASL0_OFFSET,0x00);
+                       HZDELAY(HZ / 5 + 1);
+                       byteout(cs->hw.avm.cfg_reg+ASL0_OFFSET,ASL0_W_RESET);
+                       HZDELAY(HZ / 5 + 1);
+                       byteout(cs->hw.avm.cfg_reg+ASL0_OFFSET,0x00);
+                       return 0;
+
+               case CARD_RELEASE:
+                       /* free_irq is done in HiSax_closecard(). */
+                       /* free_irq(cs->irq, cs); */
+                       return 0;
+
+               case CARD_SETIRQ:
+                       ret = request_irq(cs->irq, &avm_a1p_interrupt,
+                                       I4L_IRQ_FLAG, "HiSax", cs);
+                       if (ret)
+                               return ret;
+                       byteout(cs->hw.avm.cfg_reg+ASL0_OFFSET,
+                               ASL0_W_TDISABLE|ASL0_W_TRESET|ASL0_W_IRQENABLE);
+                        return 0;
+
+               case CARD_INIT:
+                       clear_pending_isac_ints(cs);
+                       clear_pending_hscx_ints(cs);
+                       inithscxisac(cs, 1);
+                       inithscxisac(cs, 2);
+                       return 0;
+
+               case CARD_TEST:
+                       /* we really don't need it for the PCMCIA Version */
+                       return 0;
+
+               default:
+                       /* all card drivers ignore others, so we do the same */
+                       return 0;
+       }
+       return 0;
+}
+
+__initfunc(int
+setup_avm_a1_pcmcia(struct IsdnCard *card))
+{
+       u_char model, vers;
+       struct IsdnCardState *cs = card->cs;
+       long flags;
+       char tmp[64];
+
+
+       strcpy(tmp, avm_revision);
+       printk(KERN_INFO "HiSax: AVM A1 PCMCIA driver Rev. %s\n",
+                                                HiSax_getrev(tmp));
+       if (cs->typ != ISDN_CTYPE_A1_PCMCIA)
+               return (0);
+
+       cs->hw.avm.cfg_reg = card->para[1];
+       cs->irq = card->para[0];
+
+
+       save_flags(flags);
+       outb(cs->hw.avm.cfg_reg+ASL1_OFFSET, ASL1_W_ENABLE_S0);
+        sti();
+
+       byteout(cs->hw.avm.cfg_reg+ASL0_OFFSET,0x00);
+       HZDELAY(HZ / 5 + 1);
+       byteout(cs->hw.avm.cfg_reg+ASL0_OFFSET,ASL0_W_RESET);
+       HZDELAY(HZ / 5 + 1);
+       byteout(cs->hw.avm.cfg_reg+ASL0_OFFSET,0x00);
+
+       byteout(cs->hw.avm.cfg_reg+ASL0_OFFSET, ASL0_W_TDISABLE|ASL0_W_TRESET);
+
+       restore_flags(flags);
+
+       model = bytein(cs->hw.avm.cfg_reg+MODREG_OFFSET);
+       vers = bytein(cs->hw.avm.cfg_reg+VERREG_OFFSET);
+
+       printk(KERN_INFO "AVM A1 PCMCIA: io 0x%x irq %d model %d version %d\n",
+                               cs->hw.avm.cfg_reg, cs->irq, model, vers);
+
+       cs->readisac = &ReadISAC;
+       cs->writeisac = &WriteISAC;
+       cs->readisacfifo = &ReadISACfifo;
+       cs->writeisacfifo = &WriteISACfifo;
+       cs->BC_Read_Reg = &ReadHSCX;
+       cs->BC_Write_Reg = &WriteHSCX;
+       cs->BC_Send_Data = &hscx_fill_fifo;
+       cs->cardmsg = &AVM_card_msg;
+
+       ISACVersion(cs, "AVM A1 PCMCIA:");
+       if (HscxVersion(cs, "AVM A1 PCMCIA:")) {
+               printk(KERN_WARNING
+                      "AVM A1 PCMCIA: wrong HSCX versions check IO address\n");
+               return (0);
+       }
+       return (1);
+}
diff --git a/drivers/isdn/hisax/avm_pci.c b/drivers/isdn/hisax/avm_pci.c
new file mode 100644 (file)
index 0000000..64fbcb9
--- /dev/null
@@ -0,0 +1,752 @@
+/* $Id: avm_pci.c,v 1.1.2.3 1998/09/27 23:52:57 keil Exp $
+
+ * avm_pci.c    low level stuff for AVM Fritz!PCI isdn cards
+ *              Thanks to AVM, Berlin for informations
+ *
+ * Author       Karsten Keil (keil@temic-ech.spacenet.de)
+ *
+ *
+ * $Log: avm_pci.c,v $
+ * Revision 1.1.2.3  1998/09/27 23:52:57  keil
+ * Fix error handling
+ *
+ * Revision 1.1.2.2  1998/09/27 13:03:16  keil
+ * Fix segfaults on connect
+ *
+ * Revision 1.1.2.1  1998/08/25 14:01:24  calle
+ * Ported driver for AVM Fritz!Card PCI from the 2.1 tree.
+ * I could not test it.
+ *
+ * Revision 1.1  1998/08/20 13:47:30  keil
+ * first version
+ *
+ *
+ *
+ */
+#define __NO_VERSION__
+#include <linux/config.h>
+#include "hisax.h"
+#include "isac.h"
+#include "isdnl1.h"
+#include <linux/pci.h>
+#include <linux/bios32.h>
+#include <linux/interrupt.h>
+
+extern const char *CardType[];
+static const char *avm_pci_rev = "$Revision: 1.1.2.3 $";
+
+#define  PCI_VENDOR_AVM                0x1244
+#define  PCI_FRITZPCI_ID       0xa00
+
+#define  HDLC_FIFO             0x0
+#define  HDLC_STATUS           0x4
+
+#define         AVM_HDLC_1             0x00
+#define         AVM_HDLC_2             0x01
+#define         AVM_ISAC_FIFO          0x02
+#define         AVM_ISAC_REG_LOW       0x04
+#define         AVM_ISAC_REG_HIGH      0x06
+
+#define  AVM_STATUS0_IRQ_ISAC  0x010000
+#define  AVM_STATUS0_IRQ_HDLC  0x020000
+#define  AVM_STATUS0_IRQ_TIMER 0x040000
+#define  AVM_STATUS0_IRQ_MASK  0x070000
+
+#define  AVM_STATUS0_RESET     0x01
+#define  AVM_STATUS0_DIS_TIMER 0x02
+#define  AVM_STATUS0_RES_TIMER 0x04
+#define  AVM_STATUS0_ENA_IRQ   0x08
+#define  AVM_STATUS0_TESTBIT   0x10
+
+#define  AVM_STATUS1_INT_SEL   0x0f
+#define  AVM_STATUS1_ENA_IOM   0x80
+
+#define  HDLC_MODE_ITF_FLG     0x010000
+#define  HDLC_MODE_TRANS       0x020000
+#define  HDLC_MODE_CCR_7       0x040000
+#define  HDLC_MODE_CCR_16      0x080000
+#define  HDLC_MODE_TESTLOOP    0x800000
+
+#define  HDLC_INT_XPR          0x80
+#define  HDLC_INT_XDU          0x40
+#define  HDLC_INT_RPR          0x20
+#define  HDLC_INT_MASK         0xE0
+
+#define  HDLC_STAT_RME         0x01
+#define  HDLC_STAT_RDO         0x10
+#define  HDLC_STAT_CRCVFRRAB   0x0E
+#define  HDLC_STAT_CRCVFR      0x06
+#define  HDLC_STAT_RML_MASK    0x3f00
+
+#define  HDLC_CMD_XRS          0x80
+#define  HDLC_CMD_XME          0x01
+#define  HDLC_CMD_RRS          0x20
+#define  HDLC_CMD_XML_MASK     0x3f00
+
+
+/* Interface functions */
+
+static u_char
+ReadISAC(struct IsdnCardState *cs, u_char offset)
+{
+       register u_int idx = (offset > 0x2f) ? AVM_ISAC_REG_HIGH : AVM_ISAC_REG_LOW;
+       register u_char val;
+       register long flags;
+       
+       save_flags(flags);
+       cli();
+       if (idx != inl(cs->hw.avm.cfg_reg + 4))
+               outl(idx, cs->hw.avm.cfg_reg + 4);
+       val = inb(cs->hw.avm.isac + (offset & 0xf));
+       restore_flags(flags);
+       return (val);
+}
+
+static void
+WriteISAC(struct IsdnCardState *cs, u_char offset, u_char value)
+{
+       register u_int idx = (offset > 0x2f) ? AVM_ISAC_REG_HIGH : AVM_ISAC_REG_LOW;
+       register long flags;
+       
+       save_flags(flags);
+       cli();
+       if (idx != inl(cs->hw.avm.cfg_reg + 4))
+               outl(idx, cs->hw.avm.cfg_reg + 4);  
+       outb(value, cs->hw.avm.isac + (offset & 0xf));
+       restore_flags(flags);
+}
+
+static void
+ReadISACfifo(struct IsdnCardState *cs, u_char * data, int size)
+{
+       if (AVM_ISAC_FIFO != inl(cs->hw.avm.cfg_reg + 4))
+               outl(AVM_ISAC_FIFO, cs->hw.avm.cfg_reg + 4);
+       insb(cs->hw.avm.isac, data, size);
+}
+
+static void
+WriteISACfifo(struct IsdnCardState *cs, u_char * data, int size)
+{
+       if (AVM_ISAC_FIFO != inl(cs->hw.avm.cfg_reg + 4))
+               outl(AVM_ISAC_FIFO, cs->hw.avm.cfg_reg + 4);
+       outsb(cs->hw.avm.isac, data, size);
+}
+
+static inline u_int
+ReadHDLC(struct IsdnCardState *cs, int chan, u_char offset)
+{
+       register u_int idx = chan ? AVM_HDLC_2 : AVM_HDLC_1;
+       register u_int val;
+       register long flags;
+       
+       save_flags(flags);
+       cli();
+       if (idx != inl(cs->hw.avm.cfg_reg + 4))
+               outl(idx, cs->hw.avm.cfg_reg + 4);
+       val = inl(cs->hw.avm.isac + offset);
+       restore_flags(flags);
+       return (val);
+}
+
+static inline void
+WriteHDLC(struct IsdnCardState *cs, int chan, u_char offset, u_int value)
+{
+       register u_int idx = chan ? AVM_HDLC_2 : AVM_HDLC_1;
+       register long flags;
+       
+       save_flags(flags);
+       cli();
+       if (idx != inl(cs->hw.avm.cfg_reg + 4))
+               outl(idx, cs->hw.avm.cfg_reg + 4);
+       outl(value, cs->hw.avm.isac + offset);
+       restore_flags(flags);
+}
+
+static u_char
+ReadHDLC_s(struct IsdnCardState *cs, int chan, u_char offset)
+{
+       return(0xff & ReadHDLC(cs, chan, offset));
+}
+
+static void
+WriteHDLC_s(struct IsdnCardState *cs, int chan, u_char offset, u_char value)
+{
+       WriteHDLC(cs, chan, offset, value);
+}
+
+static inline
+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);
+}
+
+void inline
+hdlc_sched_event(struct BCState *bcs, int event)
+{
+       bcs->event |= 1 << event;
+       queue_task(&bcs->tqueue, &tq_immediate);
+       mark_bh(IMMEDIATE_BH);
+}
+
+void
+modehdlc(struct BCState *bcs, int mode, int bc)
+{
+       struct IsdnCardState *cs = bcs->cs;
+       int hdlc = bcs->channel;
+
+       if (cs->debug & L1_DEB_HSCX) {
+               char tmp[40];
+               sprintf(tmp, "hdlc %c mode %d ichan %d",
+                       'A' + hdlc, mode, bc);
+               debugl1(cs, tmp);
+       }
+       bcs->mode = mode;
+       bcs->channel = bc;
+       switch (mode) {
+               case (L1_MODE_NULL):
+                       bcs->hw.hdlc.ctrl = HDLC_MODE_TRANS | HDLC_CMD_XRS | HDLC_CMD_RRS;
+                       WriteHDLC(cs, bcs->channel, HDLC_STATUS, bcs->hw.hdlc.ctrl);
+                       break;
+               case (L1_MODE_TRANS):
+                       bcs->hw.hdlc.ctrl = HDLC_MODE_TRANS | HDLC_CMD_XRS | HDLC_CMD_RRS;
+                       WriteHDLC(cs, bcs->channel, HDLC_STATUS, bcs->hw.hdlc.ctrl);
+                       bcs->hw.hdlc.ctrl = HDLC_MODE_TRANS | HDLC_CMD_XRS;
+                       WriteHDLC(cs, bcs->channel, HDLC_STATUS, bcs->hw.hdlc.ctrl);
+                       bcs->hw.hdlc.ctrl = HDLC_MODE_TRANS;
+                       hdlc_sched_event(bcs, B_XMTBUFREADY);
+                       break;
+               case (L1_MODE_HDLC):
+                       bcs->hw.hdlc.ctrl = HDLC_MODE_ITF_FLG | HDLC_CMD_XRS | HDLC_CMD_RRS;
+                       WriteHDLC(cs, bcs->channel, HDLC_STATUS, bcs->hw.hdlc.ctrl);
+                       bcs->hw.hdlc.ctrl = HDLC_MODE_ITF_FLG | HDLC_CMD_XRS;
+                       WriteHDLC(cs, bcs->channel, HDLC_STATUS, bcs->hw.hdlc.ctrl);
+                       bcs->hw.hdlc.ctrl = HDLC_MODE_ITF_FLG;
+                       hdlc_sched_event(bcs, B_XMTBUFREADY);
+                       break;
+       }
+}
+
+static inline void
+hdlc_empty_fifo(struct BCState *bcs, int count)
+{
+       register u_int *ptr;
+       u_char *p;
+       u_int idx = bcs->channel ? AVM_HDLC_2 : AVM_HDLC_1;
+       int cnt=0;
+       struct IsdnCardState *cs = bcs->cs;
+
+       if ((cs->debug & L1_DEB_HSCX) && !(cs->debug & L1_DEB_HSCX_FIFO)) {
+               u_char tmp[32];
+               sprintf(tmp, "hdlc_empty_fifo %d", count);
+               debugl1(cs, tmp);
+       }
+       if (bcs->hw.hdlc.rcvidx + count > HSCX_BUFMAX) {
+               if (cs->debug & L1_DEB_WARN)
+                       debugl1(cs, "hdlc_empty_fifo: incoming packet too large");
+               return;
+       }
+       ptr = (u_int *) p = bcs->hw.hdlc.rcvbuf + bcs->hw.hdlc.rcvidx;
+       bcs->hw.hdlc.rcvidx += count;
+       if (idx != inl(cs->hw.avm.cfg_reg + 4))
+               outl(idx, cs->hw.avm.cfg_reg + 4);
+       while (cnt<count) {
+               *ptr++ = inl(cs->hw.avm.isac);
+               cnt += 4;
+       }
+       if (cs->debug & L1_DEB_HSCX_FIFO) {
+               char tmp[256];
+               char *t = tmp;
+
+               t += sprintf(t, "hdlc_empty_fifo %c cnt %d",
+                            bcs->channel ? 'B' : 'A', count);
+               QuickHex(t, p, count);
+               debugl1(cs, tmp);
+       }
+}
+
+static inline void
+hdlc_fill_fifo(struct BCState *bcs)
+{
+       struct IsdnCardState *cs = bcs->cs;
+       int count, cnt =0;
+       int fifo_size = 32;
+       u_char *p;
+       u_int *ptr;
+       u_int idx = bcs->channel ? AVM_HDLC_2 : AVM_HDLC_1;
+
+
+       if ((cs->debug & L1_DEB_HSCX) && !(cs->debug & L1_DEB_HSCX_FIFO))
+               debugl1(cs, "hdlc_fill_fifo");
+       if (!bcs->tx_skb)
+               return;
+       if (bcs->tx_skb->len <= 0)
+               return;
+
+       bcs->hw.hdlc.ctrl &= ~HDLC_CMD_XME;
+       if (bcs->tx_skb->len > fifo_size) {
+               count = fifo_size;
+       } else {
+               count = bcs->tx_skb->len;
+               if (bcs->mode != L1_MODE_TRANS)
+                       bcs->hw.hdlc.ctrl |= HDLC_CMD_XME;
+       }
+       if ((cs->debug & L1_DEB_HSCX) && !(cs->debug & L1_DEB_HSCX_FIFO)) {
+               u_char tmp[32];
+               sprintf(tmp, "hdlc_fill_fifo %d/%ld", count, bcs->tx_skb->len);
+               debugl1(cs, tmp);
+       }
+       ptr = (u_int *) p = bcs->tx_skb->data;
+       skb_pull(bcs->tx_skb, count);
+       bcs->tx_cnt -= count;
+       bcs->hw.hdlc.count += count;
+       if (idx != inl(cs->hw.avm.cfg_reg + 4))
+               outl(idx, cs->hw.avm.cfg_reg + 4);
+       bcs->hw.hdlc.ctrl &= ~HDLC_CMD_XML_MASK;
+       bcs->hw.hdlc.ctrl |= ((count == fifo_size) ? 0 : count)<<8;
+       outl(bcs->hw.hdlc.ctrl, cs->hw.avm.isac + HDLC_STATUS);
+       while (cnt<count) {
+               outl(*ptr++, cs->hw.avm.isac);
+               cnt += 4;
+       }
+       if (cs->debug & L1_DEB_HSCX_FIFO) {
+               char tmp[256];
+               char *t = tmp;
+
+               t += sprintf(t, "hdlc_fill_fifo %c cnt %d",
+                            bcs->channel ? 'B' : 'A', count);
+               QuickHex(t, p, count);
+               debugl1(cs, tmp);
+       }
+}
+
+static void
+fill_hdlc(struct BCState *bcs)
+{
+       long flags;
+       save_flags(flags);
+       cli();
+       hdlc_fill_fifo(bcs);
+       restore_flags(flags);
+}
+
+static inline void
+HDLC_irq(struct BCState *bcs, u_int stat) {
+       u_char tmp[32];
+       int len;
+       struct sk_buff *skb;
+       
+       if (bcs->cs->debug & L1_DEB_HSCX) {
+               sprintf(tmp, "ch%d stat %#x", bcs->channel, stat);
+               debugl1(bcs->cs, tmp);
+       }       
+       if (stat & HDLC_INT_RPR) {
+               if (stat & HDLC_STAT_RDO) {
+                       if (bcs->cs->debug & L1_DEB_HSCX) {
+                               debugl1(bcs->cs, "RDO");
+                       } else {
+                               sprintf(tmp, "ch%d stat %#x", bcs->channel, stat);
+                               debugl1(bcs->cs, tmp);
+                       }
+                       bcs->hw.hdlc.ctrl &= ~HDLC_STAT_RML_MASK;
+                       bcs->hw.hdlc.ctrl |= HDLC_CMD_RRS;
+                       WriteHDLC(bcs->cs, bcs->channel, HDLC_STATUS, bcs->hw.hdlc.ctrl);
+                       bcs->hw.hdlc.ctrl &= ~HDLC_CMD_RRS;
+                       WriteHDLC(bcs->cs, bcs->channel, HDLC_STATUS, bcs->hw.hdlc.ctrl);
+                       bcs->hw.hdlc.rcvidx = 0;
+               } else {
+                       if (!(len = (stat & HDLC_STAT_RML_MASK)>>8))
+                               len = 32;
+                       hdlc_empty_fifo(bcs, len);
+                       if ((stat & HDLC_STAT_RME) || (bcs->mode == L1_MODE_TRANS)) {
+                               if (((stat & HDLC_STAT_CRCVFRRAB)==HDLC_STAT_CRCVFR) ||
+                                       (bcs->mode == L1_MODE_TRANS)) {
+                                       if (!(skb = dev_alloc_skb(bcs->hw.hdlc.rcvidx)))
+                                               printk(KERN_WARNING "HDLC: receive out of memory\n");
+                                       else {
+                                               memcpy(skb_put(skb, bcs->hw.hdlc.rcvidx),
+                                                       bcs->hw.hdlc.rcvbuf, bcs->hw.hdlc.rcvidx);
+                                               skb_queue_tail(&bcs->rqueue, skb);
+                                       }
+                                       bcs->hw.hdlc.rcvidx = 0;
+                                       hdlc_sched_event(bcs, B_RCVBUFREADY);
+                               } else {
+                                       if (bcs->cs->debug & L1_DEB_HSCX) {
+                                               debugl1(bcs->cs, "invalid frame");
+                                       } else {
+                                               sprintf(tmp, "ch%d invalid frame %#x", bcs->channel, stat);
+                                               debugl1(bcs->cs, tmp);
+                                       }
+                                       bcs->hw.hdlc.rcvidx = 0;
+                               } 
+                       }
+               }
+       }
+       if (stat & HDLC_INT_XDU) {
+               /* Here we lost an TX interrupt, so
+                * restart transmitting the whole frame.
+                */
+               if (bcs->tx_skb) {
+                       skb_push(bcs->tx_skb, bcs->hw.hdlc.count);
+                       bcs->tx_cnt += bcs->hw.hdlc.count;
+                       bcs->hw.hdlc.count = 0;
+//                     hdlc_sched_event(bcs, B_XMTBUFREADY);
+                       sprintf(tmp, "ch%d XDU", bcs->channel);
+               } else {
+                       sprintf(tmp, "ch%d XDU without skb", bcs->channel);
+               }
+               if (bcs->cs->debug & L1_DEB_WARN)
+                       debugl1(bcs->cs, tmp);
+               bcs->hw.hdlc.ctrl &= ~HDLC_STAT_RML_MASK;
+               bcs->hw.hdlc.ctrl |= HDLC_CMD_XRS;
+               WriteHDLC(bcs->cs, bcs->channel, HDLC_STATUS, bcs->hw.hdlc.ctrl);
+               bcs->hw.hdlc.ctrl &= ~HDLC_CMD_XRS;
+               WriteHDLC(bcs->cs, bcs->channel, HDLC_STATUS, bcs->hw.hdlc.ctrl);
+               hdlc_fill_fifo(bcs);
+       } else if (stat & HDLC_INT_XPR) {
+               if (bcs->tx_skb) {
+                       if (bcs->tx_skb->len) {
+                               hdlc_fill_fifo(bcs);
+                               return;
+                       } else {
+                               if (bcs->st->lli.l1writewakeup &&
+                                       (PACKET_NOACK != bcs->tx_skb->pkt_type))
+                                       bcs->st->lli.l1writewakeup(bcs->st, bcs->hw.hdlc.count);
+                               dev_kfree_skb(bcs->tx_skb, FREE_WRITE);
+                               bcs->hw.hdlc.count = 0; 
+                               bcs->tx_skb = NULL;
+                       }
+               }
+               if ((bcs->tx_skb = skb_dequeue(&bcs->squeue))) {
+                       bcs->hw.hdlc.count = 0;
+                       test_and_set_bit(BC_FLG_BUSY, &bcs->Flag);
+                       hdlc_fill_fifo(bcs);
+               } else {
+                       test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag);
+                       hdlc_sched_event(bcs, B_XMTBUFREADY);
+               }
+       }
+}
+
+inline void
+HDLC_irq_main(struct IsdnCardState *cs)
+{
+       u_int stat;
+       long  flags;
+       struct BCState *bcs;
+
+       save_flags(flags);
+       cli();  
+       stat = ReadHDLC(cs, 0, HDLC_STATUS);
+       if (stat & HDLC_INT_MASK) {
+               if (!(bcs = Sel_BCS(cs, 0))) {
+                       if (cs->debug)
+                               debugl1(cs, "hdlc spurious channel 0 IRQ");
+               } else
+                       HDLC_irq(bcs, stat);
+       }
+       stat = ReadHDLC(cs, 1, HDLC_STATUS);
+       if (stat & HDLC_INT_MASK) {
+               if (!(bcs = Sel_BCS(cs, 1))) {
+                       if (cs->debug)
+                               debugl1(cs, "hdlc spurious channel 1 IRQ");
+               } else
+                       HDLC_irq(bcs, stat);
+       }
+       restore_flags(flags);   
+}
+
+void
+hdlc_l2l1(struct PStack *st, int pr, void *arg)
+{
+       struct sk_buff *skb = arg;
+       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;
+                               test_and_set_bit(BC_FLG_BUSY, &st->l1.bcs->Flag);
+                               st->l1.bcs->hw.hdlc.count = 0;
+                               restore_flags(flags);
+                               st->l1.bcs->cs->BC_Send_Data(st->l1.bcs);
+                       }
+                       break;
+               case (PH_PULL | INDICATION):
+                       if (st->l1.bcs->tx_skb) {
+                               printk(KERN_WARNING "hdlc_l2l1: this shouldn't happen\n");
+                               break;
+                       }
+                       test_and_set_bit(BC_FLG_BUSY, &st->l1.bcs->Flag);
+                       st->l1.bcs->tx_skb = skb;
+                       st->l1.bcs->hw.hdlc.count = 0;
+                       st->l1.bcs->cs->BC_Send_Data(st->l1.bcs);
+                       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):
+                       test_and_set_bit(BC_FLG_ACTIV, &st->l1.bcs->Flag);
+                       modehdlc(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);
+                       modehdlc(st->l1.bcs, 0, st->l1.bc);
+                       st->l1.l1l2(st, PH_DEACTIVATE | CONFIRM, NULL);
+                       break;
+       }
+}
+
+void
+close_hdlcstate(struct BCState *bcs)
+{
+       modehdlc(bcs, 0, 0);
+       if (test_and_clear_bit(BC_FLG_INIT, &bcs->Flag)) {
+               if (bcs->hw.hdlc.rcvbuf) {
+                       kfree(bcs->hw.hdlc.rcvbuf);
+                       bcs->hw.hdlc.rcvbuf = NULL;
+               }
+               discard_queue(&bcs->rqueue);
+               discard_queue(&bcs->squeue);
+               if (bcs->tx_skb) {
+                       dev_kfree_skb(bcs->tx_skb, FREE_WRITE);
+                       bcs->tx_skb = NULL;
+                       test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag);
+               }
+       }
+}
+
+int
+open_hdlcstate(struct IsdnCardState *cs, struct BCState *bcs)
+{
+       if (!test_and_set_bit(BC_FLG_INIT, &bcs->Flag)) {
+               if (!(bcs->hw.hdlc.rcvbuf = kmalloc(HSCX_BUFMAX, GFP_ATOMIC))) {
+                       printk(KERN_WARNING
+                              "HiSax: No memory for hdlc.rcvbuf\n");
+                       return (1);
+               }
+               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->hw.hdlc.rcvidx = 0;
+       bcs->tx_cnt = 0;
+       return (0);
+}
+
+int
+setstack_hdlc(struct PStack *st, struct BCState *bcs)
+{
+       bcs->channel = st->l1.bc;
+       if (open_hdlcstate(st->l1.hardware, bcs))
+               return (-1);
+       st->l1.bcs = bcs;
+       st->l2.l2l1 = hdlc_l2l1;
+       setstack_manager(st);
+       bcs->st = st;
+       setstack_l1_B(st);
+       return (0);
+}
+
+HISAX_INITFUNC(void
+clear_pending_hdlc_ints(struct IsdnCardState *cs))
+{
+       int val;
+       char tmp[64];
+
+       val = ReadHDLC(cs, 0, HDLC_STATUS);
+       sprintf(tmp, "HDLC 1 STA %x", val);
+       debugl1(cs, tmp);
+       val = ReadHDLC(cs, 1, HDLC_STATUS);
+       sprintf(tmp, "HDLC 2 STA %x", val);
+       debugl1(cs, tmp);
+}
+
+HISAX_INITFUNC(void 
+inithdlc(struct IsdnCardState *cs))
+{
+       cs->bcs[0].BC_SetStack = setstack_hdlc;
+       cs->bcs[1].BC_SetStack = setstack_hdlc;
+       cs->bcs[0].BC_Close = close_hdlcstate;
+       cs->bcs[1].BC_Close = close_hdlcstate;
+       modehdlc(cs->bcs, 0, 0);
+       modehdlc(cs->bcs + 1, 0, 0);
+}
+
+static void
+avm_pci_interrupt(int intno, void *dev_id, struct pt_regs *regs)
+{
+       struct IsdnCardState *cs = dev_id;
+       u_char val, stat = 0;
+       u_int sval;
+
+       if (!cs) {
+               printk(KERN_WARNING "AVM PCI: Spurious interrupt!\n");
+               return;
+       }
+       sval = inl(cs->hw.avm.cfg_reg);
+       if ((sval & AVM_STATUS0_IRQ_MASK) == AVM_STATUS0_IRQ_MASK)
+               /* possible a shared  IRQ reqest */
+               return;
+       if (!(sval & AVM_STATUS0_IRQ_ISAC)) {
+               val = ReadISAC(cs, ISAC_ISTA);
+               isac_interrupt(cs, val);
+               stat |= 2;
+       }
+       if (!(sval & AVM_STATUS0_IRQ_HDLC)) {
+               HDLC_irq_main(cs);
+       }
+       if (stat & 2) {
+               WriteISAC(cs, ISAC_MASK, 0xFF);
+               WriteISAC(cs, ISAC_MASK, 0x0);
+       }
+}
+
+static void
+reset_avmpci(struct IsdnCardState *cs)
+{
+       long flags;
+
+       save_flags(flags);
+       sti();
+       outb(AVM_STATUS0_RESET | AVM_STATUS0_DIS_TIMER, cs->hw.avm.cfg_reg + 2);
+       current->state = TASK_INTERRUPTIBLE;
+       current->timeout = jiffies + (10 * HZ) / 1000;  /* Timeout 10ms */
+       schedule();
+       outb(AVM_STATUS0_DIS_TIMER | AVM_STATUS0_RES_TIMER | AVM_STATUS0_ENA_IRQ, cs->hw.avm.cfg_reg + 2);
+       outb(AVM_STATUS1_ENA_IOM, cs->hw.avm.cfg_reg + 3);
+       current->state = TASK_INTERRUPTIBLE;
+       current->timeout = jiffies + (10 * HZ) / 1000;  /* Timeout 10ms */
+       schedule();
+}
+
+static int
+AVM_card_msg(struct IsdnCardState *cs, int mt, void *arg)
+{
+       switch (mt) {
+               case CARD_RESET:
+                       reset_avmpci(cs);
+                       return(0);
+               case CARD_RELEASE:
+                       outb(0, cs->hw.avm.cfg_reg + 2);
+                       release_region(cs->hw.avm.cfg_reg, 32);
+                       return(0);
+               case CARD_SETIRQ:
+                       return(request_irq(cs->irq, &avm_pci_interrupt,
+                                       I4L_IRQ_FLAG | SA_SHIRQ, "HiSax", cs));
+               case CARD_INIT:
+                       clear_pending_isac_ints(cs);
+                       initisac(cs);
+                       clear_pending_hdlc_ints(cs);
+                       inithdlc(cs);
+                       outb(AVM_STATUS0_DIS_TIMER | AVM_STATUS0_RES_TIMER,
+                               cs->hw.avm.cfg_reg + 2);
+                       WriteISAC(cs, ISAC_MASK, 0);
+                       outb(AVM_STATUS0_DIS_TIMER | AVM_STATUS0_RES_TIMER | 
+                               AVM_STATUS0_ENA_IRQ, cs->hw.avm.cfg_reg + 2);
+                       /* RESET Receiver and Transmitter */
+                       WriteISAC(cs, ISAC_CMDR, 0x41);
+                       return(0);
+               case CARD_TEST:
+                       return(0);
+       }
+       return(0);
+}
+
+static         int pci_index __initdata = 0;
+
+__initfunc(int
+setup_avm_pci(struct IsdnCard *card))
+{
+       u_int val;
+       struct IsdnCardState *cs = card->cs;
+       char tmp[64];
+
+       strcpy(tmp, avm_pci_rev);
+       printk(KERN_INFO "HiSax: AVM PCI driver Rev. %s\n", HiSax_getrev(tmp));
+       if (cs->typ != ISDN_CTYPE_FRITZPCI)
+               return (0);
+#if CONFIG_PCI
+       for (pci_index = 0; pci_index < 255; pci_index++) {
+               unsigned char pci_bus, pci_device_fn;
+               unsigned int ioaddr;
+               unsigned char irq;
+
+               if (pcibios_find_device (PCI_VENDOR_AVM,
+                                       PCI_FRITZPCI_ID, pci_index,
+                                       &pci_bus, &pci_device_fn) != 0) {
+                       continue;
+               }
+               pcibios_read_config_byte(pci_bus, pci_device_fn,
+                               PCI_INTERRUPT_LINE, &irq);
+               pcibios_read_config_dword(pci_bus, pci_device_fn,
+                               PCI_BASE_ADDRESS_1, &ioaddr);
+               cs->irq = irq;
+               cs->hw.avm.cfg_reg = ioaddr & PCI_BASE_ADDRESS_IO_MASK; 
+               if (!cs->hw.avm.cfg_reg) {
+                       printk(KERN_WARNING "FritzPCI: No IO-Adr for PCI card found\n");
+                       return(0);
+               }
+               cs->hw.avm.isac = cs->hw.avm.cfg_reg + 0x10;
+       }       
+       if (pci_index == 8) {
+               printk(KERN_WARNING "FritzPCI: No PCI card found\n");
+               return(0);
+        }
+#else
+       printk(KERN_WARNING "FritzPCI: NO_PCI_BIOS\n");
+       return (0);
+#endif /* CONFIG_PCI */
+
+       if (check_region((cs->hw.avm.cfg_reg), 32)) {
+               printk(KERN_WARNING
+                      "HiSax: %s config port %x-%x already in use\n",
+                      CardType[card->typ],
+                      cs->hw.avm.cfg_reg,
+                      cs->hw.avm.cfg_reg + 31);
+               return (0);
+       } else {
+               request_region(cs->hw.avm.cfg_reg, 32, "avm PCI");
+       }
+
+       val = inl(cs->hw.avm.cfg_reg);
+       printk(KERN_INFO "AVM PCI: stat %#x\n", val);
+       printk(KERN_INFO "AVM PCI: Class %X Rev %d\n",
+              val & 0xff, (val>>8) & 0xff);
+
+       printk(KERN_INFO
+              "HiSax: %s config irq:%d base:0x%X\n",
+              CardType[cs->typ], cs->irq,
+              cs->hw.avm.cfg_reg);
+
+       cs->readisac = &ReadISAC;
+       cs->writeisac = &WriteISAC;
+       cs->readisacfifo = &ReadISACfifo;
+       cs->writeisacfifo = &WriteISACfifo;
+       cs->BC_Read_Reg = &ReadHDLC_s;
+       cs->BC_Write_Reg = &WriteHDLC_s;
+       cs->BC_Send_Data = &fill_hdlc;
+       cs->cardmsg = &AVM_card_msg;
+       ISACVersion(cs, "AVM PCI:");
+       return (1);
+}
index 3cb5f9ce7c4f30d8e36a92c6444a3d1180813bce..e35d271e1c6d95780aadc9534dea6dc01ae03cb7 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: callc.c,v 1.30.2.9 1998/05/27 18:04:53 keil Exp $
+/* $Id: callc.c,v 1.30.2.11 1998/09/30 22:20:05 keil Exp $
 
  * Author       Karsten Keil (keil@temic-ech.spacenet.de)
  *              based on the teles driver from Jan den Ouden
@@ -7,6 +7,12 @@
  *              Fritz Elfert
  *
  * $Log: callc.c,v $
+ * Revision 1.30.2.11  1998/09/30 22:20:05  keil
+ * Cosmetics
+ *
+ * Revision 1.30.2.10  1998/09/27 13:05:35  keil
+ * Apply most changes from 2.1.X (HiSax 3.1)
+ *
  * Revision 1.30.2.9  1998/05/27 18:04:53  keil
  * HiSax 3.0
  *
@@ -71,7 +77,7 @@ extern long mod_use_count_;
 #define MOD_USE_COUNT mod_use_count_
 #endif                         /* MODULE */
 
-const char *lli_revision = "$Revision: 1.30.2.9 $";
+const char *lli_revision = "$Revision: 1.30.2.11 $";
 
 extern struct IsdnCard cards[];
 extern int nrcards;
@@ -87,7 +93,7 @@ static struct Fsm callcfsm =
 static int chancount = 0;
 
 /* experimental REJECT after ALERTING for CALLBACK to beat the 4s delay */ 
-#define ALERT_REJECT 1
+#define ALERT_REJECT 0
 
 /* Value to delay the sending of the first B-channel paket after CONNECT
  * here is no value given by ITU, but experience shows that 300 ms will
@@ -1260,7 +1266,7 @@ dchan_l3l4(struct PStack *st, int pr, void *arg)
                        chanp++;
                        i++;
                }
-                       return;
+               return;
        } else if (pr == (CC_SETUP | INDICATION)) {
                if (!(chanp = selectfreechannel(pc->st))) {
                        pc->st->lli.l4l3(pc->st, CC_DLRL | REQUEST, pc);
@@ -1269,9 +1275,11 @@ dchan_l3l4(struct PStack *st, int pr, void *arg)
                        pc->chan = chanp;
                        FsmEvent(&chanp->fi, EV_SETUP_IND, NULL);
                }
-                       return;
-               }
-       chanp = pc->chan;
+               return;
+       }
+       if (!(chanp = pc->chan))
+               return;
+       
        switch (pr) {
                case (CC_DISCONNECT | INDICATION):
                        FsmEvent(&chanp->fi, EV_DISCONNECT_IND, NULL);
@@ -1318,7 +1326,7 @@ dchan_l3l4(struct PStack *st, int pr, void *arg)
                default:
                        if (chanp->debug & 0x800) {
                                jiftime(tm, jiffies);
-                               sprintf(tmp, "%s Channel %d L3->L4 unknown primitiv %d\n",
+                               sprintf(tmp, "%s Channel %d L3->L4 unknown primitiv %x\n",
                                        tm, chanp->chan, pr);
                                HiSax_putstatus(chanp->cs, tmp);
                        }
@@ -1344,10 +1352,7 @@ init_d_st(struct Channel *chanp)
        st->l2.window = 1;
        st->l2.T200 = 1000;     /* 1000 milliseconds  */
        st->l2.N200 = 3;        /* try 3 times        */
-       if (st->protocol == ISDN_PTYPE_1TR6)
-               st->l2.T203 = 10000;    /* 10000 milliseconds */
-       else
-               st->l2.T203 = 10000;    /* 5000 milliseconds  */
+       st->l2.T203 = 10000;    /* 10000 milliseconds */
        if (test_bit(FLG_TWO_DCHAN, &cs->HW_Flags))
                sprintf(tmp, "DCh%d Q.921", chanp->chan);
        else
@@ -1433,9 +1438,9 @@ CallcNewChan(struct IsdnCardState *csta)
        printk(KERN_INFO "HiSax: 2 channels added\n");
        if (test_bit(FLG_PTP, &csta->channel->d_st->l2.flag)) {
                printk(KERN_INFO "LAYER2 WATCHING ESTABLISH\n");
-       test_and_set_bit(FLG_START_D, &csta->channel->Flags);
-       csta->channel->d_st->lli.l4l3(csta->channel->d_st,
-               DL_ESTABLISH | REQUEST, NULL);
+               test_and_set_bit(FLG_START_D, &csta->channel->Flags);
+               csta->channel->d_st->lli.l4l3(csta->channel->d_st,
+                       DL_ESTABLISH | REQUEST, NULL);
        }
        return (2);
 }
@@ -1501,7 +1506,7 @@ lldata_handler(struct PStack *st, int pr, void *arg)
                        FsmEvent(&chanp->fi, EV_BC_REL, NULL);
                        break;
                default:
-                       printk(KERN_WARNING "lldata_handler unknown primitive %d\n",
+                       printk(KERN_WARNING "lldata_handler unknown primitive %x\n",
                               pr);
                        break;
        }
@@ -1531,7 +1536,7 @@ lltrans_handler(struct PStack *st, int pr, void *arg)
                        FsmEvent(&chanp->fi, EV_BC_REL, NULL);
                        break;
                default:
-                       printk(KERN_WARNING "lltrans_handler unknown primitive %d\n",
+                       printk(KERN_WARNING "lltrans_handler unknown primitive %x\n",
                               pr);
                        break;
        }
@@ -1558,7 +1563,10 @@ init_b_st(struct Channel *chanp, int incoming)
        char tmp[128];
 
        st->l1.hardware = cs;
-       chanp->bcs->mode = 2;
+       if (chanp->leased)
+               st->l1.bc = chanp->chan & 1;
+       else
+               st->l1.bc = chanp->proc->para.bchannel - 1;
        switch (chanp->l2_active_protocol) {
                case (ISDN_PROTO_L2_X75I):
                case (ISDN_PROTO_L2_HDLC):
@@ -1607,10 +1615,6 @@ init_b_st(struct Channel *chanp, int incoming)
                        setstack_l3bc(st, chanp);
                        break;
        }
-                       if (chanp->leased)
-                               st->l1.bc = chanp->chan & 1;
-                       else
-                               st->l1.bc = chanp->proc->para.bchannel - 1;
        return (0);
 }
 
@@ -1631,7 +1635,7 @@ leased_l4l3(struct PStack *st, int pr, void *arg)
                case (DL_RELEASE | REQUEST):
                        break;
                default:
-                       printk(KERN_WARNING "transd_l4l3 unknown primitive %d\n",
+                       printk(KERN_WARNING "transd_l4l3 unknown primitive %x\n",
                               pr);
                        break;
        }
@@ -1666,7 +1670,7 @@ leased_l1l2(struct PStack *st, int pr, void *arg)
                        break;
                default:
                        printk(KERN_WARNING
-                               "transd_l1l2 unknown primitive %d\n", pr);
+                               "transd_l1l2 unknown primitive %x\n", pr);
                        break;
        }
 }
@@ -1761,7 +1765,8 @@ HiSax_command(isdn_ctrl * ic)
        struct Channel *chanp;
        char tmp[128];
        int i;
-       unsigned int num;
+       u_int num;
+       u_long adr;
 
        if (!csta) {
                printk(KERN_ERR
@@ -1784,12 +1789,21 @@ HiSax_command(isdn_ctrl * ic)
                        }
                        chanp->l2_protocol = ic->arg >> 8;
                        break;
+               case (ISDN_CMD_SETL3):
+                       chanp = csta->channel + (ic->arg & 0xff);
+                       if (chanp->debug & 1) {
+                               sprintf(tmp, "SETL3 card %d %ld", csta->cardnr + 1,
+                                       ic->arg >> 8);
+                               link_debug(chanp, tmp, 1);
+                       }
+                       chanp->l3_protocol = ic->arg >> 8;
+                       break;
                case (ISDN_CMD_DIAL):
                        chanp = csta->channel + (ic->arg & 0xff);
                        if (chanp->debug & 1) {
                                sprintf(tmp, "DIAL %s -> %s (%d,%d)",
                                        ic->parm.setup.eazmsn, ic->parm.setup.phone,
-                                ic->parm.setup.si1, ic->parm.setup.si2);
+                                       ic->parm.setup.si1, ic->parm.setup.si2);
                                link_debug(chanp, tmp, 1);
                        }
                        chanp->setup = ic->parm.setup;
@@ -1839,7 +1853,7 @@ HiSax_command(isdn_ctrl * ic)
                                                lli_got_manufacturer(chanp, csta, &ic->parm.cmsg);
                                        break;
                                default:
-                       break;
+                                       break;
                        }
                        break;
 #endif
@@ -1924,15 +1938,27 @@ HiSax_command(isdn_ctrl * ic)
                                                        PH_TESTLOOP | REQUEST, (void *) (long)num);
                                        break;
                                case (7):       /* set card in PTP mode */
+                                       num = *(unsigned int *) ic->parm.num;
                                        if (test_bit(FLG_TWO_DCHAN, &csta->HW_Flags)) {
                                                printk(KERN_ERR "HiSax PTP mode only with one TEI possible\n");
-                                       } else {
+                                       } else if (num) {
                                                test_and_set_bit(FLG_PTP, &csta->channel[0].d_st->l2.flag);
                                                test_and_set_bit(FLG_FIXED_TEI, &csta->channel[0].d_st->l2.flag);
                                                csta->channel[0].d_st->l2.tei = 0;
                                                sprintf(tmp, "set card in PTP mode\n");
                                                HiSax_putstatus(csta, tmp);
                                                printk(KERN_DEBUG "HiSax: %s", tmp);
+                                               printk(KERN_INFO "LAYER2 WATCHING ESTABLISH\n");
+                                               test_and_set_bit(FLG_START_D, &csta->channel[0].Flags);
+                                               test_and_set_bit(FLG_START_D, &csta->channel[1].Flags);
+                                               csta->channel[0].d_st->lli.l4l3(csta->channel[0].d_st,
+                                                       DL_ESTABLISH | REQUEST, NULL);
+                                       } else {
+                                               test_and_clear_bit(FLG_PTP, &csta->channel[0].d_st->l2.flag);
+                                               test_and_clear_bit(FLG_FIXED_TEI, &csta->channel[0].d_st->l2.flag);
+                                               sprintf(tmp, "set card in PTMP mode\n");
+                                               HiSax_putstatus(csta, tmp);
+                                               printk(KERN_DEBUG "HiSax: %s", tmp);
                                        }
                                        break;
                                case (8):       /* set card in FIXED TEI mode */
@@ -1945,6 +1971,11 @@ HiSax_command(isdn_ctrl * ic)
                                        HiSax_putstatus(csta, tmp);
                                        printk(KERN_DEBUG "HiSax: %s", tmp);
                                        break;
+                               case (9): /* load firmware */
+                                       memcpy(&adr, ic->parm.num, sizeof(ulong));
+                                       csta->cardmsg(csta, CARD_LOAD_FIRM,
+                                               (void *) adr);
+                                       break;
 #ifdef MODULE
                                case (55):
                                        MOD_USE_COUNT = 0;
index f23309cc404ed7092deba6c871ef03a9abb9c8a3..e44acf78d968ffde77c2d5c89ac2f707af122711 100644 (file)
@@ -1,10 +1,27 @@
-/* $Id: config.c,v 1.15.2.11 1998/05/27 18:05:07 keil Exp $
+/* $Id: config.c,v 1.15.2.16 1998/09/27 13:05:48 keil Exp $
 
  * Author       Karsten Keil (keil@temic-ech.spacenet.de)
  *              based on the teles driver from Jan den Ouden
  *
  *
  * $Log: config.c,v $
+ * Revision 1.15.2.16  1998/09/27 13:05:48  keil
+ * Apply most changes from 2.1.X (HiSax 3.1)
+ *
+ * Revision 1.15.2.15  1998/09/12 18:43:56  niemann
+ * Added new card: Sedlbauer ISDN-Controller PC/104
+ *
+ * Revision 1.15.2.14  1998/08/25 14:01:27  calle
+ * Ported driver for AVM Fritz!Card PCI from the 2.1 tree.
+ * I could not test it.
+ *
+ * Revision 1.15.2.13  1998/07/30 20:51:24  niemann
+ * Fixed Sedlbauer Speed Card PCMCIA missing isdnl3new
+ *
+ * Revision 1.15.2.12  1998/07/15 14:43:29  calle
+ * Support for AVM passive PCMCIA cards:
+ *    A1 PCMCIA, FRITZ!Card PCMCIA and FRITZ!Card PCMCIA 2.0
+ *
  * Revision 1.15.2.11  1998/05/27 18:05:07  keil
  * HiSax 3.0
  *
@@ -56,7 +73,7 @@
 #include <linux/timer.h>
 #include <linux/config.h>
 #include "hisax.h"
-
+#include <linux/module.h>
 /*
  * This structure array contains one entry per card. An entry looks
  * like this:
  *   23 reserved
  *   24 Dr Neuhaus Niccy PnP/PCI card p0=irq p1=IO0 p2=IO1 (PnP only)
  *   25 Teles S0Box             p0=irq p1=iobase (from isapnp setup)
- *
+ *   26 AVM A1 PCMCIA (Fritz)   p0=irq p1=iobase
+ *   27 AVM PCI (Fritz!PCI)     no parameter
+ *   28 reserved
  *
  * protocol can be either ISDN_PTYPE_EURO or ISDN_PTYPE_1TR6 or ISDN_PTYPE_NI1
  *
 #ifdef CONFIG_HISAX_ELSA
 #define DEFAULT_CARD ISDN_CTYPE_ELSA
 #define DEFAULT_CFG {0,0,0,0}
-int elsa_init_pcmcia(void*, int, int*, int);
 #ifdef MODULE
+int elsa_init_pcmcia(void*, int, int*, int);
 static struct symbol_table hisax_syms_elsa = {
 #include <linux/symtab_begin.h>
        X(elsa_init_pcmcia),
@@ -117,6 +136,32 @@ void register_elsa_symbols(void) {
 #define DEFAULT_CARD ISDN_CTYPE_A1
 #define DEFAULT_CFG {10,0x340,0,0}
 #endif
+
+#ifdef CONFIG_HISAX_AVM_A1_PCMCIA
+#undef DEFAULT_CARD
+#undef DEFAULT_CFG
+#define DEFAULT_CARD ISDN_CTYPE_A1_PCMCIA
+#define DEFAULT_CFG {11,0x170,0,0}
+#ifdef MODULE
+int avm_a1_init_pcmcia(void*, int, int*, int);
+void HiSax_closecard(int cardnr);
+static struct symbol_table hisax_syms_avm_a1= {
+#include <linux/symtab_begin.h>
+       X(avm_a1_init_pcmcia),
+       X(HiSax_closecard),
+#include <linux/symtab_end.h>
+};
+void register_avm_a1_symbols(void) {
+       register_symtab(&hisax_syms_avm_a1);
+}
+#endif
+#endif
+#ifdef CONFIG_HISAX_FRITZPCI
+#undef DEFAULT_CARD
+#undef DEFAULT_CFG
+#define DEFAULT_CARD ISDN_CTYPE_FRITZPCI
+#define DEFAULT_CFG {0,0,0,0}
+#endif
 #ifdef CONFIG_HISAX_16_3
 #undef DEFAULT_CARD
 #undef DEFAULT_CFG
@@ -176,8 +221,8 @@ void register_elsa_symbols(void) {
 #undef DEFAULT_CFG
 #define DEFAULT_CARD ISDN_CTYPE_SEDLBAUER
 #define DEFAULT_CFG {11,0x270,0,0}
-int sedl_init_pcmcia(void*, int, int*, int);
 #ifdef MODULE
+int sedl_init_pcmcia(void*, int, int*, int);
 static struct symbol_table hisax_syms_sedl= {
 #include <linux/symtab_begin.h>
        X(sedl_init_pcmcia),
@@ -352,7 +397,7 @@ HiSaxVersion(void))
        char tmp[64];
 
        printk(KERN_INFO "HiSax: Linux Driver for passive ISDN cards\n");
-       printk(KERN_INFO "HiSax: Version 3.0\n");
+       printk(KERN_INFO "HiSax: Version 3.0b\n");
        strcpy(tmp, l1_revision);
        printk(KERN_INFO "HiSax: Layer1 Revision %s\n", HiSax_getrev(tmp)); 
        strcpy(tmp, l2_revision);
@@ -445,6 +490,13 @@ HiSax_init(void))
                return 0;
        }
 #endif
+#ifdef CONFIG_HISAX_AVM_A1_PCMCIA
+       if (type[0] == ISDN_CTYPE_A1_PCMCIA) {
+               /* we have to export  and return in this case */
+               register_avm_a1_symbols();
+               return 0;
+       }
+#endif
 #endif
        nrcards = 0;
        HiSaxVersion();
@@ -489,6 +541,7 @@ HiSax_init(void))
                        case ISDN_CTYPE_16_3:
                        case ISDN_CTYPE_TELESPCMCIA:
                        case ISDN_CTYPE_A1:
+                       case ISDN_CTYPE_A1_PCMCIA:
                        case ISDN_CTYPE_ELSA_PNP:
                        case ISDN_CTYPE_ELSA_PCMCIA:
                        case ISDN_CTYPE_IX1MICROR2:
@@ -497,6 +550,7 @@ HiSax_init(void))
                        case ISDN_CTYPE_TELEINT:
                        case ISDN_CTYPE_SEDLBAUER:
                        case ISDN_CTYPE_SEDLBAUER_PCMCIA:
+                       case ISDN_CTYPE_SEDLBAUER_FAX:
                        case ISDN_CTYPE_SPORTSTER:
                        case ISDN_CTYPE_MIC:
                        case ISDN_CTYPE_TELES3C:
@@ -508,6 +562,7 @@ HiSax_init(void))
                        case ISDN_CTYPE_NETJET:
                        case ISDN_CTYPE_AMD7930:
                        case ISDN_CTYPE_TELESPCI:
+                       case ISDN_CTYPE_FRITZPCI:
                                break;
                }
        }
@@ -647,6 +702,55 @@ int sedl_init_pcmcia(void *pcm_iob, int pcm_irq, int *busy_flag, int prot)
        cards[0].typ = ISDN_CTYPE_SEDLBAUER_PCMCIA;
        nzproto = 1;
 
+       if (!HiSax_id)
+               HiSax_id = HiSaxID;
+       if (!HiSaxID[0])
+               strcpy(HiSaxID, "HiSax");
+       for (i = 0; i < HISAX_MAX_CARDS; i++)
+               if (cards[i].typ > 0)
+                       nrcards++;
+       printk(KERN_DEBUG "HiSax: Total %d card%s defined\n",
+              nrcards, (nrcards > 1) ? "s" : "");
+
+       CallcNew();
+       Isdnl3New();
+       Isdnl2New();
+       Isdnl1New();
+       TeiNew();
+       HiSax_inithardware(busy_flag);
+       printk(KERN_NOTICE "HiSax: module installed\n");
+       return (0);
+}
+#endif
+
+#ifdef CONFIG_HISAX_AVM_A1_PCMCIA
+int avm_a1_init_pcmcia(void *pcm_iob, int pcm_irq, int *busy_flag, int prot)
+{
+       int i;
+       int nzproto = 0;
+
+       nrcards = 0;
+       HiSaxVersion();
+       if (id)                 /* If id= string used */
+               HiSax_id = id;
+       /* Initialize all 16 structs, even though we only accept
+          two pcmcia cards
+          */
+       for (i = 0; i < 16; i++) {
+               cards[i].para[0] = irq[i];
+               cards[i].para[1] = io[i];
+               cards[i].typ = type[i];
+               if (protocol[i]) {
+                       cards[i].protocol = protocol[i];
+                       nzproto++;
+               }
+       }
+       cards[0].para[0] = pcm_irq;
+       cards[0].para[1] = (int)pcm_iob;
+       cards[0].protocol = prot;
+       cards[0].typ = ISDN_CTYPE_A1_PCMCIA;
+       nzproto = 1;
+
        if (!HiSax_id)
                HiSax_id = HiSaxID;
        if (!HiSaxID[0])
index 92972565c5fd9d4a985d1bf18a8874960bbab425..f133dfbfef6e1ed56c038bff5f5748ead7810288 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: elsa.c,v 1.14.2.11 1998/05/27 18:05:14 keil Exp $
+/* $Id: elsa.c,v 1.14.2.12 1998/09/27 13:05:53 keil Exp $
 
  * elsa.c     low level stuff for Elsa isdn cards
  *
@@ -11,6 +11,9 @@
  *
  *
  * $Log: elsa.c,v $
+ * Revision 1.14.2.12  1998/09/27 13:05:53  keil
+ * Apply most changes from 2.1.X (HiSax 3.1)
+ *
  * Revision 1.14.2.11  1998/05/27 18:05:14  keil
  * HiSax 3.0
  *
@@ -69,7 +72,7 @@
 
 extern const char *CardType[];
 
-const char *Elsa_revision = "$Revision: 1.14.2.11 $";
+const char *Elsa_revision = "$Revision: 1.14.2.12 $";
 const char *Elsa_Types[] =
 {"None", "PC", "PCC-8", "PCC-16", "PCF", "PCF-Pro",
  "PCMCIA", "QS 1000", "QS 3000", "QS 1000 PCI", "QS 3000 PCI"};
@@ -422,9 +425,19 @@ elsa_interrupt_ipac(int intno, void *dev_id, struct pt_regs *regs)
                printk(KERN_WARNING "Elsa: Spurious interrupt!\n");
                return;
        }
-               val = bytein(cs->hw.elsa.cfg + 0x4c); /* PCI IRQ */
+       val = bytein(cs->hw.elsa.cfg + 0x4c); /* PCI IRQ */
        if (!(val & ELSA_PCI_IRQ_MASK))
-         return;
+               return;
+#if ARCOFI_USE
+       if (cs->hw.elsa.MFlag) {
+               val = serial_inp(cs, UART_IIR);
+               if (!(val & UART_IIR_NO_INT)) {
+                       sprintf(tmp,"IIR %02x", val);
+                       debugl1(cs, tmp);
+                       rs_interrupt_elsa(intno, cs);
+               }
+       }
+#endif
        ista = readreg(cs->hw.elsa.ale, cs->hw.elsa.isac, IPAC_ISTA);
 Start_IPAC:
        if (cs->debug & L1_DEB_IPAC) {
@@ -478,7 +491,7 @@ release_io_elsa(struct IsdnCardState *cs)
                release_region(cs->hw.elsa.cfg, 0x80);
        }
        if (cs->subtyp == ELSA_QS3000PCI) {
-               byteout(cs->hw.elsa.cfg + 0x4c, 0x03); /* enable ELSA PCI IRQ */
+               byteout(cs->hw.elsa.cfg + 0x4c, 0x03); /* disable ELSA PCI IRQ */
                writereg(cs->hw.elsa.ale, cs->hw.elsa.isac, IPAC_ATX, 0xff);
                release_region(cs->hw.elsa.cfg, 0x80);
        }
@@ -576,6 +589,8 @@ set_arcofi(struct IsdnCardState *cs, int bc) {
        udelay(ARCDEL);
        send_arcofi(cs, ARCOFI_XOP_F, bc, 0);
        restore_flags(flags);
+       sprintf(tmp,"end set_arcofi bc=%d", bc);
+       debugl1(cs, tmp);
 }
 
 static int
@@ -720,7 +735,7 @@ Elsa_card_msg(struct IsdnCardState *cs, int mt, void *arg)
 {
        int pwr, len, ret = 0;
        u_char *msg;
-       long flags;     
+       long flags;
 
        switch (mt) {
                case CARD_RESET:
@@ -733,10 +748,11 @@ Elsa_card_msg(struct IsdnCardState *cs, int mt, void *arg)
                        if ((cs->subtyp == ELSA_QS1000PCI) ||
                                (cs->subtyp == ELSA_QS3000PCI))
                                ret = request_irq(cs->irq, &elsa_interrupt_ipac,
-                                       I4L_IRQ_FLAG, "HiSax", cs);
+                                       I4L_IRQ_FLAG | SA_SHIRQ, "HiSax", cs);
                        else
                                ret = request_irq(cs->irq, &elsa_interrupt,
                                        I4L_IRQ_FLAG, "HiSax", cs);
+                       reset_elsa(cs);
                        return(ret);
                case CARD_INIT:
                        cs->debug |= L1_DEB_IPAC;
@@ -772,7 +788,7 @@ Elsa_card_msg(struct IsdnCardState *cs, int mt, void *arg)
                                byteout(cs->hw.elsa.ctrl, cs->hw.elsa.ctrl_reg);
                                cs->hw.elsa.status &= ~ELSA_TIMER_AKTIV;
                                printk(KERN_INFO "Elsa: %d timer tics in 110 msek\n",
-                                       cs->hw.elsa.counter);
+                                      cs->hw.elsa.counter);
                                if (abs(cs->hw.elsa.counter - 13) < 3) {
                                        printk(KERN_INFO "Elsa: timer and irq OK\n");
                                        ret = 0;
@@ -1150,7 +1166,6 @@ setup_elsa(struct IsdnCard *card)
                }
                printk(KERN_INFO "Elsa: timer OK; resetting card\n");
        }
-       reset_elsa(cs);
        cs->BC_Read_Reg = &ReadHSCX;
        cs->BC_Write_Reg = &WriteHSCX;
        cs->BC_Send_Data = &hscx_fill_fifo;
index 49b1dc1b3701337f61098b1ce5fa5432d0e914c9..611214cf808063dd0b5d62edec9e492dda5ba8c2 100644 (file)
@@ -1,4 +1,3 @@
-#include <linux/config.h> /* CONFIG_SERIAL_NOPAUSE_IO */
 #include <linux/serial.h>
 #include <linux/serial_reg.h>
 
 #define MIN(a,b)       ((a) < (b) ? (a) : (b))
 #endif
 
-#define SERIAL_DEBUG_OPEN 1
-#define SERIAL_DEBUG_INTR 1
-#define SERIAL_DEBUG_FLOW 1
+//#define SERIAL_DEBUG_OPEN 1
+//#define SERIAL_DEBUG_INTR 1
+//#define SERIAL_DEBUG_FLOW 1
+#undef SERIAL_DEBUG_OPEN
+#undef SERIAL_DEBUG_INTR
+#undef SERIAL_DEBUG_FLOW
 #undef SERIAL_DEBUG_REG
-//#define SERIAL_DEBUG_REG
+//#define SERIAL_DEBUG_REG 1
 
 #ifdef SERIAL_DEBUG_REG
 static u_char deb[32];
@@ -23,9 +25,18 @@ const char *ModemIn[] = {"RBR","IER","IIR","LCR","MCR","LSR","MSR","SCR"};
 const char *ModemOut[] = {"THR","IER","FCR","LCR","MCR","LSR","MSR","SCR"};
 #endif
 
-static char *MInit_1 = "AT &F &C1 E0 &D2 L2 M1 S64=13\n\0";
-static char *MInit_2 = "AT+FCLASS=0 V1 S2=128 X1 \\V8\n\0";
-static char *MInit_3 = "AT %G0 %B2400 L0 M0 &G0 %E1 %L1 %M0 %C3 \\N3\n\0";
+static char *MInit_1 = "AT&F&C1E0&D2\r\0";
+static char *MInit_2 = "ATL2M1S64=13\r\0";
+static char *MInit_3 = "AT+FCLASS=0\r\0";
+static char *MInit_4 = "ATV1S2=128X1\r\0";
+static char *MInit_5 = "AT\\V8\\N3\r\0";
+static char *MInit_6 = "ATL0M0&G0%E1\r\0";
+static char *MInit_7 = "AT%L1%M0%C3\r\0";
+
+static char *MInit_speed28800 = "AT%G0%B28800\r\0";
+
+static char *MInit_dialout = "ATs7=60 x1 d\r\0";
+static char *MInit_dialin = "ATs7=60 x1 a\r\0";
 
 
 static inline unsigned int serial_in(struct IsdnCardState *cs, int offset)
@@ -123,11 +134,13 @@ static void change_speed(struct IsdnCardState *cs, int baud)
 
        sprintf(tmp,"modem quot=0x%x", quot);
        debugl1(cs, tmp);
-       save_flags(flags); cli();
+       save_flags(flags);
+       cli();
        serial_outp(cs, UART_LCR, cval | UART_LCR_DLAB);/* set DLAB */
        serial_outp(cs, UART_DLL, quot & 0xff);         /* LS of divisor */
        serial_outp(cs, UART_DLM, quot >> 8);           /* MS of divisor */
        serial_outp(cs, UART_LCR, cval);                /* reset DLAB */
+       serial_inp(cs, UART_RX);
        restore_flags(flags);
 }
 
@@ -191,7 +204,7 @@ static int mstartup(struct IsdnCardState *cs)
        /*
         * and set the speed of the serial port
         */
-       change_speed(cs, 57600*2);
+       change_speed(cs, BASE_BAUD);
        cs->hw.elsa.MFlag = 1;
 errout:
        restore_flags(flags);
@@ -208,7 +221,7 @@ static void mshutdown(struct IsdnCardState *cs)
 
 
 #ifdef SERIAL_DEBUG_OPEN
-       printk("Shutting down serial ....");
+       printk(KERN_DEBUG"Shutting down serial ....");
 #endif
        
        save_flags(flags); cli(); /* Disable interrupts */
@@ -233,6 +246,9 @@ static void mshutdown(struct IsdnCardState *cs)
        serial_inp(cs, UART_RX);    /* read data port to reset things */
        
        restore_flags(flags);
+#ifdef SERIAL_DEBUG_OPEN
+       printk(" done\n");
+#endif
 }
 
 inline int
@@ -242,31 +258,33 @@ write_modem(struct BCState *bcs) {
        int count, len, fp, buflen;
        long flags;
        
-       if (!bcs->hw.hscx.tx_skb)
+       if (!bcs->tx_skb)
                return 0;
-       if (bcs->hw.hscx.tx_skb->len <= 0)
+       if (bcs->tx_skb->len <= 0)
                return 0;
        save_flags(flags);
        cli();
        buflen = MAX_MODEM_BUF - cs->hw.elsa.transcnt;
-       len = MIN(buflen, bcs->hw.hscx.tx_skb->len);            
+       len = MIN(buflen, bcs->tx_skb->len);            
        fp = cs->hw.elsa.transcnt + cs->hw.elsa.transp;
        fp &= (MAX_MODEM_BUF -1);
        count = MIN(len, MAX_MODEM_BUF - fp);
        if (count < len) {
-               memcpy(cs->hw.elsa.transbuf + fp, skb_pull(bcs->hw.hscx.tx_skb, count), count);
+               memcpy(cs->hw.elsa.transbuf + fp, bcs->tx_skb->data, count);
+               skb_pull(bcs->tx_skb, count);
                cs->hw.elsa.transcnt += count;
                ret = count;
                count = len - count;
                fp = 0;
        }
-       memcpy(cs->hw.elsa.transbuf + fp, skb_pull(bcs->hw.hscx.tx_skb, count), count);
+       memcpy((cs->hw.elsa.transbuf + fp), bcs->tx_skb->data, count);
+       skb_pull(bcs->tx_skb, count);
        cs->hw.elsa.transcnt += count;
        ret += count;
        
        if (cs->hw.elsa.transcnt && 
            !(cs->hw.elsa.IER & UART_IER_THRI)) {
-               cs->hw.elsa.IER |= UART_IER_THRI;
+                       cs->hw.elsa.IER |= UART_IER_THRI;
                serial_outp(cs, UART_IER, cs->hw.elsa.IER);
        }
        restore_flags(flags);
@@ -276,20 +294,20 @@ write_modem(struct BCState *bcs) {
 inline void
 modem_fill(struct BCState *bcs) {
                
-       if (bcs->hw.hscx.tx_skb) {
-               if (bcs->hw.hscx.tx_skb->len) {
+       if (bcs->tx_skb) {
+               if (bcs->tx_skb->len) {
                        write_modem(bcs);
                        return;
                } else {
                        if (bcs->st->lli.l1writewakeup &&
-                               (PACKET_NOACK != bcs->hw.hscx.tx_skb->pkt_type))
+                               (PACKET_NOACK != bcs->tx_skb->pkt_type))
                                        bcs->st->lli.l1writewakeup(bcs->st,
                                                bcs->hw.hscx.count);
-                       dev_kfree_skb(bcs->hw.hscx.tx_skb, FREE_WRITE);
-                       bcs->hw.hscx.tx_skb = NULL;
+                       dev_kfree_skb(bcs->tx_skb, FREE_WRITE);
+                       bcs->tx_skb = NULL;
                }
        }
-       if ((bcs->hw.hscx.tx_skb = skb_dequeue(&bcs->squeue))) {
+       if ((bcs->tx_skb = skb_dequeue(&bcs->squeue))) {
                bcs->hw.hscx.count = 0;
                test_and_set_bit(BC_FLG_BUSY, &bcs->Flag);
                write_modem(bcs);
@@ -350,12 +368,12 @@ static inline void transmit_chars(struct IsdnCardState *cs, int *intr_done)
        sprintf(tmp, "transmit_chars: p(%x) cnt(%x)", cs->hw.elsa.transp, 
                cs->hw.elsa.transcnt);
        debugl1(cs, tmp);
+       
        if (cs->hw.elsa.transcnt <= 0) {
                cs->hw.elsa.IER &= ~UART_IER_THRI;
                serial_out(cs, UART_IER, cs->hw.elsa.IER);
                return;
        }
-       
        count = 16;
        do {
                serial_outp(cs, UART_TX, cs->hw.elsa.transbuf[cs->hw.elsa.transp++]);
@@ -486,7 +504,7 @@ static void rs_interrupt_elsa(int irq, struct IsdnCardState *cs)
 #endif
 }
 
-extern int open_hscxstate(struct IsdnCardState *cs, int bc);
+extern int open_hscxstate(struct IsdnCardState *cs, struct BCState *bcs);
 extern void modehscx(struct BCState *bcs, int mode, int bc);
 extern void hscx_l2l1(struct PStack *st, int pr, void *arg);
 
@@ -495,7 +513,7 @@ close_elsastate(struct BCState *bcs)
 {
        struct sk_buff *skb;
 
-//     modehscx(bcs, 0, 0);
+       modehscx(bcs, 0, bcs->channel);
        if (test_and_clear_bit(BC_FLG_INIT, &bcs->Flag)) {
                if (bcs->hw.hscx.rcvbuf) {
                        if (bcs->mode != L1_MODE_MODEM)
@@ -508,47 +526,14 @@ close_elsastate(struct BCState *bcs)
                while ((skb = skb_dequeue(&bcs->squeue))) {
                        dev_kfree_skb(skb, FREE_WRITE);
                }
-               if (bcs->hw.hscx.tx_skb) {
-                       dev_kfree_skb(bcs->hw.hscx.tx_skb, FREE_WRITE);
-                       bcs->hw.hscx.tx_skb = NULL;
+               if (bcs->tx_skb) {
+                       dev_kfree_skb(bcs->tx_skb, FREE_WRITE);
+                       bcs->tx_skb = NULL;
                        test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag);
                }
        }
 }
 
-void
-modem_l2l1(struct PStack *st, int pr, void *arg)
-{
-       struct sk_buff *skb = arg;
-       long flags;
-
-       if (pr == (PH_DATA | REQUEST)) {
-               save_flags(flags);
-               cli();
-               if (st->l1.bcs->hw.hscx.tx_skb) {
-                       skb_queue_tail(&st->l1.bcs->squeue, skb);
-                       restore_flags(flags);
-               } else {
-                       st->l1.bcs->hw.hscx.tx_skb = skb;
-                       test_and_set_bit(BC_FLG_BUSY, &st->l1.bcs->Flag);
-                       st->l1.bcs->hw.hscx.count = 0;
-                       restore_flags(flags);
-                       write_modem(st->l1.bcs);
-               }
-       } else if (pr == (PH_ACTIVATE | REQUEST)) {
-               test_and_set_bit(BC_FLG_ACTIV, &st->l1.bcs->Flag);
-               st->l1.l1l2(st, PH_ACTIVATE | CONFIRM, NULL);
-               set_arcofi(st->l1.bcs->cs, st->l1.bc);
-               st->l1.bcs->cs->hw.elsa.MFlag=2;
-       } else if (pr == (PH_DEACTIVATE | REQUEST)) {
-               test_and_clear_bit(BC_FLG_ACTIV, &st->l1.bcs->Flag);
-               send_arcofi(st->l1.bcs->cs, ARCOFI_XOP_0, st->l1.bc, 0);
-               st->l1.bcs->cs->hw.elsa.MFlag=1;
-       } else {
-               printk(KERN_WARNING"ElsaSer: unknown pr %x\n", pr);
-       }
-}
-
 void
 modem_write_cmd(struct IsdnCardState *cs, u_char *buf, int len) {
        int count, fp;
@@ -587,35 +572,135 @@ void
 modem_set_init(struct IsdnCardState *cs) {
        long flags;
        int timeout;
-       
+       u_char tmp[32];
+#define RCV_DELAY 20000        
        save_flags(flags);
        sti();
        modem_write_cmd(cs, MInit_1, strlen(MInit_1));
        timeout = 1000;
        while(timeout-- && cs->hw.elsa.transcnt)
                udelay(1000);
-       udelay(50000);
+       sprintf(tmp, "msi tout=%d", timeout);
+       debugl1(cs, tmp);
+       udelay(RCV_DELAY);
        modem_write_cmd(cs, MInit_2, strlen(MInit_2));
        timeout = 1000;
        while(timeout-- && cs->hw.elsa.transcnt)
                udelay(1000);
-       udelay(50000);
+       sprintf(tmp, "msi tout=%d", timeout);
+       debugl1(cs, tmp);
+       udelay(RCV_DELAY);
        modem_write_cmd(cs, MInit_3, strlen(MInit_3));
        timeout = 1000;
        while(timeout-- && cs->hw.elsa.transcnt)
                udelay(1000);
-       udelay(50000);
+       sprintf(tmp, "msi tout=%d", timeout);
+       debugl1(cs, tmp);
+       udelay(RCV_DELAY);
+       modem_write_cmd(cs, MInit_4, strlen(MInit_4));
+       timeout = 1000;
+       while(timeout-- && cs->hw.elsa.transcnt)
+               udelay(1000);
+       sprintf(tmp, "msi tout=%d", timeout);
+       debugl1(cs, tmp);
+       udelay(RCV_DELAY );
+       modem_write_cmd(cs, MInit_5, strlen(MInit_5));
+       timeout = 1000;
+       while(timeout-- && cs->hw.elsa.transcnt)
+               udelay(1000);
+       sprintf(tmp, "msi tout=%d", timeout);
+       debugl1(cs, tmp);
+       udelay(RCV_DELAY);
+       modem_write_cmd(cs, MInit_6, strlen(MInit_6));
+       timeout = 1000;
+       while(timeout-- && cs->hw.elsa.transcnt)
+               udelay(1000);
+       sprintf(tmp, "msi tout=%d", timeout);
+       debugl1(cs, tmp);
+       udelay(RCV_DELAY);
+       modem_write_cmd(cs, MInit_7, strlen(MInit_7));
+       timeout = 1000;
+       while(timeout-- && cs->hw.elsa.transcnt)
+               udelay(1000);
+       sprintf(tmp, "msi tout=%d", timeout);
+       debugl1(cs, tmp);
+       udelay(RCV_DELAY);
+       restore_flags(flags);
+}
+
+void
+modem_set_dial(struct IsdnCardState *cs, int outgoing) {
+       long flags;
+       int timeout;
+       u_char tmp[32];
+#define RCV_DELAY 20000        
+
+       save_flags(flags);
+       sti();
+       modem_write_cmd(cs, MInit_speed28800, strlen(MInit_speed28800));
+       timeout = 1000;
+       while(timeout-- && cs->hw.elsa.transcnt)
+               udelay(1000);
+       sprintf(tmp, "msi tout=%d", timeout);
+       debugl1(cs, tmp);
+       udelay(RCV_DELAY);
+       if (outgoing)
+               modem_write_cmd(cs, MInit_dialout, strlen(MInit_dialout));
+       else
+               modem_write_cmd(cs, MInit_dialin, strlen(MInit_dialin));
+       timeout = 1000;
+       while(timeout-- && cs->hw.elsa.transcnt)
+               udelay(1000);
+       sprintf(tmp, "msi tout=%d", timeout);
+       debugl1(cs, tmp);
+       udelay(RCV_DELAY);
        restore_flags(flags);
 }
 
+void
+modem_l2l1(struct PStack *st, int pr, void *arg)
+{
+       struct sk_buff *skb = arg;
+       long flags;
+
+       if (pr == (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;
+                       test_and_set_bit(BC_FLG_BUSY, &st->l1.bcs->Flag);
+                       st->l1.bcs->hw.hscx.count = 0;
+                       restore_flags(flags);
+                       write_modem(st->l1.bcs);
+               }
+       } else if (pr == (PH_ACTIVATE | REQUEST)) {
+               test_and_set_bit(BC_FLG_ACTIV, &st->l1.bcs->Flag);
+               st->l1.l1l2(st, PH_ACTIVATE | CONFIRM, NULL);
+               set_arcofi(st->l1.bcs->cs, st->l1.bc);
+               mstartup(st->l1.bcs->cs);
+               modem_set_dial(st->l1.bcs->cs, test_bit(FLG_ORIG, &st->l2.flag));
+               st->l1.bcs->cs->hw.elsa.MFlag=2;
+       } else if (pr == (PH_DEACTIVATE | REQUEST)) {
+               test_and_clear_bit(BC_FLG_ACTIV, &st->l1.bcs->Flag);
+               send_arcofi(st->l1.bcs->cs, ARCOFI_XOP_0, st->l1.bc, 0);
+               st->l1.bcs->cs->hw.elsa.MFlag=1;
+       } else {
+               printk(KERN_WARNING"ElsaSer: unknown pr %x\n", pr);
+       }
+}
+
 int
 setstack_elsa(struct PStack *st, struct BCState *bcs)
 {
 
+       bcs->channel = st->l1.bc;
        switch (st->l1.mode) {
                case L1_MODE_HDLC:
                case L1_MODE_TRANS:
-                       if (open_hscxstate(st->l1.hardware, bcs->channel))
+                       if (open_hscxstate(st->l1.hardware, bcs))
                                return (-1);
                        st->l2.l2l1 = hscx_l2l1;
                        break;
@@ -626,7 +711,7 @@ setstack_elsa(struct PStack *st, struct BCState *bcs)
                                skb_queue_head_init(&bcs->rqueue);
                                skb_queue_head_init(&bcs->squeue);
                        }
-                       bcs->hw.hscx.tx_skb = NULL;
+                       bcs->tx_skb = NULL;
                        test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag);
                        bcs->event = 0;
                        bcs->hw.hscx.rcvidx = 0;
@@ -666,7 +751,7 @@ init_modem(struct IsdnCardState *cs) {
        if (mstartup(cs)) {
                printk(KERN_WARNING "Elsa: problem startup modem\n");
        }
-//     modem_set_init(cs);
+       modem_set_init(cs);
 }
 
 void
index 10f0e27f9156c76a75943594135b5edd53773c22..d1c3dc59363897f21256b24913d0349bc891761f 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: hfc_2bds0.c,v 1.1.2.6 1998/06/27 22:54:07 keil Exp $
+/* $Id: hfc_2bds0.c,v 1.1.2.8 1998/09/30 22:23:55 keil Exp $
  *
  *  specific routines for CCD's HFC 2BDS0
  *
@@ -6,6 +6,12 @@
  *
  *
  * $Log: hfc_2bds0.c,v $
+ * Revision 1.1.2.8  1998/09/30 22:23:55  keil
+ * Fix missing line in setstack*
+ *
+ * Revision 1.1.2.7  1998/09/27 13:06:01  keil
+ * Apply most changes from 2.1.X (HiSax 3.1)
+ *
  * Revision 1.1.2.6  1998/06/27 22:54:07  keil
  * make 16.3c working with 3.0
  *
@@ -330,9 +336,9 @@ hfc_fill_fifo(struct BCState *bcs)
        char tmp[64];
        
 
-       if (!bcs->hw.hfc.tx_skb)
+       if (!bcs->tx_skb)
                return;
-       if (bcs->hw.hfc.tx_skb->len <= 0)
+       if (bcs->tx_skb->len <= 0)
                return;
 
        save_flags(flags);
@@ -365,11 +371,11 @@ hfc_fill_fifo(struct BCState *bcs)
        count = GetFreeFifoBytes_B(bcs);
        if (cs->debug & L1_DEB_HSCX) {
                sprintf(tmp, "hfc_fill_fifo %d count(%ld/%d),%lx",
-                       bcs->channel, bcs->hw.hfc.tx_skb->len,
+                       bcs->channel, bcs->tx_skb->len,
                        count, current->state);
                debugl1(cs, tmp);
        }
-       if (count < bcs->hw.hfc.tx_skb->len) {
+       if (count < bcs->tx_skb->len) {
                if (cs->debug & L1_DEB_HSCX)
                        debugl1(cs, "hfc_fill_fifo no fifo mem");
                restore_flags(flags);
@@ -380,26 +386,26 @@ hfc_fill_fifo(struct BCState *bcs)
        cli();
        WaitForBusy(cs);
        WaitNoBusy(cs);
-       WriteReg(cs, HFCD_DATA_NODEB, cip, bcs->hw.hfc.tx_skb->data[idx++]);
-       while (idx < bcs->hw.hfc.tx_skb->len) {
+       WriteReg(cs, HFCD_DATA_NODEB, cip, bcs->tx_skb->data[idx++]);
+       while (idx < bcs->tx_skb->len) {
                cli();
                if (!WaitNoBusy(cs))
                        break;
-               WriteReg(cs, HFCD_DATA_NODEB, cip, bcs->hw.hfc.tx_skb->data[idx]);
+               WriteReg(cs, HFCD_DATA_NODEB, cip, bcs->tx_skb->data[idx]);
                sti();
                idx++;
        }
-       if (idx != bcs->hw.hfc.tx_skb->len) {
+       if (idx != bcs->tx_skb->len) {
                sti();
                debugl1(cs, "FIFO Send BUSY error");
                printk(KERN_WARNING "HFC S FIFO channel %d BUSY Error\n", bcs->channel);
        } else {
-               bcs->tx_cnt -= bcs->hw.hfc.tx_skb->len;
+               bcs->tx_cnt -= bcs->tx_skb->len;
                if (bcs->st->lli.l1writewakeup &&
-                       (PACKET_NOACK != bcs->hw.hfc.tx_skb->pkt_type))
-                       bcs->st->lli.l1writewakeup(bcs->st, bcs->hw.hfc.tx_skb->len);
-               dev_kfree_skb(bcs->hw.hfc.tx_skb, FREE_WRITE);
-               bcs->hw.hfc.tx_skb = NULL;
+                       (PACKET_NOACK != bcs->tx_skb->pkt_type))
+                       bcs->st->lli.l1writewakeup(bcs->st, bcs->tx_skb->len);
+               dev_kfree_skb(bcs->tx_skb, FREE_WRITE);
+               bcs->tx_skb = NULL;
        }
        WaitForBusy(cs);
        cli();
@@ -558,30 +564,30 @@ hfc_l2l1(struct PStack *st, int pr, void *arg)
                case (PH_DATA | REQUEST):
                        save_flags(flags);
                        cli();
-                       if (st->l1.bcs->hw.hfc.tx_skb) {
+                       if (st->l1.bcs->tx_skb) {
                                skb_queue_tail(&st->l1.bcs->squeue, skb);
                                restore_flags(flags);
                        } else {
-                               st->l1.bcs->hw.hfc.tx_skb = skb;
+                               st->l1.bcs->tx_skb = skb;
 /*                             test_and_set_bit(BC_FLG_BUSY, &st->l1.bcs->Flag);
 */                             st->l1.bcs->cs->BC_Send_Data(st->l1.bcs);
                                restore_flags(flags);
                        }
                        break;
                case (PH_PULL | INDICATION):
-                       if (st->l1.bcs->hw.hfc.tx_skb) {
+                       if (st->l1.bcs->tx_skb) {
                                printk(KERN_WARNING "hfc_l2l1: this shouldn't happen\n");
                                break;
                        }
                        save_flags(flags);
                        cli();
 /*                     test_and_set_bit(BC_FLG_BUSY, &st->l1.bcs->Flag);
-*/                     st->l1.bcs->hw.hfc.tx_skb = skb;
+*/                     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->hw.hfc.tx_skb) {
+                       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
@@ -590,12 +596,16 @@ hfc_l2l1(struct PStack *st, int pr, void *arg)
                case (PH_ACTIVATE | REQUEST):
                        test_and_set_bit(BC_FLG_ACTIV, &st->l1.bcs->Flag);
                        mode_2bs0(st->l1.bcs, st->l1.mode, st->l1.bc);
-                       st->l1.l1l2(st, PH_ACTIVATE | CONFIRM, NULL);
+                       l1_msg_b(st, pr, arg);
                        break;
                case (PH_DEACTIVATE | REQUEST):
-                       if (!test_bit(BC_FLG_BUSY, &st->l1.bcs->Flag))
-                               mode_2bs0(st->l1.bcs, 0, 0);
+                       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_2bs0(st->l1.bcs, 0, st->l1.bc);
+                       st->l1.l1l2(st, PH_DEACTIVATE | CONFIRM, NULL);
                        break;
        }
 }
@@ -603,29 +613,26 @@ hfc_l2l1(struct PStack *st, int pr, void *arg)
 void
 close_2bs0(struct BCState *bcs)
 {
-       mode_2bs0(bcs, 0, 0);
+       mode_2bs0(bcs, 0, bcs->channel);
        if (test_and_clear_bit(BC_FLG_INIT, &bcs->Flag)) {
                discard_queue(&bcs->rqueue);
                discard_queue(&bcs->squeue);
-               if (bcs->hw.hfc.tx_skb) {
-                       dev_kfree_skb(bcs->hw.hfc.tx_skb, FREE_WRITE);
-                       bcs->hw.hfc.tx_skb = NULL;
+               if (bcs->tx_skb) {
+                       dev_kfree_skb(bcs->tx_skb, FREE_WRITE);
+                       bcs->tx_skb = NULL;
                        test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag);
                }
        }
 }
 
 static int
-open_hfcstate(struct IsdnCardState *cs,
-             int bc)
+open_hfcstate(struct IsdnCardState *cs, struct BCState *bcs)
 {
-       struct BCState *bcs = cs->bcs + bc;
-
        if (!test_and_set_bit(BC_FLG_INIT, &bcs->Flag)) {
                skb_queue_head_init(&bcs->rqueue);
                skb_queue_head_init(&bcs->squeue);
        }
-       bcs->hw.hfc.tx_skb = NULL;
+       bcs->tx_skb = NULL;
        test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag);
        bcs->event = 0;
        bcs->tx_cnt = 0;
@@ -635,12 +642,14 @@ open_hfcstate(struct IsdnCardState *cs,
 int
 setstack_2b(struct PStack *st, struct BCState *bcs)
 {
-       if (open_hfcstate(st->l1.hardware, bcs->channel))
+       bcs->channel = st->l1.bc;
+       if (open_hfcstate(st->l1.hardware, bcs))
                return (-1);
        st->l1.bcs = bcs;
        st->l2.l2l1 = hfc_l2l1;
        setstack_manager(st);
        bcs->st = st;
+       setstack_l1_B(st);
        return (0);
 }
 
@@ -970,7 +979,7 @@ hfc2bds0_interrupt(struct IsdnCardState *cs, u_char val)
                                if (cs->debug)
                                        debugl1(cs, "hfcd spurious 0x01 IRQ");
                        } else {
-                               if (bcs->hw.hfc.tx_skb) {
+                               if (bcs->tx_skb) {
                                        if (!test_and_set_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags)) {
                                                hfc_fill_fifo(bcs);
                                                test_and_clear_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags);
@@ -979,7 +988,7 @@ hfc2bds0_interrupt(struct IsdnCardState *cs, u_char val)
                                                debugl1(cs, tmp);
                                        }
                                } else {
-                                       if ((bcs->hw.hfc.tx_skb = skb_dequeue(&bcs->squeue))) {
+                                       if ((bcs->tx_skb = skb_dequeue(&bcs->squeue))) {
                                                if (!test_and_set_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags)) {
                                                        hfc_fill_fifo(bcs);
                                                        test_and_clear_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags);
@@ -998,7 +1007,7 @@ hfc2bds0_interrupt(struct IsdnCardState *cs, u_char val)
                                if (cs->debug)
                                        debugl1(cs, "hfcd spurious 0x02 IRQ");
                        } else {
-                               if (bcs->hw.hfc.tx_skb) {
+                               if (bcs->tx_skb) {
                                        if (!test_and_set_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags)) {
                                                hfc_fill_fifo(bcs);
                                                test_and_clear_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags);
@@ -1007,7 +1016,7 @@ hfc2bds0_interrupt(struct IsdnCardState *cs, u_char val)
                                                debugl1(cs, tmp);
                                        }
                                } else {
-                                       if ((bcs->hw.hfc.tx_skb = skb_dequeue(&bcs->squeue))) {
+                                       if ((bcs->tx_skb = skb_dequeue(&bcs->squeue))) {
                                                if (!test_and_set_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags)) {
                                                        hfc_fill_fifo(bcs);
                                                        test_and_clear_bit(FLG_LOCK_ATOMIC, &cs->HW_Flags);
index 08209e4a0d9dee4ecc64b68c384fe400df1a6358..0c1c33cd7b310aa8c5fae94df1f4d521948d96b6 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: hfc_2bs0.c,v 1.1.2.5 1998/05/27 18:05:27 keil Exp $
+/* $Id: hfc_2bs0.c,v 1.1.2.7 1998/09/30 22:23:59 keil Exp $
 
  *  specific routines for CCD's HFC 2BS0
  *
@@ -6,6 +6,12 @@
  *
  *
  * $Log: hfc_2bs0.c,v $
+ * Revision 1.1.2.7  1998/09/30 22:23:59  keil
+ * Fix missing line in setstack*
+ *
+ * Revision 1.1.2.6  1998/09/27 13:06:05  keil
+ * Apply most changes from 2.1.X (HiSax 3.1)
+ *
  * Revision 1.1.2.5  1998/05/27 18:05:27  keil
  * HiSax 3.0
  *
@@ -270,9 +276,9 @@ hfc_fill_fifo(struct BCState *bcs)
        u_char cip;
        char tmp[64];
 
-       if (!bcs->hw.hfc.tx_skb)
+       if (!bcs->tx_skb)
                return;
-       if (bcs->hw.hfc.tx_skb->len <= 0)
+       if (bcs->tx_skb->len <= 0)
                return;
 
        save_flags(flags);
@@ -306,11 +312,11 @@ hfc_fill_fifo(struct BCState *bcs)
        count = GetFreeFifoBytes(bcs);
        if (cs->debug & L1_DEB_HSCX) {
                sprintf(tmp, "hfc_fill_fifo %d count(%ld/%d)",
-                       bcs->channel, bcs->hw.hfc.tx_skb->len,
+                       bcs->channel, bcs->tx_skb->len,
                        count);
                debugl1(cs, tmp);
        }
-       if (count < bcs->hw.hfc.tx_skb->len) {
+       if (count < bcs->tx_skb->len) {
                if (cs->debug & L1_DEB_HSCX)
                        debugl1(cs, "hfc_fill_fifo no fifo mem");
                restore_flags(flags);
@@ -318,18 +324,18 @@ hfc_fill_fifo(struct BCState *bcs)
        }
        cip = HFC_CIP | HFC_FIFO_IN | HFC_SEND | HFC_CHANNEL(bcs->channel);
        idx = 0;
-       while ((idx < bcs->hw.hfc.tx_skb->len) && WaitNoBusy(cs))
-               cs->BC_Write_Reg(cs, HFC_DATA_NODEB, cip, bcs->hw.hfc.tx_skb->data[idx++]);
-       if (idx != bcs->hw.hfc.tx_skb->len) {
+       while ((idx < bcs->tx_skb->len) && WaitNoBusy(cs))
+               cs->BC_Write_Reg(cs, HFC_DATA_NODEB, cip, bcs->tx_skb->data[idx++]);
+       if (idx != bcs->tx_skb->len) {
                debugl1(cs, "FIFO Send BUSY error");
                printk(KERN_WARNING "HFC S FIFO channel %d BUSY Error\n", bcs->channel);
        } else {
-               count =  bcs->hw.hfc.tx_skb->len;
+               count =  bcs->tx_skb->len;
                bcs->tx_cnt -= count;
-               if (PACKET_NOACK == bcs->hw.hfc.tx_skb->pkt_type)
+               if (PACKET_NOACK == bcs->tx_skb->pkt_type)
                        count = -1;
-               dev_kfree_skb(bcs->hw.hfc.tx_skb, FREE_WRITE);
-               bcs->hw.hfc.tx_skb = NULL;
+               dev_kfree_skb(bcs->tx_skb, FREE_WRITE);
+               bcs->tx_skb = NULL;
                WaitForBusy(cs);
                WaitNoBusy(cs);
                cs->BC_Read_Reg(cs, HFC_DATA, HFC_CIP | HFC_F1_INC | HFC_SEND | HFC_CHANNEL(bcs->channel));
@@ -395,14 +401,14 @@ main_irq_hfc(struct BCState *bcs)
        restore_flags(flags);
        udelay(1);
        cli();
-       if (bcs->hw.hfc.tx_skb) {
+       if (bcs->tx_skb) {
                transmit = 1;
                test_and_set_bit(BC_FLG_BUSY, &bcs->Flag);
                hfc_fill_fifo(bcs);
                if (test_bit(BC_FLG_BUSY, &bcs->Flag))
                        transmit = 0;
        } else {
-               if ((bcs->hw.hfc.tx_skb = skb_dequeue(&bcs->squeue))) {
+               if ((bcs->tx_skb = skb_dequeue(&bcs->squeue))) {
                        transmit = 1;
                        test_and_set_bit(BC_FLG_BUSY, &bcs->Flag);
                        hfc_fill_fifo(bcs);
@@ -432,6 +438,7 @@ mode_hfc(struct BCState *bcs, int mode, int bc)
        }
        bcs->mode = mode;
        bcs->channel = bc;
+
        switch (mode) {
                case (L1_MODE_NULL):
                        if (bc)
@@ -478,30 +485,30 @@ hfc_l2l1(struct PStack *st, int pr, void *arg)
                case (PH_DATA | REQUEST):
                        save_flags(flags);
                        cli();
-                       if (st->l1.bcs->hw.hfc.tx_skb) {
+                       if (st->l1.bcs->tx_skb) {
                                skb_queue_tail(&st->l1.bcs->squeue, skb);
                                restore_flags(flags);
                        } else {
-                               st->l1.bcs->hw.hfc.tx_skb = skb;
+                               st->l1.bcs->tx_skb = skb;
                                test_and_set_bit(BC_FLG_BUSY, &st->l1.bcs->Flag);
                                st->l1.bcs->cs->BC_Send_Data(st->l1.bcs);
                                restore_flags(flags);
                        }
                        break;
                case (PH_PULL | INDICATION):
-                       if (st->l1.bcs->hw.hfc.tx_skb) {
+                       if (st->l1.bcs->tx_skb) {
                                printk(KERN_WARNING "hfc_l2l1: this shouldn't happen\n");
                                break;
                        }
                        save_flags(flags);
                        cli();
                        test_and_set_bit(BC_FLG_BUSY, &st->l1.bcs->Flag);
-                       st->l1.bcs->hw.hfc.tx_skb = skb;
+                       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->hw.hfc.tx_skb) {
+                       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
@@ -510,12 +517,16 @@ hfc_l2l1(struct PStack *st, int pr, void *arg)
                case (PH_ACTIVATE | REQUEST):
                        test_and_set_bit(BC_FLG_ACTIV, &st->l1.bcs->Flag);
                        mode_hfc(st->l1.bcs, st->l1.mode, st->l1.bc);
-                       st->l1.l1l2(st, PH_ACTIVATE | CONFIRM, NULL);
+                       l1_msg_b(st, pr, arg);
                        break;
                case (PH_DEACTIVATE | REQUEST):
-                       if (!test_bit(BC_FLG_BUSY, &st->l1.bcs->Flag))
-                               mode_hfc(st->l1.bcs, 0, 0);
+                       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_hfc(st->l1.bcs, 0, st->l1.bc);
+                       st->l1.l1l2(st, PH_DEACTIVATE | CONFIRM, NULL);
                        break;
        }
 }
@@ -524,13 +535,13 @@ hfc_l2l1(struct PStack *st, int pr, void *arg)
 void
 close_hfcstate(struct BCState *bcs)
 {
-       mode_hfc(bcs, 0, 0);
+       mode_hfc(bcs, 0, bcs->channel);
        if (test_bit(BC_FLG_INIT, &bcs->Flag)) {
                discard_queue(&bcs->rqueue);
                discard_queue(&bcs->squeue);
-               if (bcs->hw.hfc.tx_skb) {
-                       dev_kfree_skb(bcs->hw.hfc.tx_skb, FREE_WRITE);
-                       bcs->hw.hfc.tx_skb = NULL;
+               if (bcs->tx_skb) {
+                       dev_kfree_skb(bcs->tx_skb, FREE_WRITE);
+                       bcs->tx_skb = NULL;
                        test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag);
                }
        }
@@ -538,16 +549,13 @@ close_hfcstate(struct BCState *bcs)
 }
 
 static int
-open_hfcstate(struct IsdnCardState *cs,
-             int bc)
+open_hfcstate(struct IsdnCardState *cs, struct BCState *bcs)
 {
-       struct BCState *bcs = cs->bcs + bc;
-
        if (!test_and_set_bit(BC_FLG_INIT, &bcs->Flag)) {
                skb_queue_head_init(&bcs->rqueue);
                skb_queue_head_init(&bcs->squeue);
        }
-       bcs->hw.hfc.tx_skb = NULL;
+       bcs->tx_skb = NULL;
        test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag);
        bcs->event = 0;
        bcs->tx_cnt = 0;
@@ -557,12 +565,14 @@ open_hfcstate(struct IsdnCardState *cs,
 int
 setstack_hfc(struct PStack *st, struct BCState *bcs)
 {
-       if (open_hfcstate(st->l1.hardware, bcs->channel))
+       bcs->channel = st->l1.bc;
+       if (open_hfcstate(st->l1.hardware, bcs))
                return (-1);
        st->l1.bcs = bcs;
        st->l2.l2l1 = hfc_l2l1;
        setstack_manager(st);
        bcs->st = st;
+       setstack_l1_B(st);
        return (0);
 }
 
index 92ad7a62eefb6f8987667b2f1b237e48990f58f5..9aa790ffff017ef34bb542fbded937733d759939 100644 (file)
@@ -1,8 +1,22 @@
-/* $Id: hisax.h,v 1.13.2.11 1998/05/27 18:05:30 keil Exp $
+/* $Id: hisax.h,v 1.13.2.15 1998/09/30 22:28:04 keil Exp $
 
  *   Basic declarations, defines and prototypes
  *
  * $Log: hisax.h,v $
+ * Revision 1.13.2.15  1998/09/30 22:28:04  keil
+ * more work for isar support
+ *
+ * Revision 1.13.2.14  1998/09/27 13:06:09  keil
+ * Apply most changes from 2.1.X (HiSax 3.1)
+ *
+ * Revision 1.13.2.13  1998/08/25 14:01:30  calle
+ * Ported driver for AVM Fritz!Card PCI from the 2.1 tree.
+ * I could not test it.
+ *
+ * Revision 1.13.2.12  1998/07/15 14:43:33  calle
+ * Support for AVM passive PCMCIA cards:
+ *    A1 PCMCIA, FRITZ!Card PCMCIA and FRITZ!Card PCMCIA 2.0
+ *
  * Revision 1.13.2.11  1998/05/27 18:05:30  keil
  * HiSax 3.0
  *
 #define CARD_RELEASE   0x00F3
 #define CARD_TEST      0x00F4
 #define CARD_AUX_IND   0x00F5
+#define CARD_LOAD_FIRM 0x00F6
 
 #define PH_ACTIVATE    0x0100
 #define PH_DEACTIVATE  0x0110
 #define MDL_INFO_CONN  0x02E4
 #define MDL_INFO_REL   0x02E8
 
-
 #define CC_SETUP       0x0300
 #define CC_RESUME      0x0304
 #define CC_MORE_INFO   0x0310
 #ifdef __KERNEL__
 
 #define MAX_DFRAME_LEN 260
+#define MAX_DFRAME_LEN_L1      300
 #define HSCX_BUFMAX    4096
 #define MAX_DATA_SIZE  (HSCX_BUFMAX - 4)
 #define MAX_DATA_MEM   (HSCX_BUFMAX + 64)
@@ -346,21 +361,34 @@ struct l3_process {
 };
 
 struct hscx_hw {
+       int hscx;
+       int rcvidx;
+       int count;              /* Current skb sent count */
+       u_char *rcvbuf;         /* B-Channel receive Buffer */
+};
+
+struct isar_hw {
+       int dpath;
+       int rcvidx;
+       int txcnt;
+       u_char *rcvbuf;         /* B-Channel receive Buffer */
+};
+
+struct hdlc_hw {
+       u_int ctrl;
+       u_int stat;
        int rcvidx;
        int count;              /* Current skb sent count */
        u_char *rcvbuf;         /* B-Channel receive Buffer */
-       struct sk_buff *tx_skb; /* B-Channel transmit Buffer */
 };
 
 struct hfcB_hw {
        unsigned int *send;
        int f1;
        int f2;
-       struct sk_buff *tx_skb; /* B-Channel transmit Buffer */
 };
 
 struct tiger_hw {
-       struct sk_buff *tx_skb; /* B-Channel transmit Buffer */
        u_int *send;
        u_int *s_irq;
        u_int *s_end;
@@ -391,7 +419,6 @@ struct amd7930_hw {
        struct hdlc_state *hdlc_state;
        struct tq_struct tq_rcv;
        struct tq_struct tq_xmt;
-       struct sk_buff *tx_skb; /* B-Channel transmit Buffer */
 };
 
 
@@ -413,15 +440,19 @@ struct BCState {
        int Flag;
        struct IsdnCardState *cs;
        int tx_cnt;             /* B-Channel transmit counter */
+       struct sk_buff *tx_skb; /* B-Channel transmit Buffer */
        struct sk_buff_head rqueue;     /* B-Channel receive Queue */
        struct sk_buff_head squeue;     /* B-Channel send Queue */
        struct PStack *st;
+       struct timer_list transbusy;
        struct tq_struct tqueue;
        int event;
        int  (*BC_SetStack) (struct PStack *, struct BCState *);
        void (*BC_Close) (struct BCState *);
        union {
                struct hscx_hw hscx;
+               struct hdlc_hw hdlc;
+               struct isar_hw isar;
                struct hfcB_hw hfc;
                struct tiger_hw tiger;
                struct amd7930_hw  amd7930;
@@ -438,6 +469,7 @@ struct Channel {
        struct FsmTimer drel_timer, dial_timer;
        int debug;
        int l2_protocol, l2_active_protocol;
+       int l3_protocol;
        int data_open;
        struct l3_process *proc;
        setup_parm setup;       /* from isdnif.h numbers and Serviceindicator */
@@ -471,7 +503,7 @@ struct elsa_hw {
        u_char LCR;
        u_char MCR;
        u_char ctrl_reg;
-};     
+};
 
 struct teles3_hw {
        unsigned int cfg_reg;
@@ -540,8 +572,14 @@ struct sedl_hw {
        unsigned int adr;
        unsigned int isac;
        unsigned int hscx;
+       unsigned int isar;
        unsigned int reset_on;
        unsigned int reset_off;
+       volatile u_char bstat;
+       volatile u_char iis;
+       volatile u_char cmsb;
+       volatile u_char clsb;
+       volatile u_char par[8];
 };
 
 struct spt_hw {
@@ -593,6 +631,7 @@ struct hfcD_hw {
 
 #define HW_IOM1                0
 #define HW_IPAC                1
+#define HW_ISAR                2
 #define FLG_TWO_DCHAN  4
 #define FLG_L1_DBUSY   5
 #define FLG_DBUSY_TIMER 6
@@ -696,8 +735,11 @@ struct IsdnCardState {
 #define  ISDN_CTYPE_AMD7930    23
 #define  ISDN_CTYPE_NICCY      24
 #define  ISDN_CTYPE_S0BOX      25
+#define  ISDN_CTYPE_A1_PCMCIA  26
+#define  ISDN_CTYPE_FRITZPCI   27
+#define  ISDN_CTYPE_SEDLBAUER_FAX     28
 
-#define  ISDN_CTYPE_COUNT      25
+#define  ISDN_CTYPE_COUNT      28
 
 #ifdef ISDN_CHIP_ISAC
 #undef ISDN_CHIP_ISAC
@@ -751,6 +793,24 @@ struct IsdnCardState {
 #define  CARD_AVM_A1  0
 #endif
 
+#ifdef CONFIG_HISAX_AVM_A1_PCMCIA
+#define  CARD_AVM_A1_PCMCIA (1<< ISDN_CTYPE_A1_PCMCIA)
+#ifndef ISDN_CHIP_ISAC 
+#define ISDN_CHIP_ISAC 1
+#endif
+#else
+#define  CARD_AVM_A1_PCMCIA  0
+#endif
+
+#ifdef CONFIG_HISAX_FRITZPCI
+#define  CARD_FRITZPCI (1<< ISDN_CTYPE_FRITZPCI)
+#ifndef ISDN_CHIP_ISAC 
+#define ISDN_CHIP_ISAC 1
+#endif
+#else
+#define  CARD_FRITZPCI  0
+#endif
+
 #ifdef CONFIG_HISAX_ELSA
 #define  CARD_ELSA (1<< ISDN_CTYPE_ELSA) | (1<< ISDN_CTYPE_ELSA_PNP) | \
                   (1<< ISDN_CTYPE_ELSA_PCMCIA) | (1<< ISDN_CTYPE_ELSA_PCI)
@@ -803,7 +863,7 @@ struct IsdnCardState {
 #endif
 
 #ifdef  CONFIG_HISAX_SEDLBAUER
-#define CARD_SEDLBAUER (1 << ISDN_CTYPE_SEDLBAUER) | (1 << ISDN_CTYPE_SEDLBAUER_PCMCIA)
+#define CARD_SEDLBAUER (1 << ISDN_CTYPE_SEDLBAUER) | (1 << ISDN_CTYPE_SEDLBAUER_PCMCIA) | ( 1 << ISDN_CTYPE_SEDLBAUER_FAX)
 #ifndef ISDN_CHIP_ISAC
 #define ISDN_CHIP_ISAC 1
 #endif
@@ -872,6 +932,7 @@ struct IsdnCardState {
                         | CARD_IX1MICROR2 | CARD_DIEHLDIVA | CARD_ASUSCOM \
                         | CARD_TELEINT | CARD_SEDLBAUER | CARD_SPORTSTER \
                         | CARD_MIC | CARD_NETJET | CARD_TELES3C | CARD_AMD7930 \
+                        | CARD_AVM_A1_PCMCIA | CARD_FRITZPCI\
                         | CARD_NICCY | CARD_S0BOX | CARD_TELESPCI)
 
 #define TEI_PER_CARD 0
@@ -885,9 +946,14 @@ struct IsdnCardState {
 #undef TEI_PER_CARD
 #define TEI_PER_CARD 1
 #define HISAX_EURO_SENDCOMPLETE 1
-#ifdef CONFIG_HISAX_ML
+#define EXT_BEARER_CAPS 1
+#define HISAX_SEND_STD_LLC_IE 1
+#ifdef CONFIG_HISAX_NO_SENDCOMPLETE
 #undef HISAX_EURO_SENDCOMPLETE
 #endif
+#ifdef CONFIG_HISAX_NO_LLC
+#undef HISAX_SEND_STD_LLC_IE
+#endif
 #undef HISAX_DE_AOC
 #ifdef CONFIG_DE_AOC
 #define HISAX_DE_AOC 1
index 13a7e709bf8e4c378762a1b568f4a4693d0736b2..c235de1e42a2f849e450270cf7c7560c7fa53aca 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: hscx.c,v 1.3.2.7 1998/06/26 22:02:55 keil Exp $
+/* $Id: hscx.c,v 1.3.2.9 1998/09/27 13:06:14 keil Exp $
 
  * hscx.c   HSCX specific routines
  *
@@ -6,6 +6,12 @@
  *
  *
  * $Log: hscx.c,v $
+ * Revision 1.3.2.9  1998/09/27 13:06:14  keil
+ * Apply most changes from 2.1.X (HiSax 3.1)
+ *
+ * Revision 1.3.2.8  1998/09/15 15:25:04  keil
+ * Repair HSCX init
+ *
  * Revision 1.3.2.7  1998/06/26 22:02:55  keil
  * send flags between hdlc frames
  *
@@ -67,7 +73,7 @@ void
 modehscx(struct BCState *bcs, int mode, int bc)
 {
        struct IsdnCardState *cs = bcs->cs;
-       int hscx = bcs->channel;
+       int hscx = bcs->hw.hscx.hscx;
 
        if (cs->debug & L1_DEB_HSCX) {
                char tmp[40];
@@ -76,11 +82,16 @@ modehscx(struct BCState *bcs, int mode, int bc)
                debugl1(cs, tmp);
        }
        bcs->mode = mode;
+       bcs->channel = bc;
+       cs->BC_Write_Reg(cs, hscx, HSCX_CCR1, 
+               test_bit(HW_IPAC, &cs->HW_Flags) ? 0x82 : 0x85);
        cs->BC_Write_Reg(cs, hscx, HSCX_XAD1, 0xFF);
        cs->BC_Write_Reg(cs, hscx, HSCX_XAD2, 0xFF);
        cs->BC_Write_Reg(cs, hscx, HSCX_RAH2, 0xFF);
        cs->BC_Write_Reg(cs, hscx, HSCX_XBCH, 0x0);
        cs->BC_Write_Reg(cs, hscx, HSCX_RLCR, 0x0);
+       cs->BC_Write_Reg(cs, hscx, HSCX_CCR1, 
+               test_bit(HW_IPAC, &cs->HW_Flags) ? 0x82 : 0x85);
        cs->BC_Write_Reg(cs, hscx, HSCX_CCR2, 0x30);
        cs->BC_Write_Reg(cs, hscx, HSCX_XCCR, 7);
        cs->BC_Write_Reg(cs, hscx, HSCX_RCCR, 7);
@@ -100,8 +111,8 @@ modehscx(struct BCState *bcs, int mode, int bc)
        }
        switch (mode) {
                case (L1_MODE_NULL):
-                       cs->BC_Write_Reg(cs, hscx, HSCX_TSAX, 0xff);
-                       cs->BC_Write_Reg(cs, hscx, HSCX_TSAR, 0xff);
+                       cs->BC_Write_Reg(cs, hscx, HSCX_TSAX, 0x1f);
+                       cs->BC_Write_Reg(cs, hscx, HSCX_TSAR, 0x1f);
                        cs->BC_Write_Reg(cs, hscx, HSCX_MODE, 0x84);
                        break;
                case (L1_MODE_TRANS):
@@ -136,11 +147,11 @@ hscx_l2l1(struct PStack *st, int pr, void *arg)
                case (PH_DATA | REQUEST):
                        save_flags(flags);
                        cli();
-                       if (st->l1.bcs->hw.hscx.tx_skb) {
+                       if (st->l1.bcs->tx_skb) {
                                skb_queue_tail(&st->l1.bcs->squeue, skb);
                                restore_flags(flags);
                        } else {
-                               st->l1.bcs->hw.hscx.tx_skb = skb;
+                               st->l1.bcs->tx_skb = skb;
                                test_and_set_bit(BC_FLG_BUSY, &st->l1.bcs->Flag);
                                st->l1.bcs->hw.hscx.count = 0;
                                restore_flags(flags);
@@ -148,17 +159,17 @@ hscx_l2l1(struct PStack *st, int pr, void *arg)
                        }
                        break;
                case (PH_PULL | INDICATION):
-                       if (st->l1.bcs->hw.hscx.tx_skb) {
+                       if (st->l1.bcs->tx_skb) {
                                printk(KERN_WARNING "hscx_l2l1: this shouldn't happen\n");
                                break;
                        }
                        test_and_set_bit(BC_FLG_BUSY, &st->l1.bcs->Flag);
-                       st->l1.bcs->hw.hscx.tx_skb = skb;
+                       st->l1.bcs->tx_skb = skb;
                        st->l1.bcs->hw.hscx.count = 0;
                        st->l1.bcs->cs->BC_Send_Data(st->l1.bcs);
                        break;
                case (PH_PULL | REQUEST):
-                       if (!st->l1.bcs->hw.hscx.tx_skb) {
+                       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
@@ -184,7 +195,7 @@ hscx_l2l1(struct PStack *st, int pr, void *arg)
 void
 close_hscxstate(struct BCState *bcs)
 {
-       modehscx(bcs, 0, 0);
+       modehscx(bcs, 0, bcs->channel);
        if (test_and_clear_bit(BC_FLG_INIT, &bcs->Flag)) {
                if (bcs->hw.hscx.rcvbuf) {
                        kfree(bcs->hw.hscx.rcvbuf);
@@ -192,20 +203,17 @@ close_hscxstate(struct BCState *bcs)
                }
                discard_queue(&bcs->rqueue);
                discard_queue(&bcs->squeue);
-               if (bcs->hw.hscx.tx_skb) {
-                       dev_kfree_skb(bcs->hw.hscx.tx_skb, FREE_WRITE);
-                       bcs->hw.hscx.tx_skb = NULL;
+               if (bcs->tx_skb) {
+                       dev_kfree_skb(bcs->tx_skb, FREE_WRITE);
+                       bcs->tx_skb = NULL;
                        test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag);
                }
        }
 }
 
 int
-open_hscxstate(struct IsdnCardState *cs,
-              int bc)
+open_hscxstate(struct IsdnCardState *cs, struct BCState *bcs)
 {
-       struct BCState *bcs = cs->bcs + bc;
-
        if (!test_and_set_bit(BC_FLG_INIT, &bcs->Flag)) {
                if (!(bcs->hw.hscx.rcvbuf = kmalloc(HSCX_BUFMAX, GFP_ATOMIC))) {
                        printk(KERN_WARNING
@@ -215,7 +223,7 @@ open_hscxstate(struct IsdnCardState *cs,
                skb_queue_head_init(&bcs->rqueue);
                skb_queue_head_init(&bcs->squeue);
        }
-       bcs->hw.hscx.tx_skb = NULL;
+       bcs->tx_skb = NULL;
        test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag);
        bcs->event = 0;
        bcs->hw.hscx.rcvidx = 0;
@@ -226,7 +234,8 @@ open_hscxstate(struct IsdnCardState *cs,
 int
 setstack_hscx(struct PStack *st, struct BCState *bcs)
 {
-       if (open_hscxstate(st->l1.hardware, bcs->channel))
+       bcs->channel = st->l1.bc;
+       if (open_hscxstate(st->l1.hardware, bcs))
                return (-1);
        st->l1.bcs = bcs;
        st->l2.l2l1 = hscx_l2l1;
@@ -276,6 +285,8 @@ inithscx(struct IsdnCardState *cs))
        cs->bcs[1].BC_SetStack = setstack_hscx;
        cs->bcs[0].BC_Close = close_hscxstate;
        cs->bcs[1].BC_Close = close_hscxstate;
+       cs->bcs[0].hw.hscx.hscx = 0;
+       cs->bcs[1].hw.hscx.hscx = 1;
        modehscx(cs->bcs, 0, 0);
        modehscx(cs->bcs + 1, 0, 0);
 }
index 46da67f15d7e50dc41394c2e6a08ad05c2db4648..f3844876045a7751765387b30ffbc624db56c762 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: hscx_irq.c,v 1.5.2.3 1998/06/24 14:43:56 keil Exp $
+/* $Id: hscx_irq.c,v 1.5.2.4 1998/09/27 13:06:16 keil Exp $
 
  * hscx_irq.c     low level b-channel stuff for Siemens HSCX
  *
@@ -7,6 +7,9 @@
  * This is an include file for fast inline IRQ stuff
  *
  * $Log: hscx_irq.c,v $
+ * Revision 1.5.2.4  1998/09/27 13:06:16  keil
+ * Apply most changes from 2.1.X (HiSax 3.1)
+ *
  * Revision 1.5.2.3  1998/06/24 14:43:56  keil
  * Fix recovery of TX IRQ loss
  *
@@ -83,7 +86,7 @@ hscx_empty_fifo(struct BCState *bcs, int count)
        if (bcs->hw.hscx.rcvidx + count > HSCX_BUFMAX) {
                if (cs->debug & L1_DEB_WARN)
                        debugl1(cs, "hscx_empty_fifo: incoming packet too large");
-               WriteHSCXCMDR(cs, bcs->channel, 0x80);
+               WriteHSCXCMDR(cs, bcs->hw.hscx.hscx, 0x80);
                bcs->hw.hscx.rcvidx = 0;
                return;
        }
@@ -91,15 +94,15 @@ hscx_empty_fifo(struct BCState *bcs, int count)
        bcs->hw.hscx.rcvidx += count;
        save_flags(flags);
        cli();
-       READHSCXFIFO(cs, bcs->channel, ptr, count);
-       WriteHSCXCMDR(cs, bcs->channel, 0x80);
+       READHSCXFIFO(cs, bcs->hw.hscx.hscx, ptr, count);
+       WriteHSCXCMDR(cs, bcs->hw.hscx.hscx, 0x80);
        restore_flags(flags);
        if (cs->debug & L1_DEB_HSCX_FIFO) {
                char tmp[256];
                char *t = tmp;
 
                t += sprintf(t, "hscx_empty_fifo %c cnt %d",
-                            bcs->channel ? 'B' : 'A', count);
+                            bcs->hw.hscx.hscx ? 'B' : 'A', count);
                QuickHex(t, ptr, count);
                debugl1(cs, tmp);
        }
@@ -118,34 +121,34 @@ hscx_fill_fifo(struct BCState *bcs)
        if ((cs->debug & L1_DEB_HSCX) && !(cs->debug & L1_DEB_HSCX_FIFO))
                debugl1(cs, "hscx_fill_fifo");
 
-       if (!bcs->hw.hscx.tx_skb)
+       if (!bcs->tx_skb)
                return;
-       if (bcs->hw.hscx.tx_skb->len <= 0)
+       if (bcs->tx_skb->len <= 0)
                return;
 
        more = (bcs->mode == L1_MODE_TRANS) ? 1 : 0;
-       if (bcs->hw.hscx.tx_skb->len > fifo_size) {
+       if (bcs->tx_skb->len > fifo_size) {
                more = !0;
                count = fifo_size;
        } else
-               count = bcs->hw.hscx.tx_skb->len;
+               count = bcs->tx_skb->len;
 
-       waitforXFW(cs, bcs->channel);
+       waitforXFW(cs, bcs->hw.hscx.hscx);
        save_flags(flags);
        cli();
-       ptr = bcs->hw.hscx.tx_skb->data;
-       skb_pull(bcs->hw.hscx.tx_skb, count);
+       ptr = bcs->tx_skb->data;
+       skb_pull(bcs->tx_skb, count);
        bcs->tx_cnt -= count;
        bcs->hw.hscx.count += count;
-       WRITEHSCXFIFO(cs, bcs->channel, ptr, count);
-       WriteHSCXCMDR(cs, bcs->channel, more ? 0x8 : 0xa);
+       WRITEHSCXFIFO(cs, bcs->hw.hscx.hscx, ptr, count);
+       WriteHSCXCMDR(cs, bcs->hw.hscx.hscx, more ? 0x8 : 0xa);
        restore_flags(flags);
        if (cs->debug & L1_DEB_HSCX_FIFO) {
                char tmp[256];
                char *t = tmp;
 
                t += sprintf(t, "hscx_fill_fifo %c cnt %d",
-                            bcs->channel ? 'B' : 'A', count);
+                            bcs->hw.hscx.hscx ? 'B' : 'A', count);
                QuickHex(t, ptr, count);
                debugl1(cs, tmp);
        }
@@ -219,20 +222,20 @@ hscx_interrupt(struct IsdnCardState *cs, u_char val, u_char hscx)
                }
        }
        if (val & 0x10) {       /* XPR */
-               if (bcs->hw.hscx.tx_skb) {
-                       if (bcs->hw.hscx.tx_skb->len) {
+               if (bcs->tx_skb) {
+                       if (bcs->tx_skb->len) {
                                hscx_fill_fifo(bcs);
                                return;
                        } else {
                                if (bcs->st->lli.l1writewakeup &&
-                                       (PACKET_NOACK != bcs->hw.hscx.tx_skb->pkt_type))
+                                       (PACKET_NOACK != bcs->tx_skb->pkt_type))
                                        bcs->st->lli.l1writewakeup(bcs->st, bcs->hw.hscx.count);
-                               dev_kfree_skb(bcs->hw.hscx.tx_skb, FREE_WRITE);
-                               bcs->hw.hscx.count = 0;
-                               bcs->hw.hscx.tx_skb = NULL;
+                               dev_kfree_skb(bcs->tx_skb, FREE_WRITE);
+                               bcs->hw.hscx.count = 0; 
+                               bcs->tx_skb = NULL;
                        }
                }
-               if ((bcs->hw.hscx.tx_skb = skb_dequeue(&bcs->squeue))) {
+               if ((bcs->tx_skb = skb_dequeue(&bcs->squeue))) {
                        bcs->hw.hscx.count = 0;
                        test_and_set_bit(BC_FLG_BUSY, &bcs->Flag);
                        hscx_fill_fifo(bcs);
@@ -261,12 +264,12 @@ hscx_int_main(struct IsdnCardState *cs, u_char val)
                                /* Here we lost an TX interrupt, so
                                   * restart transmitting the whole frame.
                                 */
-                               if (bcs->hw.hscx.tx_skb) {
-                                       skb_push(bcs->hw.hscx.tx_skb, bcs->hw.hscx.count);
+                               if (bcs->tx_skb) {
+                                       skb_push(bcs->tx_skb, bcs->hw.hscx.count);
                                        bcs->tx_cnt += bcs->hw.hscx.count;
                                        bcs->hw.hscx.count = 0;
                                }
-                               WriteHSCXCMDR(cs, bcs->channel, 0x01);
+                               WriteHSCXCMDR(cs, bcs->hw.hscx.hscx, 0x01);
                                if (cs->debug & L1_DEB_WARN) {
                                        sprintf(tmp, "HSCX B EXIR %x Lost TX", exval);
                                        debugl1(cs, tmp);
@@ -294,12 +297,12 @@ hscx_int_main(struct IsdnCardState *cs, u_char val)
                                /* Here we lost an TX interrupt, so
                                   * restart transmitting the whole frame.
                                 */
-                               if (bcs->hw.hscx.tx_skb) {
-                                       skb_push(bcs->hw.hscx.tx_skb, bcs->hw.hscx.count);
+                               if (bcs->tx_skb) {
+                                       skb_push(bcs->tx_skb, bcs->hw.hscx.count);
                                        bcs->tx_cnt += bcs->hw.hscx.count;
                                        bcs->hw.hscx.count = 0;
                                }
-                               WriteHSCXCMDR(cs, bcs->channel, 0x01);
+                               WriteHSCXCMDR(cs, bcs->hw.hscx.hscx, 0x01);
                                if (cs->debug & L1_DEB_WARN) {
                                        sprintf(tmp, "HSCX A EXIR %x Lost TX", exval);
                                        debugl1(cs, tmp);
index ee6ec7b695cd3dcd8492665073cd44deb70b4e6b..d100fdfa2609536b82bd22f47da2a6d768305cce 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: isac.c,v 1.7.2.7 1998/05/27 18:05:38 keil Exp $
+/* $Id: isac.c,v 1.7.2.8 1998/09/27 13:06:18 keil Exp $
 
  * isac.c   ISAC specific routines
  *
@@ -6,6 +6,9 @@
  *
  *
  * $Log: isac.c,v $
+ * Revision 1.7.2.8  1998/09/27 13:06:18  keil
+ * Apply most changes from 2.1.X (HiSax 3.1)
+ *
  * Revision 1.7.2.7  1998/05/27 18:05:38  keil
  * HiSax 3.0
  *
@@ -156,7 +159,7 @@ isac_empty_fifo(struct IsdnCardState *cs, int count)
        if ((cs->debug & L1_DEB_ISAC) && !(cs->debug & L1_DEB_ISAC_FIFO))
                debugl1(cs, "isac_empty_fifo");
 
-       if ((cs->rcvidx + count) >= MAX_DFRAME_LEN) {
+       if ((cs->rcvidx + count) >= MAX_DFRAME_LEN_L1) {
                if (cs->debug & L1_DEB_WARN) {
                        char tmp[40];
                        sprintf(tmp, "isac_empty_fifo overrun %d",
@@ -322,12 +325,12 @@ isac_interrupt(struct IsdnCardState *cs, u_char val)
                }
                if (exval & 2) {
                        cs->ph_state = (exval >> 2) & 0xf;
-               if (cs->debug & L1_DEB_ISAC) {
-                       sprintf(tmp, "ph_state change %x", cs->ph_state);
-                       debugl1(cs, tmp);
+                       if (cs->debug & L1_DEB_ISAC) {
+                               sprintf(tmp, "ph_state change %x", cs->ph_state);
+                               debugl1(cs, tmp);
+                       }
+                       isac_sched_event(cs, D_L1STATECHANGE);
                }
-               isac_sched_event(cs, D_L1STATECHANGE);
-       }
                if (exval & 1) {
                        exval = cs->readisac(cs, ISAC_CIR1);
                        if (cs->debug & L1_DEB_ISAC) {
@@ -412,9 +415,9 @@ isac_interrupt(struct IsdnCardState *cs, u_char val)
                                        sprintf(tmp, "ISAC MOR1 %02x", cs->mon_rx[cs->mon_rxp -1]);
                                        debugl1(cs, tmp);
                                }
-                                       cs->mocr |= 0x40;
-                                       cs->writeisac(cs, ISAC_MOCR, cs->mocr);
-                               }
+                               cs->mocr |= 0x40;
+                               cs->writeisac(cs, ISAC_MOCR, cs->mocr);
+                       }
                      afterMONR1:
                        if (v1 & 0x04) {
                                cs->mocr &= 0xf0;
index 5608600fe71eb52198a8b87e52b113c9697dcadb..b2eb696bfa4c75cc3ed016c500979b88763d881f 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: isdnl1.c,v 1.15.2.12 1998/05/27 18:05:43 keil Exp $
+/* $Id: isdnl1.c,v 1.15.2.18 1998/09/30 22:26:35 keil Exp $
 
  * isdnl1.c     common low level stuff for Siemens Chipsetbased isdn cards
  *              based on the teles driver from Jan den Ouden
  *
  *
  * $Log: isdnl1.c,v $
+ * Revision 1.15.2.18  1998/09/30 22:26:35  keil
+ * Add init of l1.Flags
+ *
+ * Revision 1.15.2.17  1998/09/27 23:54:17  keil
+ * cosmetics
+ *
+ * Revision 1.15.2.16  1998/09/27 13:06:22  keil
+ * Apply most changes from 2.1.X (HiSax 3.1)
+ *
+ * Revision 1.15.2.15  1998/09/12 18:44:00  niemann
+ * Added new card: Sedlbauer ISDN-Controller PC/104
+ *
+ * Revision 1.15.2.14  1998/08/25 14:01:35  calle
+ * Ported driver for AVM Fritz!Card PCI from the 2.1 tree.
+ * I could not test it.
+ *
+ * Revision 1.15.2.13  1998/07/15 14:43:37  calle
+ * Support for AVM passive PCMCIA cards:
+ *    A1 PCMCIA, FRITZ!Card PCMCIA and FRITZ!Card PCMCIA 2.0
+ *
  * Revision 1.15.2.12  1998/05/27 18:05:43  keil
  * HiSax 3.0
  *
@@ -77,7 +97,7 @@
  *
  */
 
-const char *l1_revision = "$Revision: 1.15.2.12 $";
+const char *l1_revision = "$Revision: 1.15.2.18 $";
 
 #define __NO_VERSION__
 #include <linux/config.h>
@@ -106,6 +126,14 @@ extern int setup_telespci(struct IsdnCard *card);
 extern int setup_avm_a1(struct IsdnCard *card);
 #endif
 
+#if CARD_AVM_A1_PCMCIA
+extern int setup_avm_a1_pcmcia(struct IsdnCard *card);
+#endif
+
+#if CARD_FRITZPCI
+extern int setup_avm_pci(struct IsdnCard *card);
+#endif
+
 #if CARD_ELSA
 extern int setup_elsa(struct IsdnCard *card);
 #endif
@@ -165,7 +193,8 @@ const char *CardType[] =
  "Elsa PCMCIA", "Eicon.Diehl Diva", "ISDNLink", "TeleInt", "Teles 16.3c", 
  "Sedlbauer Speed Card", "USR Sportster", "ith mic Linux", "Elsa PCI",
  "Compaq ISA", "NETjet", "Teles PCI", "Sedlbauer Speed Star (PCMCIA)",
- "AMD 7930", "NICCY", "S0Box"
+ "AMD 7930", "NICCY", "S0Box", "AVM A1 (PCMCIA)", "AVM Fritz!PCI",
+ "Sedlbauer Speed Fax +"
 };
 
 extern struct IsdnCard cards[];
@@ -530,8 +559,10 @@ BChannel_proc_xmt(struct BCState *bcs)
 {
        struct PStack *st = bcs->st;
 
-       if (test_bit(BC_FLG_BUSY, &bcs->Flag))
+       if (test_bit(BC_FLG_BUSY, &bcs->Flag)) {
+               debugl1(bcs->cs, "BC_BUSY Error");
                return;
+       }
 
        if (test_and_clear_bit(FLG_L1_PULL_REQ, &st->l1.Flags))
                st->l1.l1l2(st, PH_PULL | CONFIRM, NULL);
@@ -641,7 +672,8 @@ closecard(int cardnr)
                csta->mon_tx = NULL;
        }
        csta->cardmsg(csta, CARD_RELEASE, NULL);
-       del_timer(&csta->dbusytimer);
+       if (csta->dbusytimer.function != NULL)
+               del_timer(&csta->dbusytimer);
        ll_unload(csta);
 }
 
@@ -658,6 +690,7 @@ HISAX_INITFUNC(static int init_card(struct IsdnCardState *cs))
        if (cs->cardmsg(cs, CARD_SETIRQ, NULL)) {
                printk(KERN_WARNING "HiSax: couldn't get interrupt %d\n",
                        cs->irq);
+               restore_flags(flags);
                return(1);
        }
        while (cnt) {
@@ -672,8 +705,8 @@ HISAX_INITFUNC(static int init_card(struct IsdnCardState *cs))
                        cs->irq, kstat_irqs(cs->irq));
                if (kstat_irqs(cs->irq) == irq_cnt) {
                        printk(KERN_WARNING
-                               "%s: IRQ(%d) getting no interrupts during init %d\n",
-                               CardType[cs->typ], cs->irq, 4 - cnt);
+                              "%s: IRQ(%d) getting no interrupts during init %d\n",
+                              CardType[cs->typ], cs->irq, 4 - cnt);
                        if (cnt == 1) {
                                free_irq(cs->irq, cs);
                                return (2);
@@ -701,13 +734,14 @@ checkcard(int cardnr, char *id, int *busy_flag))
        save_flags(flags);
        cli();
        if (!(cs = (struct IsdnCardState *)
-             kmalloc(sizeof(struct IsdnCardState), GFP_ATOMIC))) {
+               kmalloc(sizeof(struct IsdnCardState), GFP_ATOMIC))) {
                printk(KERN_WARNING
                       "HiSax: No memory for IsdnCardState(card %d)\n",
                       cardnr + 1);
                restore_flags(flags);
                return (0);
        }
+       memset(cs, 0, sizeof(struct IsdnCardState));
        card->cs = cs;
        cs->cardnr = cardnr;
        cs->debug = L1_DEB_WARN;
@@ -821,6 +855,16 @@ checkcard(int cardnr, char *id, int *busy_flag))
                        ret = setup_avm_a1(card);
                        break;
 #endif
+#if CARD_AVM_A1_PCMCIA
+               case ISDN_CTYPE_A1_PCMCIA:
+                       ret = setup_avm_a1_pcmcia(card);
+                       break;
+#endif
+#if CARD_FRITZPCI
+               case ISDN_CTYPE_FRITZPCI:
+                       ret = setup_avm_pci(card);
+                       break;
+#endif
 #if CARD_ELSA
                case ISDN_CTYPE_ELSA:
                case ISDN_CTYPE_ELSA_PNP:
@@ -852,6 +896,7 @@ checkcard(int cardnr, char *id, int *busy_flag))
 #if CARD_SEDLBAUER
                case ISDN_CTYPE_SEDLBAUER:
                case ISDN_CTYPE_SEDLBAUER_PCMCIA:
+               case ISDN_CTYPE_SEDLBAUER_FAX:
                        ret = setup_sedlbauer(card);
                        break;
 #endif
@@ -897,7 +942,7 @@ checkcard(int cardnr, char *id, int *busy_flag))
                restore_flags(flags);
                return (0);
        }
-       if (!(cs->rcvbuf = kmalloc(MAX_DFRAME_LEN, GFP_ATOMIC))) {
+       if (!(cs->rcvbuf = kmalloc(MAX_DFRAME_LEN_L1, GFP_ATOMIC))) {
                printk(KERN_WARNING
                       "HiSax: No memory for isac rcvbuf\n");
                return (1);
@@ -923,7 +968,9 @@ checkcard(int cardnr, char *id, int *busy_flag))
        }
        init_tei(cs, cs->protocol);
        CallcNewChan(cs);
-       ll_run(cs);
+       /* ISAR needs firmware download first */
+       if (!test_bit(HW_ISAR, &cs->HW_Flags))
+               ll_run(cs);
        restore_flags(flags);
        return (1);
 }
@@ -1002,7 +1049,7 @@ HiSax_closecard(int cardnr)
        while (i!=last) {
                cards[i] = cards[i+1];
                i++;
-               }
+       }
        nrcards--;
 }
 
@@ -1020,6 +1067,12 @@ HiSax_reportcard(int cardnr)
        printk(KERN_DEBUG "HiSax: HiSax_reportcard address 0x%lX\n",
               (ulong) & HiSax_reportcard);
        printk(KERN_DEBUG "HiSax: cs 0x%lX\n", (ulong) cs);
+       printk(KERN_DEBUG "HiSax: HW_Flags %x bc0 flg %x bc0 flg %x\n",
+               cs->HW_Flags, cs->bcs[0].Flag, cs->bcs[1].Flag);
+       printk(KERN_DEBUG "HiSax: bcs 0 mode %d ch%d\n",
+               cs->bcs[0].mode, cs->bcs[0].channel);
+       printk(KERN_DEBUG "HiSax: bcs 1 mode %d ch%d\n",
+               cs->bcs[1].mode, cs->bcs[1].channel);
        printk(KERN_DEBUG "HiSax: cs stl 0x%lX\n", (ulong) & (cs->stlist));
        stptr = cs->stlist;
        while (stptr != NULL) {
@@ -1224,12 +1277,12 @@ static void
 l1_timer3(struct FsmInst *fi, int event, void *arg)
 {
        struct PStack *st = fi->userdata;
-       
+
        test_and_clear_bit(FLG_L1_T3RUN, &st->l1.Flags);        
-        if (test_and_clear_bit(FLG_L1_ACTIVATING, &st->l1.Flags))
+       if (test_and_clear_bit(FLG_L1_ACTIVATING, &st->l1.Flags))
                L1deactivated(st->l1.hardware);
-        if (st->l1.l1m.state != ST_L1_F6) {
-               FsmChangeState(fi, ST_L1_F3);
+       if (st->l1.l1m.state != ST_L1_F6) {
+               FsmChangeState(fi, ST_L1_F3);
                st->l1.l1hw(st, HW_ENABLE | REQUEST, NULL);
        }
 }
@@ -1263,9 +1316,22 @@ l1_activate(struct FsmInst *fi, int event, void *arg)
        st->l1.l1hw(st, HW_RESET | REQUEST, NULL);
 }
 
+static void
+l1_activate_no(struct FsmInst *fi, int event, void *arg)
+{
+       struct PStack *st = fi->userdata;
+
+       if ((!test_bit(FLG_L1_DEACTTIMER, &st->l1.Flags)) && (!test_bit(FLG_L1_T3RUN, &st->l1.Flags))) {
+               test_and_clear_bit(FLG_L1_ACTIVATING, &st->l1.Flags);
+               L1deactivated(st->l1.hardware);
+       }
+}
+
 static struct FsmNode L1DFnList[] HISAX_INITDATA =
 {
        {ST_L1_F3, EV_PH_ACTIVATE, l1_activate},
+       {ST_L1_F6, EV_PH_ACTIVATE, l1_activate_no},
+       {ST_L1_F8, EV_PH_ACTIVATE, l1_activate_no},
        {ST_L1_F3, EV_RESET_IND, l1_reset},
        {ST_L1_F4, EV_RESET_IND, l1_reset},
        {ST_L1_F5, EV_RESET_IND, l1_reset},
@@ -1429,34 +1495,34 @@ l1_msg(struct IsdnCardState *cs, int pr, void *arg) {
        while (st) {
                switch(pr) {
                        case (HW_RESET | INDICATION):
-                       FsmEvent(&st->l1.l1m, EV_RESET_IND, arg);
-                       break;
+                               FsmEvent(&st->l1.l1m, EV_RESET_IND, arg);
+                               break;
                        case (HW_DEACTIVATE | CONFIRM):
-                       FsmEvent(&st->l1.l1m, EV_DEACT_CNF, arg);
-                       break;
+                               FsmEvent(&st->l1.l1m, EV_DEACT_CNF, arg);
+                               break;
                        case (HW_DEACTIVATE | INDICATION):
-                       FsmEvent(&st->l1.l1m, EV_DEACT_IND, arg);
-                       break;
+                               FsmEvent(&st->l1.l1m, EV_DEACT_IND, arg);
+                               break;
                        case (HW_POWERUP | CONFIRM):
-                       FsmEvent(&st->l1.l1m, EV_POWER_UP, arg);
-                       break;
+                               FsmEvent(&st->l1.l1m, EV_POWER_UP, arg);
+                               break;
                        case (HW_RSYNC | INDICATION):
-                       FsmEvent(&st->l1.l1m, EV_RSYNC_IND, arg);
-                       break;
+                               FsmEvent(&st->l1.l1m, EV_RSYNC_IND, arg);
+                               break;
                        case (HW_INFO2 | INDICATION):
-                       FsmEvent(&st->l1.l1m, EV_INFO2_IND, arg);
-                       break;
+                               FsmEvent(&st->l1.l1m, EV_INFO2_IND, arg);
+                               break;
                        case (HW_INFO4_P8 | INDICATION):
                        case (HW_INFO4_P10 | INDICATION):
-                       FsmEvent(&st->l1.l1m, EV_INFO4_IND, arg);
-                       break;
-               default:
-                       if (cs->debug) {
+                               FsmEvent(&st->l1.l1m, EV_INFO4_IND, arg);
+                               break;
+                       default:
+                               if (cs->debug) {
                                        sprintf(tmp, "l1msg %04X unhandled", pr);
-                               debugl1(cs, tmp);
-                       }
-                       break;
-       }
+                                       debugl1(cs, tmp);
+                               }
+                               break;
+               }
                st = st->next;
        }
 }
@@ -1504,5 +1570,6 @@ setstack_l1_B(struct PStack *st)
        st->l1.l1m.userdata = st;
        st->l1.l1m.userint = 0;
        st->l1.l1m.printdebug = l1m_debug;
+       st->l1.Flags = 0;
        FsmInitTimer(&st->l1.l1m, &st->l1.timer);
 }
index d40a3bb32a6636f24158a10f4c4359e461fb7dde..a874ef36d548f9094d9dcb147529fea51534fca8 100644 (file)
@@ -1,6 +1,12 @@
-/* $Id: isdnl1.h,v 1.4.2.4 1998/05/27 18:05:49 keil Exp $
+/* $Id: isdnl1.h,v 1.4.2.6 1998/09/30 22:20:04 keil Exp $
 
  * $Log: isdnl1.h,v $
+ * Revision 1.4.2.6  1998/09/30 22:20:04  keil
+ * Cosmetics
+ *
+ * Revision 1.4.2.5  1998/09/27 13:06:28  keil
+ * Apply most changes from 2.1.X (HiSax 3.1)
+ *
  * Revision 1.4.2.4  1998/05/27 18:05:49  keil
  * HiSax 3.0
  *
@@ -38,7 +44,7 @@
 #define        L1_DEB_HSCX_FIFO        0x20
 #define        L1_DEB_LAPD             0x40
 #define        L1_DEB_IPAC             0x80
-#define L1_DEB_RECEIVE_FRAME   0x100
+#define        L1_DEB_RECEIVE_FRAME    0x100
 #define L1_DEB_MONITOR         0x200
 
 #define D_RCVBUFREADY  0
@@ -53,7 +59,7 @@
 #define B_RCVBUFREADY 0
 #define B_XMTBUFREADY 1
 
-extern void debugl1(struct IsdnCardState *sp, char *msg);
+extern void debugl1(struct IsdnCardState *cs, char *msg);
 extern void DChannel_proc_xmt(struct IsdnCardState *cs);
 extern void DChannel_proc_rcv(struct IsdnCardState *cs);
 extern void l1_msg(struct IsdnCardState *cs, int pr, void *arg);
index 9bb4f3599b150dfa06b18de68642f2d8baa3ab79..ff9046290f6522af07a23b68d47f77e2cb0e21df 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: isdnl2.c,v 1.10.2.9 1998/06/19 15:17:56 keil Exp $
+/* $Id: isdnl2.c,v 1.10.2.10 1998/09/27 13:06:30 keil Exp $
 
  * Author       Karsten Keil (keil@temic-ech.spacenet.de)
  *              based on the teles driver from Jan den Ouden
@@ -7,6 +7,9 @@
  *              Fritz Elfert
  *
  * $Log: isdnl2.c,v $
+ * Revision 1.10.2.10  1998/09/27 13:06:30  keil
+ * Apply most changes from 2.1.X (HiSax 3.1)
+ *
  * Revision 1.10.2.9  1998/06/19 15:17:56  keil
  * fix LAPB tx_cnt for none I-frames
  *
@@ -48,7 +51,7 @@
 #include "hisax.h"
 #include "isdnl2.h"
 
-const char *l2_revision = "$Revision: 1.10.2.9 $";
+const char *l2_revision = "$Revision: 1.10.2.10 $";
 
 static void l2m_debug(struct FsmInst *fi, char *s);
 
@@ -253,6 +256,16 @@ IsRR(u_char * data, int ext)
                return ((data[0] & 0xf) == 1);
 }
 
+inline int
+IsSFrame(u_char * data, int ext)
+{
+       register u_char d = *data;
+       
+       if (!ext)
+               d &= 0xf;
+       return(((d & 0xf3) == 1) && ((d & 0x0c) != 0x0c));
+}
+
 inline int
 IsSABMX(u_char * data, int ext)
 {
@@ -398,9 +411,16 @@ l2_dl_establish(struct FsmInst *fi, int event, void *arg)
        struct PStack *st = fi->userdata;
        int state = fi->state;
 
-       FsmChangeState(fi, ST_L2_3); 
-       if (state == ST_L2_1)
-               st->l2.l2tei(st, MDL_ASSIGN | INDICATION, NULL);
+       
+       if (test_bit(FLG_FIXED_TEI, &st->l2.flag)) {
+               FsmChangeState(fi, ST_L2_4);
+               establishlink(fi);
+               test_and_set_bit(FLG_L3_INIT, &st->l2.flag);
+       } else {
+               FsmChangeState(fi, ST_L2_3);
+               if (state == ST_L2_1)
+                       st->l2.l2tei(st, MDL_ASSIGN | INDICATION, NULL);
+       }
 }
 
 static void
@@ -692,19 +712,37 @@ l2_got_dm(struct FsmInst *fi, int event, void *arg)
                        establishlink(fi);
                        test_and_clear_bit(FLG_L3_INIT, &st->l2.flag);
                        FsmChangeState(fi, ST_L2_5);
+               } else if ((fi->state == ST_L2_7) || (fi->state == ST_L2_8)) {
+                       st->ma.layer(st, MDL_ERROR | INDICATION, (void *) 'E');
+                       establishlink(fi);
+               }
+       } else {
+               switch (fi->state) {
+                       case ST_L2_8:
+                                establishlink(fi);
+                       case ST_L2_7:
+                               st->ma.layer(st, MDL_ERROR | INDICATION, (void *) 'B');
+                               break;
+                       case ST_L2_4:
+                               break;
+                       case ST_L2_5:
+                               if (test_and_clear_bit(FLG_T200_RUN, &st->l2.flag))
+                                       FsmDelTimer(&st->l2.t200, 2);
+                               discard_queue(&st->l2.i_queue);
+                               if (test_bit(FLG_LAPB, &st->l2.flag))
+                                       st->l2.l2l1(st, PH_DEACTIVATE | REQUEST, NULL);
+                               st->l2.l2l3(st, DL_RELEASE | INDICATION, NULL);
+                               FsmChangeState(fi, ST_L2_4);
+                               break;
+                       case ST_L2_6:
+                               if (test_and_clear_bit(FLG_T200_RUN, &st->l2.flag))
+                                       FsmDelTimer(&st->l2.t200, 2);
+                               if (test_bit(FLG_LAPB, &st->l2.flag))
+                                       st->l2.l2l1(st, PH_DEACTIVATE | REQUEST, NULL);
+                               st->l2.l2l3(st, DL_RELEASE | CONFIRM, NULL);
+                               FsmChangeState(fi, ST_L2_4);
+                               break;
                }
-       } else if (fi->state != ST_L2_4) {
-               if (test_and_clear_bit(FLG_T200_RUN, &st->l2.flag))
-                       FsmDelTimer(&st->l2.t200, 2);
-               if (fi->state == ST_L2_5)
-                       discard_queue(&st->l2.i_queue);
-               if (test_bit(FLG_LAPB, &st->l2.flag))
-                       st->l2.l2l1(st, PH_DEACTIVATE | REQUEST, NULL);
-               if (fi->state == ST_L2_6)
-                       st->l2.l2l3(st, DL_RELEASE | CONFIRM, NULL);
-               else
-                       st->l2.l2l3(st, DL_RELEASE | INDICATION, NULL);
-               FsmChangeState(fi, ST_L2_4);
        }
 }
 
@@ -817,9 +855,11 @@ l2_got_st7_super(struct FsmInst *fi, int event, void *arg)
                        PollFlag = (skb->data[1] & 0x1) == 0x1;
                        nr = skb->data[1] >> 1;
                } else {
-                       st->ma.layer(st, MDL_ERROR | INDICATION, (void *) 'N');
+                       if (skb->len >2) {
+                               st->ma.layer(st, MDL_ERROR | INDICATION, (void *) 'N');
+                               establishlink(fi);
+                       }
                        FreeSkb(skb);
-                       establishlink(fi);
                        return;
                }
        } else {
@@ -908,9 +948,7 @@ l2_got_iframe(struct FsmInst *fi, int event, void *arg)
        i = l2addrsize(l2);
        if (test_bit(FLG_MOD128, &l2->flag)) {
                if (skb->len <= (i + 1)) {
-                       st->ma.layer(st, MDL_ERROR | INDICATION, (void *) 'N');
                        FreeSkb(skb);
-                       establishlink(fi);
                        return;
                } else if ((skb->len - i - 1) > l2->maxlen) { 
                        st->ma.layer(st, MDL_ERROR | INDICATION, (void *) 'O');
@@ -1369,8 +1407,8 @@ static struct FsmNode L2FnList[] HISAX_INITDATA =
        {ST_L2_4, EV_L2_DM, l2_got_dm},
        {ST_L2_5, EV_L2_DM, l2_got_dm},
        {ST_L2_6, EV_L2_DM, l2_got_dm},
-       {ST_L2_7, EV_L2_DM, l2_mdl_error},
-       {ST_L2_8, EV_L2_DM, l2_mdl_error},
+       {ST_L2_7, EV_L2_DM, l2_got_dm},
+       {ST_L2_8, EV_L2_DM, l2_got_dm},
        {ST_L2_1, EV_L2_UI, l2_got_ui},
        {ST_L2_2, EV_L2_UI, l2_got_ui},
        {ST_L2_3, EV_L2_UI, l2_got_ui},
@@ -1424,7 +1462,7 @@ isdnl2_l1l2(struct PStack *st, int pr, void *arg)
                        }
                        if (!(*datap & 1))      /* I-Frame */
                                ret = FsmEvent(&st->l2.l2m, EV_L2_I, skb);
-                       else if ((*datap & 3) == 1)     /* S-Frame */
+                       else if (IsSFrame(datap, test_bit(FLG_MOD128, &st->l2.flag)))
                                ret = FsmEvent(&st->l2.l2m, EV_L2_SUPER, skb);
                        else if (IsUI(datap, test_bit(FLG_MOD128, &st->l2.flag)))
                                ret = FsmEvent(&st->l2.l2m, EV_L2_UI, skb);
@@ -1439,9 +1477,11 @@ isdnl2_l1l2(struct PStack *st, int pr, void *arg)
                        else if (IsFRMR(datap, test_bit(FLG_MOD128, &st->l2.flag)))
                                ret = FsmEvent(&st->l2.l2m, EV_L2_FRMR, skb);
                        else {
-                               ret = 0;
+                               ret = 1;
+                               if ((st->l2.l2m.state == ST_L2_7) ||
+                                       (st->l2.l2m.state == ST_L2_8))
+                                       establishlink(&st->l2.l2m);
                                st->ma.layer(st, MDL_ERROR | INDICATION, (void *) 'L');
-                               FreeSkb(skb);
                        }
                        if (ret) {
                                FreeSkb(skb);
@@ -1576,13 +1616,13 @@ transl2_l3l2(struct PStack *st, int pr, void *arg)
        switch (pr) {
                case (DL_DATA | REQUEST):
                case (DL_UNIT_DATA | REQUEST):
-                       st->l2.l2l1(st, PH_DATA, arg);
+                       st->l2.l2l1(st, PH_DATA | REQUEST, arg);
                        break;
                case (DL_ESTABLISH | REQUEST):
-                       st->l2.l2l1(st, PH_ACTIVATE, NULL);
+                       st->l2.l2l1(st, PH_ACTIVATE | REQUEST, NULL);
                        break;
                case (DL_RELEASE | REQUEST):
-                       st->l2.l2l1(st, PH_DEACTIVATE, NULL);
+                       st->l2.l2l1(st, PH_DEACTIVATE | REQUEST, NULL);
                        break;
        }
 }
index 5b1663c689b546b67e45ff45d34251d5d06e7c5c..fd50c3b8adc6e8ec6c2e0207a189a301647bbb57 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: isdnl3.c,v 1.10.2.4 1998/05/27 18:05:59 keil Exp $
+/* $Id: isdnl3.c,v 1.10.2.5 1998/09/27 13:06:39 keil Exp $
 
  * Author       Karsten Keil (keil@temic-ech.spacenet.de)
  *              based on the teles driver from Jan den Ouden
@@ -7,6 +7,9 @@
  *              Fritz Elfert
  *
  * $Log: isdnl3.c,v $
+ * Revision 1.10.2.5  1998/09/27 13:06:39  keil
+ * Apply most changes from 2.1.X (HiSax 3.1)
+ *
  * Revision 1.10.2.4  1998/05/27 18:05:59  keil
  * HiSax 3.0
  *
@@ -42,7 +45,7 @@
 #include "isdnl3.h"
 #include <linux/config.h>
 
-const char *l3_revision = "$Revision: 1.10.2.4 $";
+const char *l3_revision = "$Revision: 1.10.2.5 $";
 
 static
 struct Fsm l3fsm =
@@ -329,7 +332,8 @@ release_l3_process(struct l3_process *p)
                pp = np;
                np = np->next;
        }
-       printk(KERN_ERR "HiSax internal L3 error CR not in list\n");
+       printk(KERN_ERR "HiSax internal L3 error CR(%d) not in list\n", p->callref);
+       l3_debug(p->st, "HiSax internal L3 error CR(%d) not in list", p->callref);
 };
 
 void
index 1448185dd6dadcc013de2d4c180f7a90aa4632ce..568ed489a07649887c67516452875c26157cb6e3 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: l3_1tr6.c,v 1.11.2.3 1998/05/27 18:06:04 keil Exp $
+/* $Id: l3_1tr6.c,v 1.11.2.4 1998/09/27 13:06:42 keil Exp $
 
  *  German 1TR6 D-channel protocol
  *
@@ -6,6 +6,9 @@
  *
  *
  * $Log: l3_1tr6.c,v $
+ * Revision 1.11.2.4  1998/09/27 13:06:42  keil
+ * Apply most changes from 2.1.X (HiSax 3.1)
+ *
  * Revision 1.11.2.3  1998/05/27 18:06:04  keil
  * HiSax 3.0
  *
@@ -38,7 +41,7 @@
 #include <linux/ctype.h>
 
 extern char *HiSax_getrev(const char *revision);
-const char *l3_1tr6_revision = "$Revision: 1.11.2.3 $";
+const char *l3_1tr6_revision = "$Revision: 1.11.2.4 $";
 
 #define MsgHead(ptr, cref, mty, dis) \
        *ptr++ = dis; \
@@ -56,66 +59,34 @@ l3_1TR6_message(struct l3_process *pc, u_char mt, u_char pd)
                return;
        p = skb_put(skb, 4);
        MsgHead(p, pc->callref, mt, pd);
-       pc->st->l3.l3l2(pc->st, DL_DATA | REQUEST, skb);
+       l3_msg(pc->st, DL_DATA | REQUEST, skb);
 }
 
-static int
-l31tr6_check_messagetype_validity(int mt, int pd) {
-/* verify if a message type exists */
-
-       if (pd == PROTO_DIS_N0)
-               switch(mt) {
-                  case MT_N0_REG_IND:
-                  case MT_N0_CANC_IND:
-                  case MT_N0_FAC_STA:
-                  case MT_N0_STA_ACK:
-                  case MT_N0_STA_REJ:
-                  case MT_N0_FAC_INF:
-                  case MT_N0_INF_ACK:
-                  case MT_N0_INF_REJ:
-                  case MT_N0_CLOSE:
-                  case MT_N0_CLO_ACK:
-                       return(1);
-                  default:
-                       return(0);
-               }
-       else if (pd == PROTO_DIS_N1)
-               switch(mt) {
-                  case MT_N1_ESC:
-                  case MT_N1_ALERT:
-                  case MT_N1_CALL_SENT:
-                  case MT_N1_CONN:
-                  case MT_N1_CONN_ACK:
-                  case MT_N1_SETUP:
-                  case MT_N1_SETUP_ACK:
-                  case MT_N1_RES:
-                  case MT_N1_RES_ACK:
-                  case MT_N1_RES_REJ:
-                  case MT_N1_SUSP:
-                  case MT_N1_SUSP_ACK:
-                  case MT_N1_SUSP_REJ:
-                  case MT_N1_USER_INFO:
-                  case MT_N1_DET:
-                  case MT_N1_DISC:
-                  case MT_N1_REL:
-                  case MT_N1_REL_ACK:
-                  case MT_N1_CANC_ACK:
-                  case MT_N1_CANC_REJ:
-                  case MT_N1_CON_CON:
-                  case MT_N1_FAC:
-                  case MT_N1_FAC_ACK:
-                  case MT_N1_FAC_CAN:
-                  case MT_N1_FAC_REG:
-                  case MT_N1_FAC_REJ:
-                  case MT_N1_INFO:
-                  case MT_N1_REG_ACK:
-                  case MT_N1_REG_REJ:
-                  case MT_N1_STAT:
-                       return (1);
-                  default:
-                       return(0);
-               }
-       return(0);
+static void
+l3_1tr6_release_req(struct l3_process *pc, u_char pr, void *arg)
+{
+       StopAllL3Timer(pc);
+       newl3state(pc, 19);
+       l3_1TR6_message(pc, MT_N1_REL, PROTO_DIS_N1);
+       L3AddTimer(&pc->timer, T308, CC_T308_1);
+}
+
+static void
+l3_1tr6_invalid(struct l3_process *pc, u_char pr, void *arg)
+{
+       struct sk_buff *skb = arg;
+
+       dev_kfree_skb(skb, FREE_READ);
+       l3_1tr6_release_req(pc, 0, NULL);
+}
+
+static void
+l3_1tr6_error(struct l3_process *pc, u_char *msg, struct sk_buff *skb)
+{
+       dev_kfree_skb(skb, FREE_READ);
+       if (pc->st->l3.debug & L3_DEB_WARN)
+               l3_debug(pc->st, msg);
+       l3_1tr6_release_req(pc, 0, NULL);
 }
 
 static void
@@ -204,7 +175,7 @@ l3_1tr6_setup_req(struct l3_process *pc, u_char pr, void *arg)
        L3DelTimer(&pc->timer);
        L3AddTimer(&pc->timer, T303, CC_T303);
        newl3state(pc, 1);
-       pc->st->l3.l3l2(pc->st, DL_DATA | REQUEST, skb);
+       l3_msg(pc->st, DL_DATA | REQUEST, skb);
 }
 
 static void
@@ -220,17 +191,29 @@ l3_1tr6_setup(struct l3_process *pc, u_char pr, void *arg)
        /* Channel Identification */
        p = skb->data;
        if ((p = findie(p, skb->len, WE0_chanID, 0))) {
-               pc->para.bchannel = p[2] & 0x3;
-               bcfound++;
-       } else if (pc->st->l3.debug & L3_DEB_WARN)
-               l3_debug(pc->st, "setup without bchannel");
+               if (p[1] != 1) {
+                       l3_1tr6_error(pc, "setup wrong chanID len", skb);
+                       return;
+               }
+               if ((p[2] & 0xf4) != 0x80) {
+                       l3_1tr6_error(pc, "setup wrong WE0_chanID", skb);
+                       return;
+               }
+               if ((pc->para.bchannel = p[2] & 0x3))
+                               bcfound++;
+       } else {
+               l3_1tr6_error(pc, "missing setup chanID", skb);
+               return;
+       }
 
        p = skb->data;
        if ((p = findie(p, skb->len, WE6_serviceInd, 6))) {
                pc->para.setup.si1 = p[2];
                pc->para.setup.si2 = p[3];
-       } else if (pc->st->l3.debug & L3_DEB_WARN)
-               l3_debug(pc->st, "setup without service indicator");
+       } else {
+               l3_1tr6_error(pc, "missing setup SI", skb);
+               return;
+       }
 
        p = skb->data;
        if ((p = findie(p, skb->len, WE0_destAddr, 0)))
@@ -276,9 +259,19 @@ l3_1tr6_setup_ack(struct l3_process *pc, u_char pr, void *arg)
        p = skb->data;
        newl3state(pc, 2);
        if ((p = findie(p, skb->len, WE0_chanID, 0))) {
+               if (p[1] != 1) {
+                       l3_1tr6_error(pc, "setup_ack wrong chanID len", skb);
+                       return;
+               }
+               if ((p[2] & 0xf4) != 0x80) {
+                       l3_1tr6_error(pc, "setup_ack wrong WE0_chanID", skb);
+                       return;
+               }
                pc->para.bchannel = p[2] & 0x3;
-       } else if (pc->st->l3.debug & L3_DEB_WARN)
-               l3_debug(pc->st, "setup answer without bchannel");
+       } else {
+               l3_1tr6_error(pc, "missing setup_ack WE0_chanID", skb);
+               return;
+       }
        dev_kfree_skb(skb, FREE_READ);
        L3AddTimer(&pc->timer, T304, CC_T304);
        pc->st->l3.l3l4(pc->st, CC_MORE_INFO | INDICATION, pc);
@@ -293,9 +286,23 @@ l3_1tr6_call_sent(struct l3_process *pc, u_char pr, void *arg)
        L3DelTimer(&pc->timer);
        p = skb->data;
        if ((p = findie(p, skb->len, WE0_chanID, 0))) {
+               if (p[1] != 1) {
+                       l3_1tr6_error(pc, "call sent wrong chanID len", skb);
+                       return;
+               }
+               if ((p[2] & 0xf4) != 0x80) {
+                       l3_1tr6_error(pc, "call sent wrong WE0_chanID", skb);
+                       return;
+               }
+               if ((pc->state == 2) && (pc->para.bchannel != (p[2] & 0x3))) {
+                       l3_1tr6_error(pc, "call sent wrong chanID value", skb);
+                       return;
+               }
                pc->para.bchannel = p[2] & 0x3;
-       } else if (pc->st->l3.debug & L3_DEB_WARN)
-               l3_debug(pc->st, "setup answer without bchannel");
+       } else {
+               l3_1tr6_error(pc, "missing call sent WE0_chanID", skb);
+               return;
+       }
        dev_kfree_skb(skb, FREE_READ);
        L3AddTimer(&pc->timer, T310, CC_T310);
        newl3state(pc, 3);
@@ -356,6 +363,10 @@ l3_1tr6_connect(struct l3_process *pc, u_char pr, void *arg)
        struct sk_buff *skb = arg;
 
        L3DelTimer(&pc->timer); /* T310 */
+       if (!findie(skb->data, skb->len, WE6_date, 6)) {
+               l3_1tr6_error(pc, "missing connect date", skb);
+               return;
+       }
        newl3state(pc, 10);
        dev_kfree_skb(skb, FREE_READ);
        pc->para.chargeinfo = 0;
@@ -380,8 +391,11 @@ l3_1tr6_rel(struct l3_process *pc, u_char pr, void *arg)
                        pc->para.cause = 0;
                        pc->para.loc = 0;
                }
-       } else
+       } else {
                pc->para.cause = -1;
+               l3_1tr6_error(pc, "missing REL cause", skb);
+               return;
+       }
        dev_kfree_skb(skb, FREE_READ);
        StopAllL3Timer(pc);
        newl3state(pc, 0);
@@ -448,6 +462,10 @@ l3_1tr6_disc(struct l3_process *pc, u_char pr, void *arg)
                        l3_debug(pc->st, "cause not found");
                pc->para.cause = -1;
        }
+       if (!findie(skb->data, skb->len, WE6_date, 6)) {
+               l3_1tr6_error(pc, "missing connack date", skb);
+               return;
+       }
        dev_kfree_skb(skb, FREE_READ);
        newl3state(pc, 12);
        pc->st->l3.l3l4(pc->st, CC_DISCONNECT | INDICATION, pc);
@@ -459,6 +477,10 @@ l3_1tr6_connect_ack(struct l3_process *pc, u_char pr, void *arg)
 {
        struct sk_buff *skb = arg;
 
+       if (!findie(skb->data, skb->len, WE6_date, 6)) {
+               l3_1tr6_error(pc, "missing connack date", skb);
+               return;
+       }
        dev_kfree_skb(skb, FREE_READ);
        newl3state(pc, 10);
        pc->para.chargeinfo = 0;
@@ -502,7 +524,7 @@ l3_1tr6_setup_rsp(struct l3_process *pc, u_char pr, void *arg)
        if (!(skb = l3_alloc_skb(l)))
                return;
        memcpy(skb_put(skb, l), tmp, l);
-       pc->st->l3.l3l2(pc->st, DL_DATA | REQUEST, skb);
+       l3_msg(pc->st, DL_DATA | REQUEST, skb);
        L3DelTimer(&pc->timer);
        L3AddTimer(&pc->timer, T313, CC_T313);
 }
@@ -545,19 +567,10 @@ l3_1tr6_disconnect_req(struct l3_process *pc, u_char pr, void *arg)
        if (!(skb = l3_alloc_skb(l)))
                return;
        memcpy(skb_put(skb, l), tmp, l);
-       pc->st->l3.l3l2(pc->st, DL_DATA | REQUEST, skb);
+       l3_msg(pc->st, DL_DATA | REQUEST, skb);
        L3AddTimer(&pc->timer, T305, CC_T305);
 }
 
-static void
-l3_1tr6_release_req(struct l3_process *pc, u_char pr, void *arg)
-{
-       StopAllL3Timer(pc);
-       newl3state(pc, 19);
-       l3_1TR6_message(pc, MT_N1_REL, PROTO_DIS_N1);
-       L3AddTimer(&pc->timer, T308, CC_T308_1);
-}
-
 static void
 l3_1tr6_t303(struct l3_process *pc, u_char pr, void *arg)
 {
@@ -567,8 +580,8 @@ l3_1tr6_t303(struct l3_process *pc, u_char pr, void *arg)
                l3_1tr6_setup_req(pc, pr, arg);
        } else {
                L3DelTimer(&pc->timer);
-               pc->st->l3.l3l4(pc->st, CC_NOSETUP_RSP, pc);
-               release_l3_process(pc);
+               pc->para.cause = 0;
+               l3_1tr6_disconnect_req(pc, 0, NULL);
        }
 }
 
@@ -613,7 +626,7 @@ l3_1tr6_t305(struct l3_process *pc, u_char pr, void *arg)
        if (!(skb = l3_alloc_skb(l)))
                return;
        memcpy(skb_put(skb, l), tmp, l);
-       pc->st->l3.l3l2(pc->st, DL_DATA | REQUEST, skb);
+       l3_msg(pc->st, DL_DATA | REQUEST, skb);
        L3AddTimer(&pc->timer, T308, CC_T308_1);
 }
 
@@ -692,6 +705,8 @@ sizeof(struct stateentry);
 
 static struct stateentry datastln1[] =
 {
+       {SBIT(0),
+        MT_N1_INVALID, l3_1tr6_invalid},
        {SBIT(0),
         MT_N1_SETUP, l3_1tr6_setup},
        {SBIT(1),
@@ -711,8 +726,13 @@ static struct stateentry datastln1[] =
        {SBIT(10),
         MT_N1_INFO, l3_1tr6_info},
        {SBIT(0) | SBIT(1) | SBIT(2) | SBIT(3) | SBIT(4) | SBIT(7) | SBIT(8) |
-        SBIT(10) | SBIT(11) | SBIT(12) | SBIT(15) | SBIT(17) | SBIT(19),
+        SBIT(10) | SBIT(11) | SBIT(12) | SBIT(15) | SBIT(17),
         MT_N1_REL, l3_1tr6_rel},
+       {SBIT(19),
+        MT_N1_REL, l3_1tr6_rel_ack},
+       {SBIT(0) | SBIT(1) | SBIT(2) | SBIT(3) | SBIT(4) | SBIT(7) | SBIT(8) |
+        SBIT(10) | SBIT(11) | SBIT(12) | SBIT(15) | SBIT(17),
+        MT_N1_REL_ACK, l3_1tr6_invalid},
        {SBIT(19),
         MT_N1_REL_ACK, l3_1tr6_rel_ack}
 };
@@ -781,7 +801,28 @@ up1tr6(struct PStack *st, int pr, void *arg)
                }
        } else if (skb->data[0] == PROTO_DIS_N1) {
                if (!(proc = getl3proc(st, cr))) {
-                       if ((mt == MT_N1_SETUP) && (cr < 128)) {
+                       if (mt == MT_N1_SETUP) { 
+                               if (cr < 128) {
+                                       if (!(proc = new_l3_process(st, cr))) {
+                                               if (st->l3.debug & L3_DEB_PROTERR) {
+                                                       sprintf(tmp, "up1tr6 no roc mem");
+                                                       l3_debug(st, tmp);
+                                               }
+                                               dev_kfree_skb(skb, FREE_READ);
+                                               return;
+                                       }
+                               } else {
+                                       dev_kfree_skb(skb, FREE_READ);
+                                       return;
+                               }
+                       } else if ((mt == MT_N1_REL) || (mt == MT_N1_REL_ACK) ||
+                               (mt == MT_N1_CANC_ACK) || (mt == MT_N1_CANC_REJ) ||
+                               (mt == MT_N1_REG_ACK) || (mt == MT_N1_REG_REJ) ||
+                               (mt == MT_N1_SUSP_ACK) || (mt == MT_N1_RES_REJ) ||
+                               (mt == MT_N1_INFO)) {
+                               dev_kfree_skb(skb, FREE_READ);
+                               return;
+                       } else {
                                if (!(proc = new_l3_process(st, cr))) {
                                        if (st->l3.debug & L3_DEB_PROTERR) {
                                                sprintf(tmp, "up1tr6 no roc mem");
@@ -790,9 +831,7 @@ up1tr6(struct PStack *st, int pr, void *arg)
                                        dev_kfree_skb(skb, FREE_READ);
                                        return;
                                }
-                       } else {
-                               dev_kfree_skb(skb, FREE_READ);
-                               return;
+                               mt = MT_N1_INVALID;
                        }
                }
                for (i = 0; i < datastln1_len; i++)
index f192de49c32bf8c179b6d5140aa954757c1a5013..63da58ee02a0022839f28c85ff432dc095febc57 100644 (file)
@@ -1,8 +1,11 @@
-/* $Id: l3_1tr6.h,v 1.1.2.1 1997/10/17 22:14:15 keil Exp $
+/* $Id: l3_1tr6.h,v 1.1.2.2 1998/09/27 13:06:46 keil Exp $
  *
  *  German 1TR6 D-channel protocol defines
  *
  * $Log: l3_1tr6.h,v $
+ * Revision 1.1.2.2  1998/09/27 13:06:46  keil
+ * Apply most changes from 2.1.X (HiSax 3.1)
+ *
  * Revision 1.1.2.1  1997/10/17 22:14:15  keil
  * update to last hisax version
  *
@@ -67,6 +70,7 @@
 #define MT_N1_REG_ACK 0x6C
 #define MT_N1_REG_REJ 0x6F
 #define MT_N1_STAT 0x63
+#define MT_N1_INVALID 0
 
 /*
  * W Elemente
index 217a440ebf3581b13f0ba276f2547d5552da9b1b..8bba9c04590e34293470982159c33a3924878048 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: l3dss1.c,v 1.16.2.4 1998/05/27 18:06:08 keil Exp $
+/* $Id: l3dss1.c,v 1.16.2.5 1998/09/27 13:06:48 keil Exp $
 
  * EURO/DSS1 D-channel protocol
  *
@@ -9,6 +9,9 @@
  *              Fritz Elfert
  *
  * $Log: l3dss1.c,v $
+ * Revision 1.16.2.5  1998/09/27 13:06:48  keil
+ * Apply most changes from 2.1.X (HiSax 3.1)
+ *
  * Revision 1.16.2.4  1998/05/27 18:06:08  keil
  * HiSax 3.0
  *
@@ -47,7 +50,7 @@
 #include <linux/ctype.h>
 
 extern char *HiSax_getrev(const char *revision);
-const char *dss1_revision = "$Revision: 1.16.2.4 $";
+const char *dss1_revision = "$Revision: 1.16.2.5 $";
 
 #define EXT_BEARER_CAPS 1
 
@@ -58,9 +61,9 @@ const char *dss1_revision = "$Revision: 1.16.2.4 $";
        *ptr++ = mty
 
 
-#ifdef HISAX_DE_AOC
+#if HISAX_DE_AOC
 static void
-l3dss1_parse_facility(struct l3_process *pc, u_char *p)
+l3dss1_parse_facility(struct l3_process *pc, u_char * p)
 {
        int qd_len = 0;
 
@@ -70,91 +73,99 @@ l3dss1_parse_facility(struct l3_process *pc, u_char *p)
                l3_debug(pc->st, "qd_len == 0");
                return;
        }
-       if((*p & 0x1F) != 0x11) {       /* Service discriminator, supplementary service */
+       if ((*p & 0x1F) != 0x11) {      /* Service discriminator, supplementary service */
                l3_debug(pc->st, "supplementary service != 0x11");
                return;
        }
-       while(qd_len > 0 && !(*p & 0x80)) {     /* extension ? */
-               p++; qd_len--;
-       } 
-       if(qd_len < 2) {
+       while (qd_len > 0 && !(*p & 0x80)) {    /* extension ? */
+               p++;
+               qd_len--;
+       }
+       if (qd_len < 2) {
                l3_debug(pc->st, "qd_len < 2");
                return;
        }
-       p++; qd_len--;
-       if((*p & 0xE0) != 0xA0) {       /* class and form */
+       p++;
+       qd_len--;
+       if ((*p & 0xE0) != 0xA0) {      /* class and form */
                l3_debug(pc->st, "class and form != 0xA0");
                return;
        }
-       switch(*p & 0x1F) {             /* component tag */
-           case 1: /* invoke */
-               {
-                   unsigned char nlen, ilen;
-                   int ident;
-    
-                   p++; qd_len--;
-                   if(qd_len < 1) {
-                           l3_debug(pc->st, "qd_len < 1");
-                           break;
-                   }
-                   if(*p & 0x80) { /* length format */
-                           l3_debug(pc->st, "*p & 0x80 length format");
-                           break;
-                   }
-                   nlen = *p++; qd_len--;
-                   if(qd_len < nlen) {
-                           l3_debug(pc->st, "qd_len < nlen");
-                           return;
-                   }
-                   qd_len -= nlen;
-    
-                   if(nlen < 2) {
-                           l3_debug(pc->st, "nlen < 2");
-                           return;
-                   }
-                   if(*p != 0x02) {    /* invoke identifier tag */
-                           l3_debug(pc->st, "invoke identifier tag !=0x02");
-                           return;
-                   }
-                   p++; nlen--;
-                   if(*p & 0x80) { /* length format */
-                           l3_debug(pc->st, "*p & 0x80 length format 2");
-                           break;
-                   }
-                   ilen = *p++; nlen--;
-                   if(ilen > nlen || ilen == 0) {
-                           l3_debug(pc->st, "ilen > nlen || ilen == 0");
-                           return;
-                   }
-                   nlen -= ilen;
-                   ident = 0;
-                   while(ilen > 0) {
-                           ident = (ident << 8) | (*p++ & 0xFF);       /* invoke identifier */
-                           ilen--;
-                   }
-    
-                   if(nlen < 2) {
-                           l3_debug(pc->st, "nlen < 2 22");
-                           return;
-                   }
-                   if(*p != 0x02)      {       /* operation value */ 
-                           l3_debug(pc->st, "operation value !=0x02");
-                           return;
-                   }
-                   p++; nlen--;
-                   ilen = *p++; nlen--;
-                   if(ilen > nlen || ilen == 0) {
-                           l3_debug(pc->st, "ilen > nlen || ilen == 0 22");
-                           return;
-                   }
-                   nlen -= ilen;
-                   ident = 0;
-                   while(ilen > 0) {
-                           ident = (ident << 8) | (*p++ & 0xFF);
-                           ilen--;
-                   }
-    
-    #define FOO1(s,a,b) \
+       switch (*p & 0x1F) {    /* component tag */
+               case 1: /* invoke */
+                       {
+                               unsigned char nlen, ilen;
+                               int ident;
+
+                               p++;
+                               qd_len--;
+                               if (qd_len < 1) {
+                                       l3_debug(pc->st, "qd_len < 1");
+                                       break;
+                               }
+                               if (*p & 0x80) {        /* length format */
+                                       l3_debug(pc->st, "*p & 0x80 length format");
+                                       break;
+                               }
+                               nlen = *p++;
+                               qd_len--;
+                               if (qd_len < nlen) {
+                                       l3_debug(pc->st, "qd_len < nlen");
+                                       return;
+                               }
+                               qd_len -= nlen;
+
+                               if (nlen < 2) {
+                                       l3_debug(pc->st, "nlen < 2");
+                                       return;
+                               }
+                               if (*p != 0x02) {       /* invoke identifier tag */
+                                       l3_debug(pc->st, "invoke identifier tag !=0x02");
+                                       return;
+                               }
+                               p++;
+                               nlen--;
+                               if (*p & 0x80) {        /* length format */
+                                       l3_debug(pc->st, "*p & 0x80 length format 2");
+                                       break;
+                               }
+                               ilen = *p++;
+                               nlen--;
+                               if (ilen > nlen || ilen == 0) {
+                                       l3_debug(pc->st, "ilen > nlen || ilen == 0");
+                                       return;
+                               }
+                               nlen -= ilen;
+                               ident = 0;
+                               while (ilen > 0) {
+                                       ident = (ident << 8) | (*p++ & 0xFF);   /* invoke identifier */
+                                       ilen--;
+                               }
+
+                               if (nlen < 2) {
+                                       l3_debug(pc->st, "nlen < 2 22");
+                                       return;
+                               }
+                               if (*p != 0x02) {       /* operation value */
+                                       l3_debug(pc->st, "operation value !=0x02");
+                                       return;
+                               }
+                               p++;
+                               nlen--;
+                               ilen = *p++;
+                               nlen--;
+                               if (ilen > nlen || ilen == 0) {
+                                       l3_debug(pc->st, "ilen > nlen || ilen == 0 22");
+                                       return;
+                               }
+                               nlen -= ilen;
+                               ident = 0;
+                               while (ilen > 0) {
+                                       ident = (ident << 8) | (*p++ & 0xFF);
+                                       ilen--;
+                               }
+
+#define FOO1(s,a,b) \
            while(nlen > 1) {           \
                    int ilen = p[1];    \
                    if(nlen < ilen+2) { \
@@ -170,68 +181,72 @@ l3dss1_parse_facility(struct l3_process *pc, u_char *p)
                            p += ilen+2;        \
                    }                   \
            }
-                           
-                   switch(ident) {
-                   default:
-                           break;
-                   case 0x22: /* during */
-                           FOO1("1A",0x30,FOO1("1C",0xA1,FOO1("1D",0x30,FOO1("1E",0x02,({
-                                   ident = 0;
-                                   while(ilen > 0) {
-                                           ident = (ident<<8) | *p++;
-                                           ilen--;
-                                   }
-                                   if (ident > pc->para.chargeinfo) {
-                                           pc->para.chargeinfo = ident;
-                                           pc->st->l3.l3l4(pc->st, CC_CHARGE | INDICATION, pc);
-                                   }
-                                   if (pc->st->l3.debug & L3_DEB_CHARGE) {
-                                           if (*(p+2) == 0) {
-                                                   l3_debug(pc->st, "charging info during %d", pc->para.chargeinfo);
-                                           } else {
-                                                   l3_debug(pc->st, "charging info final %d", pc->para.chargeinfo);
-                                           }
-                                   }
-                           })))))
-                           break;
-                   case 0x24: /* final */
-                           FOO1("2A",0x30,FOO1("2B",0x30,FOO1("2C",0xA1,FOO1("2D",0x30,FOO1("2E",0x02,({
-                                   ident = 0;
-                                   while(ilen > 0) {
-                                           ident = (ident<<8) | *p++;
-                                           ilen--;
-                                   }
-                                   if (ident > pc->para.chargeinfo) {
-                                           pc->para.chargeinfo = ident;
-                                           pc->st->l3.l3l4(pc->st, CC_CHARGE | INDICATION, pc);
-                                   }
-                                   if (pc->st->l3.debug & L3_DEB_CHARGE) {
-                                           l3_debug(pc->st, "charging info final %d", pc->para.chargeinfo);
-                                   }
-                           }))))))
-                   break;
-                   }
-    #undef FOO1
-    
-               }
-           break;
-           case 2: /* return result */
-                   l3_debug(pc->st, "return result break");
-                   break;
-           case 3: /* return error */
-                   l3_debug(pc->st, "return error break");
-                   break;
-           default:
-                   l3_debug(pc->st, "default break");
-                   break;
+
+                               switch (ident) {
+                                       default:
+                                               break;
+                                       case 0x22:      /* during */
+                                               FOO1("1A", 0x30, FOO1("1C", 0xA1, FOO1("1D", 0x30, FOO1("1E", 0x02, ( {
+                                                              ident = 0;
+                                                       while (ilen > 0) {
+                                                                                                                    ident = (ident << 8) | *p++;
+                                                                 ilen--;
+                                                                       }
+                                                                                                                    if (ident > pc->para.chargeinfo) {
+                                                                                                                    pc->para.chargeinfo = ident;
+                                                                                                                    pc->st->l3.l3l4(pc->st, CC_CHARGE | INDICATION, pc);
+                                                                       }
+                                                                                                                    if (pc->st->l3.debug & L3_DEB_CHARGE) {
+                                                                                                                    if (*(p + 2) == 0) {
+                                                                                                                    l3_debug(pc->st, "charging info during %d", pc->para.chargeinfo);
+                                                                       }
+                                                                  else {
+                                                                                                                    l3_debug(pc->st, "charging info final %d", pc->para.chargeinfo);
+                                                                       }
+                                                                       }
+                                                                       }
+                                                                   )))))
+                                                       break;
+                                       case 0x24:      /* final */
+                                               FOO1("2A", 0x30, FOO1("2B", 0x30, FOO1("2C", 0xA1, FOO1("2D", 0x30, FOO1("2E", 0x02, ( {
+                                                              ident = 0;
+                                                       while (ilen > 0) {
+                                                                                                                                     ident = (ident << 8) | *p++;
+                                                                 ilen--;
+                                                                       }
+                                                                                                                                     if (ident > pc->para.chargeinfo) {
+                                                                                                                                     pc->para.chargeinfo = ident;
+                                                                                                                                     pc->st->l3.l3l4(pc->st, CC_CHARGE | INDICATION, pc);
+                                                                       }
+                                                                                                                                     if (pc->st->l3.debug & L3_DEB_CHARGE) {
+                                                                                                                                     l3_debug(pc->st, "charging info final %d", pc->para.chargeinfo);
+                                                                       }
+                                                                       }
+                                                                  ))))))
+                                                       break;
+                               }
+#undef FOO1
+
+                       }
+                       break;
+               case 2: /* return result */
+                       l3_debug(pc->st, "return result break");
+                       break;
+               case 3: /* return error */
+                       l3_debug(pc->st, "return error break");
+                       break;
+               default:
+                       l3_debug(pc->st, "default break");
+                       break;
        }
 }
-#endif 
+#endif
 
-static int 
-l3dss1_check_messagetype_validity(int mt) {
+static int
+l3dss1_check_messagetype_validity(int mt)
+{
 /* verify if a message type exists */
-       switch(mt) {
+       switch (mt) {
                case MT_ALERTING:
                case MT_CALL_PROCEEDING:
                case MT_CONNECT:
@@ -310,161 +325,240 @@ l3dss1_release_cmpl(struct l3_process *pc, u_char pr, void *arg)
        release_l3_process(pc);
 }
 
-#ifdef EXT_BEARER_CAPS
-
-u_char *EncodeASyncParams(u_char *p, u_char si2)
-{ // 7c 06 88  90 21 42 00 bb
-
-  p[0] = p[1] = 0; p[2] = 0x80;
-  if (si2 & 32) // 7 data bits
-    p[2] += 16;
-  else          // 8 data bits
-    p[2] +=24;
-
-  if (si2 & 16) // 2 stop bits
-    p[2] += 96;
-  else          // 1 stop bit
-    p[2] = 32;
-
-  if (si2 & 8)  // even parity
-    p[2] += 2;
-  else          // no parity
-    p[2] += 3;
-
-  switch (si2 & 0x07)
-  {
-    case 0:     p[0] = 66;      // 1200 bit/s
-                break;
-    case 1:     p[0] = 88;      // 1200/75 bit/s
-                break;
-    case 2:     p[0] = 87;      // 75/1200 bit/s
-                break;
-    case 3:     p[0] = 67;      // 2400 bit/s
-                break;
-    case 4:     p[0] = 69;      // 4800 bit/s
-                break;
-    case 5:     p[0] = 72;      // 9600 bit/s
-                break;
-    case 6:     p[0] = 73;      // 14400 bit/s
-                break;
-    case 7:     p[0] = 75;      // 19200 bit/s
-                break;
-  }
-  return p+3;
+#if EXT_BEARER_CAPS
+
+u_char *
+EncodeASyncParams(u_char * p, u_char si2)
+{                              // 7c 06 88  90 21 42 00 bb
+
+       p[0] = p[1] = 0;
+       p[2] = 0x80;
+       if (si2 & 32)           // 7 data bits
+
+               p[2] += 16;
+       else                    // 8 data bits
+
+               p[2] += 24;
+
+       if (si2 & 16)           // 2 stop bits
+
+               p[2] += 96;
+       else                    // 1 stop bit
+
+               p[2] = 32;
+
+       if (si2 & 8)            // even parity
+
+               p[2] += 2;
+       else                    // no parity
+
+               p[2] += 3;
+
+       switch (si2 & 0x07) {
+               case 0:
+                       p[0] = 66;      // 1200 bit/s
+
+                       break;
+               case 1:
+                       p[0] = 88;      // 1200/75 bit/s
+
+                       break;
+               case 2:
+                       p[0] = 87;      // 75/1200 bit/s
+
+                       break;
+               case 3:
+                       p[0] = 67;      // 2400 bit/s
+
+                       break;
+               case 4:
+                       p[0] = 69;      // 4800 bit/s
+
+                       break;
+               case 5:
+                       p[0] = 72;      // 9600 bit/s
+
+                       break;
+               case 6:
+                       p[0] = 73;      // 14400 bit/s
+
+                       break;
+               case 7:
+                       p[0] = 75;      // 19200 bit/s
+
+                       break;
+       }
+       return p + 3;
 }
 
-u_char EncodeSyncParams(u_char si2, u_char ai)
+u_char
+EncodeSyncParams(u_char si2, u_char ai)
 {
 
-  switch (si2)
-  {
-    case 0:     return ai + 2;  // 1200 bit/s
-    case 1:     return ai + 24; // 1200/75 bit/s
-    case 2:     return ai + 23; // 75/1200 bit/s
-    case 3:     return ai + 3;  // 2400 bit/s
-    case 4:     return ai + 5;  // 4800 bit/s
-    case 5:     return ai + 8;  // 9600 bit/s
-    case 6:     return ai + 9;  // 14400 bit/s
-    case 7:     return ai + 11; // 19200 bit/s
-    case 8:     return ai + 14; // 48000 bit/s
-    case 9:     return ai + 15; // 56000 bit/s
-    case 15:    return ai + 40; // negotiate bit/s
-    default:    break;
-  }
-  return ai;
+       switch (si2) {
+               case 0:
+                       return ai + 2;  // 1200 bit/s
+
+               case 1:
+                       return ai + 24;         // 1200/75 bit/s
+
+               case 2:
+                       return ai + 23;         // 75/1200 bit/s
+
+               case 3:
+                       return ai + 3;  // 2400 bit/s
+
+               case 4:
+                       return ai + 5;  // 4800 bit/s
+
+               case 5:
+                       return ai + 8;  // 9600 bit/s
+
+               case 6:
+                       return ai + 9;  // 14400 bit/s
+
+               case 7:
+                       return ai + 11;         // 19200 bit/s
+
+               case 8:
+                       return ai + 14;         // 48000 bit/s
+
+               case 9:
+                       return ai + 15;         // 56000 bit/s
+
+               case 15:
+                       return ai + 40;         // negotiate bit/s
+
+               default:
+                       break;
+       }
+       return ai;
 }
 
 
-static u_char DecodeASyncParams(u_char si2, u_char *p)
-{ u_char info;
-
-  switch (p[5])
-  {
-    case 66: // 1200 bit/s
-             break; // si2 bleibt gleich
-    case 88: // 1200/75 bit/s
-             si2 += 1;
-             break;
-    case 87: // 75/1200 bit/s
-             si2 += 2;
-             break;
-    case 67: // 2400 bit/s
-             si2 += 3;
-             break;
-    case 69: // 4800 bit/s
-             si2 += 4;
-             break;
-    case 72: // 9600 bit/s
-             si2 += 5;
-             break;
-    case 73: // 14400 bit/s
-             si2 += 6;
-             break;
-    case 75: // 19200 bit/s
-             si2 += 7;
-             break;
-  }
-
-  info = p[7] & 0x7f;
-  if ((info & 16) && (!(info & 8)))   // 7 data bits
-    si2 += 32;                        // else 8 data bits
-  if ((info & 96) == 96)              // 2 stop bits
-    si2 += 16;                        // else 1 stop bit
-  if ((info & 2) && (!(info & 1)))    // even parity
-    si2 += 8;                         // else no parity
-
-  return si2;
+static u_char
+DecodeASyncParams(u_char si2, u_char * p)
+{
+       u_char info;
+
+       switch (p[5]) {
+               case 66:        // 1200 bit/s
+
+                       break;  // si2 don't change
+
+               case 88:        // 1200/75 bit/s
+
+                       si2 += 1;
+                       break;
+               case 87:        // 75/1200 bit/s
+
+                       si2 += 2;
+                       break;
+               case 67:        // 2400 bit/s
+
+                       si2 += 3;
+                       break;
+               case 69:        // 4800 bit/s
+
+                       si2 += 4;
+                       break;
+               case 72:        // 9600 bit/s
+
+                       si2 += 5;
+                       break;
+               case 73:        // 14400 bit/s
+
+                       si2 += 6;
+                       break;
+               case 75:        // 19200 bit/s
+
+                       si2 += 7;
+                       break;
+       }
+
+       info = p[7] & 0x7f;
+       if ((info & 16) && (!(info & 8)))       // 7 data bits
+
+               si2 += 32;      // else 8 data bits
+
+       if ((info & 96) == 96)  // 2 stop bits
+
+               si2 += 16;      // else 1 stop bit
+
+       if ((info & 2) && (!(info & 1)))        // even parity
+
+               si2 += 8;       // else no parity
+
+       return si2;
 }
 
 
-static u_char DecodeSyncParams(u_char si2, u_char info)
+static u_char
+DecodeSyncParams(u_char si2, u_char info)
 {
-  info &= 0x7f;
-  switch (info)
-  {
-    case 40: // bit/s aushandeln  --- hat nicht geklappt, ai wird 165 statt 175!
-      return si2 + 15;
-    case 15: // 56000 bit/s --- hat nicht geklappt, ai wird 0 statt 169 !
-      return si2 + 9;
-    case 14: // 48000 bit/s
-      return si2 + 8;
-    case 11: // 19200 bit/s
-      return si2 + 7;
-    case 9:  // 14400 bit/s
-      return si2 + 6;
-    case 8:  // 9600  bit/s
-      return si2 + 5;
-    case 5:  // 4800  bit/s
-      return si2 + 4;
-    case 3:  // 2400  bit/s
-      return si2 + 3;
-    case 23: // 75/1200 bit/s
-      return si2 + 2;
-    case 24: // 1200/75 bit/s
-      return si2 + 1;
-    default: // 1200 bit/s
-      return si2;
-  }
+       info &= 0x7f;
+       switch (info) {
+               case 40:        // bit/s negotiation failed  ai := 165 not 175!
+
+                       return si2 + 15;
+               case 15:        // 56000 bit/s failed, ai := 0 not 169 !
+
+                       return si2 + 9;
+               case 14:        // 48000 bit/s
+
+                       return si2 + 8;
+               case 11:        // 19200 bit/s
+
+                       return si2 + 7;
+               case 9: // 14400 bit/s
+
+                       return si2 + 6;
+               case 8: // 9600  bit/s
+
+                       return si2 + 5;
+               case 5: // 4800  bit/s
+
+                       return si2 + 4;
+               case 3: // 2400  bit/s
+
+                       return si2 + 3;
+               case 23:        // 75/1200 bit/s
+
+                       return si2 + 2;
+               case 24:        // 1200/75 bit/s
+
+                       return si2 + 1;
+               default:        // 1200 bit/s
+
+                       return si2;
+       }
 }
 
-static u_char DecodeSI2(struct sk_buff *skb)
-{ u_char *p; //, *pend=skb->data + skb->len;
-
-        if ((p = findie(skb->data, skb->len, 0x7c, 0)))
-        {
-          switch (p[4] & 0x0f)
-          {
-            case 0x01:  if (p[1] == 0x04) // sync. Bitratenadaption
-                          return DecodeSyncParams(160, p[5]); // V.110/X.30
-                        else if (p[1] == 0x06) // async. Bitratenadaption
-                          return DecodeASyncParams(192, p);   // V.110/X.30
-                        break;
-            case 0x08:  // if (p[5] == 0x02) // sync. Bitratenadaption
-                          return DecodeSyncParams(176, p[5]); // V.120
-                        break;
-          }
-        }
-        return 0;
+static u_char
+DecodeSI2(struct sk_buff *skb)
+{
+       u_char *p;              //, *pend=skb->data + skb->len;
+
+       if ((p = findie(skb->data, skb->len, 0x7c, 0))) {
+               switch (p[4] & 0x0f) {
+                       case 0x01:
+                               if (p[1] == 0x04)       // sync. Bitratenadaption
+
+                                       return DecodeSyncParams(160, p[5]);     // V.110/X.30
+
+                               else if (p[1] == 0x06)  // async. Bitratenadaption
+
+                                       return DecodeASyncParams(192, p);       // V.110/X.30
+
+                               break;
+                       case 0x08:      // if (p[5] == 0x02) // sync. Bitratenadaption
+
+                               return DecodeSyncParams(176, p[5]);     // V.120
+
+                               break;
+               }
+       }
+       return 0;
 }
 
 #endif
@@ -490,7 +584,7 @@ l3dss1_setup_req(struct l3_process *pc, u_char pr,
        /*
         * Set Bearer Capability, Map info from 1TR6-convention to EDSS1
         */
-#ifdef HISAX_EURO_SENDCOMPLETE
+#if HISAX_EURO_SENDCOMPLETE
        *p++ = 0xa1;            /* complete indicator */
 #endif
        switch (pc->para.setup.si1) {
@@ -550,11 +644,11 @@ l3dss1_setup_req(struct l3_process *pc, u_char pr,
        msn = pc->para.setup.eazmsn;
        sub = NULL;
        sp = msn;
-       while (*sp) { 
+       while (*sp) {
                if ('.' == *sp) {
                        sub = sp;
                        *sp = 0;
-               } else 
+               } else
                        sp++;
        }
        if (*msn) {
@@ -571,20 +665,20 @@ l3dss1_setup_req(struct l3_process *pc, u_char pr,
        }
        if (sub) {
                *sub++ = '.';
-               *p++ = 0x6d; /* Calling party subaddress */
-               *p++ = strlen(sub) + 2;
+               *p++ = 0x6d;    /* Calling party subaddress */
+               *p++ = strlen(sub) + 2;
                *p++ = 0x80;    /* NSAP coded */
                *p++ = 0x50;    /* local IDI format */
-               while (*sub)
+               while (*sub)
                        *p++ = *sub++ & 0x7f;
        }
        sub = NULL;
        sp = teln;
-       while (*sp) { 
+       while (*sp) {
                if ('.' == *sp) {
                        sub = sp;
                        *sp = 0;
-               } else 
+               } else
                        sp++;
        }
        *p++ = 0x70;
@@ -596,33 +690,47 @@ l3dss1_setup_req(struct l3_process *pc, u_char pr,
 
        if (sub) {
                *sub++ = '.';
-               *p++ = 0x71; /* Called party subaddress */
-               *p++ = strlen(sub) + 2;
+               *p++ = 0x71;    /* Called party subaddress */
+               *p++ = strlen(sub) + 2;
                *p++ = 0x80;    /* NSAP coded */
                *p++ = 0x50;    /* local IDI format */
-               while (*sub)
+               while (*sub)
                        *p++ = *sub++ & 0x7f;
        }
-
-#ifdef EXT_BEARER_CAPS
-        if ((pc->para.setup.si2 >= 160) && (pc->para.setup.si2 <= 175))
-        { // sync. Bitratenadaption, V.110/X.30
-          *p++ = 0x7c; *p++ = 0x04; *p++ = 0x88; *p++ = 0x90; *p++ = 0x21;
-          *p++ = EncodeSyncParams(pc->para.setup.si2 - 160, 0x80);
-        }
-        else if ((pc->para.setup.si2 >= 176) && (pc->para.setup.si2 <= 191))
-        { // sync. Bitratenadaption, V.120
-          *p++ = 0x7c; *p++ = 0x05; *p++ = 0x88; *p++ = 0x90; *p++ = 0x28;
-          *p++ = EncodeSyncParams(pc->para.setup.si2 - 176, 0);
-          *p++ = 0x82;
-        }
-        else if (pc->para.setup.si2 >= 192)
-        { // async. Bitratenadaption, V.110/X.30
-          *p++ = 0x7c; *p++ = 0x06; *p++ = 0x88; *p++ = 0x90; *p++ = 0x21;
-          p = EncodeASyncParams(p, pc->para.setup.si2 - 192);
-        } else {
-               *p++ = 0x7c; *p++ = 0x02; *p++ = 0x88; *p++ = 0x90;
-        }
+#if EXT_BEARER_CAPS
+       if ((pc->para.setup.si2 >= 160) && (pc->para.setup.si2 <= 175)) {       // sync. Bitratenadaption, V.110/X.30
+
+               *p++ = 0x7c;
+               *p++ = 0x04;
+               *p++ = 0x88;
+               *p++ = 0x90;
+               *p++ = 0x21;
+               *p++ = EncodeSyncParams(pc->para.setup.si2 - 160, 0x80);
+       } else if ((pc->para.setup.si2 >= 176) && (pc->para.setup.si2 <= 191)) {        // sync. Bitratenadaption, V.120
+
+               *p++ = 0x7c;
+               *p++ = 0x05;
+               *p++ = 0x88;
+               *p++ = 0x90;
+               *p++ = 0x28;
+               *p++ = EncodeSyncParams(pc->para.setup.si2 - 176, 0);
+               *p++ = 0x82;
+       } else if (pc->para.setup.si2 >= 192) {         // async. Bitratenadaption, V.110/X.30
+
+               *p++ = 0x7c;
+               *p++ = 0x06;
+               *p++ = 0x88;
+               *p++ = 0x90;
+               *p++ = 0x21;
+               p = EncodeASyncParams(p, pc->para.setup.si2 - 192);
+#if HISAX_SEND_STD_LLC_IE
+       } else {
+               *p++ = 0x7c;
+               *p++ = 0x02;
+               *p++ = 0x88;
+               *p++ = 0x90;
+#endif
+       }
 #endif
        l = p - tmp;
        if (!(skb = l3_alloc_skb(l)))
@@ -722,30 +830,30 @@ l3dss1_alerting(struct l3_process *pc, u_char pr, void *arg)
 static void
 l3dss1_msg_without_setup(struct l3_process *pc, u_char pr, void *arg)
 {
-  /* This routine is called if here was no SETUP made (checks in dss1up and in
-   * l3dss1_setup) and a RELEASE_COMPLETE have to be sent with an error code
-   * MT_STATUS_ENQUIRE in the NULL state is handled too
-   */
+       /* This routine is called if here was no SETUP made (checks in dss1up and in
+        * l3dss1_setup) and a RELEASE_COMPLETE have to be sent with an error code
+        * MT_STATUS_ENQUIRE in the NULL state is handled too
+        */
        u_char tmp[16];
-       u_char *p=tmp;
+       u_char *p = tmp;
        int l;
        struct sk_buff *skb;
 
        switch (pc->para.cause) {
-         case  81: /* 0x51 invalid callreference */
-         case  88: /* 0x58 incomp destination */
-         case  96: /* 0x60 mandory IE missing */
-         case 101: /* 0x65 incompatible Callstate */
-               MsgHead(p, pc->callref, MT_RELEASE_COMPLETE);
-               *p++ = IE_CAUSE;
-               *p++ = 0x2;
-               *p++ = 0x80;
-               *p++ = pc->para.cause | 0x80;
-               break;
-         default:
-               printk(KERN_ERR "HiSax internal error l3dss1_msg_without_setup\n");
-               return;
-       }       
+               case 81:        /* 0x51 invalid callreference */
+               case 88:        /* 0x58 incomp destination */
+               case 96:        /* 0x60 mandory IE missing */
+               case 101:       /* 0x65 incompatible Callstate */
+                       MsgHead(p, pc->callref, MT_RELEASE_COMPLETE);
+                       *p++ = IE_CAUSE;
+                       *p++ = 0x2;
+                       *p++ = 0x80;
+                       *p++ = pc->para.cause | 0x80;
+                       break;
+               default:
+                       printk(KERN_ERR "HiSax internal error l3dss1_msg_without_setup\n");
+                       return;
+       }
        l = p - tmp;
        if (!(skb = l3_alloc_skb(l)))
                return;
@@ -757,7 +865,7 @@ l3dss1_msg_without_setup(struct l3_process *pc, u_char pr, void *arg)
 static void
 l3dss1_setup(struct l3_process *pc, u_char pr, void *arg)
 {
-        u_char *p, *ptmp[8];
+       u_char *p, *ptmp[8];
        int i;
        int bcfound = 0;
        char tmp[80];
@@ -765,9 +873,9 @@ l3dss1_setup(struct l3_process *pc, u_char pr, void *arg)
 
        /* ETS 300-104 1.3.4 and 1.3.5
         * we need to detect unknown inform. element from 0 to 7
-        */     
+        */
        p = skb->data;
-       for(i = 0; i < 8; i++)
+       for (i = 0; i < 8; i++)
                ptmp[i] = skb->data;
        if (findie(ptmp[1], skb->len, 0x01, 0)
            || findie(ptmp[2], skb->len, 0x02, 0)
@@ -775,15 +883,14 @@ l3dss1_setup(struct l3_process *pc, u_char pr, void *arg)
            || findie(ptmp[5], skb->len, 0x05, 0)
            || findie(ptmp[6], skb->len, 0x06, 0)
            || findie(ptmp[7], skb->len, 0x07, 0)) {
-               /* if ie is < 8 and not 0 nor 4, send RELEASE_COMPLETE 
-                * cause 0x60
-                */
-               pc->para.cause = 0x60;
+               /* if ie is < 8 and not 0 nor 4, send RELEASE_COMPLETE
+                * cause 0x60
+                */
+               pc->para.cause = 0x60;
                dev_kfree_skb(skb, FREE_READ);
-                       l3dss1_msg_without_setup(pc, pr, NULL);
+               l3dss1_msg_without_setup(pc, pr, NULL);
                return;
        }
-
        /*
         * Channel Identification
         */
@@ -796,8 +903,8 @@ l3dss1_setup(struct l3_process *pc, u_char pr, void *arg)
                        l3_debug(pc->st, "setup without bchannel");
        } else {
                if (pc->debug & L3_DEB_WARN)
-               l3_debug(pc->st, "setup without bchannel");
-               pc->para.cause = 0x60;
+                       l3_debug(pc->st, "setup without bchannel");
+               pc->para.cause = 0x60;
                dev_kfree_skb(skb, FREE_READ);
                l3dss1_msg_without_setup(pc, pr, NULL);
                return;
@@ -819,10 +926,10 @@ l3dss1_setup(struct l3_process *pc, u_char pr, void *arg)
                                /* Unrestricted digital information */
                                pc->para.setup.si1 = 7;
 /* JIM, 05.11.97 I wanna set service indicator 2 */
-#ifdef EXT_BEARER_CAPS
-                                pc->para.setup.si2 = DecodeSI2(skb);
-                                printk(KERN_DEBUG "HiSax: SI=%d, AI=%d\n",
-                                       pc->para.setup.si1, pc->para.setup.si2);
+#if EXT_BEARER_CAPS
+                               pc->para.setup.si2 = DecodeSI2(skb);
+                               printk(KERN_DEBUG "HiSax: SI=%d, AI=%d\n",
+                                pc->para.setup.si1, pc->para.setup.si2);
 #endif
                                break;
                        case 0x09:
@@ -844,9 +951,9 @@ l3dss1_setup(struct l3_process *pc, u_char pr, void *arg)
                if (pc->debug & L3_DEB_WARN)
                        l3_debug(pc->st, "setup without bearer capabilities");
                /* ETS 300-104 1.3.3 */
-               pc->para.cause = 0x60;
+               pc->para.cause = 0x60;
                dev_kfree_skb(skb, FREE_READ);
-                       l3dss1_msg_without_setup(pc, pr, NULL);
+               l3dss1_msg_without_setup(pc, pr, NULL);
                return;
        }
 
@@ -859,8 +966,8 @@ l3dss1_setup(struct l3_process *pc, u_char pr, void *arg)
        p = skb->data;
        if ((p = findie(p, skb->len, 0x71, 0))) {
                /* Called party subaddress */
-               if ((p[1]>=2) && (p[2]==0x80) && (p[3]==0x50)) {
-                       tmp[0]='.';
+               if ((p[1] >= 2) && (p[2] == 0x80) && (p[3] == 0x50)) {
+                       tmp[0] = '.';
                        iecpy(&tmp[1], p, 2);
                        strcat(pc->para.setup.eazmsn, tmp);
                } else if (pc->debug & L3_DEB_WARN)
@@ -884,24 +991,23 @@ l3dss1_setup(struct l3_process *pc, u_char pr, void *arg)
        p = skb->data;
        if ((p = findie(p, skb->len, 0x6d, 0))) {
                /* Calling party subaddress */
-               if ((p[1]>=2) && (p[2]==0x80) && (p[3]==0x50)) {
-                       tmp[0]='.';
+               if ((p[1] >= 2) && (p[2] == 0x80) && (p[3] == 0x50)) {
+                       tmp[0] = '.';
                        iecpy(&tmp[1], p, 2);
                        strcat(pc->para.setup.phone, tmp);
                } else if (pc->debug & L3_DEB_WARN)
                        l3_debug(pc->st, "wrong calling subaddress");
        }
-
        dev_kfree_skb(skb, FREE_READ);
 
        if (bcfound) {
                if ((pc->para.setup.si1 != 7) && (pc->debug & L3_DEB_WARN)) {
                        l3_debug(pc->st, "non-digital call: %s -> %s",
-                               pc->para.setup.phone, pc->para.setup.eazmsn);
+                           pc->para.setup.phone, pc->para.setup.eazmsn);
                }
                if ((pc->para.setup.si1 != 7) &&
-                       test_bit(FLG_PTP, &pc->st->l2.flag)) {
-                       pc->para.cause = 0x58;
+                   test_bit(FLG_PTP, &pc->st->l2.flag)) {
+                       pc->para.cause = 0x58;
                        l3dss1_msg_without_setup(pc, pr, NULL);
                        return;
                }
@@ -1013,8 +1119,8 @@ l3dss1_release(struct l3_process *pc, u_char pr, void *arg)
        }
        p = skb->data;
        if ((p = findie(p, skb->len, IE_FACILITY, 0))) {
-#ifdef HISAX_DE_AOC
-           l3dss1_parse_facility(pc,p);
+#if HISAX_DE_AOC
+               l3dss1_parse_facility(pc, p);
 #else
                p = NULL;
 #endif
@@ -1067,9 +1173,9 @@ l3dss1_status_enq(struct l3_process *pc, u_char pr, void *arg)
 static void
 l3dss1_status_req(struct l3_process *pc, u_char pr, void *arg)
 {
-  /* ETS 300-104 7.4.1, 8.4.1, 10.3.1, 11.4.1, 12.4.1, 13.4.1, 14.4.1...
-     if setup has been made and a non expected message type is received, we must send MT_STATUS cause 0x62  */
-        u_char tmp[16];
+       /* ETS 300-104 7.4.1, 8.4.1, 10.3.1, 11.4.1, 12.4.1, 13.4.1, 14.4.1...
+          if setup has been made and a non expected message type is received, we must send MT_STATUS cause 0x62  */
+       u_char tmp[16];
        u_char *p = tmp;
        int l;
        struct sk_buff *skb = arg;
@@ -1081,7 +1187,7 @@ l3dss1_status_req(struct l3_process *pc, u_char pr, void *arg)
        *p++ = IE_CAUSE;
        *p++ = 0x2;
        *p++ = 0x80;
-       *p++ = 0x62 | 0x80;             /* status sending */
+       *p++ = 0x62 | 0x80;     /* status sending */
 
        *p++ = 0x14;            /* CallState */
        *p++ = 0x1;
@@ -1104,10 +1210,10 @@ l3dss1_release_ind(struct l3_process *pc, u_char pr, void *arg)
 
        if ((p = findie(p, skb->len, IE_CALL_STATE, 0))) {
                p++;
-               if (1== *p++)
+               if (1 == *p++)
                        callState = *p;
        }
-       if(callState == 0) {
+       if (callState == 0) {
                /* ETS 300-104 7.6.1, 8.6.1, 10.6.1... and 16.1
                 * set down layer 3 without sending any message
                 */
@@ -1211,8 +1317,8 @@ static void
 l3dss1_t318(struct l3_process *pc, u_char pr, void *arg)
 {
        L3DelTimer(&pc->timer);
-       pc->para.cause = 0x66; /* Timer expiry */
-       pc->para.loc = 0; /* local */
+       pc->para.cause = 0x66;  /* Timer expiry */
+       pc->para.loc = 0;       /* local */
        pc->st->l3.l3l4(pc->st, CC_RESUME_ERR, pc);
        newl3state(pc, 19);
        l3dss1_message(pc, MT_RELEASE);
@@ -1223,8 +1329,8 @@ static void
 l3dss1_t319(struct l3_process *pc, u_char pr, void *arg)
 {
        L3DelTimer(&pc->timer);
-       pc->para.cause = 0x66; /* Timer expiry */
-       pc->para.loc = 0; /* local */
+       pc->para.cause = 0x66;  /* Timer expiry */
+       pc->para.loc = 0;       /* local */
        pc->st->l3.l3l4(pc->st, CC_SUSPEND_ERR, pc);
        newl3state(pc, 10);
 }
@@ -1252,30 +1358,30 @@ l3dss1_status(struct l3_process *pc, u_char pr, void *arg)
        if ((p = findie(p, skb->len, IE_CAUSE, 0))) {
                p++;
                l = *p++;
-               t += sprintf(t,"Status CR %x Cause:", pc->callref);
+               t += sprintf(t, "Status CR %x Cause:", pc->callref);
                while (l--) {
-                       cause = *p;
-                       t += sprintf(t," %2x",*p++);
+                       cause = *p;
+                       t += sprintf(t, " %2x", *p++);
                }
        } else
-               sprintf(t,"Status CR %x no Cause", pc->callref);
+               sprintf(t, "Status CR %x no Cause", pc->callref);
        l3_debug(pc->st, tmp);
        p = skb->data;
        t = tmp;
-       t += sprintf(t,"Status state %x ", pc->state);
+       t += sprintf(t, "Status state %x ", pc->state);
        if ((p = findie(p, skb->len, IE_CALL_STATE, 0))) {
                p++;
-               if (1== *p++) {
-                       callState = *p;
-                       t += sprintf(t,"peer state %x" , *p);
+               if (1 == *p++) {
+                       callState = *p;
+                       t += sprintf(t, "peer state %x", *p);
                } else
-                       t += sprintf(t,"peer state len error");
+                       t += sprintf(t, "peer state len error");
        } else
-               sprintf(t,"no peer state");
+               sprintf(t, "no peer state");
        l3_debug(pc->st, tmp);
-       if(((cause & 0x7f) == 0x6f) && (callState == 0)) {
-               /* ETS 300-104 7.6.1, 8.6.1, 10.6.1... 
-                * if received MT_STATUS with cause == 0x6f and call 
+       if (((cause & 0x7f) == 0x6f) && (callState == 0)) {
+               /* ETS 300-104 7.6.1, 8.6.1, 10.6.1...
+                * if received MT_STATUS with cause == 0x6f and call
                 * state == 0, then we must set down layer 3
                 */
                l3dss1_release_ind(pc, pr, arg);
@@ -1286,13 +1392,13 @@ l3dss1_status(struct l3_process *pc, u_char pr, void *arg)
 static void
 l3dss1_facility(struct l3_process *pc, u_char pr, void *arg)
 {
-        u_char *p;
+       u_char *p;
        struct sk_buff *skb = arg;
 
        p = skb->data;
        if ((p = findie(p, skb->len, IE_FACILITY, 0))) {
-#ifdef HISAX_DE_AOC
-           l3dss1_parse_facility(pc,p);
+#if HISAX_DE_AOC
+               l3dss1_parse_facility(pc, p);
 #else
                p = NULL;
 #endif
@@ -1305,21 +1411,21 @@ l3dss1_suspend_req(struct l3_process *pc, u_char pr, void *arg)
        struct sk_buff *skb;
        u_char tmp[32];
        u_char *p = tmp;
-       u_char i,l;
+       u_char i, l;
        u_char *msg = pc->chan->setup.phone;
 
        MsgHead(p, pc->callref, MT_SUSPEND);
-       
+
        *p++ = IE_CALLID;
        l = *msg++;
-       if (l && (l<=10)) { /* Max length 10 octets */
+       if (l && (l <= 10)) {   /* Max length 10 octets */
                *p++ = l;
-               for (i=0;i<l;i++)
+               for (i = 0; i < l; i++)
                        *p++ = *msg++;
        } else {
                l3_debug(pc->st, "SUS wrong CALLID len %d", l);
                return;
-        }
+       }
        l = p - tmp;
        if (!(skb = l3_alloc_skb(l)))
                return;
@@ -1369,21 +1475,21 @@ l3dss1_resume_req(struct l3_process *pc, u_char pr, void *arg)
        struct sk_buff *skb;
        u_char tmp[32];
        u_char *p = tmp;
-       u_char i,l;
+       u_char i, l;
        u_char *msg = pc->para.setup.phone;
 
        MsgHead(p, pc->callref, MT_RESUME);
-       
+
        *p++ = IE_CALLID;
        l = *msg++;
-       if (l && (l<=10)) { /* Max length 10 octets */
+       if (l && (l <= 10)) {   /* Max length 10 octets */
                *p++ = l;
-               for (i=0;i<l;i++)
+               for (i = 0; i < l; i++)
                        *p++ = *msg++;
        } else {
                l3_debug(pc->st, "RES wrong CALLID len %d", l);
                return;
-        }
+       }
        l = p - tmp;
        if (!(skb = l3_alloc_skb(l)))
                return;
@@ -1433,23 +1539,23 @@ l3dss1_resume_rej(struct l3_process *pc, u_char pr, void *arg)
        pc->st->l3.l3l4(pc->st, CC_RESUME_ERR, pc);
        release_l3_process(pc);
 }
-       
+
 static void
 l3dss1_global_restart(struct l3_process *pc, u_char pr, void *arg)
 {
        u_char tmp[32];
        u_char *p;
-       u_char ri, ch=0, chan=0;
+       u_char ri, ch = 0, chan = 0;
        int l;
        struct sk_buff *skb = arg;
        struct l3_process *up;
-       
+
        newl3state(pc, 2);
        L3DelTimer(&pc->timer);
        p = skb->data;
        if ((p = findie(p, skb->len, IE_RESTART_IND, 0))) {
-               ri = p[2];
-                       l3_debug(pc->st, "Restart %x", ri);
+               ri = p[2];
+               l3_debug(pc->st, "Restart %x", ri);
        } else {
                l3_debug(pc->st, "Restart without restart IE");
                ri = 0x86;
@@ -1458,17 +1564,17 @@ l3dss1_global_restart(struct l3_process *pc, u_char pr, void *arg)
        if ((p = findie(p, skb->len, IE_CHANNEL_ID, 0))) {
                chan = p[2] & 3;
                ch = p[2];
-               if (pc->st->l3.debug)
+               if (pc->st->l3.debug)
                        l3_debug(pc->st, "Restart for channel %d", chan);
        }
        dev_kfree_skb(skb, FREE_READ);
        newl3state(pc, 2);
        up = pc->st->l3.proc;
        while (up) {
-               if ((ri & 7)==7)
+               if ((ri & 7) == 7)
                        up->st->lli.l4l3(up->st, CC_RESTART | REQUEST, up);
                else if (up->para.bchannel == chan)
-                               up->st->lli.l4l3(up->st, CC_RESTART | REQUEST, up);
+                       up->st->lli.l4l3(up->st, CC_RESTART | REQUEST, up);
                up = up->next;
        }
        p = tmp;
@@ -1478,7 +1584,7 @@ l3dss1_global_restart(struct l3_process *pc, u_char pr, void *arg)
                *p++ = 1;
                *p++ = ch | 0x80;
        }
-       *p++ = 0x79; /* RESTART Ind */
+       *p++ = 0x79;            /* RESTART Ind */
        *p++ = 1;
        *p++ = ri;
        l = p - tmp;
@@ -1488,7 +1594,6 @@ l3dss1_global_restart(struct l3_process *pc, u_char pr, void *arg)
        newl3state(pc, 0);
        l3_msg(pc->st, DL_DATA | REQUEST, skb);
 }
-
 /* *INDENT-OFF* */
 static struct stateentry downstatelist[] =
 {
@@ -1597,34 +1702,24 @@ static int datasllen = sizeof(datastatelist) / sizeof(struct stateentry);
 static struct stateentry globalmes_list[] =
 {
        {ALL_STATES,
-         MT_STATUS, l3dss1_status},
+        MT_STATUS, l3dss1_status},
        {SBIT(0),
         MT_RESTART, l3dss1_global_restart},
 /*     {SBIT(1),
-        MT_RESTART_ACKNOWLEDGE, l3dss1_restart_ack},                                  
+        MT_RESTART_ACKNOWLEDGE, l3dss1_restart_ack},
 */
 };
 static int globalm_len = sizeof(globalmes_list) / sizeof(struct stateentry);
 
-#if 0
-static struct stateentry globalcmd_list[] =
-{
-       {ALL_STATES,
-         CC_STATUS | REQUEST, l3dss1_status_req},
-       {SBIT(0),
-        CC_RESTART | REQUEST, l3dss1_restart_req},
-};
-
-static int globalc_len = sizeof(globalcmd_list) / sizeof(struct stateentry);
-#endif
 /* *INDENT-ON* */
 
+
 static void
 global_handler(struct PStack *st, int mt, struct sk_buff *skb)
 {
        int i;
        struct l3_process *proc = st->l3.global;
-       
+
        for (i = 0; i < globalm_len; i++)
                if ((mt == globalmes_list[i].primitive) &&
                    ((1 << proc->state) & globalmes_list[i].state))
@@ -1668,18 +1763,18 @@ dss1up(struct PStack *st, int pr, void *arg)
        if (skb->data[0] != PROTO_DIS_EURO) {
                if (st->l3.debug & L3_DEB_PROTERR) {
                        l3_debug(st, "dss1up%sunexpected discriminator %x message len %d",
-                               (pr == (DL_DATA | INDICATION)) ? " " : "(broadcast) ",
-                               skb->data[0], skb->len);
+                                (pr == (DL_DATA | INDICATION)) ? " " : "(broadcast) ",
+                                skb->data[0], skb->len);
                }
                dev_kfree_skb(skb, FREE_READ);
                return;
        }
        cr = getcallref(skb->data);
        mt = skb->data[skb->data[1] + 2];
-       if (!cr) {                              /* Global CallRef */
+       if (!cr) {              /* Global CallRef */
                global_handler(st, mt, skb);
                return;
-       } else if (cr == -1) {                  /* Dummy Callref */
+       } else if (cr == -1) {  /* Dummy Callref */
                dev_kfree_skb(skb, FREE_READ);
                return;
        } else if (!(proc = getl3proc(st, cr))) {
@@ -1687,7 +1782,7 @@ dss1up(struct PStack *st, int pr, void *arg)
                 * this callreference is active
                 */
                if (mt == MT_SETUP) {
-               /* Setup creates a new transaction process */
+                       /* Setup creates a new transaction process */
                        if (!(proc = new_l3_process(st, cr))) {
                                /* May be to answer with RELEASE_COMPLETE and
                                 * CAUSE 0x2f "Resource unavailable", but this
@@ -1698,14 +1793,14 @@ dss1up(struct PStack *st, int pr, void *arg)
                        }
                } else if (mt == MT_STATUS) {
                        cause = 0;
-                       if((ptr = findie(skb->data, skb->len, IE_CAUSE, 0)) != NULL) {
-                                 ptr++;
-                                 if (*ptr++ == 2)
-                                       ptr++;
-                                 cause = *ptr & 0x7f;
+                       if ((ptr = findie(skb->data, skb->len, IE_CAUSE, 0)) != NULL) {
+                               ptr++;
+                               if (*ptr++ == 2)
+                                       ptr++;
+                               cause = *ptr & 0x7f;
                        }
                        callState = 0;
-                       if((ptr = findie(skb->data, skb->len, IE_CALL_STATE, 0)) != NULL) {
+                       if ((ptr = findie(skb->data, skb->len, IE_CALL_STATE, 0)) != NULL) {
                                ptr++;
                                if (*ptr++ == 2)
                                        ptr++;
@@ -1721,28 +1816,28 @@ dss1up(struct PStack *st, int pr, void *arg)
                                return;
                        } else {
                                /* ETS 300-104 part 2.4.2
-                                * if setup has not been made and a message type 
+                                * if setup has not been made and a message type
                                 * MT_STATUS is received with call state != 0,
                                 * we must send MT_RELEASE_COMPLETE cause 101
                                 */
                                dev_kfree_skb(skb, FREE_READ);
                                if ((proc = new_l3_process(st, cr))) {
-                                       proc->para.cause = 0x65; /* 101 */
+                                       proc->para.cause = 0x65;        /* 101 */
                                        l3dss1_msg_without_setup(proc, 0, NULL);
                                }
                                return;
                        }
-               } else if (mt == MT_RELEASE_COMPLETE){
+               } else if (mt == MT_RELEASE_COMPLETE) {
                        dev_kfree_skb(skb, FREE_READ);
                        return;
                } else {
                        /* ETS 300-104 part 2
-                        * if setup has not been made and a message type 
+                        * if setup has not been made and a message type
                         * (except MT_SETUP and RELEASE_COMPLETE) is received,
                         * we must send MT_RELEASE_COMPLETE cause 81 */
                        dev_kfree_skb(skb, FREE_READ);
                        if ((proc = new_l3_process(st, cr))) {
-                               proc->para.cause = 0x51; /* 81 */
+                               proc->para.cause = 0x51;        /* 81 */
                                l3dss1_msg_without_setup(proc, 0, NULL);
                        }
                        return;
@@ -1753,9 +1848,8 @@ dss1up(struct PStack *st, int pr, void *arg)
                 * if setup has been made and invalid message type is received,
                 * we must send MT_STATUS cause 0x62
                 */
-               mt = MT_INVALID;  /* sorry, not clean, but do the right thing ;-) */
+               mt = MT_INVALID;        /* sorry, not clean, but do the right thing ;-) */
        }
-
        for (i = 0; i < datasllen; i++)
                if ((mt == datastatelist[i].primitive) &&
                    ((1 << proc->state) & datastatelist[i].state))
@@ -1785,7 +1879,7 @@ dss1down(struct PStack *st, int pr, void *arg)
        struct l3_process *proc;
        struct Channel *chan;
 
-       if (((DL_ESTABLISH | REQUEST)== pr) || ((DL_RELEASE | REQUEST)== pr)) {
+       if (((DL_ESTABLISH | REQUEST) == pr) || ((DL_RELEASE | REQUEST) == pr)) {
                l3_msg(st, pr, NULL);
                return;
        } else if (((CC_SETUP | REQUEST) == pr) || ((CC_RESUME | REQUEST) == pr)) {
index 83a0991d8d7661b4c91c8dd1b030bd8a56d48b60..28277c528ae96d8afe06fcade16cee90fe28a349 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: netjet.c,v 1.1.2.7 1998/05/27 18:06:17 keil Exp $
+/* $Id: netjet.c,v 1.1.2.9 1998/09/30 22:24:02 keil Exp $
 
  * netjet.c     low level stuff for Traverse Technologie NETJet ISDN cards
  *
@@ -8,6 +8,12 @@
  *
  *
  * $Log: netjet.c,v $
+ * Revision 1.1.2.9  1998/09/30 22:24:02  keil
+ * Fix missing line in setstack*
+ *
+ * Revision 1.1.2.8  1998/09/27 13:06:56  keil
+ * Apply most changes from 2.1.X (HiSax 3.1)
+ *
  * Revision 1.1.2.7  1998/05/27 18:06:17  keil
  * HiSax 3.0
  *
@@ -53,7 +59,7 @@
 
 extern const char *CardType[];
 
-const char *NETjet_revision = "$Revision: 1.1.2.7 $";
+const char *NETjet_revision = "$Revision: 1.1.2.9 $";
 
 #define byteout(addr,val) outb(val,addr)
 #define bytein(addr) inb(addr)
@@ -338,14 +344,14 @@ static int make_raw_data(struct BCState *bcs) {
        u_int fcs;
        char tmp[64];
        
-       if (!bcs->hw.tiger.tx_skb) {
+       if (!bcs->tx_skb) {
                debugl1(bcs->cs, "tiger make_raw: NULL skb");
                return(1);
        }
        bcs->hw.tiger.sendbuf[s_cnt++] = HDLC_FLAG_VALUE;
        fcs = PPP_INITFCS;
-       for (i=0; i<bcs->hw.tiger.tx_skb->len; i++) {
-               val = bcs->hw.tiger.tx_skb->data[i];
+       for (i=0; i<bcs->tx_skb->len; i++) {
+               val = bcs->tx_skb->data[i];
                fcs = PPP_FCS (fcs, val);
                MAKE_RAW_BYTE;
        }
@@ -370,7 +376,7 @@ static int make_raw_data(struct BCState *bcs) {
        }
        if (bcs->cs->debug & L1_DEB_HSCX) {
                sprintf(tmp,"tiger make_raw: in %ld out %d.%d",
-                       bcs->hw.tiger.tx_skb->len, s_cnt, bitcnt);
+                       bcs->tx_skb->len, s_cnt, bitcnt);
                debugl1(bcs->cs,tmp);
        }
        if (bitcnt) {
@@ -381,7 +387,7 @@ static int make_raw_data(struct BCState *bcs) {
                bcs->hw.tiger.sendbuf[s_cnt++] = s_val;
        }
        bcs->hw.tiger.sendcnt = s_cnt;
-       bcs->tx_cnt -= bcs->hw.tiger.tx_skb->len;
+       bcs->tx_cnt -= bcs->tx_skb->len;
        bcs->hw.tiger.sp = bcs->hw.tiger.sendbuf;
        return(0);
 }
@@ -605,7 +611,7 @@ static void fill_dma(struct BCState *bcs)
        register u_int *p, *sp;
        register int cnt;
 
-       if (!bcs->hw.tiger.tx_skb)
+       if (!bcs->tx_skb)
                return;
        if (bcs->cs->debug & L1_DEB_HSCX) {
                sprintf(tmp,"tiger fill_dma1: c%d %4x", bcs->channel,
@@ -706,15 +712,15 @@ static void write_raw(struct BCState *bcs, u_int *buf, int cnt) {
                bcs->hw.tiger.sp += s_cnt;
                bcs->hw.tiger.sendp = p;
                if (!bcs->hw.tiger.sendcnt) {
-                       if (!bcs->hw.tiger.tx_skb) {
+                       if (!bcs->tx_skb) {
                                sprintf(tmp,"tiger write_raw: NULL skb s_cnt %d", s_cnt);
                                debugl1(bcs->cs, tmp);
                        } else {
                                if (bcs->st->lli.l1writewakeup &&
-                                       (PACKET_NOACK != bcs->hw.tiger.tx_skb->pkt_type))
-                                       bcs->st->lli.l1writewakeup(bcs->st, bcs->hw.tiger.tx_skb->len);
-                               dev_kfree_skb(bcs->hw.tiger.tx_skb, FREE_WRITE);
-                       bcs->hw.tiger.tx_skb = NULL;
+                                       (PACKET_NOACK != bcs->tx_skb->pkt_type))
+                                       bcs->st->lli.l1writewakeup(bcs->st, bcs->tx_skb->len);
+                               dev_kfree_skb(bcs->tx_skb, FREE_WRITE);
+                               bcs->tx_skb = NULL;
                        }
                        test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag);
                        bcs->hw.tiger.free = cnt - s_cnt;
@@ -724,7 +730,7 @@ static void write_raw(struct BCState *bcs, u_int *buf, int cnt) {
                                test_and_clear_bit(BC_FLG_HALF, &bcs->Flag);
                                test_and_set_bit(BC_FLG_NOFRAME, &bcs->Flag);
                        }
-                       if ((bcs->hw.tiger.tx_skb = skb_dequeue(&bcs->squeue))) {
+                       if ((bcs->tx_skb = skb_dequeue(&bcs->squeue))) {
                                fill_dma(bcs);
                        } else {
                                mask ^= 0xffffffff;
@@ -797,28 +803,28 @@ tiger_l2l1(struct PStack *st, int pr, void *arg)
                case (PH_DATA | REQUEST):
                        save_flags(flags);
                        cli();
-                       if (st->l1.bcs->hw.tiger.tx_skb) {
+                       if (st->l1.bcs->tx_skb) {
                                skb_queue_tail(&st->l1.bcs->squeue, skb);
                                restore_flags(flags);
                        } else {
-                               st->l1.bcs->hw.tiger.tx_skb = skb;
+                               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->hw.tiger.tx_skb) {
+                       if (st->l1.bcs->tx_skb) {
                                printk(KERN_WARNING "tiger_l2l1: this shouldn't happen\n");
                                break;
                        }
                        save_flags(flags);
                        cli();
-                       st->l1.bcs->hw.tiger.tx_skb = skb;
+                       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->hw.tiger.tx_skb) {
+                       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
@@ -827,12 +833,16 @@ tiger_l2l1(struct PStack *st, int pr, void *arg)
                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);
-                       st->l1.l1l2(st, PH_ACTIVATE | CONFIRM, NULL);
+                       l1_msg_b(st, pr, arg);
                        break;
                case (PH_DEACTIVATE | REQUEST):
-                       if (!test_bit(BC_FLG_BUSY, &st->l1.bcs->Flag))
-                               mode_tiger(st->l1.bcs, 0, 0);
+                       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_tiger(st->l1.bcs, 0, st->l1.bc);
+                       st->l1.l1l2(st, PH_DEACTIVATE | CONFIRM, NULL);
                        break;
        }
 }
@@ -841,7 +851,7 @@ tiger_l2l1(struct PStack *st, int pr, void *arg)
 void
 close_tigerstate(struct BCState *bcs)
 {
-       mode_tiger(bcs, 0, 0);
+       mode_tiger(bcs, 0, bcs->channel);
        if (test_and_clear_bit(BC_FLG_INIT, &bcs->Flag)) {
                if (bcs->hw.tiger.rcvbuf) {
                        kfree(bcs->hw.tiger.rcvbuf);
@@ -853,26 +863,24 @@ close_tigerstate(struct BCState *bcs)
                }
                discard_queue(&bcs->rqueue);
                discard_queue(&bcs->squeue);
-               if (bcs->hw.tiger.tx_skb) {
-                       dev_kfree_skb(bcs->hw.tiger.tx_skb, FREE_WRITE);
-                       bcs->hw.tiger.tx_skb = NULL;
+               if (bcs->tx_skb) {
+                       dev_kfree_skb(bcs->tx_skb, FREE_WRITE);
+                       bcs->tx_skb = NULL;
                        test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag);
                }
        }
 }
 
 static int
-open_tigerstate(struct IsdnCardState *cs, int bc)
+open_tigerstate(struct IsdnCardState *cs, struct BCState *bcs)
 {
-       struct BCState *bcs = cs->bcs + bc;
-
        if (!test_and_set_bit(BC_FLG_INIT, &bcs->Flag)) {
-               if (!(bcs->hw.tiger.rcvbuf = kmalloc(HSCX_BUFMAX, GFP_KERNEL))) {
+               if (!(bcs->hw.tiger.rcvbuf = kmalloc(HSCX_BUFMAX, GFP_ATOMIC))) {
                        printk(KERN_WARNING
                               "HiSax: No memory for tiger.rcvbuf\n");
                        return (1);
                }
-               if (!(bcs->hw.tiger.sendbuf = kmalloc(RAW_BUFMAX, GFP_KERNEL))) {
+               if (!(bcs->hw.tiger.sendbuf = kmalloc(RAW_BUFMAX, GFP_ATOMIC))) {
                        printk(KERN_WARNING
                               "HiSax: No memory for tiger.sendbuf\n");
                        return (1);
@@ -880,7 +888,7 @@ open_tigerstate(struct IsdnCardState *cs, int bc)
                skb_queue_head_init(&bcs->rqueue);
                skb_queue_head_init(&bcs->squeue);
        }
-       bcs->hw.tiger.tx_skb = NULL;
+       bcs->tx_skb = NULL;
        bcs->hw.tiger.sendcnt = 0;
        test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag);
        bcs->event = 0;
@@ -891,12 +899,14 @@ open_tigerstate(struct IsdnCardState *cs, int bc)
 int
 setstack_tiger(struct PStack *st, struct BCState *bcs)
 {
-       if (open_tigerstate(st->l1.hardware, bcs->channel))
+       bcs->channel = st->l1.bc;
+       if (open_tigerstate(st->l1.hardware, bcs))
                return (-1);
        st->l1.bcs = bcs;
        st->l2.l2l1 = tiger_l2l1;
        setstack_manager(st);
        bcs->st = st;
+       setstack_l1_B(st);
        return (0);
 }
 
index d754c41429130c34f0af5434ecbb25227e6de147..b9a5a3e73485c9e397275daa127d7ebf338f76e5 100644 (file)
@@ -1,11 +1,12 @@
-/* $Id: sedlbauer.c,v 1.1.2.5 1998/04/08 21:58:44 keil Exp $
+/* $Id: sedlbauer.c,v 1.1.2.8 1998/09/30 22:28:10 keil Exp $
 
  * sedlbauer.c  low level stuff for Sedlbauer cards
- *              includes Support for the Sedlbauer Speed Star 
- *              derived from the original file dynalink.c from Karsten Keil
+ *              includes support for the Sedlbauer Speed Star 
+ *              and support for the Sedlbauer ISDN-Controller PC/104
+ *              derived from the original file asuscom.c from Karsten Keil
  *
  * Copyright (C) 1997,1998 Marcus Niemann (for the modifications to
- *                                         the original file dynalink.c)
+ *                                         the original file asuscom.c)
  *
  * Author     Marcus Niemann (niemann@www-bib.fh-bielefeld.de)
  *
  *            Edgar Toernig
  *
  * $Log: sedlbauer.c,v $
+ * Revision 1.1.2.8  1998/09/30 22:28:10  keil
+ * more work for isar support
+ *
+ * Revision 1.1.2.7  1998/09/27 13:07:01  keil
+ * Apply most changes from 2.1.X (HiSax 3.1)
+ *
+ * Revision 1.1.2.6  1998/09/12 18:44:06  niemann
+ * Added new card: Sedlbauer ISDN-Controller PC/104
+ *
  * Revision 1.1.2.5  1998/04/08 21:58:44  keil
  * New init code
  *
 #define __NO_VERSION__
 #include "hisax.h"
 #include "isac.h"
+#include "ipac.h"
 #include "hscx.h"
 #include "isdnl1.h"
 
 extern const char *CardType[];
 
-const char *Sedlbauer_revision = "$Revision: 1.1.2.5 $";
+const char *Sedlbauer_revision = "$Revision: 1.1.2.8 $";
 
 const char *Sedlbauer_Types[] =
-{"None", "Speed Card", "Speed Win", "Speed Star"};
+{"None", "Speed Card", "Speed Win", "Speed Star", "Speed Fax+", "ISDN PC/104"};
  
 #define SEDL_SPEED_CARD 1
 #define SEDL_SPEED_WIN  2
 #define SEDL_SPEED_STAR 3
+#define SEDL_SPEED_FAX 4
+#define SEDL_SPEED_PC104 5
 
 #define byteout(addr,val) outb(val,addr)
 #define bytein(addr) inb(addr)
@@ -66,6 +79,9 @@ const char *Sedlbauer_Types[] =
 #define SEDL_PCMCIA_HSCX       2
 #define SEDL_PCMCIA_ADR                4
 
+#define SEDL_PC104_ADR         0
+#define SEDL_PC104_IPAC        2
+
 #define SEDL_RESET      0x3    /* same as DOS driver */
 
 static inline u_char
@@ -138,6 +154,29 @@ WriteISACfifo(struct IsdnCardState *cs, u_char * data, int size)
        writefifo(cs->hw.sedl.adr, cs->hw.sedl.isac, 0, data, size);
 }
 
+static u_char
+ReadISAC_IPAC(struct IsdnCardState *cs, u_char offset)
+{
+        return (readreg(cs->hw.sedl.adr, cs->hw.sedl.isac, offset|0x80));}
+
+static void
+WriteISAC_IPAC(struct IsdnCardState *cs, u_char offset, u_char value)
+{
+        writereg(cs->hw.sedl.adr, cs->hw.sedl.isac, offset|0x80, value);
+}
+
+static void
+ReadISACfifo_IPAC(struct IsdnCardState *cs, u_char * data, int size)
+{
+        readfifo(cs->hw.sedl.adr, cs->hw.sedl.isac, 0x80, data, size);
+}
+
+static void
+WriteISACfifo_IPAC(struct IsdnCardState *cs, u_char * data, int size)
+{
+        writefifo(cs->hw.sedl.adr, cs->hw.sedl.isac, 0x80, data, size);
+}
+
 static u_char
 ReadHSCX(struct IsdnCardState *cs, int hscx, u_char offset)
 {
@@ -223,6 +262,55 @@ sedlbauer_interrupt(int intno, void *dev_id, struct pt_regs *regs)
        }
 }
 
+static void
+sedlbauer_interrupt_ipac(int intno, void *dev_id, struct pt_regs *regs)
+{
+       struct IsdnCardState *cs = dev_id;
+       u_char ista, val, icnt = 20;
+       char   tmp[64];
+
+       if (!cs) {
+               printk(KERN_WARNING "Sedlbauer: Spurious interrupt!\n");
+               return;
+       }
+       ista = readreg(cs->hw.sedl.adr, cs->hw.sedl.isac, IPAC_ISTA);
+Start_IPAC:
+       if (cs->debug & L1_DEB_IPAC) {
+               sprintf(tmp, "IPAC ISTA %02X", ista);
+               debugl1(cs, tmp);
+       }
+       if (ista & 0x0f) {
+               val = readreg(cs->hw.sedl.adr, cs->hw.sedl.hscx, HSCX_ISTA + 0x40);
+               if (ista & 0x01)
+                       val |= 0x01;
+               if (ista & 0x04)
+                       val |= 0x02;
+               if (ista & 0x08)
+                       val |= 0x04;
+               if (val)
+                       hscx_int_main(cs, val);
+       }
+       if (ista & 0x20) {
+               val = 0xfe & readreg(cs->hw.sedl.adr, cs->hw.sedl.isac, ISAC_ISTA | 0x80);
+               if (val) {
+                       isac_interrupt(cs, val);
+               }
+       }
+       if (ista & 0x10) {
+               val = 0x01;
+               isac_interrupt(cs, val);
+       }
+       ista  = readreg(cs->hw.sedl.adr, cs->hw.sedl.isac, IPAC_ISTA);
+       if ((ista & 0x3f) && icnt) {
+               icnt--;
+               goto Start_IPAC;
+       }
+       if (!icnt)
+               printk(KERN_WARNING "Sedlbauer IRQ LOOP\n");
+       writereg(cs->hw.sedl.adr, cs->hw.sedl.isac, IPAC_MASK, 0xFF);
+       writereg(cs->hw.sedl.adr, cs->hw.sedl.isac, IPAC_MASK, 0xC0);
+}
+
 void
 release_io_sedlbauer(struct IsdnCardState *cs)
 {
@@ -237,17 +325,33 @@ reset_sedlbauer(struct IsdnCardState *cs)
 {
        long flags;
 
-       if (cs->typ != ISDN_CTYPE_SEDLBAUER_PCMCIA) {
-               byteout(cs->hw.sedl.reset_on, SEDL_RESET);      /* Reset On */
+       printk(KERN_INFO "Sedlbauer %s: resetting card\n",
+               Sedlbauer_Types[cs->subtyp]);
+       if (cs->subtyp != SEDL_SPEED_STAR) {
+               if (cs->subtyp == SEDL_SPEED_PC104)
+                       writereg(cs->hw.sedl.adr, cs->hw.sedl.isac, IPAC_POTA2, 0x20);
+               else
+                       byteout(cs->hw.sedl.reset_on, SEDL_RESET);      /* Reset On */
                save_flags(flags);
                sti();
                current->state = TASK_INTERRUPTIBLE;
                current->timeout = jiffies + 1;
                schedule();
-               byteout(cs->hw.sedl.reset_off, 0);      /* Reset Off */
+               if (cs->subtyp == SEDL_SPEED_PC104)
+                       writereg(cs->hw.sedl.adr, cs->hw.sedl.isac, IPAC_POTA2, 0x0);
+               else
+                       byteout(cs->hw.sedl.reset_off, 0);      /* Reset Off */
                current->state = TASK_INTERRUPTIBLE;
                current->timeout = jiffies + 1;
                schedule();
+               if (cs->subtyp == SEDL_SPEED_PC104) {
+                       writereg(cs->hw.sedl.adr, cs->hw.sedl.isac, IPAC_CONF, 0x0);
+                       writereg(cs->hw.sedl.adr, cs->hw.sedl.isac, IPAC_ACFG, 0xff);
+                       writereg(cs->hw.sedl.adr, cs->hw.sedl.isac, IPAC_AOE, 0x0);
+                       writereg(cs->hw.sedl.adr, cs->hw.sedl.isac, IPAC_MASK, 0xc0);
+                       writereg(cs->hw.sedl.adr, cs->hw.sedl.isac, IPAC_PCFG, 0x12);
+               }
+
                restore_flags(flags);
        }
 }
@@ -263,8 +367,13 @@ Sedl_card_msg(struct IsdnCardState *cs, int mt, void *arg)
                        release_io_sedlbauer(cs);
                        return(0);
                case CARD_SETIRQ:
-                       return(request_irq(cs->irq, &sedlbauer_interrupt,
+                       if (cs->subtyp == SEDL_SPEED_PC104) {
+                               return(request_irq(cs->irq, &sedlbauer_interrupt_ipac,
                                        I4L_IRQ_FLAG, "HiSax", cs));
+                       } else {
+                               return(request_irq(cs->irq, &sedlbauer_interrupt,
+                                       I4L_IRQ_FLAG, "HiSax", cs));
+                       }
                case CARD_INIT:
                        inithscxisac(cs, 3);
                        return(0);
@@ -277,7 +386,7 @@ Sedl_card_msg(struct IsdnCardState *cs, int mt, void *arg)
 __initfunc(int
 setup_sedlbauer(struct IsdnCard *card))
 {
-       int bytecnt;
+       int bytecnt, val;
        struct IsdnCardState *cs = card->cs;
        char tmp[64];
 
@@ -310,44 +419,58 @@ setup_sedlbauer(struct IsdnCard *card))
        /* 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. */
-       if (cs->typ != ISDN_CTYPE_SEDLBAUER_PCMCIA &&
-          check_region((cs->hw.sedl.cfg_reg), bytecnt)) {
+       if ((cs->typ != ISDN_CTYPE_SEDLBAUER_PCMCIA) &&
+               check_region((cs->hw.sedl.cfg_reg), bytecnt)) {
                printk(KERN_WARNING
-                      "HiSax: %s config port %x-%x already in use\n",
-                      CardType[card->typ],
-                      cs->hw.sedl.cfg_reg,
-                      cs->hw.sedl.cfg_reg + bytecnt);
-               return (0);
+                       "HiSax: %s config port %x-%x already in use\n",
+                       CardType[card->typ],
+                       cs->hw.sedl.cfg_reg,
+                       cs->hw.sedl.cfg_reg + bytecnt);
+                       return (0);
        } else {
                request_region(cs->hw.sedl.cfg_reg, bytecnt, "sedlbauer isdn");
        }
 
        printk(KERN_INFO
-              "Sedlbauer: defined at 0x%x IRQ %d\n",
+              "Sedlbauer: defined at 0x%x-0x%x IRQ %d\n",
               cs->hw.sedl.cfg_reg,
+              cs->hw.sedl.cfg_reg + bytecnt,
               cs->irq);
-       printk(KERN_WARNING
-                      "Sedlbauer %s uses ports 0x%x-0x%x\n",
-                      Sedlbauer_Types[cs->subtyp],
-                      cs->hw.sedl.cfg_reg,
-                      cs->hw.sedl.cfg_reg + bytecnt);
-
-       printk(KERN_INFO "Sedlbauer: resetting card\n");
-       reset_sedlbauer(cs);
-       cs->readisac = &ReadISAC;
-       cs->writeisac = &WriteISAC;
-       cs->readisacfifo = &ReadISACfifo;
-       cs->writeisacfifo = &WriteISACfifo;
+
        cs->BC_Read_Reg = &ReadHSCX;
        cs->BC_Write_Reg = &WriteHSCX;
        cs->BC_Send_Data = &hscx_fill_fifo;
        cs->cardmsg = &Sedl_card_msg;
-       ISACVersion(cs, "Sedlbauer:");
-       if (HscxVersion(cs, "Sedlbauer:")) {
-               printk(KERN_WARNING
-                   "Sedlbauer: wrong HSCX versions check IO address\n");
-               release_io_sedlbauer(cs);
-               return (0);
+       
+       val = readreg(cs->hw.sedl.cfg_reg + SEDL_PC104_ADR,
+                cs->hw.sedl.cfg_reg + SEDL_PC104_IPAC, IPAC_ID);
+        if (val == 1) {
+                cs->subtyp = SEDL_SPEED_PC104;
+                cs->hw.sedl.adr  = cs->hw.sedl.cfg_reg + SEDL_PC104_ADR;
+                cs->hw.sedl.isac = cs->hw.sedl.cfg_reg + SEDL_PC104_IPAC;
+                cs->hw.sedl.hscx = cs->hw.sedl.cfg_reg + SEDL_PC104_IPAC;
+                test_and_set_bit(HW_IPAC, &cs->HW_Flags);
+                cs->readisac = &ReadISAC_IPAC;
+                cs->writeisac = &WriteISAC_IPAC;
+                cs->readisacfifo = &ReadISACfifo_IPAC;
+                cs->writeisacfifo = &WriteISACfifo_IPAC;
+                printk(KERN_INFO "Sedlbauer %s: IPAC version %x\n",
+                       Sedlbauer_Types[cs->subtyp], val);
+               reset_sedlbauer(cs);
+       } else {
+               cs->readisac = &ReadISAC;
+               cs->writeisac = &WriteISAC;
+               cs->readisacfifo = &ReadISACfifo;
+               cs->writeisacfifo = &WriteISACfifo;
+               ISACVersion(cs, "Sedlbauer:");
+               if (HscxVersion(cs, "Sedlbauer:")) {
+                       printk(KERN_WARNING
+                               "Sedlbauer %s: wrong HSCX versions check IO address\n",
+                               Sedlbauer_Types[cs->subtyp]);
+                       release_io_sedlbauer(cs);
+                       return (0);
+               }
+               reset_sedlbauer(cs);
        }
        return (1);
 }
index 18544d1a5dcb054d8b1baf94b78437be2fbdbe16..2c3a6b26b199f73525b35aaff902a1a09a5e1812 100644 (file)
@@ -1,19 +1,15 @@
 /* eepro.c: Intel EtherExpress Pro/10 device driver for Linux. */
 /*
-       Written 1994, 1995,1996 by Bao C. Ha.
-       Last Update, 2/7/98, Phillip R. Jaenke
+       Written 1994-1998 by Bao C. Ha.
 
-       Copyright (C) 1994, 1995,1996 by Bao C. Ha.
+       Copyright (C) 1994-1998 by Bao C. Ha.
 
        This software may be used and distributed
        according to the terms of the GNU Public License,
        incorporated herein by reference.
 
-       The author may be reached at bao.ha@srs.gov 
-       or 418 Hastings Place, Martinez, GA 30907.
-
-       Phillip R. Jaenke may be reached at prj@nls.net
-       or P.O. Box 413, Twinsburg, OH 44087, ATTN: Linux
+       The author may be reached at bao@hacom.net 
+       or Hacom, 2477 Wrightsboro Rd., Augusta, GA 30904.
 
        Things remaining to do:
        Better record keeping of errors.
        This is a compatibility hardware problem.
 
        Versions:
-       
-       0.10    Added several I/O addresses previously not included.
-               (PRJ, 2/7/98)
+
+       0.10c   Some cosmetic changes. (9/28/98, BCH)
+
+        0.10b  Should work now with (some) Pro/10+. At least for 
+               me (and my two cards) it does. _No_ guarantee for 
+               function with non-Pro/10+ cards! (don't have any)
+               (RMC, 9/11/96)
+
+       0.10    Added support for the Etherexpress Pro/10+.  The
+               IRQ map was changed significantly from the old
+               pro/10.  The new interrupt map was provided by
+               Rainer M. Canavan (Canavan@Zeus.cs.bonn.edu).
+               (BCH, 9/3/96)
 
        0.09    Fixed a race condition in the transmit algorithm,
                which causes crashes under heavy load with fast
@@ -67,7 +73,7 @@
 */
 
 static const char *version =
-       "eepro.c: v0.10 7/31/96 Bao C. Ha (bao.ha@srs.gov)\n";
+       "eepro.c: v0.10c 9/28/98 Bao C. Ha (bao@hacom.net)\n";
 
 #include <linux/module.h>
 
@@ -113,22 +119,26 @@ static const char *version =
 #include <linux/etherdevice.h>
 #include <linux/skbuff.h>
 
-
 /* First, a few definitions that the brave might change. */
+
 /* A zero-terminated list of I/O addresses to be probed. */
 static unsigned int eepro_portlist[] =
-   { 0x200, 0x240, 0x260, 0x280, 0x2C0, 0x300, 0x310, 0x320, 0x340, 0x360, 0};
+   { 0x300, 0x240, 0x280, 0x2C0, 0x200, 0x320, 0x340, 0x360, 0};
 
 /* use 0 for production, 1 for verification, >2 for debug */
+
 #ifndef NET_DEBUG
-#define NET_DEBUG 3
+#define NET_DEBUG 1
 #endif
+
 static unsigned int net_debug = NET_DEBUG;
 
 /* The number of low I/O ports used by the ethercard. */
+
 #define EEPRO_IO_EXTENT        16
 
 /* Different 82595 chips */
+
 #define        LAN595          0
 #define        LAN595TX        1
 #define        LAN595FX        2
@@ -140,18 +150,29 @@ struct eepro_local {
        unsigned tx_start; /* start of the transmit chain */
        int tx_last;  /* pointer to last packet in the transmit chain */
        unsigned tx_end;   /* end of the transmit chain (plus 1) */
-       int eepro;      /* a flag, TRUE=1 for the EtherExpress Pro/10,
-                          FALSE = 0 for other 82595-based lan cards. */
+       int eepro;      /* 1 for the EtherExpress Pro/10,
+                          2 for the EtherExpress Pro/10+,
+                          0 for other 82595-based lan cards. */
        int version;    /* a flag to indicate if this is a TX or FX
                                   version of the 82595 chip. */
        int stepping;
 };
 
 /* The station (ethernet) address prefix, used for IDing the board. */
-#define SA_ADDR0 0x00
+
+#define SA_ADDR0 0x00  /* Etherexpress Pro/10 */
 #define SA_ADDR1 0xaa
 #define SA_ADDR2 0x00
 
+#define SA2_ADDR0 0x00 /* Etherexpress Pro/10+ */
+#define SA2_ADDR1 0xa0
+#define SA2_ADDR2 0xc9
+
+#define SA3_ADDR0 0x00 /* more Etherexpress Pro/10+ */
+#define SA3_ADDR1 0xaa
+#define SA3_ADDR2 0x00
+#define SA3_ADDR3 0xc9
+
 /* Index to functions, as function prototypes. */
 
 extern int eepro_probe(struct device *dev);    
@@ -200,14 +221,18 @@ it is reset to the default of 24K, and, hence, 8K for the trasnmit
 buffer (transmit-buffer = 32K - receive-buffer).
 
 */
+
 #define        RAM_SIZE        0x8000
 #define        RCV_HEADER      8
 #define RCV_RAM         0x6000  /* 24KB default for RCV buffer */
 #define RCV_LOWER_LIMIT 0x00    /* 0x0000 */
+
 /* #define RCV_UPPER_LIMIT ((RCV_RAM - 2) >> 8) */    /* 0x5ffe */
 #define RCV_UPPER_LIMIT (((rcv_ram) - 2) >> 8)   
+
 /* #define XMT_RAM         (RAM_SIZE - RCV_RAM) */    /* 8KB for XMT buffer */
 #define XMT_RAM         (RAM_SIZE - (rcv_ram))    /* 8KB for XMT buffer */
+
 /* #define XMT_LOWER_LIMIT (RCV_RAM >> 8) */  /* 0x6000 */
 #define XMT_LOWER_LIMIT ((rcv_ram) >> 8) 
 #define XMT_UPPER_LIMIT ((RAM_SIZE - 2) >> 8)   /* 0x7ffe */
@@ -228,6 +253,7 @@ buffer (transmit-buffer = 32K - receive-buffer).
 #define        BANK2_SELECT    0x80            
 
 /* Bank 0 registers */
+
 #define        COMMAND_REG     0x00    /* Register 0 */
 #define        MC_SETUP        0x03
 #define        XMT_CMD         0x04
@@ -263,6 +289,7 @@ buffer (transmit-buffer = 32K - receive-buffer).
 #define        IO_PORT_32_BIT  0x0c
 
 /* Bank 1 registers */
+
 #define        REG1    0x01
 #define        WORD_WIDTH      0x02
 #define        INT_ENABLE      0x80
@@ -273,6 +300,7 @@ buffer (transmit-buffer = 32K - receive-buffer).
 #define        XMT_UPPER_LIMIT_REG     0x0b
 
 /* Bank 2 registers */
+
 #define        XMT_Chain_Int   0x20    /* Interrupt at the end of the transmit chain */
 #define        XMT_Chain_ErrStop       0x40 /* Interrupt at the end of the chain even if there are errors */
 #define        RCV_Discard_BadFrame    0x80 /* Throw bad frames away, and continue to receive others */
@@ -285,7 +313,7 @@ buffer (transmit-buffer = 32K - receive-buffer).
 #define        REG13           0x0d
 #define        FDX             0x00
 #define        A_N_ENABLE      0x02
-       
+
 #define        I_ADD_REG0      0x04
 #define        I_ADD_REG1      0x05
 #define        I_ADD_REG2      0x06
@@ -299,20 +327,26 @@ buffer (transmit-buffer = 32K - receive-buffer).
 #define EEDI 0x04
 #define EEDO 0x08
 
+/* Check for a network adaptor of this type, and return '0' if one exists.
 
-/* Check for a network adaptor of this type, and return '0' iff one exists.
    If dev->base_addr == 0, probe all likely locations.
    If dev->base_addr == 1, always return failure.
    If dev->base_addr == 2, allocate space for the device and return success
    (detachable devices only).
+
    */
+
 #ifdef HAVE_DEVLIST
+
 /* Support for a alternate probe manager, which will eliminate the
    boilerplate below. */
+
 struct netdev_entry netcard_drv =
 {"eepro", eepro_probe1, EEPRO_IO_EXTENT, eepro_portlist};
+
 #else
-int
+
+int 
 eepro_probe(struct device *dev)
 {
        int i;
@@ -327,6 +361,7 @@ eepro_probe(struct device *dev)
                int ioaddr = eepro_portlist[i];
                if (check_region(ioaddr, EEPRO_IO_EXTENT))
                        continue;
+
                if (eepro_probe1(dev, ioaddr) == 0)
                        return 0;
        }
@@ -339,24 +374,23 @@ eepro_probe(struct device *dev)
    probes on the ISA bus.  A good device probes avoids doing writes, and
    verifies that the correct device exists and functions.  */
 
-int eepro_probe1(struct device *dev, short ioaddr)
+int 
+eepro_probe1(struct device *dev, short ioaddr)
 {
        unsigned short station_addr[6], id, counter;
        int i;
-       int eepro;      /* a flag, TRUE=1 for the EtherExpress Pro/10,
-                          FALSE = 0 for other 82595-based lan cards. */
+       int eepro;
        const char *ifmap[] = {"AUI", "10Base2", "10BaseT"};
        enum iftype { AUI=0, BNC=1, TPE=2 };
 
        /* Now, we are going to check for the signature of the
           ID_REG (register 2 of bank 0) */
-
        if (((id=inb(ioaddr + ID_REG)) & ID_REG_MASK) == ID_REG_SIG) {
 
                /* We seem to have the 82595 signature, let's
                   play with its counter (last 2 bits of
                   register 2 of bank 0) to be sure. */
-       
+
                counter = (id & R_ROBIN_BITS);  
                if (((id=inb(ioaddr+ID_REG)) & R_ROBIN_BITS) == 
                        (counter + 0x40)) {
@@ -372,44 +406,54 @@ int eepro_probe1(struct device *dev, short ioaddr)
 
                        /* Check the station address for the manufacturer's code */
 
-                       if (station_addr[2] != 0x00aa || (station_addr[1] & 0xff00) != 0x0000) {
-                               eepro = 0;
-                               printk("%s: Intel 82595-based lan card at %#x,", 
+                       if ((station_addr[2] == 0x00aa) && (station_addr[1]!= 0x00c9)) {
+                               eepro = 1;
+                               printk("%s: Intel EtherExpress Pro/10 ISA at %#x,", 
+                                       dev->name, ioaddr);
+                       } else
+                       if ( (station_addr[2] == 0x00a0)
+                            || ((station_addr[2] == 0x00aa) && (station_addr[1] == 0x00c9) )) {
+                               eepro = 2;
+                               printk("%s: Intel EtherExpress Pro/10+ ISA\n at %#x,", 
                                        dev->name, ioaddr);
                        }
                        else {
-                               eepro = 1;
-                               printk("%s: Intel EtherExpress Pro/10 at %#x,", 
+                               eepro = 0;
+                               printk("%s: Intel 82595-based lan card at %#x,", 
                                        dev->name, ioaddr);
                        }
 
                        /* Fill in the 'dev' fields. */
                        dev->base_addr = ioaddr;
-                       
+
                        for (i=0; i < 6; i++) {
                                dev->dev_addr[i] = ((unsigned char *) station_addr)[5-i];
                                printk("%c%02x", i ? ':' : ' ', dev->dev_addr[i]);
                        }
-                       
+
                        if ((dev->mem_end & 0x3f) < 3 ||        /* RX buffer must be more than 3K */
                                (dev->mem_end & 0x3f) > 29)     /* and less than 29K */
                                dev->mem_end = RCV_RAM;         /* or it will be set to 24K */
                        else dev->mem_end = 1024*dev->mem_end;  /* Maybe I should shift << 10 */
 
                        /* From now on, dev->mem_end contains the actual size of rx buffer */
-                       
+
                        if (net_debug > 3)
                                printk(", %dK RCV buffer", (int)(dev->mem_end)/1024);
-                               
+
                        outb(BANK2_SELECT, ioaddr); /* be CAREFUL, BANK 2 now */
                        id = inb(ioaddr + REG3);
                        if (id & TPE_BIT)
                                dev->if_port = TPE;
                        else dev->if_port = BNC;
 
+                       if (net_debug>3) 
+                               printk("id: %x\n", id);
+
                        if (dev->irq < 2 && eepro) {
                                i = read_eeprom(ioaddr, 1);
-                               switch (i & 0x07) {
+                               if (eepro == 1)
+                                  switch (i & 0x07) {
                                        case 0: dev->irq = 9; break;
                                        case 1: dev->irq = 3; break;
                                        case 2: dev->irq = 5; break;
@@ -419,6 +463,16 @@ int eepro_probe1(struct device *dev, short ioaddr)
                                                printk(" illegal interrupt vector stored in EEPROM.\n");
                                                return ENODEV;
                                        }
+                               else switch (i & 0x07) {
+                                       case 0: dev->irq = 3; break;
+                                       case 1: dev->irq = 4; break;
+                                       case 2: dev->irq = 5; break;
+                                       case 3: dev->irq = 7; break;
+                                       case 4: dev->irq = 9; break;
+                                       case 5: dev->irq = 10; break;
+                                       case 6: dev->irq = 11; break;
+                                       case 7: dev->irq = 12; break;
+                                       }
                                }
                        else if (dev->irq == 2)
                                dev->irq = 9;
@@ -432,7 +486,7 @@ int eepro_probe1(struct device *dev, short ioaddr)
                                }
                        }
                        else printk(", %s.\n", ifmap[dev->if_port]);
-                       
+
                        if ((dev->mem_start & 0xf) > 0) /* I don't know if this is */
                                net_debug = dev->mem_start & 7; /* still useful or not */
 
@@ -486,9 +540,12 @@ int eepro_probe1(struct device *dev, short ioaddr)
    */
 
 static char irqrmap[] = {-1,-1,0,1,-1,2,-1,-1,-1,0,3,4,-1,-1,-1,-1};
-static int     eepro_grab_irq(struct device *dev)
+static char irqrmap2[] = {-1,-1,4,0,1,2,-1,3,-1,4,5,6,7,-1,-1,-1};
+
+static int     
+eepro_grab_irq(struct device *dev)
 {
-       int irqlist[] = { 5, 9, 10, 11, 4, 3, 0};       
+       int irqlist[] = { 3, 4, 5, 7, 9, 10, 11, 12 };  
        int *irqp = irqlist, temp_reg, ioaddr = dev->base_addr;
 
        outb(BANK1_SELECT, ioaddr); /* be CAREFUL, BANK 1 now */
@@ -496,32 +553,28 @@ static int        eepro_grab_irq(struct device *dev)
        /* Enable the interrupt line. */
        temp_reg = inb(ioaddr + REG1);
        outb(temp_reg | INT_ENABLE, ioaddr + REG1); 
-       
+
        outb(BANK0_SELECT, ioaddr); /* be CAREFUL, BANK 0 now */
 
        /* clear all interrupts */
        outb(ALL_MASK, ioaddr + STATUS_REG); 
+
        /* Let EXEC event to interrupt */
        outb(ALL_MASK & ~(EXEC_MASK), ioaddr + INT_MASK_REG); 
 
        do {
                outb(BANK1_SELECT, ioaddr); /* be CAREFUL, BANK 1 now */
-
                temp_reg = inb(ioaddr + INT_NO_REG);
                outb((temp_reg & 0xf8) | irqrmap[*irqp], ioaddr + INT_NO_REG); 
-
                outb(BANK0_SELECT, ioaddr); /* Switch back to Bank 0 */
-
                if (request_irq (*irqp, NULL, 0, "bogus", NULL) != EBUSY) {
                        /* Twinkle the interrupt, and check if it's seen */
                        autoirq_setup(0);
-
                        outb(DIAGNOSE_CMD, ioaddr); /* RESET the 82595 */
                                
                        if (*irqp == autoirq_report(2) &&  /* It's a good IRQ line */
                                (request_irq(dev->irq = *irqp, &eepro_interrupt, 0, "eepro", NULL) == 0)) 
                                        break;
-
                        /* clear all interrupts */
                        outb(ALL_MASK, ioaddr + STATUS_REG); 
                }
@@ -532,7 +585,6 @@ static int  eepro_grab_irq(struct device *dev)
        /* Disable the physical interrupt line. */
        temp_reg = inb(ioaddr + REG1);
        outb(temp_reg & 0x7f, ioaddr + REG1); 
-
        outb(BANK0_SELECT, ioaddr); /* Switch back to Bank 0 */
 
        /* Mask all the interrupts. */
@@ -554,10 +606,27 @@ eepro_open(struct device *dev)
        if (net_debug > 3)
                printk("eepro: entering eepro_open routine.\n");
 
-       if (dev->dev_addr[0] == SA_ADDR0 &&
+       if ((dev->dev_addr[0] == SA_ADDR0 &&
                        dev->dev_addr[1] == SA_ADDR1 &&
-                       dev->dev_addr[2] == SA_ADDR2)
-               lp->eepro = 1; /* Yes, an Intel EtherExpress Pro/10 */
+                       dev->dev_addr[2] == SA_ADDR2)&&
+                       (dev->dev_addr[3] != SA3_ADDR3))
+               { 
+                       lp->eepro = 1;
+                       if (net_debug > 3) printk("p->eepro = 1;\n"); 
+               }  /* Yes, an Intel EtherExpress Pro/10 */
+
+       else if ((dev->dev_addr[0] == SA2_ADDR0 &&
+                       dev->dev_addr[1] == SA2_ADDR1 &&
+                       dev->dev_addr[2] == SA2_ADDR2)||
+               (dev->dev_addr[0] == SA3_ADDR0 &&
+                       dev->dev_addr[1] == SA3_ADDR1 &&
+                       dev->dev_addr[2] == SA3_ADDR2 &&
+                       dev->dev_addr[3] == SA3_ADDR3))
+               {
+                       lp->eepro = 2; /* Yes, an Intel EtherExpress Pro/10+ */
+                       if (net_debug > 3) printk("p->eepro = 2;\n"); 
+               }
+       
        else lp->eepro = 0; /* No, it is a generic 82585 lan card */
 
        /* Get the interrupt vector for the 82595 */    
@@ -571,15 +640,12 @@ eepro_open(struct device *dev)
                return -EAGAIN;
 
        /* Initialize the 82595. */
-
        outb(BANK2_SELECT, ioaddr); /* be CAREFUL, BANK 2 now */
        temp_reg = inb(ioaddr + EEPROM_REG);
-
        lp->stepping = temp_reg >> 5;   /* Get the stepping number of the 595 */
        
        if (net_debug > 3)
                printk("The stepping of the 82595 is %d\n", lp->stepping);
-
        if (temp_reg & 0x10) /* Check the TurnOff Enable bit */
                outb(temp_reg & 0xef, ioaddr + EEPROM_REG);
        for (i=0; i < 6; i++) 
@@ -588,19 +654,31 @@ eepro_open(struct device *dev)
        temp_reg = inb(ioaddr + REG1);    /* Setup Transmit Chaining */
        outb(temp_reg | XMT_Chain_Int | XMT_Chain_ErrStop /* and discard bad RCV frames */
                | RCV_Discard_BadFrame, ioaddr + REG1);  
-
        temp_reg = inb(ioaddr + REG2); /* Match broadcast */
        outb(temp_reg | 0x14, ioaddr + REG2);
-
        temp_reg = inb(ioaddr + REG3);
        outb(temp_reg & 0x3f, ioaddr + REG3); /* clear test mode */
 
        /* Set the receiving mode */
        outb(BANK1_SELECT, ioaddr); /* be CAREFUL, BANK 1 now */
+
+       /* Set the interrupt vector */  
+       temp_reg = inb(ioaddr + INT_NO_REG);
        
+       if (lp->eepro == 2)
+               outb((temp_reg & 0xf8) | irqrmap2[dev->irq], ioaddr + INT_NO_REG); 
+       else outb((temp_reg & 0xf8) | irqrmap[dev->irq], ioaddr + INT_NO_REG); 
+    
        temp_reg = inb(ioaddr + INT_NO_REG);
-       outb((temp_reg & 0xf8) | irqrmap[dev->irq], ioaddr + INT_NO_REG); 
-
+    
+       if (lp->eepro == 2)
+                       outb((temp_reg & 0xf0) | irqrmap2[dev->irq] | 0x08,ioaddr+INT_NO_REG);
+       else outb((temp_reg & 0xf8) | irqrmap[dev->irq], ioaddr + INT_NO_REG);
+    
+       if (net_debug > 3)
+                       printk("eepro_open: content of INT Reg is %x\n", temp_reg);
+       
+       
        /* Initialize the RCV and XMT upper and lower limits */
        outb(RCV_LOWER_LIMIT, ioaddr + RCV_LOWER_LIMIT_REG); 
        outb(RCV_UPPER_LIMIT, ioaddr + RCV_UPPER_LIMIT_REG); 
@@ -610,25 +688,26 @@ eepro_open(struct device *dev)
        /* Enable the interrupt line. */
        temp_reg = inb(ioaddr + REG1);
        outb(temp_reg | INT_ENABLE, ioaddr + REG1); 
-
        outb(BANK0_SELECT, ioaddr); /* Switch back to Bank 0 */
-
+       
        /* Let RX and TX events to interrupt */
        outb(ALL_MASK & ~(RX_MASK | TX_MASK), ioaddr + INT_MASK_REG); 
+       
        /* clear all interrupts */
        outb(ALL_MASK, ioaddr + STATUS_REG); 
-
+       
        /* Initialize RCV */
        outw(RCV_LOWER_LIMIT << 8, ioaddr + RCV_BAR); 
        lp->rx_start = (RCV_LOWER_LIMIT << 8) ;
        outw((RCV_UPPER_LIMIT << 8) | 0xfe, ioaddr + RCV_STOP); 
-
+       
        /* Initialize XMT */
        outw(XMT_LOWER_LIMIT << 8, ioaddr + XMT_BAR); 
-
+       
        /* Check for the i82595TX and i82595FX */
        old8 = inb(ioaddr + 8);
        outb(~old8, ioaddr + 8);
+       
        if ((temp_reg = inb(ioaddr + 8)) == old8) {
                if (net_debug > 3)
                        printk("i82595 detected!\n");
@@ -639,45 +718,55 @@ eepro_open(struct device *dev)
                outb(old8, ioaddr + 8);
                old9 = inb(ioaddr + 9);
                outb(~old9, ioaddr + 9);
-               if ((temp_reg = inb(ioaddr + 9)) == ~old9) {
+       
+               if (((temp_reg = inb(ioaddr + 9)) == ( (~old9)&0xff) )) {
                        enum iftype { AUI=0, BNC=1, TPE=2 };
-                       if (net_debug > 3)
+       
+                       if (net_debug > 3) {
+                               printk("temp_reg: %#x  ~old9: %#x\n",temp_reg, ~old9);
                                printk("i82595FX detected!\n");
+                       }
+       
                        lp->version = LAN595FX;
                        outb(old9, ioaddr + 9);
+       
                        if (dev->if_port != TPE) {      /* Hopefully, this will fix the
                                                        problem of using Pentiums and
                                                        pro/10 w/ BNC. */
                                outb(BANK2_SELECT, ioaddr); /* be CAREFUL, BANK 2 now */
                                temp_reg = inb(ioaddr + REG13);
+       
                                /* disable the full duplex mode since it is not
                                applicable with the 10Base2 cable. */
                                outb(temp_reg & ~(FDX | A_N_ENABLE), REG13);
                                outb(BANK0_SELECT, ioaddr); /* be CAREFUL, BANK 0 now */
                        }
                }
-               else if (net_debug > 3)
+               else if (net_debug > 3) {
+                       printk("temp_reg: %#x  ~old9: %#x\n",temp_reg,((~old9)&0xff));
                        printk("i82595TX detected!\n");
+               }
        }
        
        outb(SEL_RESET_CMD, ioaddr);
+       
        /* We are supposed to wait for 2 us after a SEL_RESET */
        SLOW_DOWN_IO;
        SLOW_DOWN_IO;   
-
+       
        lp->tx_start = lp->tx_end = XMT_LOWER_LIMIT << 8; /* or = RCV_RAM */
        lp->tx_last = 0;  
        
        dev->tbusy = 0;
        dev->interrupt = 0;
        dev->start = 1;
-
+       
        if (net_debug > 3)
                printk("eepro: exiting eepro_open routine.\n");
-
+       
        outb(RCV_ENABLE_CMD, ioaddr);
-
        MOD_INC_USE_COUNT;
+       
        return 0;
 }
 
@@ -694,64 +783,68 @@ eepro_send_packet(struct sk_buff *skb, struct device *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. */
+       
                int tickssofar = jiffies - dev->trans_start;
+       
                if (tickssofar < 40)
                        return 1;
+       
                if (net_debug > 1)
                        printk("%s: transmit timed out, %s?\n", dev->name,
                                   "network cable problem");
+       
                lp->stats.tx_errors++;
-
+       
                /* Try to restart the adaptor. */
                outb(SEL_RESET_CMD, ioaddr); 
+       
                /* We are supposed to wait for 2 us after a SEL_RESET */
                SLOW_DOWN_IO;
                SLOW_DOWN_IO;
-
+       
                /* Do I also need to flush the transmit buffers here? YES? */
                lp->tx_start = lp->tx_end = rcv_ram; 
                lp->tx_last = 0;
        
                dev->tbusy=0;
                dev->trans_start = jiffies;
-
                outb(RCV_ENABLE_CMD, ioaddr);
-
        }
-
+       
        /* If some higher layer thinks we've missed an tx-done interrupt
           we are passed NULL. Caution: dev_tint() handles the cli()/sti()
           itself. */
+       
        if (skb == NULL) {
                dev_tint(dev);
                return 0;
        }
-
+       
        /* Block a timer-based transmit from overlapping. */
+       
        if (set_bit(0, (void*)&dev->tbusy) != 0)
                printk("%s: Transmitter access conflict.\n", dev->name);
        else {
                short length = ETH_ZLEN < skb->len ? skb->len : ETH_ZLEN;
                unsigned char *buf = skb->data;
-
                hardware_send_packet(dev, buf, length);
                dev->trans_start = jiffies;
        }
-
+       
        dev_kfree_skb (skb, FREE_WRITE);
-
+       
        /* You might need to clean up and record Tx statistics here. */
        /* lp->stats.tx_aborted_errors++; */
-
+       
        if (net_debug > 5)
                printk("eepro: exiting eepro_send_packet routine.\n");
        
        return 0;
 }
 
-
 /*     The typical workload of the driver:
        Handle the network interface interrupts. */
+
 static void
 eepro_interrupt(int irq, void *dev_id, struct pt_regs * regs)
 {
@@ -765,38 +858,35 @@ eepro_interrupt(int irq, void *dev_id, struct pt_regs * regs)
                printk ("eepro_interrupt(): irq %d for unknown device.\n", irq);
                return;
        }
+       
        dev->interrupt = 1;
        
        ioaddr = dev->base_addr;
-
+       
        do { 
                status = inb(ioaddr + STATUS_REG);
                
                if (status & RX_INT) {
                        if (net_debug > 4)
                                printk("eepro: packet received interrupt.\n");
-
                        /* Acknowledge the RX_INT */
                        outb(RX_INT, ioaddr + STATUS_REG); 
-
                        /* Get the received packets */
                        eepro_rx(dev);
                }
-
                else if (status & TX_INT) {
                        if (net_debug > 4)
                                printk("eepro: packet transmit interrupt.\n");
-
                        /* Acknowledge the TX_INT */
                        outb(TX_INT, ioaddr + STATUS_REG); 
-
                        /* Process the status of transmitted packets */
                        eepro_transmit_interrupt(dev);
                }
        
        } while ((boguscount-- > 0) && (status & 0x06));
-
+       
        dev->interrupt = 0;
+               
        if (net_debug > 5)
                printk("eepro: exiting eepro_interrupt routine.\n");
        
@@ -813,41 +903,39 @@ eepro_close(struct device *dev)
 
        dev->tbusy = 1;
        dev->start = 0;
-
+       
        outb(BANK1_SELECT, ioaddr); /* Switch back to Bank 1 */
-
+       
        /* Disable the physical interrupt line. */
        temp_reg = inb(ioaddr + REG1);
        outb(temp_reg & 0x7f, ioaddr + REG1); 
-
        outb(BANK0_SELECT, ioaddr); /* Switch back to Bank 0 */
-
+       
        /* Flush the Tx and disable Rx. */
        outb(STOP_RCV_CMD, ioaddr); 
+       
        lp->tx_start = lp->tx_end = rcv_ram ;
        lp->tx_last = 0;  
-
+       
        /* Mask all the interrupts. */
        outb(ALL_MASK, ioaddr + INT_MASK_REG); 
-
+       
        /* clear all interrupts */
        outb(ALL_MASK, ioaddr + STATUS_REG); 
-
+       
        /* Reset the 82595 */
        outb(RESET_CMD, ioaddr); 
-
+       
        /* release the interrupt */
        free_irq(dev->irq, NULL);
-
        irq2dev_map[dev->irq] = 0;
-
+       
        /* Update the statistics here. What statistics? */
-
        /* We are supposed to wait for 200 us after a RESET */
        SLOW_DOWN_IO;
        SLOW_DOWN_IO; /* May not be enough? */
-
        MOD_DEC_USE_COUNT;
+       
        return 0;
 }
 
@@ -857,12 +945,12 @@ static struct enet_statistics *
 eepro_get_stats(struct device *dev)
 {
        struct eepro_local *lp = (struct eepro_local *)dev->priv;
-
        return &lp->stats;
 }
 
 /* Set or clear the multicast filter for this adaptor.
  */
+
 static void
 set_multicast_list(struct device *dev)
 {
@@ -870,7 +958,7 @@ set_multicast_list(struct device *dev)
        short ioaddr = dev->base_addr;
        unsigned short mode;
        struct dev_mc_list *dmi=dev->mc_list;
-
+       
        if (dev->flags&(IFF_ALLMULTI|IFF_PROMISC) || dev->mc_count > 63) 
        {
                /*
@@ -880,7 +968,6 @@ set_multicast_list(struct device *dev)
                 *      flag is already set. If not we assert it.
                 */
                dev->flags|=IFF_PROMISC;                
-
                outb(BANK2_SELECT, ioaddr); /* be CAREFUL, BANK 2 now */
                mode = inb(ioaddr + REG2);
                outb(mode | PRMSC_Mode, ioaddr + REG2); 
@@ -889,6 +976,7 @@ set_multicast_list(struct device *dev)
                outb(BANK0_SELECT, ioaddr); /* Return to BANK 0 now */
                printk("%s: promiscuous mode enabled.\n", dev->name);
        } 
+       
        else if (dev->mc_count==0 ) 
        {
                outb(BANK2_SELECT, ioaddr); /* be CAREFUL, BANK 2 now */
@@ -898,6 +986,7 @@ set_multicast_list(struct device *dev)
                outb(mode, ioaddr + REG3); /* writing reg. 3 to complete the update */
                outb(BANK0_SELECT, ioaddr); /* Return to BANK 0 now */
        }
+       
        else 
        {
                unsigned short status, *eaddrs;
@@ -907,7 +996,6 @@ set_multicast_list(struct device *dev)
                   corruption of the HOST_ADDRESS_REG by interrupt
                   service routines. */
                outb(ALL_MASK, ioaddr + INT_MASK_REG);
-
                outb(BANK2_SELECT, ioaddr); /* be CAREFUL, BANK 2 now */
                mode = inb(ioaddr + REG2);
                outb(mode | Multi_IA, ioaddr + REG2);   
@@ -919,6 +1007,7 @@ set_multicast_list(struct device *dev)
                outw(0, ioaddr + IO_PORT);
                outw(0, ioaddr + IO_PORT);
                outw(6*(dev->mc_count + 1), ioaddr + IO_PORT);
+       
                for (i = 0; i < dev->mc_count; i++) 
                {
                        eaddrs=(unsigned short *)dmi->dmi_addr;
@@ -927,15 +1016,17 @@ set_multicast_list(struct device *dev)
                        outw(*eaddrs++, ioaddr + IO_PORT);
                        outw(*eaddrs++, ioaddr + IO_PORT);
                }
+       
                eaddrs = (unsigned short *) dev->dev_addr;
                outw(eaddrs[0], ioaddr + IO_PORT);
                outw(eaddrs[1], ioaddr + IO_PORT);
                outw(eaddrs[2], ioaddr + IO_PORT);
                outw(lp->tx_end, ioaddr + XMT_BAR);
                outb(MC_SETUP, ioaddr);
-
+       
                /* Update the transmit queue */
                i = lp->tx_end + XMT_HEADER + 6*(dev->mc_count + 1);
+       
                if (lp->tx_start != lp->tx_end) 
                { 
                        /* update the next address and the chain bit in the 
@@ -950,15 +1041,17 @@ set_multicast_list(struct device *dev)
                else {
                        lp->tx_start = lp->tx_end = i ;
                }
-
+       
                /* Acknowledge that the MC setup is done */
                do { /* We should be doing this in the eepro_interrupt()! */
                        SLOW_DOWN_IO;
                        SLOW_DOWN_IO;
+       
                        if (inb(ioaddr + STATUS_REG) & 0x08) 
                        {
                                i = inb(ioaddr);
                                outb(0x08, ioaddr + STATUS_REG);
+       
                                if (i & 0x20) { /* command ABORTed */
                                        printk("%s: multicast setup failed.\n", 
                                                dev->name);
@@ -970,7 +1063,7 @@ set_multicast_list(struct device *dev)
                                }
                        }
                } while (++boguscount < 100);
-
+       
                /* Re-enable RX and TX interrupts */
                outb(ALL_MASK & ~(RX_MASK | TX_MASK), ioaddr + INT_MASK_REG); 
        
@@ -980,8 +1073,8 @@ set_multicast_list(struct device *dev)
 
 /* The horrible routine to read a word from the serial EEPROM. */
 /* IMPORTANT - the 82595 will be set to Bank 0 after the eeprom is read */
-
 /* The delay between EEPROM clock transitions. */
+
 #define eeprom_delay() { int _i = 40; while (--_i > 0) { __SLOW_DOWN_IO; }}
 #define EE_READ_CMD (6 << 6)
 
@@ -1014,7 +1107,6 @@ read_eeprom(int ioaddr, int location)
                retval = (retval << 1) | ((inb(ee_addr) & EEDO) ? 1 : 0);
                outb(ctrl_val, ee_addr);  eeprom_delay();
        }
-
        /* Terminate the EEPROM access. */
        ctrl_val &= ~EECS;
        outb(ctrl_val | EESK, ee_addr);
@@ -1035,47 +1127,47 @@ hardware_send_packet(struct device *dev, void *buf, short length)
 
        if (net_debug > 5)
                printk("eepro: entering hardware_send_packet routine.\n");
-
+       
        while (boguscount-- > 0) {
-
+       
                /* Disable RX and TX interrupts.  Necessary to avoid
                corruption of the HOST_ADDRESS_REG by interrupt
                service routines. */
                outb(ALL_MASK, ioaddr + INT_MASK_REG);
-
+       
                if (dev->interrupt == 1) {  
                        /* Enable RX and TX interrupts */
                        outb(ALL_MASK & ~(RX_MASK | TX_MASK), ioaddr + INT_MASK_REG); 
                        continue;
                }
-
+       
                /* determine how much of the transmit buffer space is available */
                if (lp->tx_end > lp->tx_start)
                        tx_available = XMT_RAM - (lp->tx_end - lp->tx_start);
                else if (lp->tx_end < lp->tx_start)
                        tx_available = lp->tx_start - lp->tx_end;
                else tx_available = XMT_RAM;
-
+       
                if (((((length + 3) >> 1) << 1) + 2*XMT_HEADER) 
                        >= tx_available)   /* No space available ??? */
                        {
                        eepro_transmit_interrupt(dev); /* Clean up the transmiting queue */
-
                        /* Enable RX and TX interrupts */
                        outb(ALL_MASK & ~(RX_MASK | TX_MASK), ioaddr + INT_MASK_REG); 
                        continue;
                }
-
+       
                last = lp->tx_end;
                end = last + (((length + 3) >> 1) << 1) + XMT_HEADER;
-
                if (end >= RAM_SIZE) { /* the transmit buffer is wrapped around */
+       
                        if ((RAM_SIZE - last) <= XMT_HEADER) {  
                        /* Arrrr!!!, must keep the xmt header together,
                          several days were lost to chase this one down. */
                                last = rcv_ram;
                                end = last + (((length + 3) >> 1) << 1) + XMT_HEADER;
                        }       
+
                        else end = rcv_ram + (end - RAM_SIZE);
                }
 
@@ -1084,19 +1176,20 @@ hardware_send_packet(struct device *dev, void *buf, short length)
                outw(0, ioaddr + IO_PORT);
                outw(end, ioaddr + IO_PORT);
                outw(length, ioaddr + IO_PORT);
-
+       
                if (lp->version == LAN595)
                        outsw(ioaddr + IO_PORT, buf, (length + 3) >> 1);
+       
                else {  /* LAN595TX or LAN595FX, capable of 32-bit I/O processing */
                        unsigned short temp = inb(ioaddr + INT_MASK_REG);
                        outb(temp | IO_32_BIT, ioaddr + INT_MASK_REG);
                        outsl(ioaddr + IO_PORT_32_BIT, buf, (length + 3) >> 2);
                        outb(temp & ~(IO_32_BIT), ioaddr + INT_MASK_REG);
                }
-
+       
                /* A dummy read to flush the DRAM write pipeline */
                status = inw(ioaddr + IO_PORT); 
-
+       
                if (lp->tx_start == lp->tx_end) {       
                        outw(last, ioaddr + XMT_BAR);
                        outb(XMT_CMD, ioaddr);
@@ -1105,34 +1198,36 @@ hardware_send_packet(struct device *dev, void *buf, short length)
                else {
                        /* update the next address and the chain bit in the 
                        last packet */
+
                        if (lp->tx_end != last) {
                                outw(lp->tx_last + XMT_CHAIN, ioaddr + HOST_ADDRESS_REG);
                                outw(last, ioaddr + IO_PORT);
                        }
+       
                        outw(lp->tx_last + XMT_COUNT, ioaddr + HOST_ADDRESS_REG);
                        status = inw(ioaddr + IO_PORT);
                        outw(status | CHAIN_BIT, ioaddr + IO_PORT);
-
+       
                        /* Continue the transmit command */
                        outb(RESUME_XMT_CMD, ioaddr);
                }
-
                lp->tx_last = last;
                lp->tx_end = end;
-
+       
                /* Enable RX and TX interrupts */
                outb(ALL_MASK & ~(RX_MASK | TX_MASK), ioaddr + INT_MASK_REG); 
        
                if (dev->tbusy) {
                        dev->tbusy = 0;
                }
-
+       
                if (net_debug > 5)
                        printk("eepro: exiting hardware_send_packet routine.\n");
+       
                return;
        }
-
        dev->tbusy = 1;
+       
        if (net_debug > 5)
                printk("eepro: exiting hardware_send_packet routine.\n");
 }
@@ -1151,68 +1246,78 @@ eepro_rx(struct device *dev)
        
        /* Set the read pointer to the start of the RCV */
        outw(rcv_car, ioaddr + HOST_ADDRESS_REG);
+       
        rcv_event = inw(ioaddr + IO_PORT);
-
        while (rcv_event == RCV_DONE) {
+
                rcv_status = inw(ioaddr + IO_PORT);
                rcv_next_frame = inw(ioaddr + IO_PORT);
                rcv_size = inw(ioaddr + IO_PORT);
-
+       
                if ((rcv_status & (RX_OK | RX_ERROR)) == RX_OK) {
+       
                        /* Malloc up new buffer. */
                        struct sk_buff *skb;
-
                        rcv_size &= 0x3fff;
                        skb = dev_alloc_skb(rcv_size+5);
+       
                        if (skb == NULL) {
                                printk("%s: Memory squeeze, dropping packet.\n", dev->name);
                                lp->stats.rx_dropped++;
                                break;
                        }
+       
                        skb->dev = dev;
                        skb_reserve(skb,2);
-
+       
                        if (lp->version == LAN595)
                                insw(ioaddr+IO_PORT, skb_put(skb,rcv_size), (rcv_size + 3) >> 1);
+       
                        else {  /* LAN595TX or LAN595FX, capable of 32-bit I/O processing */
                                unsigned short temp = inb(ioaddr + INT_MASK_REG);
                                outb(temp | IO_32_BIT, ioaddr + INT_MASK_REG);
                                insl(ioaddr+IO_PORT_32_BIT, skb_put(skb,rcv_size), (rcv_size + 3) >> 2);
                                outb(temp & ~(IO_32_BIT), ioaddr + INT_MASK_REG);
                        }
-
        
                        skb->protocol = eth_type_trans(skb,dev);        
                        netif_rx(skb);
                        lp->stats.rx_packets++;
                }
+       
                else { /* Not sure will ever reach here, 
                          I set the 595 to discard bad received frames */
                        lp->stats.rx_errors++;
+       
                        if (rcv_status & 0x0100)
                                lp->stats.rx_over_errors++;
+       
                        else if (rcv_status & 0x0400)
                                lp->stats.rx_frame_errors++;
+       
                        else if (rcv_status & 0x0800)
                                lp->stats.rx_crc_errors++;
+       
                        printk("%s: event = %#x, status = %#x, next = %#x, size = %#x\n", 
                                dev->name, rcv_event, rcv_status, rcv_next_frame, rcv_size);
                }
+       
                if (rcv_status & 0x1000)
                        lp->stats.rx_length_errors++;
+       
                if (--boguscount == 0)
                        break;
-
+       
                rcv_car = lp->rx_start + RCV_HEADER + rcv_size;
                lp->rx_start = rcv_next_frame;
                outw(rcv_next_frame, ioaddr + HOST_ADDRESS_REG);
                rcv_event = inw(ioaddr + IO_PORT);
-
        } 
        if (rcv_car == 0)
                rcv_car = (RCV_UPPER_LIMIT << 8) | 0xff;
+       
        outw(rcv_car - 1, ioaddr + RCV_STOP);
-
+       
        if (net_debug > 5)
                printk("eepro: exiting eepro_rx routine.\n");
 }
@@ -1226,17 +1331,17 @@ eepro_transmit_interrupt(struct device *dev)
        short xmt_status;
 
        while (lp->tx_start != lp->tx_end) { 
-
+       
                outw(lp->tx_start, ioaddr + HOST_ADDRESS_REG);
                xmt_status = inw(ioaddr+IO_PORT);
+       
                if ((xmt_status & TX_DONE_BIT) == 0) break;
-
+       
                xmt_status = inw(ioaddr+IO_PORT);
                lp->tx_start = inw(ioaddr+IO_PORT);
-
                dev->tbusy = 0;
                mark_bh(NET_BH);
-
+       
                if (xmt_status & 0x2000)
                        lp->stats.tx_packets++; 
                else {
@@ -1246,41 +1351,45 @@ eepro_transmit_interrupt(struct device *dev)
                        printk("%s: XMT status = %#x\n",
                                dev->name, xmt_status);
                }
+       
                if (xmt_status & 0x000f) {
                        lp->stats.collisions += (xmt_status & 0x000f);
                }
+       
                if ((xmt_status & 0x0040) == 0x0) {
                        lp->stats.tx_heartbeat_errors++;
                }
-
+       
                if (--boguscount == 0)
                        break;  
        }
 }
 
 #ifdef MODULE
+
 static char devicename[9] = { 0, };
 static struct device dev_eepro = {
        devicename, /* device name is inserted by linux/drivers/net/net_init.c */
        0, 0, 0, 0,
        0, 0,
        0, 0, 0, NULL, eepro_probe };
-
 static int io = 0x200;
 static int irq = 0;
 static int mem = (RCV_RAM/1024);       /* Size of the rx buffer in KB */
 
-int
+int 
 init_module(void)
 {
        if (io == 0)
                printk("eepro: You should not use auto-probing with insmod!\n");
+
        dev_eepro.base_addr = io;
        dev_eepro.irq       = irq;
        dev_eepro.mem_end   = mem;
 
        if (register_netdev(&dev_eepro) != 0)
                return -EIO;
+
        return 0;
 }
 
@@ -1288,6 +1397,7 @@ void
 cleanup_module(void)
 {
        unregister_netdev(&dev_eepro);
+
        kfree_s(dev_eepro.priv,sizeof(struct eepro_local));
        dev_eepro.priv=NULL;
 
index 56d527a2516f7efb1474b32f663cb916f8171e03..369350e670dc121814d626c8070c5687c30ed07d 100644 (file)
@@ -205,14 +205,30 @@ void ext2_free_inode (struct inode * inode)
                        inode->i_nlink);
                return;
        }
-       if (!inode->i_sb) {
+       sb = inode->i_sb;
+       if (!sb) {
                printk("ext2_free_inode: inode on nonexistent device\n");
                return;
        }
 
        ext2_debug ("freeing inode %lu\n", inode->i_ino);
 
-       sb = inode->i_sb;
+       /* We need to kill quota references now, before grabbing the
+        * superblock lock because writing the quota out to disk
+        * may need to lock the superblock as well.
+        *
+        * It is safe to do this early instead of the original
+        * places because we cannot be here in ext2_free_inode
+        * if any other references to this inode exist at all.
+        *
+        * Based upon a 2.1.x fix by Bill Hawes.   --DaveM
+        */
+       if (sb->dq_op) {
+               sb->dq_op->free_inode (inode, 1);
+               if (IS_WRITABLE (inode))
+                       sb->dq_op->drop(inode);
+       }
+
        lock_super (sb);
        if (inode->i_ino < EXT2_FIRST_INO(sb) ||
            inode->i_ino > sb->u.ext2_sb.s_es->s_inodes_count) {
@@ -249,8 +265,6 @@ void ext2_free_inode (struct inode * inode)
                ll_rw_block (WRITE, 1, &bh);
                wait_on_buffer (bh);
        }
-       if (sb->dq_op)
-               sb->dq_op->free_inode (inode, 1);
        sb->s_dirt = 1;
        clear_inode (inode);
        unlock_super (sb);
index 1190e2009ab2df4febf9d57f8e195c72cb9227b7..ea31d746d3400ce2c0799e6769d40e058821fc13 100644 (file)
@@ -162,6 +162,8 @@ extern void enable_irq(unsigned int);
        "jnc 3f\n\t" \
        "cmpb "SYMBOL_NAME_STR(active_kernel_processor)", %al\n\t" \
        "je 4f\n\t" \
+       "cmpb "SYMBOL_NAME_STR(boot_cpu_id)", %al\n\t" \
+       "jne 2f\n\t" \
        "movb $1, "SYMBOL_NAME_STR(smp_blocked_interrupt_pending)"\n\t" \
        "2: " \
         SMP_PROF_INT_SPINS \
@@ -190,7 +192,10 @@ extern void enable_irq(unsigned int);
        "movb %al, "SYMBOL_NAME_STR(active_kernel_processor)"\n\t" \
        "4: " \
        "incl "SYMBOL_NAME_STR(kernel_counter)"\n\t" \
+       "cmpb "SYMBOL_NAME_STR(boot_cpu_id)", %al\n\t" \
+       "jne 7f\n\t" \
        "movb $0, "SYMBOL_NAME_STR(smp_blocked_interrupt_pending)"\n\t" \
+       "7: " \
        "popfl\n\t" \
        "popl %edx\n\t" \
        "popl %ecx\n\t" \
index 74d0fa81a6bf5c815ba021dbaa6213d1e4687bdf..6bbe740a011c4f1a552d6695b9b18675bd6cbff1 100644 (file)
@@ -65,7 +65,7 @@ struct route {
 
 #define        IPOPT_TS_TSONLY         0               /* timestamps only */
 #define        IPOPT_TS_TSANDADDR      1               /* timestamps and addresses */
-#define        IPOPT_TS_PRESPEC        2               /* specified modules only */
+#define        IPOPT_TS_PRESPEC        3               /* specified modules only */
 
 struct options {
   __u32                faddr;                          /* Saved first hop address */
index f7eda6c4d236248fb22741c0ca3cf835afbc7c41..96d260394d082623e3f25637a03272fb25d99aac 100644 (file)
@@ -5,6 +5,7 @@
  *  Swap reorganised 29.12.95, Stephen Tweedie
  */
 
+#include <linux/config.h>
 #include <linux/mm.h>
 #include <linux/sched.h>
 #include <linux/head.h>
index 64dab8cf93105d2c8d26a925fb69e92544a1e9b0..6df6e677c14c68994f92e3452d69050d0957ab7a 100644 (file)
@@ -921,7 +921,7 @@ unsigned long flags;
        skb->pkt_bridged = IS_BRIDGED;
        skb->arp = 1;   /* do not resolve... */
        skb->h.raw = skb->data + ETH_HLEN;
-       dev_queue_xmit(dev,skb);
+       dev_queue_xmit(skb, dev, SOPRI_INTERACTIVE);
        return(0);
 }
 
@@ -975,7 +975,7 @@ unsigned long flags;
        skb->arp = 1;   /* do not resolve... */
        skb->h.raw = skb->data + ETH_HLEN;
        
-       dev_queue_xmit(dev,skb);
+       dev_queue_xmit(skb, dev, SOPRI_INTERACTIVE);
        return(0);
 }
 
index 9fea00c8a56230e06166a83c93dafafef53d0d0e..7e9ca4a05ae2c33cf1e9b0557120393f97c5a7ed 100644 (file)
@@ -251,14 +251,6 @@ int ip_rcv(struct sk_buff *skb, struct device *dev, struct packet_type *pt)
 
        ip_statistics.IpInReceives++;
 
-       /*
-        *      Account for the packet (even if the packet is
-        *      not accepted by the firewall!).
-        */
-
-#ifdef CONFIG_IP_ACCT
-       ip_fw_chk(iph,dev,NULL,ip_acct_chain,0,IP_FW_MODE_ACCT_IN);
-#endif 
 
        /*
         *      Tag the ip header of this packet so we can find it
@@ -294,6 +286,24 @@ int ip_rcv(struct sk_buff *skb, struct device *dev, struct packet_type *pt)
         */
 
        skb_trim(skb,ntohs(iph->tot_len));
+       
+       if(skb->len < (iph->ihl<<2))
+       {
+               ip_statistics.IpInHdrErrors++;
+               kfree_skb(skb, FREE_WRITE);
+               return 0;
+       }
+
+       /*
+        *      Account for the packet (even if the packet is
+        *      not accepted by the firewall!). We do this after
+        *      the sanity checks and the additional ihl check
+        *      so we dont account garbage as we might do before.
+        */
+
+#ifdef CONFIG_IP_ACCT
+       ip_fw_chk(iph,dev,NULL,ip_acct_chain,0,IP_FW_MODE_ACCT_IN);
+#endif 
 
        /*
         *      Try to select closest <src,dst> alias device, if any.
index 2bfcda94b8d5685515c90acabb8bcb757d72ae86..04e8224ab0988447c671986b7f690b4a80a4ab64 100644 (file)
@@ -237,7 +237,7 @@ static struct sock *nr_find_socket(unsigned char index, unsigned char id)
 /*
  *     Find a connected NET/ROM socket given their circuit IDs.
  */
-static struct sock *nr_find_peer(unsigned char index, unsigned char id)
+static struct sock *nr_find_peer(unsigned char index, unsigned char id, ax25_address *dest)
 {
        struct sock *s;
        unsigned long flags;
@@ -246,7 +246,7 @@ static struct sock *nr_find_peer(unsigned char index, unsigned char id)
        cli();
 
        for (s = nr_list; s != NULL; s = s->next) {
-               if (s->protinfo.nr->your_index == index && s->protinfo.nr->your_id == id) {
+               if (s->protinfo.nr->your_index == index && s->protinfo.nr->your_id == id && ax25cmp(&s->protinfo.nr->dest_addr, dest) == 0) {
                        restore_flags(flags);
                        return s;
                }
@@ -936,10 +936,10 @@ int nr_rx_frame(struct sk_buff *skb, struct device *dev)
 
        if (circuit_index == 0 && circuit_id == 0) {
                if (frametype == NR_CONNACK && flags == NR_CHOKE_FLAG)
-                       sk = nr_find_peer(peer_circuit_index, peer_circuit_id);
+                       sk = nr_find_peer(peer_circuit_index, peer_circuit_id, src);
        } else {
                if (frametype == NR_CONNREQ)
-                       sk = nr_find_peer(circuit_index, circuit_id);
+                       sk = nr_find_peer(circuit_index, circuit_id, src);
                else
                        sk = nr_find_socket(circuit_index, circuit_id);
        }
index bb2c0c816ba6f88f4fb4211bcea1c1d3c64521a8..0edbeed4e3d12247b92a4c82d26378e1c2f0cdc9 100644 (file)
@@ -11,6 +11,8 @@
  *
  *     History
  *     NET/ROM 006     Tomi(OH2BNS)    Created this file.
+ *                                     Changed the way the loopback
+ *                                     queue is consumed.
  *
  */
 
@@ -53,15 +55,16 @@ int nr_loopback_queue(struct sk_buff *skb)
 {
        struct sk_buff *skbn;
 
-       skbn = skb_copy(skb, GFP_ATOMIC);
+       skbn = skb_clone(skb, GFP_ATOMIC);
 
        kfree_skb(skb, FREE_WRITE);
 
-       if (skbn != NULL)
+       if (skbn != NULL) {
                skb_queue_tail(&loopback_queue, skbn);
 
-       if (!nr_loopback_running())
-               nr_set_loopback_timer();
+               if (!nr_loopback_running())
+                       nr_set_loopback_timer();
+       }
 
        return 1;
 }
@@ -85,16 +88,16 @@ static void nr_loopback_timer(unsigned long param)
        ax25_address *nr_dest;
        struct device *dev;
 
-       while ((skb = skb_dequeue(&loopback_queue)) != NULL) {
+       if ((skb = skb_dequeue(&loopback_queue)) != NULL) {
                nr_dest = (ax25_address *)(skb->data + 7);
 
-               if ((dev = nr_dev_get(nr_dest)) == NULL) {
-                       kfree_skb(skb, FREE_READ);
-                       continue;
-               }
+               dev = nr_dev_get(nr_dest);
 
-               if (nr_rx_frame(skb, dev) == 0)
+               if (dev == NULL || nr_rx_frame(skb, dev) == 0)
                        kfree_skb(skb, FREE_READ);
+
+               if (!skb_queue_empty(&loopback_queue) && !nr_loopback_running())
+                       nr_set_loopback_timer();
        }
 }
 
index 3be5feb21a0256dbe8e646bc71862bb4d719a89e..0e30d00d0b25caffc5118f1f3f3fe370edb297cd 100644 (file)
 
 #include CURSES_LOC
 
+/*
+ * Colors in ncurses 1.9.9e do not work properly since foreground and
+ * background colors are OR'd rather than separately masked.  This version
+ * of dialog was hacked to work with ncurses 1.9.9e, making it incompatible
+ * with standard curses.  The simplest fix (to make this work with standard
+ * curses) uses the wbkgdset() function, not used in the original hack.
+ * Turn it off if we're building with 1.9.9e, since it just confuses things.
+ */
+#if defined(NCURSES_VERSION) && defined(_NEED_WRAP) && !defined(GCC_PRINTFLIKE)
+#define OLD_NCURSES 1
+#undef  wbkgdset
+#define wbkgdset(w,p) /*nothing*/
+#else
+#define OLD_NCURSES 0
+#endif
+
+#define TR(params) _tracef params
+
 #define ESC 27
 #define TAB 9
 #define MAX_LEN 2048
index fb150f7f6d6f5be5d2fad518418a947e2e074936..f84ebf527b842f792ef22692c96af0f14d029f6a 100644 (file)
@@ -63,6 +63,9 @@ main (int argc, const char * const * argv)
     (void) setlocale (LC_ALL, "");
 #endif
 
+#ifdef TRACE
+    trace(TRACE_CALLS|TRACE_UPDATE);
+#endif
     if (argc < 2) {
        Usage (argv[0]);
        exit (-1);
index ad4380870380cccc8bb79606db5f2ecec59b0d24..d717bf90af6e3a123f8b93b09911c027263a9188 100644 (file)
@@ -39,8 +39,12 @@ print_item (WINDOW * win, const char *item, int choice, int selected, int hotkey
     /* Clear 'residue' of last item */
     wattrset (win, menubox_attr);
     wmove (win, choice, 0);
+#if OLD_NCURSES
     for (i = 0; i < menu_width; i++)
        waddch (win, ' ');
+#else
+    wclrtoeol(win);
+#endif
     wattrset (win, selected ? item_selected_attr : item_attr);
     mvwaddstr (win, choice, item_x, menu_item);
     if (hotkey) {
@@ -141,6 +145,7 @@ dialog_menu (const char *title, const char *prompt, int height, int width,
     for (i = 0; i < width - 2; i++)
        waddch (dialog, ACS_HLINE);
     wattrset (dialog, dialog_attr);
+    wbkgdset (dialog, dialog_attr & A_COLOR);
     waddch (dialog, ACS_RTEE);
 
     if (title != NULL) {
index df50f2c54da4f002181c6af9a6b8dc79d5f4a66f..5127e5f2c0175dbad9b9faa3b9b5d3d645da6bb8 100644 (file)
@@ -90,6 +90,8 @@ dialog_textbox (const char *title, const char *file, int height, int width)
 
     /* Create window for text region, used for scrolling text */
     text = subwin (dialog, height - 4, width - 2, y + 1, x + 1);
+    wattrset (text, dialog_attr);
+    wbkgdset (text, dialog_attr & A_COLOR);
 
     keypad (text, TRUE);
 
@@ -101,6 +103,7 @@ dialog_textbox (const char *title, const char *file, int height, int width)
     for (i = 0; i < width - 2; i++)
        waddch (dialog, ACS_HLINE);
     wattrset (dialog, dialog_attr);
+    wbkgdset (dialog, dialog_attr & A_COLOR);
     waddch (dialog, ACS_RTEE);
 
     if (title != NULL) {
@@ -459,8 +462,12 @@ print_line (WINDOW * win, int row, int width)
 
     getyx (win, y, x);
     /* Clear 'residue' of previous line */
+#if OLD_NCURSES
     for (i = 0; i < width - x; i++)
        waddch (win, ' ');
+#else
+    wclrtoeol(win);
+#endif
 }
 
 /*
@@ -530,6 +537,7 @@ print_position (WINDOW * win, int height, int width)
        exit (-1);
     }
     wattrset (win, position_indicator_attr);
+    wbkgdset (win, position_indicator_attr & A_COLOR);
     percent = !file_size ?
        100 : ((fpos - bytes_read + page - buf) * 100) / file_size;
     wmove (win, height - 3, width - 9);