]> git.neil.brown.name Git - history.git/commitdiff
Linux 2.2.15pre15 2.2.15pre15
authorAlan Cox <alan@lxorguk.ukuu.org.uk>
Fri, 23 Nov 2007 20:21:03 +0000 (15:21 -0500)
committerAlan Cox <alan@lxorguk.ukuu.org.uk>
Fri, 23 Nov 2007 20:21:03 +0000 (15:21 -0500)
o Semaphore undo leak fix (Christian Ehrhardt)
o MSP3400 docs + config hint (Matthias Andree)
o Avoid localising version data (Matthias Andree)
o Fix an obscure nfsd hang (epx@conectiva.com.br)
o Ron Holt moved (Ron Holt)
o Fix X.25 restart collisions (Henner Eisen)
o Fix X.25 EOR flags (Henner Eisen)
o IRDA security fixes and packet accounting (Dag Brattli)
o Fix sktr compile bug (Arjan van de Ven)
o Sparc sync up (Dave Miller)
o Fix quota warnings (Adrian Sun)
o Fix quote permission check (Adrian Sun)
o Megaraid back to 1.07 + firmware check (AMI, Dell,
Doug Ledford)
o Resynchronize 2.2/2.3 drive blacklists (Tim Waugh)
o ISDN updates (mppp foxes. tty call fixes,
reog AVM driver, Eicon fixes..) (Karsten Keil and co)
o Fix full duplex on olympic TR (Mike Phillips)

82 files changed:
CREDITS
Documentation/Configure.help
Documentation/isdn/CREDITS
Documentation/isdn/README
Documentation/isdn/README.eicon
Documentation/isdn/README.x25
Makefile
arch/sparc/kernel/irq.c
arch/sparc/mm/srmmu.c
arch/sparc/mm/swift.S
arch/sparc64/kernel/entry.S
arch/sparc64/kernel/head.S
arch/sparc64/kernel/setup.c
arch/sparc64/lib/blockops.S
arch/sparc64/mm/init.c
arch/sparc64/mm/ultra.S
drivers/char/Config.in
drivers/isdn/Config.in
drivers/isdn/avmb1/Makefile
drivers/isdn/avmb1/avmcard.h
drivers/isdn/avmb1/b1.c
drivers/isdn/avmb1/b1dma.c [new file with mode: 0644]
drivers/isdn/avmb1/b1isa.c
drivers/isdn/avmb1/b1pci.c
drivers/isdn/avmb1/b1pcmcia.c
drivers/isdn/avmb1/c4.c
drivers/isdn/avmb1/capi.c
drivers/isdn/avmb1/kcapi.c
drivers/isdn/avmb1/t1isa.c
drivers/isdn/avmb1/t1pci.c
drivers/isdn/divert/divert_procfs.c
drivers/isdn/eicon/eicon.h
drivers/isdn/eicon/eicon_dsp.h
drivers/isdn/eicon/eicon_idi.c
drivers/isdn/eicon/eicon_idi.h
drivers/isdn/eicon/eicon_io.c
drivers/isdn/eicon/eicon_isa.c
drivers/isdn/eicon/eicon_isa.h
drivers/isdn/eicon/eicon_mod.c
drivers/isdn/eicon/eicon_pci.c
drivers/isdn/eicon/eicon_pci.h
drivers/isdn/hisax/config.c
drivers/isdn/hisax/hfc_pci.c
drivers/isdn/hisax/hisax.h
drivers/isdn/hisax/l3dss1.c
drivers/isdn/hisax/md5sums.asc
drivers/isdn/hisax/teles3.c
drivers/isdn/isdn_common.c
drivers/isdn/isdn_net.c
drivers/isdn/isdn_ppp.c
drivers/isdn/isdn_tty.c
drivers/isdn/isdn_tty.h
drivers/isdn/isdn_v110.c
drivers/isdn/isdn_v110.h
drivers/net/dmfe.c
drivers/net/irda/irport.c
drivers/net/irda/irtty.c
drivers/net/irda/nsc-ircc.c
drivers/net/irda/toshoboe.c
drivers/net/irda/w83977af_ir.c
drivers/net/olympic.c
drivers/net/olympic.h
drivers/net/sktr.c
drivers/scsi/hosts.h
drivers/scsi/megaraid.c
drivers/scsi/megaraid.h
drivers/scsi/scsi.c
fs/dquot.c
fs/nfsd/nfsfh.c
include/asm-sparc/asm_offsets.h
include/asm-sparc/pgtable.h
include/asm-sparc/spinlock.h
include/asm-sparc/vaddrs.h
include/asm-sparc64/asm_offsets.h
include/asm-sparc64/floppy.h
include/asm-sparc64/pgtable.h
include/asm-sparc64/system.h
include/linux/isdn.h
include/linux/kernelcapi.h
ipc/sem.c
net/x25/af_x25.c
net/x25/x25_link.c

diff --git a/CREDITS b/CREDITS
index 464a94463cf50db7867a28558329335ff4a07fee..ac0ddd994bc2b8b87945a5486a529ac20a248ce4 100644 (file)
--- a/CREDITS
+++ b/CREDITS
@@ -867,7 +867,8 @@ S: CV5 8BZ
 S: United Kingdom
 
 N: Ron Holt
-E: ron@sovereign.org
+E: ron@holt.org
+E: rholt@netcom.com
 W: http://www.holt.org/
 P: 1024/1FD44539 DF 4B EB 9F 5B 68 38 9A  40 E3 FB 71 D1 C8 0B 56
 D: Kernel development
index b47f9b92c1f316d7513061e044db98d26cd7feca..5a7885a7b279b4e7fabff95740b0393fa1d82dc2 100644 (file)
@@ -9977,6 +9977,19 @@ CONFIG_ACI_MIXER
   the radio tuner. This is supported in the video4linux
   radio-miropcm20 driver.
 
+Micronas Intermetall MSP 3400 support
+CONFIG_VIDEO_MSP3400
+  This option enables the driver for the Micronas Intermetall MSP 3400 
+  series sound decoder/mixer chips often found on BT848-style TV cards.
+
+  Say Y here if your sound card has a MSP 3400 series sound decoder or 
+  mixer chip.
+
+  This driver is also available as a module ( = code which can be
+  inserted in and removed from the running kernel whenever you want).
+  If you want to compile it as a module, say M here and read
+  Documentation/modules.txt. The module will be called msp3400.o.
+
 SB32/AWE support
 CONFIG_AWE32_SYNTH
   Say Y here if you have a Sound Blaster SB32, AWE32-PnP, SB AWE64 or
@@ -10610,6 +10623,10 @@ AVM B1 PCI support
 CONFIG_ISDN_DRV_AVMB1_B1PCI
   Enable support for the PCI version of the AVM B1 card.
 
+AVM B1 PCI V4 support
+CONFIG_ISDN_DRV_AVMB1_B1PCIV4
+  Enable support for the V4 version of AVM B1 PCI card.
+
 AVM T1/T1-B ISA support
 CONFIG_ISDN_DRV_AVMB1_T1ISA
   Enable support for the AVM T1 T1B card.
@@ -10624,6 +10641,11 @@ CONFIG_ISDN_DRV_AVMB1_T1PCI
   Enable support for the AVM T1 T1B card.
   Note: This is a PRI card and handle 30 B-channels.
 
+AVM C4 support
+CONFIG_ISDN_DRV_AVMB1_C4
+  Enable support for the AVM C4 PCI card.
+  This card handle 4 BRI ISDN lines (8 channels).
+
 Verbose reason code reporting (kernel size +=7K)
 CONFIG_ISDN_DRV_AVMB1_VERBOSE_REASON
   If you say Y here, the AVM B1 driver will give verbose reasons for
index beef990bab6baa61828ca88b15aea0d69b3d500e..e1b3023efaa8701f31886d695adb478a55fcd07f 100644 (file)
@@ -58,9 +58,13 @@ Thomas Pfeiffer (pfeiffer@pds.de)
 Max Riegel (riegel@max.franken.de)
   For making the ICN hardware-documentation and test-equipment available.
 
+Armin Schindler (mac@melware.de)
+  For the eicon active card driver.
+
 Gerhard 'Fido' Schneider (fido@wuff.mayn.de)
   For heavy-duty-beta-testing with his BBS ;)
 
 Thomas Uhl (uhl@think.de)
   For distributing the cards.
   For pushing me to work ;-)
+
index 3cf623d48eec5dfb0e69f372e34996ccb6b5a92e..afd9f45af04d4b16cc9f5a712162a880fb3c8832 100644 (file)
@@ -80,8 +80,7 @@ README for the ISDN-subsystem
    The functionality is almost the same as that of a serial device
    (the line-discs are handled by the kernel), which lets you run
    SLIP, CSLIP and asynchronous PPP through the devices. We have tested
-   Seyon, minicom, CSLIP (uri-dip) PPP and mgetty (compiled with NO_FAX),
-   XCept.
+   Seyon, minicom, CSLIP (uri-dip) PPP, mgetty, XCept and Hylafax. 
 
    The modem-emulation supports the following:
            1.3.1 Commands:
@@ -124,6 +123,10 @@ README for the ISDN-subsystem
                AT&D3    Same as AT&D2 but also resets all registers.
                AT&Ex    Set the EAZ/MSN for this channel to x.
                AT&F     Reset all registers and profile to "factory-defaults"
+               AT&Lx    Set list of phone numbers to listen on.  x is a
+                        list of wildcard patterns separated by semicolon.
+                        If this is set, it has precedence over the MSN set
+                        by AT&E.
                AT&Rx    Select V.110 bitrate adaption.
                         This command enables V.110 protocol with 9600 baud
                         (x=9600), 19200 baud (x=19200) or 38400 baud
@@ -238,7 +241,8 @@ README for the ISDN-subsystem
              15   0         Layer-3 protocol:
                                       0 = transparent
                                       1 = transparent with audio features (e.g. DSP)
-                                      2 = Fax G3 (S14 has to be set to 11)
+                                      2 = Fax G3 Class 2 commands (S14 has to be set to 11)
+                                      2 = Fax G3 Class 1 commands (S14 has to be set to 11)
              16   250       Send-Packet-size/16
              17   8         Window-size (not yet implemented)
              18   4         Bit coded register, Service-Octet-1 to accept,
@@ -309,8 +313,6 @@ README for the ISDN-subsystem
   If an incoming call matches one network interface, it gets connected to it.
   If another incoming call for the same EAZ arrives, which does not match
   a network interface, the first tty gets a "RING" and so on.
-  As soon as voice gets supported (with the availability of the Diehl-driver),
-  the service-identifier will be evaluated in addition.
 
 2 System prerequisites:
 
index b40e1ecd23c529a7d0072d47008fe982bb708740..73d8c92dd85041dea3edc0bbc3c7217aaf76ce63 100644 (file)
@@ -1,9 +1,10 @@
-$Id: README.eicon,v 1.5 1999/10/11 18:13:25 armin Exp $
+$Id: README.eicon,v 1.6 2000/01/27 09:54:44 armin Exp $
 
-(c) 1999 Cytronics & Melware (info@melware.de)
+(c) 1999,2000 Armin Schindler (mac@melware.de)
+(c) 1999,2000 Cytronics & Melware (info@melware.de)
 
 This document describes the eicon driver for the
-Eicon.Diehl active ISDN cards.
+Eicon active ISDN cards.
 
 It is meant to be used with isdn4linux, an ISDN link-level module for Linux.
 
@@ -50,7 +51,8 @@ ISDN D-Channel Protocols
 
 - ETSI (Euro-DSS1) 
 - 1TR6 (German ISDN) *not testet*
-
+- other protocols exist for the range of DIVA Server cards,
+  but they are not fully testet yet.
 
 
 You can load the module simply by using the insmod or modprobe function :
@@ -58,7 +60,7 @@ You can load the module simply by using the insmod or modprobe function :
   insmod eicon [id=driverid] [membase=<membase>] [irq=<irq>]
 
 
-The module will automatically probe the PCI-cards. If the id-options
+The module will automatically probe the PCI-cards. If the id-option
 is omitted, the driver will assume 'eicon0' for the first pci card and
 increases the digit with each further card. With a given driver-id
 the module appends a number starting with '0'.
@@ -85,6 +87,14 @@ Example for loading and starting a PRI card with E-DSS1 Protocol.
 Details about using the eiconctrl utility are in 'man eiconctrl'
 or will be printed by starting eiconctrl without any parameters.
 
+ISDNLOG:
+With eicon driver version 1.77 or newer and the eiconctrl utility
+of version 1.1 or better, you can use the isdnlog user program
+with your DIVA Server BRI card.
+Just use "eiconctrl isdnlog on" and the driver will generate
+the necessary D-Channel traces for isdnlog.
+
+
 Thanks to 
        Deutsche Mailbox Saar-Lor-Lux GmbH
        for sponsoring and testing fax
index 9794f41183f50e618b95978036504c0a11c613a6..e561a77c4e228e8d1e5cc74a87ff64a8fbfb7918 100644 (file)
@@ -61,7 +61,21 @@ X.25 on top of isdn might be useful with two different scenarios:
 
 - You might want to access a public X.25 data network from your Linux box.
   You can use i4l if you were physically connected to the X.25 switch
-  by an ISDN line (leased line as well as dial up connection should work)
+  by an ISDN B-channel (leased line as well as dial up connection should
+  work).
+
+  This corresponds to ITU-T recommendation X.31 Case A (circuit-mode
+  access to PSPDN [packet switched public data network]).
+
+  NOTE: X.31 also covers a Case B (access to PSPDN via virtual
+  circuit / packet mode service). The latter mode (which in theory
+  also allows using the D-channel) is not supported by isdn4linux.
+  It should however be possible to establish such packet mode connections
+  with certain active isdn cards provided that the firmware supports X.31
+  and the driver exports this functionality to the user. Currently, 
+  the AVM B1 driver is the only driver which does so. (It should be
+  possible to access D-channel X.31 with active AVM cards using the
+  CAPI interface of the AVM-B1 driver).
 
 - Or you might want to operate certain ISDN teleservices on your linux
   box. A lot of those teleservices run on top of the ISO-8208
index 3b3279d4e4025c7cc297adc60b63700011d353e2..0606fdabc77130bf56486e9c2fa5f5b9be61a2f9 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -1,7 +1,7 @@
 VERSION = 2
 PATCHLEVEL = 2
 SUBLEVEL = 15
-EXTRAVERSION = pre14
+EXTRAVERSION = pre15
 
 ARCH := $(shell uname -m | sed -e s/i.86/i386/ -e s/sun4u/sparc64/ -e s/arm.*/arm/ -e s/sa110/arm/)
 
@@ -282,8 +282,8 @@ include/linux/compile.h: $(CONFIGURATION) include/linux/version.h newversion
        @echo -n \#define UTS_VERSION \"\#`cat .version` > .ver
        @if [ -n "$(CONFIG_SMP)" ] ; then echo -n " SMP" >> .ver; fi
        @if [ -f .name ]; then  echo -n \-`cat .name` >> .ver; fi
-       @echo ' '`date`'"' >> .ver
-       @echo \#define LINUX_COMPILE_TIME \"`date +%T`\" >> .ver
+       @echo ' '`LANG=C date`'"' >> .ver
+       @echo \#define LINUX_COMPILE_TIME \"`LANG=C date +%T`\" >> .ver
        @echo \#define LINUX_COMPILE_BY \"`whoami`\" >> .ver
        @echo \#define LINUX_COMPILE_HOST \"`hostname`\" >> .ver
        @if [ -x /bin/dnsdomainname ]; then \
index 285de0e9f7c09d0515fca0c55d40a06301f89c99..7f70cd93c651ae7f1b4397c474a6463a8c6bdee9 100644 (file)
@@ -1,4 +1,4 @@
-/*  $Id: irq.c,v 1.93 1999/04/21 06:15:45 anton Exp $
+/*  $Id: irq.c,v 1.93.2.1 2000/02/17 18:05:29 davem Exp $
  *  arch/sparc/kernel/irq.c:  Interrupt request handling routines. On the
  *                            Sparc the IRQ's are basically 'cast in stone'
  *                            and you are supposed to probe the prom's device
index 1e94af359244a45375d6abf8917409f4814c0720..7a2365e3a81e62185cc535ecc25688f205828da6 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: srmmu.c,v 1.187.2.8 1999/12/23 01:58:38 davem Exp $
+/* $Id: srmmu.c,v 1.187.2.9 2000/03/05 17:39:18 davem Exp $
  * srmmu.c:  SRMMU specific routines for memory management.
  *
  * Copyright (C) 1995 David S. Miller  (davem@caip.rutgers.edu)
index 1e67635720e210a9fac9cf5c013f410a8e12075a..ea492b8b7daeedcedc659658d800a852c8293199 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: swift.S,v 1.1.2.3 1999/10/14 01:00:17 davem Exp $
+/* $Id: swift.S,v 1.1.2.4 2000/03/05 17:39:17 davem Exp $
  * swift.S: MicroSparc-II mmu/cache operations.
  *
  * Copyright (C) 1999 David S. Miller (davem@redhat.com)
index cab4ecc74a6945366b2002ab397feb193edc93bc..40c6803626d2a3a3f6111103ec69d2b7ca743b9d 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: entry.S,v 1.103.2.4 1999/10/24 17:29:13 davem Exp $
+/* $Id: entry.S,v 1.103.2.5 2000/03/06 22:30:22 davem Exp $
  * arch/sparc64/kernel/entry.S:  Sparc64 trap low-level entry points.
  *
  * Copyright (C) 1995,1997 David S. Miller (davem@caip.rutgers.edu)
index 8bbb6417976b7f81ca0f60e74d37e33a57705bca..deb4d02088512e6afe442946f398d7ae967776fc 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: head.S,v 1.60.2.4 1999/11/12 15:45:47 davem Exp $
+/* $Id: head.S,v 1.60.2.5 2000/03/06 22:30:25 davem Exp $
  * head.S: Initial boot code for the Sparc64 port of Linux.
  *
  * Copyright (C) 1996,1997 David S. Miller (davem@caip.rutgers.edu)
index a2ad607c4655fe3728e7593d8c7eef35f055cb5f..57e8c949bf8881be6c31ca18d84e7b9b4cf00f2b 100644 (file)
@@ -1,4 +1,4 @@
-/*  $Id: setup.c,v 1.43.2.2 1999/10/24 17:29:20 davem Exp $
+/*  $Id: setup.c,v 1.43.2.3 2000/03/03 23:50:37 davem Exp $
  *  linux/arch/sparc64/kernel/setup.c
  *
  *  Copyright (C) 1995,1996  David S. Miller (davem@caip.rutgers.edu)
index 7a5bcad0e6f8c8f00fcbb46f251f05f8b9a7a9c1..a84304362655fb3cdfbad846f6278ab0dc7094a8 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: blockops.S,v 1.16.2.1 1999/10/07 20:48:14 davem Exp $
+/* $Id: blockops.S,v 1.16.2.2 2000/03/03 23:50:32 davem Exp $
  * blockops.S: UltraSparc block zero optimized routines.
  *
  * Copyright (C) 1996,1998 David S. Miller (davem@caip.rutgers.edu)
index 55b3e3a954449e9a972b0700ab62cde86564b8cd..8f35f237e60a8f4ccc9720a77c5c58fd9ba7e83f 100644 (file)
@@ -1,4 +1,4 @@
-/*  $Id: init.c,v 1.127.2.6 1999/12/05 07:24:42 davem Exp $
+/*  $Id: init.c,v 1.127.2.8 2000/03/03 23:50:41 davem Exp $
  *  arch/sparc64/mm/init.c
  *
  *  Copyright (C) 1996-1999 David S. Miller (davem@caip.rutgers.edu)
index 9c4ac94410effd924e7e151633044e0eb6074515..9fa1421373b46deb78807d0ce152a9a55f798745 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: ultra.S,v 1.32.2.1 1999/10/24 17:29:34 davem Exp $
+/* $Id: ultra.S,v 1.32.2.3 2000/03/03 23:50:46 davem Exp $
  * ultra.S: Don't expand these all over the place...
  *
  * Copyright (C) 1997 David S. Miller (davem@caip.rutgers.edu)
index 6b9b87070bb9755fd5362b57db8e0ca3420ff525..815659059c8284bc6a44aba94a57022f30ddcaad 100644 (file)
@@ -149,6 +149,10 @@ if [ "$CONFIG_VIDEO_DEV" != "n" ]; then
   fi
   if [ "$CONFIG_PCI" != "n" ]; then
     dep_tristate 'BT848 Video For Linux' CONFIG_VIDEO_BT848 $CONFIG_VIDEO_DEV
+    if [ "$CONFIG_VIDEO_BT848" != "n" ]; then
+      comment '  MSP3400 sound decoder support is in the section "additional'
+      comment '  low level sound drivers". You may need to enable it there.'
+    fi
   fi
   if [ "$CONFIG_PARPORT" != "n" ]; then
     dep_tristate 'Quickcam BW Video For Linux' CONFIG_VIDEO_BWQCAM $CONFIG_VIDEO_DEV $CONFIG_PARPORT
index c4c07369197584469fefad66effc0add58a25a9d..2ba7789d914ccb94a3abd486fa468f58eb2ebbfc 100644 (file)
@@ -89,10 +89,17 @@ dep_tristate 'AVM CAPI2.0 support' CONFIG_ISDN_DRV_AVMB1 $CONFIG_ISDN
 if [ "$CONFIG_ISDN_DRV_AVMB1" != "n" ]; then
    bool '  AVM B1 ISA support' CONFIG_ISDN_DRV_AVMB1_B1ISA
    bool '  AVM B1 PCI support' CONFIG_ISDN_DRV_AVMB1_B1PCI
+   if [ "$CONFIG_ISDN_DRV_AVMB1_B1PCI" != "n" ]; then
+      if [ "$CONFIG_EXPERIMENTAL" != "n" ]; then
+         bool '  AVM B1 PCI V4 support' CONFIG_ISDN_DRV_AVMB1_B1PCIV4
+      fi
+   fi
    bool '  AVM T1/T1-B ISA support' CONFIG_ISDN_DRV_AVMB1_T1ISA
    bool '  AVM B1/M1/M2 PCMCIA support' CONFIG_ISDN_DRV_AVMB1_B1PCMCIA
    bool '  AVM T1/T1-B PCI support' CONFIG_ISDN_DRV_AVMB1_T1PCI
-   bool '  AVM C4 support' CONFIG_ISDN_DRV_AVMB1_C4
+   if [ "$CONFIG_EXPERIMENTAL" != "n" ]; then
+      bool '  AVM C4 support' CONFIG_ISDN_DRV_AVMB1_C4
+   fi
    bool '  Verbose reason code reporting (kernel size +=7K)' CONFIG_ISDN_DRV_AVMB1_VERBOSE_REASON
 fi
 endmenu
index 111c39466fb9409eeb0721dbd33fa1d8e6e9db90..bfeb81939a0b5ad62d422d085511e2c5ee774c9d 100644 (file)
@@ -1,5 +1,5 @@
 #
-# $Id: Makefile,v 1.7 1999/09/15 08:16:03 calle Exp $
+# $Id: Makefile,v 1.8 2000/01/25 14:33:38 calle Exp $
 #
 # Makefile for the CAPI and AVM-B1 device drivers.
 #
 # parent makes..
 #
 # $Log: Makefile,v $
+# Revision 1.8  2000/01/25 14:33:38  calle
+# - Added Support AVM B1 PCI V4.0 (tested with prototype)
+#   - splitted up t1pci.c into b1dma.c for common function with b1pciv4
+#   - support for revision register
+#
 # Revision 1.7  1999/09/15 08:16:03  calle
 # Implementation of 64Bit extention complete.
 #
@@ -99,7 +104,7 @@ ifeq ($(CONFIG_ISDN_DRV_AVMB1),y)
   ifdef CONFIG_ISDN_DRV_AVMB1_C4
   O_OBJS   += c4.o
   endif
-  OX_OBJS  += capiutil.o capidrv.o b1.o
+  OX_OBJS  += capiutil.o capidrv.o b1.o b1dma.o
 else
   ifeq ($(CONFIG_ISDN_DRV_AVMB1),m)
   O_TARGET += kernelcapi.o
@@ -123,7 +128,7 @@ else
   ifdef CONFIG_ISDN_DRV_AVMB1_C4
   M_OBJS   += c4.o
   endif
-  MX_OBJS  += capiutil.o capidrv.o b1.o
+  MX_OBJS  += capiutil.o capidrv.o b1.o b1dma.o
   endif
 endif
 
index f4b5df6891194afdf72df6402317001633862e1b..56fa0fba6d7970e88eb10eb6de9eb58475b6642c 100644 (file)
@@ -1,9 +1,14 @@
 /*
- * $Id: avmcard.h,v 1.6 1999/11/05 16:38:01 calle Exp $
+ * $Id: avmcard.h,v 1.7 2000/01/25 14:33:38 calle Exp $
  *
  * Copyright 1999 by Carsten Paeth (calle@calle.in-berlin.de)
  *
  * $Log: avmcard.h,v $
+ * Revision 1.7  2000/01/25 14:33:38  calle
+ * - Added Support AVM B1 PCI V4.0 (tested with prototype)
+ *   - splitted up t1pci.c into b1dma.c for common function with b1pciv4
+ *   - support for revision register
+ *
  * Revision 1.6  1999/11/05 16:38:01  calle
  * Cleanups before kernel 2.4:
  * - Changed all messages to use card->name or driver->name instead of
@@ -92,6 +97,8 @@ typedef struct avmcard {
        unsigned irq;
        unsigned long membase;
        enum avmcardtype cardtype;
+       unsigned char revision;
+       unsigned char class;
        int cardnr; /* for t1isa */
 
        char msgbuf[128];       /* capimsg msg part */
@@ -228,8 +235,9 @@ extern int b1_irq_table[16];
 #define B1_WRITE               0x01
 #define B1_INSTAT              0x02
 #define B1_OUTSTAT             0x03
-#define B1_RESET               0x10
 #define B1_ANALYSE             0x04
+#define B1_REVISION            0x05
+#define B1_RESET               0x10
 
 
 #define B1_STAT0(cardtype)  ((cardtype) == avm_m1 ? 0x81200000l : 0x80A00000l)
@@ -561,10 +569,13 @@ static inline void b1_setinterrupt(unsigned int base, unsigned irq,
         }
 }
 
+/* b1.c */
 int b1_detect(unsigned int base, enum avmcardtype cardtype);
+void b1_getrevision(avmcard *card);
 int b1_load_t4file(avmcard *card, capiloaddatapart * t4file);
 int b1_load_config(avmcard *card, capiloaddatapart * config);
 int b1_loaded(avmcard *card);
+
 int b1_load_firmware(struct capi_ctr *ctrl, capiloaddata *data);
 void b1_reset_ctr(struct capi_ctr *ctrl);
 void b1_register_appl(struct capi_ctr *ctrl, __u16 appl,
@@ -577,5 +588,21 @@ void b1_handle_interrupt(avmcard * card);
 int b1ctl_read_proc(char *page, char **start, off_t off,
                        int count, int *eof, struct capi_ctr *ctrl);
 
+/* b1dma.c */
+int b1pciv4_detect(avmcard *card);
+int t1pci_detect(avmcard *card);
+void b1dma_reset(avmcard *card);
+void b1dma_interrupt(int interrupt, void *devptr, struct pt_regs *regs);
+
+int b1dma_load_firmware(struct capi_ctr *ctrl, capiloaddata *data);
+void b1dma_reset_ctr(struct capi_ctr *ctrl);
+void b1dma_remove_ctr(struct capi_ctr *ctrl);
+void b1dma_register_appl(struct capi_ctr *ctrl,
+                               __u16 appl,
+                               capi_register_params *rp);
+void b1dma_release_appl(struct capi_ctr *ctrl, __u16 appl);
+void b1dma_send_message(struct capi_ctr *ctrl, struct sk_buff *skb);
+int b1dmactl_read_proc(char *page, char **start, off_t off,
+                       int count, int *eof, struct capi_ctr *ctrl);
 
 #endif /* _AVMCARD_H_ */
index 900b31c8c1632a0475ae0199482dcaab2f5b4020..65c4368cdf962a7570f6d3df5fcd5c0a9fd5a1f2 100644 (file)
@@ -1,11 +1,16 @@
 /*
- * $Id: b1.c,v 1.12 1999/11/05 16:38:01 calle Exp $
+ * $Id: b1.c,v 1.13 2000/01/25 14:33:38 calle Exp $
  * 
  * Common module for AVM B1 cards.
  * 
  * (c) Copyright 1999 by Carsten Paeth (calle@calle.in-berlin.de)
  * 
  * $Log: b1.c,v $
+ * Revision 1.13  2000/01/25 14:33:38  calle
+ * - Added Support AVM B1 PCI V4.0 (tested with prototype)
+ *   - splitted up t1pci.c into b1dma.c for common function with b1pciv4
+ *   - support for revision register
+ *
  * Revision 1.12  1999/11/05 16:38:01  calle
  * Cleanups before kernel 2.4:
  * - Changed all messages to use card->name or driver->name instead of
@@ -86,7 +91,7 @@
 #include "capicmd.h"
 #include "capiutil.h"
 
-static char *revision = "$Revision: 1.12 $";
+static char *revision = "$Revision: 1.13 $";
 
 /* ------------------------------------------------------------- */
 
@@ -158,6 +163,12 @@ int b1_detect(unsigned int base, enum avmcardtype cardtype)
        return 0;
 }
 
+void b1_getrevision(avmcard *card)
+{
+    card->class = inb(card->port + B1_ANALYSE);
+    card->revision = inb(card->port + B1_REVISION);
+}
+
 int b1_load_t4file(avmcard *card, capiloaddatapart * t4file)
 {
        unsigned char buf[256];
@@ -688,6 +699,7 @@ int b1ctl_read_proc(char *page, char **start, off_t off,
 EXPORT_SYMBOL(b1_irq_table);
 
 EXPORT_SYMBOL(b1_detect);
+EXPORT_SYMBOL(b1_getrevision);
 EXPORT_SYMBOL(b1_load_t4file);
 EXPORT_SYMBOL(b1_load_config);
 EXPORT_SYMBOL(b1_loaded);
diff --git a/drivers/isdn/avmb1/b1dma.c b/drivers/isdn/avmb1/b1dma.c
new file mode 100644 (file)
index 0000000..d61b883
--- /dev/null
@@ -0,0 +1,987 @@
+/*
+ * $Id: b1dma.c,v 1.3 2000/02/26 01:00:53 keil Exp $
+ * 
+ * Common module for AVM B1 cards that support dma with AMCC
+ * 
+ * (c) Copyright 2000 by Carsten Paeth (calle@calle.in-berlin.de)
+ * 
+ * $Log: b1dma.c,v $
+ * Revision 1.3  2000/02/26 01:00:53  keil
+ * changes from 2.3.47
+ *
+ * Revision 1.2  2000/01/25 14:44:47  calle
+ * typo in b1pciv4_detect().
+ *
+ * Revision 1.1  2000/01/25 14:36:43  calle
+ * common function for  T1 PCI and B1 PCI V4.
+ *
+ *
+ */
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/skbuff.h>
+#include <linux/delay.h>
+#include <linux/mm.h>
+#include <linux/interrupt.h>
+#include <linux/ioport.h>
+#include <linux/capi.h>
+#include <asm/io.h>
+#include <asm/uaccess.h>
+#include "capilli.h"
+#include "avmcard.h"
+#include "capicmd.h"
+#include "capiutil.h"
+
+static char *revision = "$Revision: 1.3 $";
+
+/* ------------------------------------------------------------- */
+
+MODULE_AUTHOR("Carsten Paeth <calle@calle.in-berlin.de>");
+
+int suppress_pollack = 0;
+MODULE_PARM(suppress_pollack, "0-1i");
+
+/* ------------------------------------------------------------- */
+
+static void b1dma_dispatch_tx(avmcard *card);
+
+/* ------------------------------------------------------------- */
+
+/* S5933 */
+
+#define        AMCC_RXPTR      0x24
+#define        AMCC_RXLEN      0x28
+#define        AMCC_TXPTR      0x2c
+#define        AMCC_TXLEN      0x30
+
+#define        AMCC_INTCSR     0x38
+#      define EN_READ_TC_INT           0x00008000L
+#      define EN_WRITE_TC_INT          0x00004000L
+#      define EN_TX_TC_INT             EN_READ_TC_INT
+#      define EN_RX_TC_INT             EN_WRITE_TC_INT
+#      define AVM_FLAG                 0x30000000L
+
+#      define ANY_S5933_INT            0x00800000L
+#      define  READ_TC_INT             0x00080000L
+#      define WRITE_TC_INT             0x00040000L
+#      define  TX_TC_INT               READ_TC_INT
+#      define  RX_TC_INT               WRITE_TC_INT
+#      define MASTER_ABORT_INT         0x00100000L
+#      define TARGET_ABORT_INT         0x00200000L
+#      define BUS_MASTER_INT           0x00200000L
+#      define ALL_INT                  0x000C0000L
+
+#define        AMCC_MCSR       0x3c
+#      define A2P_HI_PRIORITY          0x00000100L
+#      define EN_A2P_TRANSFERS         0x00000400L
+#      define P2A_HI_PRIORITY          0x00001000L
+#      define EN_P2A_TRANSFERS         0x00004000L
+#      define RESET_A2P_FLAGS          0x04000000L
+#      define RESET_P2A_FLAGS          0x02000000L
+
+/* ------------------------------------------------------------- */
+
+#define b1dmaoutmeml(addr, value)      writel(value, addr)
+#define b1dmainmeml(addr)      readl(addr)
+#define b1dmaoutmemw(addr, value)      writew(value, addr)
+#define b1dmainmemw(addr)      readw(addr)
+#define b1dmaoutmemb(addr, value)      writeb(value, addr)
+#define b1dmainmemb(addr)      readb(addr)
+
+/* ------------------------------------------------------------- */
+
+static inline int b1dma_tx_empty(unsigned int port)
+{
+       return inb(port + 0x03) & 0x1;
+}
+
+static inline int b1dma_rx_full(unsigned int port)
+{
+       return inb(port + 0x02) & 0x1;
+}
+
+static int b1dma_tolink(avmcard *card, void *buf, unsigned int len)
+{
+       unsigned long stop = jiffies + 1 * HZ;  /* maximum wait time 1 sec */
+       unsigned char *s = (unsigned char *)buf;
+       while (len--) {
+               while (   !b1dma_tx_empty(card->port)
+                      && time_before(jiffies, stop));
+               if (!b1dma_tx_empty(card->port)) 
+                       return -1;
+               t1outp(card->port, 0x01, *s++);
+       }
+       return 0;
+}
+
+static int b1dma_fromlink(avmcard *card, void *buf, unsigned int len)
+{
+       unsigned long stop = jiffies + 1 * HZ;  /* maximum wait time 1 sec */
+       unsigned char *s = (unsigned char *)buf;
+       while (len--) {
+               while (   !b1dma_rx_full(card->port)
+                      && time_before(jiffies, stop));
+               if (!b1dma_rx_full(card->port)) 
+                       return -1;
+               *s++ = t1inp(card->port, 0x00);
+       }
+       return 0;
+}
+
+static int WriteReg(avmcard *card, __u32 reg, __u8 val)
+{
+       __u8 cmd = 0x00;
+       if (   b1dma_tolink(card, &cmd, 1) == 0
+           && b1dma_tolink(card, &reg, 4) == 0) {
+               __u32 tmp = val;
+               return b1dma_tolink(card, &tmp, 4);
+       }
+       return -1;
+}
+
+static __u8 ReadReg(avmcard *card, __u32 reg)
+{
+       __u8 cmd = 0x01;
+       if (   b1dma_tolink(card, &cmd, 1) == 0
+           && b1dma_tolink(card, &reg, 4) == 0) {
+               __u32 tmp;
+               if (b1dma_fromlink(card, &tmp, 4) == 0)
+                       return (__u8)tmp;
+       }
+       return 0xff;
+}
+
+/* ------------------------------------------------------------- */
+
+static inline void _put_byte(void **pp, __u8 val)
+{
+       __u8 *s = *pp;
+       *s++ = val;
+       *pp = s;
+}
+
+static inline void _put_word(void **pp, __u32 val)
+{
+       __u8 *s = *pp;
+       *s++ = val & 0xff;
+       *s++ = (val >> 8) & 0xff;
+       *s++ = (val >> 16) & 0xff;
+       *s++ = (val >> 24) & 0xff;
+       *pp = s;
+}
+
+static inline void _put_slice(void **pp, unsigned char *dp, unsigned int len)
+{
+       unsigned i = len;
+       _put_word(pp, i);
+       while (i-- > 0)
+               _put_byte(pp, *dp++);
+}
+
+static inline __u8 _get_byte(void **pp)
+{
+       __u8 *s = *pp;
+       __u8 val;
+       val = *s++;
+       *pp = s;
+       return val;
+}
+
+static inline __u32 _get_word(void **pp)
+{
+       __u8 *s = *pp;
+       __u32 val;
+       val = *s++;
+       val |= (*s++ << 8);
+       val |= (*s++ << 16);
+       val |= (*s++ << 24);
+       *pp = s;
+       return val;
+}
+
+static inline __u32 _get_slice(void **pp, unsigned char *dp)
+{
+       unsigned int len, i;
+
+       len = i = _get_word(pp);
+       while (i-- > 0) *dp++ = _get_byte(pp);
+       return len;
+}
+
+/* ------------------------------------------------------------- */
+
+void b1dma_reset(avmcard *card)
+{
+       unsigned long flags;
+
+       save_flags(flags);
+       cli();
+       card->csr = 0x0;
+       b1dmaoutmeml(card->mbase+AMCC_INTCSR, card->csr);
+       b1dmaoutmeml(card->mbase+AMCC_MCSR, 0);
+       b1dmaoutmeml(card->mbase+AMCC_RXLEN, 0);
+       b1dmaoutmeml(card->mbase+AMCC_TXLEN, 0);
+
+       t1outp(card->port, 0x10, 0x00);
+       t1outp(card->port, 0x07, 0x00);
+
+       restore_flags(flags);
+
+       b1dmaoutmeml(card->mbase+AMCC_MCSR, 0);
+       udelay(10 * 1000);
+       b1dmaoutmeml(card->mbase+AMCC_MCSR, 0x0f000000); /* reset all */
+       udelay(10 * 1000);
+       b1dmaoutmeml(card->mbase+AMCC_MCSR, 0);
+       if (card->cardtype == avm_t1pci)
+               udelay(42 * 1000);
+       else
+               udelay(10 * 1000);
+}
+
+/* ------------------------------------------------------------- */
+
+int b1dma_detect(avmcard *card)
+{
+       b1dmaoutmeml(card->mbase+AMCC_MCSR, 0);
+       udelay(10 * 1000);
+       b1dmaoutmeml(card->mbase+AMCC_MCSR, 0x0f000000); /* reset all */
+       udelay(10 * 1000);
+       b1dmaoutmeml(card->mbase+AMCC_MCSR, 0);
+       udelay(42 * 1000);
+
+       b1dmaoutmeml(card->mbase+AMCC_RXLEN, 0);
+       b1dmaoutmeml(card->mbase+AMCC_TXLEN, 0);
+       card->csr = 0x0;
+       b1dmaoutmeml(card->mbase+AMCC_INTCSR, card->csr);
+
+       if (b1dmainmeml(card->mbase+AMCC_MCSR) != 0x000000E6)
+               return 1;
+
+       b1dmaoutmeml(card->mbase+AMCC_RXPTR, 0xffffffff);
+       b1dmaoutmeml(card->mbase+AMCC_TXPTR, 0xffffffff);
+       if (   b1dmainmeml(card->mbase+AMCC_RXPTR) != 0xfffffffc
+           || b1dmainmeml(card->mbase+AMCC_TXPTR) != 0xfffffffc)
+               return 2;
+
+       b1dmaoutmeml(card->mbase+AMCC_RXPTR, 0x0);
+       b1dmaoutmeml(card->mbase+AMCC_TXPTR, 0x0);
+       if (   b1dmainmeml(card->mbase+AMCC_RXPTR) != 0x0
+           || b1dmainmeml(card->mbase+AMCC_TXPTR) != 0x0)
+               return 3;
+
+       t1outp(card->port, 0x10, 0x00);
+       t1outp(card->port, 0x07, 0x00);
+       
+       t1outp(card->port, 0x02, 0x02);
+       t1outp(card->port, 0x03, 0x02);
+
+       if (   (t1inp(card->port, 0x02) & 0xFE) != 0x02
+           || t1inp(card->port, 0x3) != 0x03)
+               return 4;
+
+       t1outp(card->port, 0x02, 0x00);
+       t1outp(card->port, 0x03, 0x00);
+
+       if (   (t1inp(card->port, 0x02) & 0xFE) != 0x00
+           || t1inp(card->port, 0x3) != 0x01)
+               return 5;
+
+       return 0;
+}
+
+int t1pci_detect(avmcard *card)
+{
+       int ret;
+
+       if ((ret = b1dma_detect(card)) != 0)
+               return ret;
+       
+       /* Transputer test */
+       
+       if (   WriteReg(card, 0x80001000, 0x11) != 0
+           || WriteReg(card, 0x80101000, 0x22) != 0
+           || WriteReg(card, 0x80201000, 0x33) != 0
+           || WriteReg(card, 0x80301000, 0x44) != 0)
+               return 6;
+
+       if (   ReadReg(card, 0x80001000) != 0x11
+           || ReadReg(card, 0x80101000) != 0x22
+           || ReadReg(card, 0x80201000) != 0x33
+           || ReadReg(card, 0x80301000) != 0x44)
+               return 7;
+
+       if (   WriteReg(card, 0x80001000, 0x55) != 0
+           || WriteReg(card, 0x80101000, 0x66) != 0
+           || WriteReg(card, 0x80201000, 0x77) != 0
+           || WriteReg(card, 0x80301000, 0x88) != 0)
+               return 8;
+
+       if (   ReadReg(card, 0x80001000) != 0x55
+           || ReadReg(card, 0x80101000) != 0x66
+           || ReadReg(card, 0x80201000) != 0x77
+           || ReadReg(card, 0x80301000) != 0x88)
+               return 9;
+
+       return 0;
+}
+
+int b1pciv4_detect(avmcard *card)
+{
+       int ret, i;
+
+       if ((ret = b1dma_detect(card)) != 0)
+               return ret;
+       
+       for (i=0; i < 5 ; i++) {
+               if (WriteReg(card, 0x80A00000, 0x21) != 0)
+                       return 6;
+               if ((ReadReg(card, 0x80A00000) & 0x01) != 0x01)
+                       return 7;
+       }
+       for (i=0; i < 5 ; i++) {
+               if (WriteReg(card, 0x80A00000, 0x20) != 0)
+                       return 8;
+               if ((ReadReg(card, 0x80A00000) & 0x01) != 0x00)
+                       return 9;
+       }
+       
+       return 0;
+}
+
+/* ------------------------------------------------------------- */
+
+static void b1dma_dispatch_tx(avmcard *card)
+{
+       avmcard_dmainfo *dma = card->dma;
+       unsigned long flags;
+       struct sk_buff *skb;
+       __u8 cmd, subcmd;
+       __u16 len;
+       __u32 txlen;
+       int inint;
+       void *p;
+       
+       save_flags(flags);
+       cli();
+
+       inint = card->interrupt;
+
+       if (card->csr & EN_TX_TC_INT) { /* tx busy */
+               restore_flags(flags);
+               return;
+       }
+
+       skb = skb_dequeue(&dma->send_queue);
+       if (!skb) {
+#ifdef CONFIG_B1DMA_DEBUG
+               printk(KERN_DEBUG "tx(%d): underrun\n", inint);
+#endif
+               restore_flags(flags);
+               return;
+       }
+
+       len = CAPIMSG_LEN(skb->data);
+
+       if (len) {
+               cmd = CAPIMSG_COMMAND(skb->data);
+               subcmd = CAPIMSG_SUBCOMMAND(skb->data);
+
+               p = dma->sendbuf;
+
+               if (CAPICMD(cmd, subcmd) == CAPI_DATA_B3_REQ) {
+                       __u16 dlen = CAPIMSG_DATALEN(skb->data);
+                       _put_byte(&p, SEND_DATA_B3_REQ);
+                       _put_slice(&p, skb->data, len);
+                       _put_slice(&p, skb->data + len, dlen);
+               } else {
+                       _put_byte(&p, SEND_MESSAGE);
+                       _put_slice(&p, skb->data, len);
+               }
+               txlen = (__u8 *)p - (__u8 *)dma->sendbuf;
+#ifdef CONFIG_B1DMA_DEBUG
+               printk(KERN_DEBUG "tx(%d): put msg len=%d\n",
+                               inint, txlen);
+#endif
+       } else {
+               txlen = skb->len-2;
+#ifdef CONFIG_B1DMA_POLLDEBUG
+               if (skb->data[2] == SEND_POLLACK)
+                       printk(KERN_INFO "%s: send ack\n", card->name);
+#endif
+#ifdef CONFIG_B1DMA_DEBUG
+               printk(KERN_DEBUG "tx(%d): put 0x%x len=%d\n",
+                               inint, skb->data[2], txlen);
+#endif
+               memcpy(dma->sendbuf, skb->data+2, skb->len-2);
+       }
+       txlen = (txlen + 3) & ~3;
+
+       b1dmaoutmeml(card->mbase+AMCC_TXPTR, virt_to_phys(dma->sendbuf));
+       b1dmaoutmeml(card->mbase+AMCC_TXLEN, txlen);
+
+       card->csr |= EN_TX_TC_INT;
+
+       if (!inint)
+               b1dmaoutmeml(card->mbase+AMCC_INTCSR, card->csr);
+
+       restore_flags(flags);
+       dev_kfree_skb(skb);
+}
+
+/* ------------------------------------------------------------- */
+
+static void queue_pollack(avmcard *card)
+{
+       struct sk_buff *skb;
+       void *p;
+
+       skb = alloc_skb(3, GFP_ATOMIC);
+       if (!skb) {
+               printk(KERN_CRIT "%s: no memory, lost poll ack\n",
+                                       card->name);
+               return;
+       }
+       p = skb->data;
+       _put_byte(&p, 0);
+       _put_byte(&p, 0);
+       _put_byte(&p, SEND_POLLACK);
+       skb_put(skb, (__u8 *)p - (__u8 *)skb->data);
+
+       skb_queue_tail(&card->dma->send_queue, skb);
+       b1dma_dispatch_tx(card);
+}
+
+/* ------------------------------------------------------------- */
+
+static void b1dma_handle_rx(avmcard *card)
+{
+       avmctrl_info *cinfo = &card->ctrlinfo[0];
+       avmcard_dmainfo *dma = card->dma;
+       struct capi_ctr *ctrl = cinfo->capi_ctrl;
+       struct sk_buff *skb;
+       void *p = dma->recvbuf+4;
+       __u32 ApplId, MsgLen, DataB3Len, NCCI, WindowSize;
+       __u8 b1cmd =  _get_byte(&p);
+
+#ifdef CONFIG_B1DMA_DEBUG
+       printk(KERN_DEBUG "rx: 0x%x %lu\n", b1cmd, (unsigned long)dma->recvlen);
+#endif
+       
+       switch (b1cmd) {
+       case RECEIVE_DATA_B3_IND:
+
+               ApplId = (unsigned) _get_word(&p);
+               MsgLen = _get_slice(&p, card->msgbuf);
+               DataB3Len = _get_slice(&p, card->databuf);
+
+               if (MsgLen < 30) { /* not CAPI 64Bit */
+                       memset(card->msgbuf+MsgLen, 0, 30-MsgLen);
+                       MsgLen = 30;
+                       CAPIMSG_SETLEN(card->msgbuf, 30);
+               }
+               if (!(skb = alloc_skb(DataB3Len+MsgLen, GFP_ATOMIC))) {
+                       printk(KERN_ERR "%s: incoming packet dropped\n",
+                                       card->name);
+               } else {
+                       memcpy(skb_put(skb, MsgLen), card->msgbuf, MsgLen);
+                       memcpy(skb_put(skb, DataB3Len), card->databuf, DataB3Len);
+                       ctrl->handle_capimsg(ctrl, ApplId, skb);
+               }
+               break;
+
+       case RECEIVE_MESSAGE:
+
+               ApplId = (unsigned) _get_word(&p);
+               MsgLen = _get_slice(&p, card->msgbuf);
+               if (!(skb = alloc_skb(MsgLen, GFP_ATOMIC))) {
+                       printk(KERN_ERR "%s: incoming packet dropped\n",
+                                       card->name);
+               } else {
+                       memcpy(skb_put(skb, MsgLen), card->msgbuf, MsgLen);
+                       ctrl->handle_capimsg(ctrl, ApplId, skb);
+               }
+               break;
+
+       case RECEIVE_NEW_NCCI:
+
+               ApplId = _get_word(&p);
+               NCCI = _get_word(&p);
+               WindowSize = _get_word(&p);
+
+               ctrl->new_ncci(ctrl, ApplId, NCCI, WindowSize);
+
+               break;
+
+       case RECEIVE_FREE_NCCI:
+
+               ApplId = _get_word(&p);
+               NCCI = _get_word(&p);
+
+               if (NCCI != 0xffffffff)
+                       ctrl->free_ncci(ctrl, ApplId, NCCI);
+               else ctrl->appl_released(ctrl, ApplId);
+               break;
+
+       case RECEIVE_START:
+#ifdef CONFIG_B1DMA_POLLDEBUG
+               printk(KERN_INFO "%s: receive poll\n", card->name);
+#endif
+               if (!suppress_pollack)
+                       queue_pollack(card);
+               ctrl->resume_output(ctrl);
+               break;
+
+       case RECEIVE_STOP:
+               ctrl->suspend_output(ctrl);
+               break;
+
+       case RECEIVE_INIT:
+
+               cinfo->versionlen = _get_slice(&p, cinfo->versionbuf);
+               b1_parse_version(cinfo);
+               printk(KERN_INFO "%s: %s-card (%s) now active\n",
+                      card->name,
+                      cinfo->version[VER_CARDTYPE],
+                      cinfo->version[VER_DRIVER]);
+               ctrl->ready(ctrl);
+               break;
+
+       case RECEIVE_TASK_READY:
+               ApplId = (unsigned) _get_word(&p);
+               MsgLen = _get_slice(&p, card->msgbuf);
+               card->msgbuf[MsgLen--] = 0;
+               while (    MsgLen >= 0
+                      && (   card->msgbuf[MsgLen] == '\n'
+                          || card->msgbuf[MsgLen] == '\r'))
+                       card->msgbuf[MsgLen--] = 0;
+               printk(KERN_INFO "%s: task %d \"%s\" ready.\n",
+                               card->name, ApplId, card->msgbuf);
+               break;
+
+       case RECEIVE_DEBUGMSG:
+               MsgLen = _get_slice(&p, card->msgbuf);
+               card->msgbuf[MsgLen--] = 0;
+               while (    MsgLen >= 0
+                      && (   card->msgbuf[MsgLen] == '\n'
+                          || card->msgbuf[MsgLen] == '\r'))
+                       card->msgbuf[MsgLen--] = 0;
+               printk(KERN_INFO "%s: DEBUG: %s\n", card->name, card->msgbuf);
+               break;
+
+       default:
+               printk(KERN_ERR "%s: b1dma_interrupt: 0x%x ???\n",
+                               card->name, b1cmd);
+               return;
+       }
+}
+
+/* ------------------------------------------------------------- */
+
+static void b1dma_handle_interrupt(avmcard *card)
+{
+       __u32 status = b1dmainmeml(card->mbase+AMCC_INTCSR);
+       __u32 newcsr;
+
+       if ((status & ANY_S5933_INT) == 0) 
+               return;
+
+        newcsr = card->csr | (status & ALL_INT);
+       if (status & TX_TC_INT) newcsr &= ~EN_TX_TC_INT;
+       if (status & RX_TC_INT) newcsr &= ~EN_RX_TC_INT;
+       b1dmaoutmeml(card->mbase+AMCC_INTCSR, newcsr);
+
+       if ((status & RX_TC_INT) != 0) {
+               __u8 *recvbuf = card->dma->recvbuf;
+               __u32 rxlen;
+               if (card->dma->recvlen == 0) {
+                       card->dma->recvlen = *((__u32 *)recvbuf);
+                       rxlen = (card->dma->recvlen + 3) & ~3;
+                       b1dmaoutmeml(card->mbase+AMCC_RXPTR,
+                                       virt_to_phys(recvbuf+4));
+                       b1dmaoutmeml(card->mbase+AMCC_RXLEN, rxlen);
+               } else {
+                       b1dma_handle_rx(card);
+                       card->dma->recvlen = 0;
+                       b1dmaoutmeml(card->mbase+AMCC_RXPTR, virt_to_phys(recvbuf));
+                       b1dmaoutmeml(card->mbase+AMCC_RXLEN, 4);
+               }
+       }
+
+       if ((status & TX_TC_INT) != 0) {
+               card->csr &= ~EN_TX_TC_INT;
+               b1dma_dispatch_tx(card);
+       } else if (card->csr & EN_TX_TC_INT) {
+               if (b1dmainmeml(card->mbase+AMCC_TXLEN) == 0) {
+                       card->csr &= ~EN_TX_TC_INT;
+                       b1dma_dispatch_tx(card);
+               }
+       }
+       b1dmaoutmeml(card->mbase+AMCC_INTCSR, card->csr);
+}
+
+void b1dma_interrupt(int interrupt, void *devptr, struct pt_regs *regs)
+{
+       avmcard *card;
+
+       card = (avmcard *) devptr;
+
+       if (!card) {
+               printk(KERN_WARNING "b1dma: interrupt: wrong device\n");
+               return;
+       }
+       if (card->interrupt) {
+               printk(KERN_ERR "%s: reentering interrupt hander\n", card->name);
+               return;
+       }
+
+       card->interrupt = 1;
+
+       b1dma_handle_interrupt(card);
+
+       card->interrupt = 0;
+}
+
+/* ------------------------------------------------------------- */
+
+static int b1dma_loaded(avmcard *card)
+{
+       unsigned long stop;
+       unsigned char ans;
+       unsigned long tout = 2;
+       unsigned int base = card->port;
+
+       for (stop = jiffies + tout * HZ; time_before(jiffies, stop);) {
+               if (b1_tx_empty(base))
+                       break;
+       }
+       if (!b1_tx_empty(base)) {
+               printk(KERN_ERR "%s: b1dma_loaded: tx err, corrupted t4 file ?\n",
+                               card->name);
+               return 0;
+       }
+       b1_put_byte(base, SEND_POLLACK);
+       for (stop = jiffies + tout * HZ; time_before(jiffies, stop);) {
+               if (b1_rx_full(base)) {
+                       if ((ans = b1_get_byte(base)) == RECEIVE_POLLDWORD) {
+                               return 1;
+                       }
+                       printk(KERN_ERR "%s: b1dma_loaded: got 0x%x, firmware not running in dword mode\n", card->name, ans);
+                       return 0;
+               }
+       }
+       printk(KERN_ERR "%s: b1dma_loaded: firmware not running\n", card->name);
+       return 0;
+}
+
+/* ------------------------------------------------------------- */
+
+static void b1dma_send_init(avmcard *card)
+{
+       struct sk_buff *skb;
+       void *p;
+
+       skb = alloc_skb(15, GFP_ATOMIC);
+       if (!skb) {
+               printk(KERN_CRIT "%s: no memory, lost register appl.\n",
+                                       card->name);
+               return;
+       }
+       p = skb->data;
+       _put_byte(&p, 0);
+       _put_byte(&p, 0);
+       _put_byte(&p, SEND_INIT);
+       _put_word(&p, AVM_NAPPS);
+       _put_word(&p, AVM_NCCI_PER_CHANNEL*30);
+       _put_word(&p, card->cardnr - 1);
+       skb_put(skb, (__u8 *)p - (__u8 *)skb->data);
+
+       skb_queue_tail(&card->dma->send_queue, skb);
+       b1dma_dispatch_tx(card);
+}
+
+int b1dma_load_firmware(struct capi_ctr *ctrl, capiloaddata *data)
+{
+       avmctrl_info *cinfo = (avmctrl_info *)(ctrl->driverdata);
+       avmcard *card = cinfo->card;
+       unsigned long flags;
+       int retval;
+
+       b1dma_reset(card);
+
+       if ((retval = b1_load_t4file(card, &data->firmware))) {
+               b1dma_reset(card);
+               printk(KERN_ERR "%s: failed to load t4file!!\n",
+                                       card->name);
+               return retval;
+       }
+
+       if (data->configuration.len > 0 && data->configuration.data) {
+               if ((retval = b1_load_config(card, &data->configuration))) {
+                       b1dma_reset(card);
+                       printk(KERN_ERR "%s: failed to load config!!\n",
+                                       card->name);
+                       return retval;
+               }
+       }
+
+       if (!b1dma_loaded(card)) {
+               b1dma_reset(card);
+               printk(KERN_ERR "%s: failed to load t4file.\n", card->name);
+               return -EIO;
+       }
+
+       save_flags(flags);
+       cli();
+
+       card->csr = AVM_FLAG;
+       b1dmaoutmeml(card->mbase+AMCC_INTCSR, card->csr);
+       b1dmaoutmeml(card->mbase+AMCC_MCSR,
+               EN_A2P_TRANSFERS|EN_P2A_TRANSFERS
+               |A2P_HI_PRIORITY|P2A_HI_PRIORITY
+               |RESET_A2P_FLAGS|RESET_P2A_FLAGS);
+       t1outp(card->port, 0x07, 0x30);
+       t1outp(card->port, 0x10, 0xF0);
+
+       card->dma->recvlen = 0;
+       b1dmaoutmeml(card->mbase+AMCC_RXPTR, virt_to_phys(card->dma->recvbuf));
+       b1dmaoutmeml(card->mbase+AMCC_RXLEN, 4);
+       card->csr |= EN_RX_TC_INT;
+       b1dmaoutmeml(card->mbase+AMCC_INTCSR, card->csr);
+       restore_flags(flags);
+
+        b1dma_send_init(card);
+
+       return 0;
+}
+
+void b1dma_reset_ctr(struct capi_ctr *ctrl)
+{
+       avmctrl_info *cinfo = (avmctrl_info *)(ctrl->driverdata);
+       avmcard *card = cinfo->card;
+
+       b1dma_reset(card);
+
+       memset(cinfo->version, 0, sizeof(cinfo->version));
+       ctrl->reseted(ctrl);
+}
+
+
+/* ------------------------------------------------------------- */
+
+
+void b1dma_register_appl(struct capi_ctr *ctrl,
+                               __u16 appl,
+                               capi_register_params *rp)
+{
+       avmctrl_info *cinfo = (avmctrl_info *)(ctrl->driverdata);
+       avmcard *card = cinfo->card;
+       struct sk_buff *skb;
+       int want = rp->level3cnt;
+       int nconn;
+       void *p;
+
+       if (want > 0) nconn = want;
+       else nconn = ctrl->profile.nbchannel * -want;
+       if (nconn == 0) nconn = ctrl->profile.nbchannel;
+
+       skb = alloc_skb(23, GFP_ATOMIC);
+       if (!skb) {
+               printk(KERN_CRIT "%s: no memory, lost register appl.\n",
+                                       card->name);
+               return;
+       }
+       p = skb->data;
+       _put_byte(&p, 0);
+       _put_byte(&p, 0);
+       _put_byte(&p, SEND_REGISTER);
+       _put_word(&p, appl);
+       _put_word(&p, 1024 * (nconn+1));
+       _put_word(&p, nconn);
+       _put_word(&p, rp->datablkcnt);
+       _put_word(&p, rp->datablklen);
+       skb_put(skb, (__u8 *)p - (__u8 *)skb->data);
+
+       skb_queue_tail(&card->dma->send_queue, skb);
+       b1dma_dispatch_tx(card);
+
+       ctrl->appl_registered(ctrl, appl);
+}
+
+/* ------------------------------------------------------------- */
+
+void b1dma_release_appl(struct capi_ctr *ctrl, __u16 appl)
+{
+       avmctrl_info *cinfo = (avmctrl_info *)(ctrl->driverdata);
+       avmcard *card = cinfo->card;
+       struct sk_buff *skb;
+       void *p;
+
+       skb = alloc_skb(7, GFP_ATOMIC);
+       if (!skb) {
+               printk(KERN_CRIT "%s: no memory, lost release appl.\n",
+                                       card->name);
+               return;
+       }
+       p = skb->data;
+       _put_byte(&p, 0);
+       _put_byte(&p, 0);
+       _put_byte(&p, SEND_RELEASE);
+       _put_word(&p, appl);
+
+       skb_put(skb, (__u8 *)p - (__u8 *)skb->data);
+       skb_queue_tail(&card->dma->send_queue, skb);
+       b1dma_dispatch_tx(card);
+}
+
+/* ------------------------------------------------------------- */
+
+void b1dma_send_message(struct capi_ctr *ctrl, struct sk_buff *skb)
+{
+       avmctrl_info *cinfo = (avmctrl_info *)(ctrl->driverdata);
+       avmcard *card = cinfo->card;
+       skb_queue_tail(&card->dma->send_queue, skb);
+       b1dma_dispatch_tx(card);
+}
+
+/* ------------------------------------------------------------- */
+
+int b1dmactl_read_proc(char *page, char **start, off_t off,
+                       int count, int *eof, struct capi_ctr *ctrl)
+{
+       avmctrl_info *cinfo = (avmctrl_info *)(ctrl->driverdata);
+       avmcard *card = cinfo->card;
+       unsigned long flags;
+       __u8 flag;
+       int len = 0;
+       char *s;
+       __u32 txaddr, txlen, rxaddr, rxlen, csr;
+
+       len += sprintf(page+len, "%-16s %s\n", "name", card->name);
+       len += sprintf(page+len, "%-16s 0x%x\n", "io", card->port);
+       len += sprintf(page+len, "%-16s %d\n", "irq", card->irq);
+       len += sprintf(page+len, "%-16s 0x%lx\n", "membase", card->membase);
+       switch (card->cardtype) {
+       case avm_b1isa: s = "B1 ISA"; break;
+       case avm_b1pci: s = "B1 PCI"; break;
+       case avm_b1pcmcia: s = "B1 PCMCIA"; break;
+       case avm_m1: s = "M1"; break;
+       case avm_m2: s = "M2"; break;
+       case avm_t1isa: s = "T1 ISA (HEMA)"; break;
+       case avm_t1pci: s = "T1 PCI"; break;
+       case avm_c4: s = "C4"; break;
+       default: s = "???"; break;
+       }
+       len += sprintf(page+len, "%-16s %s\n", "type", s);
+       if ((s = cinfo->version[VER_DRIVER]) != 0)
+          len += sprintf(page+len, "%-16s %s\n", "ver_driver", s);
+       if ((s = cinfo->version[VER_CARDTYPE]) != 0)
+          len += sprintf(page+len, "%-16s %s\n", "ver_cardtype", s);
+       if ((s = cinfo->version[VER_SERIAL]) != 0)
+          len += sprintf(page+len, "%-16s %s\n", "ver_serial", s);
+
+       if (card->cardtype != avm_m1) {
+               flag = ((__u8 *)(ctrl->profile.manu))[3];
+               if (flag)
+                       len += sprintf(page+len, "%-16s%s%s%s%s%s%s%s\n",
+                       "protocol",
+                       (flag & 0x01) ? " DSS1" : "",
+                       (flag & 0x02) ? " CT1" : "",
+                       (flag & 0x04) ? " VN3" : "",
+                       (flag & 0x08) ? " NI1" : "",
+                       (flag & 0x10) ? " AUSTEL" : "",
+                       (flag & 0x20) ? " ESS" : "",
+                       (flag & 0x40) ? " 1TR6" : ""
+                       );
+       }
+       if (card->cardtype != avm_m1) {
+               flag = ((__u8 *)(ctrl->profile.manu))[5];
+               if (flag)
+                       len += sprintf(page+len, "%-16s%s%s%s%s\n",
+                       "linetype",
+                       (flag & 0x01) ? " point to point" : "",
+                       (flag & 0x02) ? " point to multipoint" : "",
+                       (flag & 0x08) ? " leased line without D-channel" : "",
+                       (flag & 0x04) ? " leased line with D-channel" : ""
+                       );
+       }
+       len += sprintf(page+len, "%-16s %s\n", "cardname", cinfo->cardname);
+
+       save_flags(flags);
+       cli();
+
+       txaddr = (__u32)phys_to_virt(b1dmainmeml(card->mbase+0x2c));
+       txaddr -= (__u32)card->dma->sendbuf;
+       txlen  = b1dmainmeml(card->mbase+0x30);
+
+       rxaddr = (__u32)phys_to_virt(b1dmainmeml(card->mbase+0x24));
+       rxaddr -= (__u32)card->dma->recvbuf;
+       rxlen  = b1dmainmeml(card->mbase+0x28);
+
+       csr  = b1dmainmeml(card->mbase+AMCC_INTCSR);
+
+       restore_flags(flags);
+
+        len += sprintf(page+len, "%-16s 0x%lx\n",
+                               "csr (cached)", (unsigned long)card->csr);
+        len += sprintf(page+len, "%-16s 0x%lx\n",
+                               "csr", (unsigned long)csr);
+        len += sprintf(page+len, "%-16s %lu\n",
+                               "txoff", (unsigned long)txaddr);
+        len += sprintf(page+len, "%-16s %lu\n",
+                               "txlen", (unsigned long)txlen);
+        len += sprintf(page+len, "%-16s %lu\n",
+                               "rxoff", (unsigned long)rxaddr);
+        len += sprintf(page+len, "%-16s %lu\n",
+                               "rxlen", (unsigned long)rxlen);
+
+       if (off+count >= len)
+          *eof = 1;
+       if (len < off)
+           return 0;
+       *start = page + off;
+       return ((count < len-off) ? count : len-off);
+}
+
+/* ------------------------------------------------------------- */
+
+EXPORT_SYMBOL(b1dma_reset);
+EXPORT_SYMBOL(t1pci_detect);
+EXPORT_SYMBOL(b1pciv4_detect);
+EXPORT_SYMBOL(b1dma_interrupt);
+
+EXPORT_SYMBOL(b1dma_load_firmware);
+EXPORT_SYMBOL(b1dma_reset_ctr);
+EXPORT_SYMBOL(b1dma_register_appl);
+EXPORT_SYMBOL(b1dma_release_appl);
+EXPORT_SYMBOL(b1dma_send_message);
+EXPORT_SYMBOL(b1dmactl_read_proc);
+
+#ifdef MODULE
+#define b1dma_init init_module
+void cleanup_module(void);
+#endif
+
+int b1dma_init(void)
+{
+       char *p;
+       char rev[10];
+
+       if ((p = strchr(revision, ':'))) {
+               strncpy(rev, p + 1, sizeof(rev));
+               p = strchr(rev, '$');
+               *p = 0;
+       } else
+               strcpy(rev, "1.0");
+
+       printk(KERN_INFO "b1dma: revision %s\n", rev);
+
+       return 0;
+}
+
+#ifdef MODULE
+void cleanup_module(void)
+{
+}
+#endif
index 01972b2d21df5a8dbaf3541cc7bec48428463b17..590e825b6d82e0d41060c8ffc8f477f709d96330 100644 (file)
@@ -1,11 +1,19 @@
 /*
- * $Id: b1isa.c,v 1.5 1999/11/05 16:38:01 calle Exp $
+ * $Id: b1isa.c,v 1.7 2000/02/02 18:36:03 calle Exp $
  * 
  * Module for AVM B1 ISA-card.
  * 
  * (c) Copyright 1999 by Carsten Paeth (calle@calle.in-berlin.de)
  * 
  * $Log: b1isa.c,v $
+ * Revision 1.7  2000/02/02 18:36:03  calle
+ * - Modules are now locked while init_module is running
+ * - fixed problem with memory mapping if address is not aligned
+ *
+ * Revision 1.6  2000/01/25 14:37:39  calle
+ * new message after successfull detection including card revision and
+ * used resources.
+ *
  * Revision 1.5  1999/11/05 16:38:01  calle
  * Cleanups before kernel 2.4:
  * - Changed all messages to use card->name or driver->name instead of
@@ -61,7 +69,7 @@
 #include "capilli.h"
 #include "avmcard.h"
 
-static char *revision = "$Revision: 1.5 $";
+static char *revision = "$Revision: 1.7 $";
 
 /* ------------------------------------------------------------- */
 
@@ -69,10 +77,6 @@ MODULE_AUTHOR("Carsten Paeth <calle@calle.in-berlin.de>");
 
 /* ------------------------------------------------------------- */
 
-static struct capi_driver_interface *di;
-
-/* ------------------------------------------------------------- */
-
 static void b1isa_interrupt(int interrupt, void *devptr, struct pt_regs *regs)
 {
        avmcard *card;
@@ -96,6 +100,10 @@ static void b1isa_interrupt(int interrupt, void *devptr, struct pt_regs *regs)
 }
 /* ------------------------------------------------------------- */
 
+static struct capi_driver_interface *di;
+
+/* ------------------------------------------------------------- */
+
 static void b1isa_remove_ctr(struct capi_ctr *ctrl)
 {
        avmctrl_info *cinfo = (avmctrl_info *)(ctrl->driverdata);
@@ -122,10 +130,13 @@ static int b1isa_add_card(struct capi_driver *driver, struct capicardparams *p)
        avmcard *card;
        int retval;
 
+       MOD_INC_USE_COUNT;
+
        card = (avmcard *) kmalloc(sizeof(avmcard), GFP_ATOMIC);
 
        if (!card) {
                printk(KERN_WARNING "b1isa: no memory.\n");
+               MOD_DEC_USE_COUNT;
                return -ENOMEM;
        }
        memset(card, 0, sizeof(avmcard));
@@ -133,6 +144,7 @@ static int b1isa_add_card(struct capi_driver *driver, struct capicardparams *p)
        if (!cinfo) {
                printk(KERN_WARNING "b1isa: no memory.\n");
                kfree(card);
+               MOD_DEC_USE_COUNT;
                return -ENOMEM;
        }
        memset(cinfo, 0, sizeof(avmctrl_info));
@@ -149,12 +161,14 @@ static int b1isa_add_card(struct capi_driver *driver, struct capicardparams *p)
                       card->port, card->port + AVMB1_PORTLEN);
                kfree(card->ctrlinfo);
                kfree(card);
+               MOD_DEC_USE_COUNT;
                return -EBUSY;
        }
        if (b1_irq_table[card->irq & 0xf] == 0) {
                printk(KERN_WARNING "b1isa: irq %d not valid.\n", card->irq);
                kfree(card->ctrlinfo);
                kfree(card);
+               MOD_DEC_USE_COUNT;
                return -EINVAL;
        }
        if (   card->port != 0x150 && card->port != 0x250
@@ -162,6 +176,7 @@ static int b1isa_add_card(struct capi_driver *driver, struct capicardparams *p)
                printk(KERN_WARNING "b1isa: illegal port 0x%x.\n", card->port);
                kfree(card->ctrlinfo);
                kfree(card);
+               MOD_DEC_USE_COUNT;
                return -EINVAL;
        }
        b1_reset(card->port);
@@ -170,9 +185,11 @@ static int b1isa_add_card(struct capi_driver *driver, struct capicardparams *p)
                                        card->port, retval);
                kfree(card->ctrlinfo);
                kfree(card);
+               MOD_DEC_USE_COUNT;
                return -EIO;
        }
        b1_reset(card->port);
+       b1_getrevision(card);
 
        request_region(p->port, AVMB1_PORTLEN, card->name);
 
@@ -182,6 +199,7 @@ static int b1isa_add_card(struct capi_driver *driver, struct capicardparams *p)
                release_region(card->port, AVMB1_PORTLEN);
                kfree(card->ctrlinfo);
                kfree(card);
+               MOD_DEC_USE_COUNT;
                return -EBUSY;
        }
 
@@ -192,10 +210,14 @@ static int b1isa_add_card(struct capi_driver *driver, struct capicardparams *p)
                release_region(card->port, AVMB1_PORTLEN);
                kfree(card->ctrlinfo);
                kfree(card);
+               MOD_DEC_USE_COUNT;
                return -EBUSY;
        }
 
-       MOD_INC_USE_COUNT;
+       printk(KERN_INFO
+               "%s: AVM B1 ISA at i/o %#x, irq %d, revision %d\n",
+               driver->name, card->port, card->irq, card->revision);
+
        return 0;
 }
 
@@ -205,11 +227,12 @@ static char *b1isa_procinfo(struct capi_ctr *ctrl)
 
        if (!cinfo)
                return "";
-       sprintf(cinfo->infobuf, "%s %s 0x%x %d",
+       sprintf(cinfo->infobuf, "%s %s 0x%x %d r%d",
                cinfo->cardname[0] ? cinfo->cardname : "-",
                cinfo->version[VER_DRIVER] ? cinfo->version[VER_DRIVER] : "-",
                cinfo->card ? cinfo->card->port : 0x0,
-               cinfo->card ? cinfo->card->irq : 0
+               cinfo->card ? cinfo->card->irq : 0,
+               cinfo->card ? cinfo->card->revision : 0
                );
        return cinfo->infobuf;
 }
index b494b614e322d57600d64a78b1b448200d2b1a66..c41fa2ad470711e9046cc20d170283f095a7967e 100644 (file)
@@ -1,11 +1,20 @@
 /*
- * $Id: b1pci.c,v 1.18 1999/11/05 16:38:01 calle Exp $
+ * $Id: b1pci.c,v 1.20 2000/02/02 18:36:03 calle Exp $
  * 
  * Module for AVM B1 PCI-card.
  * 
  * (c) Copyright 1999 by Carsten Paeth (calle@calle.in-berlin.de)
  * 
  * $Log: b1pci.c,v $
+ * Revision 1.20  2000/02/02 18:36:03  calle
+ * - Modules are now locked while init_module is running
+ * - fixed problem with memory mapping if address is not aligned
+ *
+ * Revision 1.19  2000/01/25 14:33:38  calle
+ * - Added Support AVM B1 PCI V4.0 (tested with prototype)
+ *   - splitted up t1pci.c into b1dma.c for common function with b1pciv4
+ *   - support for revision register
+ *
  * Revision 1.18  1999/11/05 16:38:01  calle
  * Cleanups before kernel 2.4:
  * - Changed all messages to use card->name or driver->name instead of
@@ -66,7 +75,7 @@
 #include "capilli.h"
 #include "avmcard.h"
 
-static char *revision = "$Revision: 1.18 $";
+static char *revision = "$Revision: 1.20 $";
 
 /* ------------------------------------------------------------- */
 
@@ -138,11 +147,12 @@ static char *b1pci_procinfo(struct capi_ctr *ctrl)
 
        if (!cinfo)
                return "";
-       sprintf(cinfo->infobuf, "%s %s 0x%x %d",
+       sprintf(cinfo->infobuf, "%s %s 0x%x %d r%d",
                cinfo->cardname[0] ? cinfo->cardname : "-",
                cinfo->version[VER_DRIVER] ? cinfo->version[VER_DRIVER] : "-",
                cinfo->card ? cinfo->card->port : 0x0,
-               cinfo->card ? cinfo->card->irq : 0
+               cinfo->card ? cinfo->card->irq : 0,
+               cinfo->card ? cinfo->card->revision : 0
                );
        return cinfo->infobuf;
 }
@@ -155,10 +165,13 @@ static int b1pci_add_card(struct capi_driver *driver, struct capicardparams *p)
        avmctrl_info *cinfo;
        int retval;
 
+       MOD_INC_USE_COUNT;
+
        card = (avmcard *) kmalloc(sizeof(avmcard), GFP_ATOMIC);
 
        if (!card) {
                printk(KERN_WARNING "%s: no memory.\n", driver->name);
+               MOD_DEC_USE_COUNT;
                return -ENOMEM;
        }
        memset(card, 0, sizeof(avmcard));
@@ -166,6 +179,7 @@ static int b1pci_add_card(struct capi_driver *driver, struct capicardparams *p)
        if (!cinfo) {
                printk(KERN_WARNING "%s: no memory.\n", driver->name);
                kfree(card);
+               MOD_DEC_USE_COUNT;
                return -ENOMEM;
        }
        memset(cinfo, 0, sizeof(avmctrl_info));
@@ -182,6 +196,7 @@ static int b1pci_add_card(struct capi_driver *driver, struct capicardparams *p)
                       driver->name, card->port, card->port + AVMB1_PORTLEN);
                kfree(card->ctrlinfo);
                kfree(card);
+               MOD_DEC_USE_COUNT;
                return -EBUSY;
        }
        b1_reset(card->port);
@@ -190,9 +205,11 @@ static int b1pci_add_card(struct capi_driver *driver, struct capicardparams *p)
                                        driver->name, card->port, retval);
                kfree(card->ctrlinfo);
                kfree(card);
+               MOD_DEC_USE_COUNT;
                return -EIO;
        }
        b1_reset(card->port);
+       b1_getrevision(card);
 
        request_region(p->port, AVMB1_PORTLEN, card->name);
 
@@ -203,6 +220,7 @@ static int b1pci_add_card(struct capi_driver *driver, struct capicardparams *p)
                release_region(card->port, AVMB1_PORTLEN);
                kfree(card->ctrlinfo);
                kfree(card);
+               MOD_DEC_USE_COUNT;
                return -EBUSY;
        }
 
@@ -214,10 +232,19 @@ static int b1pci_add_card(struct capi_driver *driver, struct capicardparams *p)
                release_region(card->port, AVMB1_PORTLEN);
                kfree(card->ctrlinfo);
                kfree(card);
+               MOD_DEC_USE_COUNT;
                return -EBUSY;
        }
 
-       MOD_INC_USE_COUNT;
+       if (card->revision >= 4) {
+               printk(KERN_INFO
+                       "%s: AVM B1 PCI V4 at i/o %#x, irq %d, revision %d (no dma)\n",
+                       driver->name, card->port, card->irq, card->revision);
+       } else {
+               printk(KERN_INFO
+                       "%s: AVM B1 PCI at i/o %#x, irq %d, revision %d\n",
+                       driver->name, card->port, card->irq, card->revision);
+       }
 
        return 0;
 }
@@ -241,6 +268,187 @@ static struct capi_driver b1pci_driver = {
     0, /* no add_card function */
 };
 
+#ifdef CONFIG_ISDN_DRV_AVMB1_B1PCIV4
+/* ------------------------------------------------------------- */
+
+static struct capi_driver_interface *div4;
+
+/* ------------------------------------------------------------- */
+
+static void b1pciv4_remove_ctr(struct capi_ctr *ctrl)
+{
+       avmctrl_info *cinfo = (avmctrl_info *)(ctrl->driverdata);
+       avmcard *card = cinfo->card;
+
+       b1dma_reset(card);
+
+       div4->detach_ctr(ctrl);
+       free_irq(card->irq, card);
+       iounmap((void *) (((unsigned long) card->mbase) & PAGE_MASK));
+       release_region(card->port, AVMB1_PORTLEN);
+       ctrl->driverdata = 0;
+       kfree(card->ctrlinfo);
+       kfree(card->dma);
+       kfree(card);
+
+       MOD_DEC_USE_COUNT;
+}
+
+static char *b1pciv4_procinfo(struct capi_ctr *ctrl)
+{
+       avmctrl_info *cinfo = (avmctrl_info *)(ctrl->driverdata);
+
+       if (!cinfo)
+               return "";
+       sprintf(cinfo->infobuf, "%s %s 0x%x %d 0x%lx r%d",
+               cinfo->cardname[0] ? cinfo->cardname : "-",
+               cinfo->version[VER_DRIVER] ? cinfo->version[VER_DRIVER] : "-",
+               cinfo->card ? cinfo->card->port : 0x0,
+               cinfo->card ? cinfo->card->irq : 0,
+               cinfo->card ? cinfo->card->membase : 0,
+               cinfo->card ? cinfo->card->revision : 0
+               );
+       return cinfo->infobuf;
+}
+
+/* ------------------------------------------------------------- */
+
+static int b1pciv4_add_card(struct capi_driver *driver, struct capicardparams *p)
+{
+       unsigned long base, page_offset;
+       avmcard *card;
+       avmctrl_info *cinfo;
+       int retval;
+
+       card = (avmcard *) kmalloc(sizeof(avmcard), GFP_ATOMIC);
+
+       if (!card) {
+               printk(KERN_WARNING "%s: no memory.\n", driver->name);
+               return -ENOMEM;
+       }
+       memset(card, 0, sizeof(avmcard));
+       card->dma = (avmcard_dmainfo *) kmalloc(sizeof(avmcard_dmainfo), GFP_ATOMIC);
+       if (!card->dma) {
+               printk(KERN_WARNING "%s: no memory.\n", driver->name);
+               kfree(card);
+               return -ENOMEM;
+       }
+       memset(card->dma, 0, sizeof(avmcard_dmainfo));
+        cinfo = (avmctrl_info *) kmalloc(sizeof(avmctrl_info), GFP_ATOMIC);
+       if (!cinfo) {
+               printk(KERN_WARNING "%s: no memory.\n", driver->name);
+               kfree(card->dma);
+               kfree(card);
+               return -ENOMEM;
+       }
+       memset(cinfo, 0, sizeof(avmctrl_info));
+       card->ctrlinfo = cinfo;
+       cinfo->card = card;
+       sprintf(card->name, "b1pciv4-%x", p->port);
+       card->port = p->port;
+       card->irq = p->irq;
+       card->membase = p->membase;
+       card->cardtype = avm_b1pci;
+
+       if (check_region(card->port, AVMB1_PORTLEN)) {
+               printk(KERN_WARNING
+                      "%s: ports 0x%03x-0x%03x in use.\n",
+                      driver->name, card->port, card->port + AVMB1_PORTLEN);
+               kfree(card->ctrlinfo);
+               kfree(card->dma);
+               kfree(card);
+               return -EBUSY;
+       }
+
+       base = card->membase & PAGE_MASK;
+       page_offset = card->membase - base;
+       card->mbase = ioremap_nocache(base, page_offset + 64);
+       if (card->mbase) {
+               card->mbase += page_offset;
+       } else {
+               printk(KERN_NOTICE "%s: can't remap memory at 0x%lx\n",
+                                       driver->name, card->membase);
+               kfree(card->ctrlinfo);
+               kfree(card->dma);
+               kfree(card);
+               return -EIO;
+       }
+
+       b1dma_reset(card);
+
+       if ((retval = b1pciv4_detect(card)) != 0) {
+               printk(KERN_NOTICE "%s: NO card at 0x%x (%d)\n",
+                                       driver->name, card->port, retval);
+                iounmap((void *) (((unsigned long) card->mbase) & PAGE_MASK));
+               kfree(card->ctrlinfo);
+               kfree(card->dma);
+               kfree(card);
+               return -EIO;
+       }
+       b1dma_reset(card);
+       b1_getrevision(card);
+
+       request_region(p->port, AVMB1_PORTLEN, card->name);
+
+       retval = request_irq(card->irq, b1dma_interrupt, SA_SHIRQ, card->name, card);
+       if (retval) {
+               printk(KERN_ERR "%s: unable to get IRQ %d.\n",
+                               driver->name, card->irq);
+                iounmap((void *) (((unsigned long) card->mbase) & PAGE_MASK));
+               release_region(card->port, AVMB1_PORTLEN);
+               kfree(card->ctrlinfo);
+               kfree(card->dma);
+               kfree(card);
+               return -EBUSY;
+       }
+
+       cinfo->capi_ctrl = div4->attach_ctr(driver, card->name, cinfo);
+       if (!cinfo->capi_ctrl) {
+               printk(KERN_ERR "%s: attach controller failed.\n", driver->name);
+                iounmap((void *) (((unsigned long) card->mbase) & PAGE_MASK));
+               free_irq(card->irq, card);
+               release_region(card->port, AVMB1_PORTLEN);
+               kfree(card->ctrlinfo);
+               kfree(card->dma);
+               kfree(card);
+               return -EBUSY;
+       }
+       card->cardnr = cinfo->capi_ctrl->cnr;
+
+       skb_queue_head_init(&card->dma->send_queue);
+
+       printk(KERN_INFO
+               "%s: AVM B1 PCI V4 at i/o %#x, irq %d, mem %#lx, revision %d (dma)\n",
+               driver->name, card->port, card->irq,
+               card->membase, card->revision);
+
+       MOD_INC_USE_COUNT;
+
+       return 0;
+}
+
+/* ------------------------------------------------------------- */
+
+
+static struct capi_driver b1pciv4_driver = {
+    "b1pciv4",
+    "0.0",
+    b1dma_load_firmware,
+    b1dma_reset_ctr,
+    b1pciv4_remove_ctr,
+    b1dma_register_appl,
+    b1dma_release_appl,
+    b1dma_send_message,
+
+    b1pciv4_procinfo,
+    b1dmactl_read_proc,
+    0, /* use standard driver_read_proc */
+
+    0, /* no add_card function */
+};
+
+#endif /* CONFIG_ISDN_DRV_AVMB1_B1PCIV4 */
+
 #ifdef MODULE
 #define b1pci_init init_module
 void cleanup_module(void);
@@ -248,9 +456,55 @@ void cleanup_module(void);
 
 static int ncards = 0;
 
+static int add_card(struct pci_dev *dev)
+{
+       struct capi_driver *driver = &b1pci_driver;
+       struct capicardparams param;
+       int retval;
+
+       if (dev->base_address[ 2] & PCI_BASE_ADDRESS_IO_MASK) { /* B1 PCI V4 */
+#ifdef CONFIG_ISDN_DRV_AVMB1_B1PCIV4
+               driver = &b1pciv4_driver;
+#endif
+               param.membase = dev->base_address[ 0] & PCI_BASE_ADDRESS_MEM_MASK;
+               param.port = dev->base_address[ 2] & PCI_BASE_ADDRESS_IO_MASK;
+               param.irq = dev->irq;
+               printk(KERN_INFO
+               "%s: PCI BIOS reports AVM-B1 V4 at i/o %#x, irq %d, mem %#x\n",
+               driver->name, param.port, param.irq, param.membase);
+#ifdef CONFIG_ISDN_DRV_AVMB1_B1PCIV4
+               retval = b1pciv4_add_card(driver, &param);
+#else
+               retval = b1pci_add_card(driver, &param);
+#endif
+               if (retval != 0) {
+                       printk(KERN_ERR
+                       "%s: no AVM-B1 V4 at i/o %#x, irq %d, mem %#x detected\n",
+                       driver->name, param.port, param.irq, param.membase);
+               }
+       } else {
+               param.membase = 0;
+               param.port = dev->base_address[ 1] & PCI_BASE_ADDRESS_IO_MASK;
+               param.irq = dev->irq;
+               printk(KERN_INFO
+               "%s: PCI BIOS reports AVM-B1 at i/o %#x, irq %d\n",
+               driver->name, param.port, param.irq);
+               retval = b1pci_add_card(driver, &param);
+               if (retval != 0) {
+                       printk(KERN_ERR
+                       "%s: no AVM-B1 at i/o %#x, irq %d detected\n",
+                       driver->name, param.port, param.irq);
+               }
+       }
+       return retval;
+}
+
 int b1pci_init(void)
 {
        struct capi_driver *driver = &b1pci_driver;
+#ifdef CONFIG_ISDN_DRV_AVMB1_B1PCIV4
+       struct capi_driver *driverv4 = &b1pciv4_driver;
+#endif
        struct pci_dev *dev = NULL;
        char *p;
        int retval;
@@ -271,26 +525,32 @@ int b1pci_init(void)
                return -EIO;
        }
 
+#ifdef CONFIG_ISDN_DRV_AVMB1_B1PCIV4
+       printk(KERN_INFO "%s: revision %s\n", driverv4->name, driverv4->revision);
+
+        div4 = attach_capi_driver(driverv4);
+
+       if (!div4) {
+               detach_capi_driver(driver);
+               printk(KERN_ERR "%s: failed to attach capi_driver\n",
+                               driverv4->name);
+               return -EIO;
+       }
+#endif
+
 #ifdef CONFIG_PCI
        if (!pci_present()) {
                printk(KERN_ERR "%s: no PCI bus present\n", driver->name);
                detach_capi_driver(driver);
+#ifdef CONFIG_ISDN_DRV_AVMB1_B1PCIV4
+               detach_capi_driver(driverv4);
+#endif
                return -EIO;
        }
 
        while ((dev = pci_find_device(PCI_VENDOR_ID_AVM, PCI_DEVICE_ID_AVM_B1, dev))) {
-               struct capicardparams param;
-
-               param.port = dev->base_address[ 1] & PCI_BASE_ADDRESS_IO_MASK;
-               param.irq = dev->irq;
-               printk(KERN_INFO
-                       "%s: PCI BIOS reports AVM-B1 at i/o %#x, irq %d\n",
-                       driver->name, param.port, param.irq);
-               retval = b1pci_add_card(driver, &param);
+               retval = add_card(dev);
                if (retval != 0) {
-                       printk(KERN_ERR
-                       "%s: no AVM-B1 at i/o %#x, irq %d detected\n",
-                       driver->name, param.port, param.irq);
 #ifdef MODULE
                        cleanup_module();
 #endif
@@ -315,5 +575,8 @@ int b1pci_init(void)
 void cleanup_module(void)
 {
     detach_capi_driver(&b1pci_driver);
+#ifdef CONFIG_ISDN_DRV_AVMB1_B1PCIV4
+    detach_capi_driver(&b1pciv4_driver);
+#endif
 }
 #endif
index 79e34316481adec4deb2182a0bb8fbdced68f3c3..6e39c43d2b685a94c94939c281141aa926ea6f0b 100644 (file)
@@ -1,11 +1,19 @@
 /*
- * $Id: b1pcmcia.c,v 1.5 1999/11/05 16:38:01 calle Exp $
+ * $Id: b1pcmcia.c,v 1.7 2000/02/02 18:36:03 calle Exp $
  * 
  * Module for AVM B1/M1/M2 PCMCIA-card.
  * 
  * (c) Copyright 1999 by Carsten Paeth (calle@calle.in-berlin.de)
  * 
  * $Log: b1pcmcia.c,v $
+ * Revision 1.7  2000/02/02 18:36:03  calle
+ * - Modules are now locked while init_module is running
+ * - fixed problem with memory mapping if address is not aligned
+ *
+ * Revision 1.6  2000/01/25 14:37:39  calle
+ * new message after successfull detection including card revision and
+ * used resources.
+ *
  * Revision 1.5  1999/11/05 16:38:01  calle
  * Cleanups before kernel 2.4:
  * - Changed all messages to use card->name or driver->name instead of
@@ -62,7 +70,7 @@
 #include "capilli.h"
 #include "avmcard.h"
 
-static char *revision = "$Revision: 1.5 $";
+static char *revision = "$Revision: 1.7 $";
 
 /* ------------------------------------------------------------- */
 
@@ -126,12 +134,16 @@ static int b1pcmcia_add_card(struct capi_driver *driver,
 {
        avmctrl_info *cinfo;
        avmcard *card;
+       char *cardname;
        int retval;
 
+       MOD_INC_USE_COUNT;
+
        card = (avmcard *) kmalloc(sizeof(avmcard), GFP_ATOMIC);
 
        if (!card) {
                printk(KERN_WARNING "%s: no memory.\n", driver->name);
+               MOD_DEC_USE_COUNT;
                return -ENOMEM;
        }
        memset(card, 0, sizeof(avmcard));
@@ -139,6 +151,7 @@ static int b1pcmcia_add_card(struct capi_driver *driver,
        if (!cinfo) {
                printk(KERN_WARNING "%s: no memory.\n", driver->name);
                kfree(card);
+               MOD_DEC_USE_COUNT;
                return -ENOMEM;
        }
        memset(cinfo, 0, sizeof(avmctrl_info));
@@ -159,9 +172,11 @@ static int b1pcmcia_add_card(struct capi_driver *driver,
                                        driver->name, card->port, retval);
                kfree(card->ctrlinfo);
                kfree(card);
+               MOD_DEC_USE_COUNT;
                return -EIO;
        }
        b1_reset(card->port);
+       b1_getrevision(card);
 
        retval = request_irq(card->irq, b1pcmcia_interrupt, 0, card->name, card);
        if (retval) {
@@ -169,6 +184,7 @@ static int b1pcmcia_add_card(struct capi_driver *driver,
                                driver->name, card->irq);
                kfree(card->ctrlinfo);
                kfree(card);
+               MOD_DEC_USE_COUNT;
                return -EBUSY;
        }
 
@@ -179,10 +195,19 @@ static int b1pcmcia_add_card(struct capi_driver *driver,
                free_irq(card->irq, card);
                kfree(card->ctrlinfo);
                kfree(card);
+               MOD_DEC_USE_COUNT;
                return -EBUSY;
        }
+       switch (cardtype) {
+               case avm_m1: cardname = "M1"; break;
+               case avm_m2: cardname = "M2"; break;
+               default    : cardname = "B1 PCMCIA"; break;
+       }
+
+       printk(KERN_INFO
+               "%s: AVM %s at i/o %#x, irq %d, revision %d\n",
+               driver->name, cardname, card->port, card->irq, card->revision);
 
-       MOD_INC_USE_COUNT;
        return cinfo->capi_ctrl->cnr;
 }
 
@@ -194,11 +219,12 @@ static char *b1pcmcia_procinfo(struct capi_ctr *ctrl)
 
        if (!cinfo)
                return "";
-       sprintf(cinfo->infobuf, "%s %s 0x%x %d",
+       sprintf(cinfo->infobuf, "%s %s 0x%x %d r%d",
                cinfo->cardname[0] ? cinfo->cardname : "-",
                cinfo->version[VER_DRIVER] ? cinfo->version[VER_DRIVER] : "-",
                cinfo->card ? cinfo->card->port : 0x0,
-               cinfo->card ? cinfo->card->irq : 0
+               cinfo->card ? cinfo->card->irq : 0,
+               cinfo->card ? cinfo->card->revision : 0
                );
        return cinfo->infobuf;
 }
index 417707026def253aa5ca434ada23d0a548a67021..05218333a451bc9b372698c55e4e22b96c7702a9 100644 (file)
@@ -1,11 +1,22 @@
 /*
- * $Id: c4.c,v 1.2 2000/01/21 20:52:58 keil Exp $
+ * $Id: c4.c,v 1.5 2000/03/16 15:21:03 calle Exp $
  * 
  * Module for AVM C4 card.
  * 
  * (c) Copyright 1999 by Carsten Paeth (calle@calle.in-berlin.de)
  * 
  * $Log: c4.c,v $
+ * Revision 1.5  2000/03/16 15:21:03  calle
+ * Bugfix in c4_remove: loop 5 times instead of 4 :-(
+ *
+ * Revision 1.4  2000/02/02 18:36:03  calle
+ * - Modules are now locked while init_module is running
+ * - fixed problem with memory mapping if address is not aligned
+ *
+ * Revision 1.3  2000/01/25 14:37:39  calle
+ * new message after successfull detection including card revision and
+ * used resources.
+ *
  * Revision 1.2  2000/01/21 20:52:58  keil
  * pci_find_subsys as local function for 2.2.X kernel
  *
@@ -32,7 +43,7 @@
 #include "capilli.h"
 #include "avmcard.h"
 
-static char *revision = "$Revision: 1.2 $";
+static char *revision = "$Revision: 1.5 $";
 
 #undef CONFIG_C4_DEBUG
 #undef CONFIG_C4_POLLDEBUG
@@ -896,7 +907,7 @@ static void c4_remove_ctr(struct capi_ctr *ctrl)
 
        c4_reset(card);
 
-        for (i=0; i <= 4; i++) {
+        for (i=0; i < 4; i++) {
                cinfo = &card->ctrlinfo[i];
                if (cinfo->capi_ctrl)
                        di->detach_ctr(cinfo->capi_ctrl);
@@ -1085,16 +1096,19 @@ static int c4_read_proc(char *page, char **start, off_t off,
 
 static int c4_add_card(struct capi_driver *driver, struct capicardparams *p)
 {
-       unsigned long page_offset, base;
+       unsigned long base, page_offset;
        avmctrl_info *cinfo;
        avmcard *card;
        int retval;
        int i;
 
+       MOD_INC_USE_COUNT;
+
        card = (avmcard *) kmalloc(sizeof(avmcard), GFP_ATOMIC);
 
        if (!card) {
                printk(KERN_WARNING "%s: no memory.\n", driver->name);
+               MOD_DEC_USE_COUNT;
                return -ENOMEM;
        }
        memset(card, 0, sizeof(avmcard));
@@ -1102,6 +1116,7 @@ static int c4_add_card(struct capi_driver *driver, struct capicardparams *p)
        if (!card->dma) {
                printk(KERN_WARNING "%s: no memory.\n", driver->name);
                kfree(card);
+               MOD_DEC_USE_COUNT;
                return -ENOMEM;
        }
        memset(card->dma, 0, sizeof(avmcard_dmainfo));
@@ -1111,6 +1126,7 @@ static int c4_add_card(struct capi_driver *driver, struct capicardparams *p)
                kfree(card->ctrlinfo);
                kfree(card->dma);
                kfree(card);
+               MOD_DEC_USE_COUNT;
                return -ENOMEM;
        }
        memset(cinfo, 0, sizeof(avmctrl_info)*4);
@@ -1132,12 +1148,24 @@ static int c4_add_card(struct capi_driver *driver, struct capicardparams *p)
                kfree(card->ctrlinfo);
                kfree(card->dma);
                kfree(card);
+               MOD_DEC_USE_COUNT;
                return -EBUSY;
        }
 
-        base = card->membase & PAGE_MASK;
+       base = card->membase & PAGE_MASK;
        page_offset = card->membase - base;
-       card->mbase = ioremap_nocache(base, page_offset + 64);
+       card->mbase = ioremap_nocache(base, page_offset + 128);
+       if (card->mbase) {
+               card->mbase += page_offset;
+       } else {
+               printk(KERN_NOTICE "%s: can't remap memory at 0x%lx\n",
+                                       driver->name, card->membase);
+               kfree(card->ctrlinfo);
+               kfree(card->dma);
+               kfree(card);
+               MOD_DEC_USE_COUNT;
+               return -EIO;
+       }
 
        if ((retval = c4_detect(card)) != 0) {
                printk(KERN_NOTICE "%s: NO card at 0x%x (%d)\n",
@@ -1146,6 +1174,7 @@ static int c4_add_card(struct capi_driver *driver, struct capicardparams *p)
                kfree(card->ctrlinfo);
                kfree(card->dma);
                kfree(card);
+               MOD_DEC_USE_COUNT;
                return -EIO;
        }
        c4_reset(card);
@@ -1161,6 +1190,7 @@ static int c4_add_card(struct capi_driver *driver, struct capicardparams *p)
                kfree(card->ctrlinfo);
                kfree(card->dma);
                kfree(card);
+               MOD_DEC_USE_COUNT;
                return -EBUSY;
        }
 
@@ -1181,6 +1211,7 @@ static int c4_add_card(struct capi_driver *driver, struct capicardparams *p)
                        kfree(card->dma);
                        kfree(card->ctrlinfo);
                        kfree(card);
+                       MOD_DEC_USE_COUNT;
                        return -EBUSY;
                }
                if (i == 0)
@@ -1189,7 +1220,9 @@ static int c4_add_card(struct capi_driver *driver, struct capicardparams *p)
 
        skb_queue_head_init(&card->dma->send_queue);
 
-       MOD_INC_USE_COUNT;
+       printk(KERN_INFO
+               "%s: AVM C4 at i/o %#x, irq %d, mem %#lx\n",
+               driver->name, card->port, card->irq, card->membase);
 
        return 0;
 }
index af2074ae6c99ed2e2ac15e219d6971e250ca53b5..8f43d414e41b53625d1aff160cc99baa2014fa25 100644 (file)
@@ -1,11 +1,14 @@
 /*
- * $Id: capi.c,v 1.22 1999/11/13 21:27:16 keil Exp $
+ * $Id: capi.c,v 1.23 2000/02/26 01:00:53 keil Exp $
  *
  * CAPI 2.0 Interface for Linux
  *
  * Copyright 1996 by Carsten Paeth (calle@calle.in-berlin.de)
  *
  * $Log: capi.c,v $
+ * Revision 1.23  2000/02/26 01:00:53  keil
+ * changes from 2.3.47
+ *
  * Revision 1.22  1999/11/13 21:27:16  keil
  * remove KERNELVERSION
  *
index f389b07def2b18acde09fe6ab740bdb77fde96d0..0c7c553bf98311ca8beb1afd85723a6ceb34026b 100644 (file)
@@ -1,11 +1,15 @@
 /*
- * $Id: kcapi.c,v 1.11 1999/11/23 13:29:29 calle Exp $
+ * $Id: kcapi.c,v 1.12 2000/01/28 16:45:39 calle Exp $
  * 
  * Kernel CAPI 2.0 Module
  * 
  * (c) Copyright 1999 by Carsten Paeth (calle@calle.in-berlin.de)
  * 
  * $Log: kcapi.c,v $
+ * Revision 1.12  2000/01/28 16:45:39  calle
+ * new manufacturer command KCAPI_CMD_ADDCARD (generic addcard),
+ * will search named driver and call the add_card function if one exist.
+ *
  * Revision 1.11  1999/11/23 13:29:29  calle
  * Bugfix: incoming capi message were never traced.
  *
@@ -82,7 +86,7 @@
 #include <linux/b1lli.h>
 #endif
 
-static char *revision = "$Revision: 1.11 $";
+static char *revision = "$Revision: 1.12 $";
 
 /* ------------------------------------------------------------- */
 
@@ -157,10 +161,6 @@ static int ncards = 0;
 static struct sk_buff_head recv_queue;
 static struct capi_interface_user *capi_users = 0;
 static struct capi_driver *drivers;
-#ifdef CONFIG_AVMB1_COMPAT
-static struct capi_driver *b1isa_driver;
-static struct capi_driver *t1isa_driver;
-#endif
 static long notify_up_set = 0;
 static long notify_down_set = 0;
 
@@ -956,12 +956,6 @@ struct capi_driver_interface *attach_capi_driver(struct capi_driver *driver)
        driver->next = 0;
        *pp = driver;
        printk(KERN_NOTICE "kcapi: driver %s attached\n", driver->name);
-#ifdef CONFIG_AVMB1_COMPAT
-        if (strcmp(driver->name, "b1isa") == 0 && driver->add_card)
-               b1isa_driver = driver;
-        if (strcmp(driver->name, "t1isa") == 0 && driver->add_card)
-               t1isa_driver = driver;
-#endif
        sprintf(driver->procfn, "capi/drivers/%s", driver->name);
        driver->procent = create_proc_entry(driver->procfn, 0, 0);
        if (driver->procent) {
@@ -983,10 +977,6 @@ void detach_capi_driver(struct capi_driver *driver)
        for (pp = &drivers; *pp && *pp != driver; pp = &(*pp)->next) ;
        if (*pp) {
                *pp = (*pp)->next;
-#ifdef CONFIG_AVMB1_COMPAT
-               if (driver == b1isa_driver) b1isa_driver = 0;
-               if (driver == t1isa_driver) t1isa_driver = 0;
-#endif
                printk(KERN_NOTICE "kcapi: driver %s detached\n", driver->name);
        } else {
                printk(KERN_ERR "kcapi: driver %s double detach ?\n", driver->name);
@@ -1201,6 +1191,15 @@ static __u16 capi_get_profile(__u32 contr, struct capi_profile *profp)
        return CAPI_NOERROR;
 }
 
+static struct capi_driver *find_driver(char *name)
+{
+       struct capi_driver *dp;
+       for (dp = drivers; dp; dp = dp->next)
+               if (strcmp(dp->name, name) == 0)
+                       return dp;
+       return 0;
+}
+
 #ifdef CONFIG_AVMB1_COMPAT
 static int old_capi_manufacturer(unsigned int cmd, void *data)
 {
@@ -1232,9 +1231,15 @@ static int old_capi_manufacturer(unsigned int cmd, void *data)
                cparams.cardnr = cdef.cardnr;
 
                 switch (cdef.cardtype) {
-                       case AVM_CARDTYPE_B1: driver = b1isa_driver; break;
-                       case AVM_CARDTYPE_T1: driver = t1isa_driver; break;
-                       default: driver = 0;
+                       case AVM_CARDTYPE_B1:
+                               driver = find_driver("b1isa");
+                               break;
+                       case AVM_CARDTYPE_T1:
+                               driver = find_driver("t1isa");
+                               break;
+                       default:
+                               driver = 0;
+                               break;
                }
                if (!driver) {
                        printk(KERN_ERR "kcapi: driver not loaded.\n");
@@ -1346,9 +1351,7 @@ static int old_capi_manufacturer(unsigned int cmd, void *data)
                        return -ESRCH;
 
                gdef.cardstate = card->cardstate;
-               if (card->driver == b1isa_driver)
-                       gdef.cardtype = AVM_CARDTYPE_B1;
-               else if (card->driver == t1isa_driver)
+               if (card->driver == find_driver("t1isa"))
                        gdef.cardtype = AVM_CARDTYPE_T1;
                else gdef.cardtype = AVM_CARDTYPE_B1;
 
@@ -1392,7 +1395,6 @@ static int old_capi_manufacturer(unsigned int cmd, void *data)
 static int capi_manufacturer(unsigned int cmd, void *data)
 {
         struct capi_ctr *card;
-       kcapi_flagdef fdef;
        int retval;
 
        switch (cmd) {
@@ -1407,6 +1409,9 @@ static int capi_manufacturer(unsigned int cmd, void *data)
                return old_capi_manufacturer(cmd, data);
 #endif
        case KCAPI_CMD_TRACE:
+       {
+               kcapi_flagdef fdef;
+
                if ((retval = copy_from_user((void *) &fdef, data,
                                         sizeof(kcapi_flagdef))))
                        return retval;
@@ -1421,6 +1426,44 @@ static int capi_manufacturer(unsigned int cmd, void *data)
                        card->cnr, card->traceflag);
                return 0;
        }
+
+       case KCAPI_CMD_ADDCARD:
+       {
+               struct capi_driver *driver;
+               capicardparams cparams;
+               kcapi_carddef cdef;
+
+               if ((retval = copy_from_user((void *) &cdef, data,
+                                                       sizeof(cdef))))
+                       return retval;
+
+               cparams.port = cdef.port;
+               cparams.irq = cdef.irq;
+               cparams.membase = cdef.membase;
+               cparams.cardnr = cdef.cardnr;
+               cparams.cardtype = 0;
+               cdef.driver[sizeof(cdef.driver)-1] = 0;
+
+               if ((driver = find_driver(cdef.driver)) == 0) {
+                       printk(KERN_ERR "kcapi: driver \"%s\" not loaded.\n",
+                                       cdef.driver);
+                       return -ESRCH;
+               }
+
+               if (!driver->add_card) {
+                       printk(KERN_ERR "kcapi: driver \"%s\" has no add card function.\n", cdef.driver);
+                       return -EIO;
+               }
+
+               return driver->add_card(driver, &cparams);
+       }
+
+       default:
+               printk(KERN_ERR "kcapi: manufacturer command %d unknown.\n",
+                                       cmd);
+               break;
+
+       }
        return -EINVAL;
 }
 
index 22a07f2ade758a0eebb8e2a5cbf0cc4d7d06ce2b..e1efd3939ffbc54faaa591c0423190a5b10ad9fe 100644 (file)
@@ -1,11 +1,19 @@
 /*
- * $Id: t1isa.c,v 1.8 1999/11/05 16:38:01 calle Exp $
+ * $Id: t1isa.c,v 1.10 2000/02/02 18:36:04 calle Exp $
  * 
  * Module for AVM T1 HEMA-card.
  * 
  * (c) Copyright 1999 by Carsten Paeth (calle@calle.in-berlin.de)
  * 
  * $Log: t1isa.c,v $
+ * Revision 1.10  2000/02/02 18:36:04  calle
+ * - Modules are now locked while init_module is running
+ * - fixed problem with memory mapping if address is not aligned
+ *
+ * Revision 1.9  2000/01/25 14:37:39  calle
+ * new message after successfull detection including card revision and
+ * used resources.
+ *
  * Revision 1.8  1999/11/05 16:38:01  calle
  * Cleanups before kernel 2.4:
  * - Changed all messages to use card->name or driver->name instead of
@@ -73,7 +81,7 @@
 #include "capilli.h"
 #include "avmcard.h"
 
-static char *revision = "$Revision: 1.8 $";
+static char *revision = "$Revision: 1.10 $";
 
 /* ------------------------------------------------------------- */
 
@@ -413,10 +421,13 @@ static int t1isa_add_card(struct capi_driver *driver, struct capicardparams *p)
        avmcard *card;
        int retval;
 
+       MOD_INC_USE_COUNT;
+
        card = (avmcard *) kmalloc(sizeof(avmcard), GFP_ATOMIC);
 
        if (!card) {
                printk(KERN_WARNING "%s: no memory.\n", driver->name);
+               MOD_DEC_USE_COUNT;
                return -ENOMEM;
        }
        memset(card, 0, sizeof(avmcard));
@@ -424,6 +435,7 @@ static int t1isa_add_card(struct capi_driver *driver, struct capicardparams *p)
        if (!cinfo) {
                printk(KERN_WARNING "%s: no memory.\n", driver->name);
                kfree(card);
+               MOD_DEC_USE_COUNT;
                return -ENOMEM;
        }
        memset(cinfo, 0, sizeof(avmctrl_info));
@@ -440,6 +452,7 @@ static int t1isa_add_card(struct capi_driver *driver, struct capicardparams *p)
                                driver->name, card->port);
                kfree(card->ctrlinfo);
                kfree(card);
+               MOD_DEC_USE_COUNT;
                return -EINVAL;
         }
 
@@ -449,6 +462,7 @@ static int t1isa_add_card(struct capi_driver *driver, struct capicardparams *p)
                       driver->name, card->port, card->port + AVMB1_PORTLEN);
                kfree(card->ctrlinfo);
                kfree(card);
+               MOD_DEC_USE_COUNT;
                return -EBUSY;
        }
        if (hema_irq_table[card->irq & 0xf] == 0) {
@@ -456,6 +470,7 @@ static int t1isa_add_card(struct capi_driver *driver, struct capicardparams *p)
                                driver->name, card->irq);
                kfree(card->ctrlinfo);
                kfree(card);
+               MOD_DEC_USE_COUNT;
                return -EINVAL;
        }
        for (ctrl = driver->controller; ctrl; ctrl = ctrl->next) {
@@ -465,6 +480,7 @@ static int t1isa_add_card(struct capi_driver *driver, struct capicardparams *p)
                                        driver->name, card->cardnr, cardp->port);
                        kfree(card->ctrlinfo);
                        kfree(card);
+                       MOD_DEC_USE_COUNT;
                        return -EBUSY;
                }
        }
@@ -473,6 +489,7 @@ static int t1isa_add_card(struct capi_driver *driver, struct capicardparams *p)
                                        driver->name, card->port, retval);
                kfree(card->ctrlinfo);
                kfree(card);
+               MOD_DEC_USE_COUNT;
                return -EIO;
        }
        t1_disable_irq(card->port);
@@ -487,6 +504,7 @@ static int t1isa_add_card(struct capi_driver *driver, struct capicardparams *p)
                release_region(card->port, AVMB1_PORTLEN);
                kfree(card->ctrlinfo);
                kfree(card);
+               MOD_DEC_USE_COUNT;
                return -EBUSY;
        }
 
@@ -498,10 +516,14 @@ static int t1isa_add_card(struct capi_driver *driver, struct capicardparams *p)
                release_region(card->port, AVMB1_PORTLEN);
                kfree(card->ctrlinfo);
                kfree(card);
+               MOD_DEC_USE_COUNT;
                return -EBUSY;
        }
 
-       MOD_INC_USE_COUNT;
+       printk(KERN_INFO
+               "%s: AVM T1 ISA at i/o %#x, irq %d, card %d\n",
+               driver->name, card->port, card->irq, card->cardnr);
+
        return 0;
 }
 
index d73e93c0a0bdc7c37e605f22c6ee0bebf4487cca..e67143130032049841cdda2c2af1a84c4c852f9f 100644 (file)
@@ -1,11 +1,20 @@
 /*
- * $Id: t1pci.c,v 1.3 1999/11/13 21:27:16 keil Exp $
+ * $Id: t1pci.c,v 1.5 2000/02/02 18:36:04 calle Exp $
  * 
  * Module for AVM T1 PCI-card.
  * 
  * (c) Copyright 1999 by Carsten Paeth (calle@calle.in-berlin.de)
  * 
  * $Log: t1pci.c,v $
+ * Revision 1.5  2000/02/02 18:36:04  calle
+ * - Modules are now locked while init_module is running
+ * - fixed problem with memory mapping if address is not aligned
+ *
+ * Revision 1.4  2000/01/25 14:33:38  calle
+ * - Added Support AVM B1 PCI V4.0 (tested with prototype)
+ *   - splitted up t1pci.c into b1dma.c for common function with b1pciv4
+ *   - support for revision register
+ *
  * Revision 1.3  1999/11/13 21:27:16  keil
  * remove KERNELVERSION
  *
@@ -38,7 +47,7 @@
 #include "capilli.h"
 #include "avmcard.h"
 
-static char *revision = "$Revision: 1.3 $";
+static char *revision = "$Revision: 1.5 $";
 
 #undef CONFIG_T1PCI_DEBUG
 #undef CONFIG_T1PCI_POLLDEBUG
@@ -55,712 +64,20 @@ static char *revision = "$Revision: 1.3 $";
 
 /* ------------------------------------------------------------- */
 
-static int suppress_pollack = 0;
-
 MODULE_AUTHOR("Carsten Paeth <calle@calle.in-berlin.de>");
 
-MODULE_PARM(suppress_pollack, "0-1i");
-
-
 /* ------------------------------------------------------------- */
 
 static struct capi_driver_interface *di;
 
 /* ------------------------------------------------------------- */
 
-static void t1pci_dispatch_tx(avmcard *card);
-
-/* ------------------------------------------------------------- */
-
-/* S5933 */
-
-#define        AMCC_RXPTR      0x24
-#define        AMCC_RXLEN      0x28
-#define        AMCC_TXPTR      0x2c
-#define        AMCC_TXLEN      0x30
-
-#define        AMCC_INTCSR     0x38
-#      define EN_READ_TC_INT           0x00008000L
-#      define EN_WRITE_TC_INT          0x00004000L
-#      define EN_TX_TC_INT             EN_READ_TC_INT
-#      define EN_RX_TC_INT             EN_WRITE_TC_INT
-#      define AVM_FLAG                 0x30000000L
-
-#      define ANY_S5933_INT            0x00800000L
-#      define  READ_TC_INT             0x00080000L
-#      define WRITE_TC_INT             0x00040000L
-#      define  TX_TC_INT               READ_TC_INT
-#      define  RX_TC_INT               WRITE_TC_INT
-#      define MASTER_ABORT_INT         0x00100000L
-#      define TARGET_ABORT_INT         0x00200000L
-#      define BUS_MASTER_INT           0x00200000L
-#      define ALL_INT                  0x000C0000L
-
-#define        AMCC_MCSR       0x3c
-#      define A2P_HI_PRIORITY          0x00000100L
-#      define EN_A2P_TRANSFERS         0x00000400L
-#      define P2A_HI_PRIORITY          0x00001000L
-#      define EN_P2A_TRANSFERS         0x00004000L
-#      define RESET_A2P_FLAGS          0x04000000L
-#      define RESET_P2A_FLAGS          0x02000000L
-
-/* ------------------------------------------------------------- */
-
-#define t1outmeml(addr, value) writel(value, addr)
-#define t1inmeml(addr) readl(addr)
-#define t1outmemw(addr, value) writew(value, addr)
-#define t1inmemw(addr) readw(addr)
-#define t1outmemb(addr, value) writeb(value, addr)
-#define t1inmemb(addr) readb(addr)
-
-/* ------------------------------------------------------------- */
-
-static inline int t1pci_tx_empty(unsigned int port)
-{
-       return inb(port + 0x03) & 0x1;
-}
-
-static inline int t1pci_rx_full(unsigned int port)
-{
-       return inb(port + 0x02) & 0x1;
-}
-
-static int t1pci_tolink(avmcard *card, void *buf, unsigned int len)
-{
-       unsigned long stop = jiffies + 1 * HZ;  /* maximum wait time 1 sec */
-       unsigned char *s = (unsigned char *)buf;
-       while (len--) {
-               while (   !t1pci_tx_empty(card->port)
-                      && time_before(jiffies, stop));
-               if (!t1pci_tx_empty(card->port)) 
-                       return -1;
-               t1outp(card->port, 0x01, *s++);
-       }
-       return 0;
-}
-
-static int t1pci_fromlink(avmcard *card, void *buf, unsigned int len)
-{
-       unsigned long stop = jiffies + 1 * HZ;  /* maximum wait time 1 sec */
-       unsigned char *s = (unsigned char *)buf;
-       while (len--) {
-               while (   !t1pci_rx_full(card->port)
-                      && time_before(jiffies, stop));
-               if (!t1pci_rx_full(card->port)) 
-                       return -1;
-               *s++ = t1inp(card->port, 0x00);
-       }
-       return 0;
-}
-
-static int WriteReg(avmcard *card, __u32 reg, __u8 val)
-{
-       __u8 cmd = 0x00;
-       if (   t1pci_tolink(card, &cmd, 1) == 0
-           && t1pci_tolink(card, &reg, 4) == 0) {
-               __u32 tmp = val;
-               return t1pci_tolink(card, &tmp, 4);
-       }
-       return -1;
-}
-
-static __u8 ReadReg(avmcard *card, __u32 reg)
-{
-       __u8 cmd = 0x01;
-       if (   t1pci_tolink(card, &cmd, 1) == 0
-           && t1pci_tolink(card, &reg, 4) == 0) {
-               __u32 tmp;
-               if (t1pci_fromlink(card, &tmp, 4) == 0)
-                       return (__u8)tmp;
-       }
-       return 0xff;
-}
-
-/* ------------------------------------------------------------- */
-
-static inline void _put_byte(void **pp, __u8 val)
-{
-       __u8 *s = *pp;
-       *s++ = val;
-       *pp = s;
-}
-
-static inline void _put_word(void **pp, __u32 val)
-{
-       __u8 *s = *pp;
-       *s++ = val & 0xff;
-       *s++ = (val >> 8) & 0xff;
-       *s++ = (val >> 16) & 0xff;
-       *s++ = (val >> 24) & 0xff;
-       *pp = s;
-}
-
-static inline void _put_slice(void **pp, unsigned char *dp, unsigned int len)
-{
-       unsigned i = len;
-       _put_word(pp, i);
-       while (i-- > 0)
-               _put_byte(pp, *dp++);
-}
-
-static inline __u8 _get_byte(void **pp)
-{
-       __u8 *s = *pp;
-       __u8 val;
-       val = *s++;
-       *pp = s;
-       return val;
-}
-
-static inline __u32 _get_word(void **pp)
-{
-       __u8 *s = *pp;
-       __u32 val;
-       val = *s++;
-       val |= (*s++ << 8);
-       val |= (*s++ << 16);
-       val |= (*s++ << 24);
-       *pp = s;
-       return val;
-}
-
-static inline __u32 _get_slice(void **pp, unsigned char *dp)
-{
-       unsigned int len, i;
-
-       len = i = _get_word(pp);
-       while (i-- > 0) *dp++ = _get_byte(pp);
-       return len;
-}
-
-/* ------------------------------------------------------------- */
-
-static void t1pci_reset(avmcard *card)
-{
-       unsigned long flags;
-
-       save_flags(flags);
-       cli();
-       card->csr = 0x0;
-       t1outmeml(card->mbase+AMCC_INTCSR, card->csr);
-       t1outmeml(card->mbase+AMCC_MCSR, 0);
-       t1outmeml(card->mbase+AMCC_RXLEN, 0);
-       t1outmeml(card->mbase+AMCC_TXLEN, 0);
-
-       t1outp(card->port, T1_RESETLINK, 0x00);
-       t1outp(card->port, 0x07, 0x00);
-
-       restore_flags(flags);
-
-       t1outmeml(card->mbase+AMCC_MCSR, 0);
-       udelay(10 * 1000);
-       t1outmeml(card->mbase+AMCC_MCSR, 0x0f000000); /* reset all */
-       udelay(10 * 1000);
-       t1outmeml(card->mbase+AMCC_MCSR, 0);
-       udelay(42 * 1000);
-
-}
-
-/* ------------------------------------------------------------- */
-
-static int t1pci_detect(avmcard *card)
-{
-       t1outmeml(card->mbase+AMCC_MCSR, 0);
-       udelay(10 * 1000);
-       t1outmeml(card->mbase+AMCC_MCSR, 0x0f000000); /* reset all */
-       udelay(10 * 1000);
-       t1outmeml(card->mbase+AMCC_MCSR, 0);
-       udelay(42 * 1000);
-
-       t1outmeml(card->mbase+AMCC_RXLEN, 0);
-       t1outmeml(card->mbase+AMCC_TXLEN, 0);
-       card->csr = 0x0;
-       t1outmeml(card->mbase+AMCC_INTCSR, card->csr);
-
-       if (t1inmeml(card->mbase+AMCC_MCSR) != 0x000000E6)
-               return 1;
-
-       t1outmeml(card->mbase+AMCC_RXPTR, 0xffffffff);
-       t1outmeml(card->mbase+AMCC_TXPTR, 0xffffffff);
-       if (   t1inmeml(card->mbase+AMCC_RXPTR) != 0xfffffffc
-           || t1inmeml(card->mbase+AMCC_TXPTR) != 0xfffffffc)
-               return 2;
-
-       t1outmeml(card->mbase+AMCC_RXPTR, 0x0);
-       t1outmeml(card->mbase+AMCC_TXPTR, 0x0);
-       if (   t1inmeml(card->mbase+AMCC_RXPTR) != 0x0
-           || t1inmeml(card->mbase+AMCC_TXPTR) != 0x0)
-               return 3;
-
-       t1outp(card->port, T1_RESETLINK, 0x00);
-       t1outp(card->port, 0x07, 0x00);
-       
-       t1outp(card->port, 0x02, 0x02);
-       t1outp(card->port, 0x03, 0x02);
-
-       if (   (t1inp(card->port, 0x02) & 0xFE) != 0x02
-           || t1inp(card->port, 0x3) != 0x03)
-               return 4;
-
-       t1outp(card->port, 0x02, 0x00);
-       t1outp(card->port, 0x03, 0x00);
-
-       if (   (t1inp(card->port, 0x02) & 0xFE) != 0x00
-           || t1inp(card->port, 0x3) != 0x01)
-               return 5;
-
-       /* Transputer test */
-       
-       if (   WriteReg(card, 0x80001000, 0x11) != 0
-           || WriteReg(card, 0x80101000, 0x22) != 0
-           || WriteReg(card, 0x80201000, 0x33) != 0
-           || WriteReg(card, 0x80301000, 0x44) != 0)
-               return 6;
-
-       if (   ReadReg(card, 0x80001000) != 0x11
-           || ReadReg(card, 0x80101000) != 0x22
-           || ReadReg(card, 0x80201000) != 0x33
-           || ReadReg(card, 0x80301000) != 0x44)
-               return 7;
-
-       if (   WriteReg(card, 0x80001000, 0x55) != 0
-           || WriteReg(card, 0x80101000, 0x66) != 0
-           || WriteReg(card, 0x80201000, 0x77) != 0
-           || WriteReg(card, 0x80301000, 0x88) != 0)
-               return 8;
-
-       if (   ReadReg(card, 0x80001000) != 0x55
-           || ReadReg(card, 0x80101000) != 0x66
-           || ReadReg(card, 0x80201000) != 0x77
-           || ReadReg(card, 0x80301000) != 0x88)
-               return 9;
-
-       return 0;
-}
-
-/* ------------------------------------------------------------- */
-
-static void t1pci_dispatch_tx(avmcard *card)
-{
-       avmcard_dmainfo *dma = card->dma;
-       unsigned long flags;
-       struct sk_buff *skb;
-       __u8 cmd, subcmd;
-       __u16 len;
-       __u32 txlen;
-       int inint;
-       void *p;
-       
-       save_flags(flags);
-       cli();
-
-       inint = card->interrupt;
-
-       if (card->csr & EN_TX_TC_INT) { /* tx busy */
-               restore_flags(flags);
-               return;
-       }
-
-       skb = skb_dequeue(&dma->send_queue);
-       if (!skb) {
-#ifdef CONFIG_T1PCI_DEBUG
-               printk(KERN_DEBUG "tx(%d): underrun\n", inint);
-#endif
-               restore_flags(flags);
-               return;
-       }
-
-       len = CAPIMSG_LEN(skb->data);
-
-       if (len) {
-               cmd = CAPIMSG_COMMAND(skb->data);
-               subcmd = CAPIMSG_SUBCOMMAND(skb->data);
-
-               p = dma->sendbuf;
-
-               if (CAPICMD(cmd, subcmd) == CAPI_DATA_B3_REQ) {
-                       __u16 dlen = CAPIMSG_DATALEN(skb->data);
-                       _put_byte(&p, SEND_DATA_B3_REQ);
-                       _put_slice(&p, skb->data, len);
-                       _put_slice(&p, skb->data + len, dlen);
-               } else {
-                       _put_byte(&p, SEND_MESSAGE);
-                       _put_slice(&p, skb->data, len);
-               }
-               txlen = (__u8 *)p - (__u8 *)dma->sendbuf;
-#ifdef CONFIG_T1PCI_DEBUG
-               printk(KERN_DEBUG "tx(%d): put msg len=%d\n",
-                               inint, txlen);
-#endif
-       } else {
-               txlen = skb->len-2;
-#ifdef CONFIG_T1PCI_POLLDEBUG
-               if (skb->data[2] == SEND_POLLACK)
-                       printk(KERN_INFO "%s: ack to t1\n", card->name);
-#endif
-#ifdef CONFIG_T1PCI_DEBUG
-               printk(KERN_DEBUG "tx(%d): put 0x%x len=%d\n",
-                               inint, skb->data[2], txlen);
-#endif
-               memcpy(dma->sendbuf, skb->data+2, skb->len-2);
-       }
-       txlen = (txlen + 3) & ~3;
-
-       t1outmeml(card->mbase+AMCC_TXPTR, virt_to_phys(dma->sendbuf));
-       t1outmeml(card->mbase+AMCC_TXLEN, txlen);
-
-       card->csr |= EN_TX_TC_INT;
-
-       if (!inint)
-               t1outmeml(card->mbase+AMCC_INTCSR, card->csr);
-
-       restore_flags(flags);
-       dev_kfree_skb(skb);
-}
-
-/* ------------------------------------------------------------- */
-
-static void queue_pollack(avmcard *card)
-{
-       struct sk_buff *skb;
-       void *p;
-
-       skb = alloc_skb(3, GFP_ATOMIC);
-       if (!skb) {
-               printk(KERN_CRIT "%s: no memory, lost poll ack\n",
-                                       card->name);
-               return;
-       }
-       p = skb->data;
-       _put_byte(&p, 0);
-       _put_byte(&p, 0);
-       _put_byte(&p, SEND_POLLACK);
-       skb_put(skb, (__u8 *)p - (__u8 *)skb->data);
-
-       skb_queue_tail(&card->dma->send_queue, skb);
-       t1pci_dispatch_tx(card);
-}
-
-/* ------------------------------------------------------------- */
-
-static void t1pci_handle_rx(avmcard *card)
-{
-       avmctrl_info *cinfo = &card->ctrlinfo[0];
-       avmcard_dmainfo *dma = card->dma;
-       struct capi_ctr *ctrl = cinfo->capi_ctrl;
-       struct sk_buff *skb;
-       void *p = dma->recvbuf+4;
-       __u32 ApplId, MsgLen, DataB3Len, NCCI, WindowSize;
-       __u8 b1cmd =  _get_byte(&p);
-
-#ifdef CONFIG_T1PCI_DEBUG
-       printk(KERN_DEBUG "rx: 0x%x %lu\n", b1cmd, (unsigned long)dma->recvlen);
-#endif
-       
-       switch (b1cmd) {
-       case RECEIVE_DATA_B3_IND:
-
-               ApplId = (unsigned) _get_word(&p);
-               MsgLen = _get_slice(&p, card->msgbuf);
-               DataB3Len = _get_slice(&p, card->databuf);
-
-               if (MsgLen < 30) { /* not CAPI 64Bit */
-                       memset(card->msgbuf+MsgLen, 0, 30-MsgLen);
-                       MsgLen = 30;
-                       CAPIMSG_SETLEN(card->msgbuf, 30);
-               }
-               if (!(skb = alloc_skb(DataB3Len+MsgLen, GFP_ATOMIC))) {
-                       printk(KERN_ERR "%s: incoming packet dropped\n",
-                                       card->name);
-               } else {
-                       memcpy(skb_put(skb, MsgLen), card->msgbuf, MsgLen);
-                       memcpy(skb_put(skb, DataB3Len), card->databuf, DataB3Len);
-                       ctrl->handle_capimsg(ctrl, ApplId, skb);
-               }
-               break;
-
-       case RECEIVE_MESSAGE:
-
-               ApplId = (unsigned) _get_word(&p);
-               MsgLen = _get_slice(&p, card->msgbuf);
-               if (!(skb = alloc_skb(MsgLen, GFP_ATOMIC))) {
-                       printk(KERN_ERR "%s: incoming packet dropped\n",
-                                       card->name);
-               } else {
-                       memcpy(skb_put(skb, MsgLen), card->msgbuf, MsgLen);
-                       ctrl->handle_capimsg(ctrl, ApplId, skb);
-               }
-               break;
-
-       case RECEIVE_NEW_NCCI:
-
-               ApplId = _get_word(&p);
-               NCCI = _get_word(&p);
-               WindowSize = _get_word(&p);
-
-               ctrl->new_ncci(ctrl, ApplId, NCCI, WindowSize);
-
-               break;
-
-       case RECEIVE_FREE_NCCI:
-
-               ApplId = _get_word(&p);
-               NCCI = _get_word(&p);
-
-               if (NCCI != 0xffffffff)
-                       ctrl->free_ncci(ctrl, ApplId, NCCI);
-               else ctrl->appl_released(ctrl, ApplId);
-               break;
-
-       case RECEIVE_START:
-#ifdef CONFIG_T1PCI_POLLDEBUG
-               printk(KERN_INFO "%s: poll from t1\n", card->name);
-#endif
-               if (!suppress_pollack)
-                       queue_pollack(card);
-               ctrl->resume_output(ctrl);
-               break;
-
-       case RECEIVE_STOP:
-               ctrl->suspend_output(ctrl);
-               break;
-
-       case RECEIVE_INIT:
-
-               cinfo->versionlen = _get_slice(&p, cinfo->versionbuf);
-               b1_parse_version(cinfo);
-               printk(KERN_INFO "%s: %s-card (%s) now active\n",
-                      card->name,
-                      cinfo->version[VER_CARDTYPE],
-                      cinfo->version[VER_DRIVER]);
-               ctrl->ready(ctrl);
-               break;
-
-       case RECEIVE_TASK_READY:
-               ApplId = (unsigned) _get_word(&p);
-               MsgLen = _get_slice(&p, card->msgbuf);
-               card->msgbuf[MsgLen--] = 0;
-               while (    MsgLen >= 0
-                      && (   card->msgbuf[MsgLen] == '\n'
-                          || card->msgbuf[MsgLen] == '\r'))
-                       card->msgbuf[MsgLen--] = 0;
-               printk(KERN_INFO "%s: task %d \"%s\" ready.\n",
-                               card->name, ApplId, card->msgbuf);
-               break;
-
-       case RECEIVE_DEBUGMSG:
-               MsgLen = _get_slice(&p, card->msgbuf);
-               card->msgbuf[MsgLen--] = 0;
-               while (    MsgLen >= 0
-                      && (   card->msgbuf[MsgLen] == '\n'
-                          || card->msgbuf[MsgLen] == '\r'))
-                       card->msgbuf[MsgLen--] = 0;
-               printk(KERN_INFO "%s: DEBUG: %s\n", card->name, card->msgbuf);
-               break;
-
-       default:
-               printk(KERN_ERR "%s: t1pci_interrupt: 0x%x ???\n",
-                               card->name, b1cmd);
-               return;
-       }
-}
-
-/* ------------------------------------------------------------- */
-
-static void t1pci_handle_interrupt(avmcard *card)
-{
-       __u32 status = t1inmeml(card->mbase+AMCC_INTCSR);
-       __u32 newcsr;
-
-       if ((status & ANY_S5933_INT) == 0) 
-               return;
-
-        newcsr = card->csr | (status & ALL_INT);
-       if (status & TX_TC_INT) newcsr &= ~EN_TX_TC_INT;
-       if (status & RX_TC_INT) newcsr &= ~EN_RX_TC_INT;
-       t1outmeml(card->mbase+AMCC_INTCSR, newcsr);
-
-       if ((status & RX_TC_INT) != 0) {
-               __u8 *recvbuf = card->dma->recvbuf;
-               __u32 rxlen;
-               if (card->dma->recvlen == 0) {
-                       card->dma->recvlen = *((__u32 *)recvbuf);
-                       rxlen = (card->dma->recvlen + 3) & ~3;
-                       t1outmeml(card->mbase+AMCC_RXPTR,
-                                       virt_to_phys(recvbuf+4));
-                       t1outmeml(card->mbase+AMCC_RXLEN, rxlen);
-               } else {
-                       t1pci_handle_rx(card);
-                       card->dma->recvlen = 0;
-                       t1outmeml(card->mbase+AMCC_RXPTR, virt_to_phys(recvbuf));
-                       t1outmeml(card->mbase+AMCC_RXLEN, 4);
-               }
-       }
-
-       if ((status & TX_TC_INT) != 0) {
-               card->csr &= ~EN_TX_TC_INT;
-               t1pci_dispatch_tx(card);
-       } else if (card->csr & EN_TX_TC_INT) {
-               if (t1inmeml(card->mbase+AMCC_TXLEN) == 0) {
-                       card->csr &= ~EN_TX_TC_INT;
-                       t1pci_dispatch_tx(card);
-               }
-       }
-       t1outmeml(card->mbase+AMCC_INTCSR, card->csr);
-}
-
-static void t1pci_interrupt(int interrupt, void *devptr, struct pt_regs *regs)
-{
-       avmcard *card;
-
-       card = (avmcard *) devptr;
-
-       if (!card) {
-               printk(KERN_WARNING "t1pci: interrupt: wrong device\n");
-               return;
-       }
-       if (card->interrupt) {
-               printk(KERN_ERR "%s: reentering interrupt hander\n", card->name);
-               return;
-       }
-
-       card->interrupt = 1;
-
-       t1pci_handle_interrupt(card);
-
-       card->interrupt = 0;
-}
-
-/* ------------------------------------------------------------- */
-
-static int t1pci_loaded(avmcard *card)
-{
-       unsigned long stop;
-       unsigned char ans;
-       unsigned long tout = 2;
-       unsigned int base = card->port;
-
-       for (stop = jiffies + tout * HZ; time_before(jiffies, stop);) {
-               if (b1_tx_empty(base))
-                       break;
-       }
-       if (!b1_tx_empty(base)) {
-               printk(KERN_ERR "%s: t1pci_loaded: tx err, corrupted t4 file ?\n",
-                               card->name);
-               return 0;
-       }
-       b1_put_byte(base, SEND_POLLACK);
-       for (stop = jiffies + tout * HZ; time_before(jiffies, stop);) {
-               if (b1_rx_full(base)) {
-                       if ((ans = b1_get_byte(base)) == RECEIVE_POLLDWORD) {
-                               return 1;
-                       }
-                       printk(KERN_ERR "%s: t1pci_loaded: got 0x%x, firmware not running in dword mode\n", card->name, ans);
-                       return 0;
-               }
-       }
-       printk(KERN_ERR "%s: t1pci_loaded: firmware not running\n", card->name);
-       return 0;
-}
-
-/* ------------------------------------------------------------- */
-
-static void t1pci_send_init(avmcard *card)
-{
-       struct sk_buff *skb;
-       void *p;
-
-       skb = alloc_skb(15, GFP_ATOMIC);
-       if (!skb) {
-               printk(KERN_CRIT "%s: no memory, lost register appl.\n",
-                                       card->name);
-               return;
-       }
-       p = skb->data;
-       _put_byte(&p, 0);
-       _put_byte(&p, 0);
-       _put_byte(&p, SEND_INIT);
-       _put_word(&p, AVM_NAPPS);
-       _put_word(&p, AVM_NCCI_PER_CHANNEL*30);
-       _put_word(&p, card->cardnr - 1);
-       skb_put(skb, (__u8 *)p - (__u8 *)skb->data);
-
-       skb_queue_tail(&card->dma->send_queue, skb);
-       t1pci_dispatch_tx(card);
-}
-
-static int t1pci_load_firmware(struct capi_ctr *ctrl, capiloaddata *data)
-{
-       avmctrl_info *cinfo = (avmctrl_info *)(ctrl->driverdata);
-       avmcard *card = cinfo->card;
-       unsigned long flags;
-       int retval;
-
-       t1pci_reset(card);
-
-       if ((retval = b1_load_t4file(card, &data->firmware))) {
-               t1pci_reset(card);
-               printk(KERN_ERR "%s: failed to load t4file!!\n",
-                                       card->name);
-               return retval;
-       }
-
-       if (data->configuration.len > 0 && data->configuration.data) {
-               if ((retval = b1_load_config(card, &data->configuration))) {
-                       t1pci_reset(card);
-                       printk(KERN_ERR "%s: failed to load config!!\n",
-                                       card->name);
-                       return retval;
-               }
-       }
-
-       if (!t1pci_loaded(card)) {
-               t1pci_reset(card);
-               printk(KERN_ERR "%s: failed to load t4file.\n", card->name);
-               return -EIO;
-       }
-
-       save_flags(flags);
-       cli();
-
-       card->csr = AVM_FLAG;
-       t1outmeml(card->mbase+AMCC_INTCSR, card->csr);
-       t1outmeml(card->mbase+AMCC_MCSR,
-               EN_A2P_TRANSFERS|EN_P2A_TRANSFERS
-               |A2P_HI_PRIORITY|P2A_HI_PRIORITY
-               |RESET_A2P_FLAGS|RESET_P2A_FLAGS);
-       t1outp(card->port, 0x07, 0x30);
-       t1outp(card->port, 0x10, 0xF0);
-
-       card->dma->recvlen = 0;
-       t1outmeml(card->mbase+AMCC_RXPTR, virt_to_phys(card->dma->recvbuf));
-       t1outmeml(card->mbase+AMCC_RXLEN, 4);
-       card->csr |= EN_RX_TC_INT;
-       t1outmeml(card->mbase+AMCC_INTCSR, card->csr);
-       restore_flags(flags);
-
-        t1pci_send_init(card);
-
-       return 0;
-}
-
-void t1pci_reset_ctr(struct capi_ctr *ctrl)
-{
-       avmctrl_info *cinfo = (avmctrl_info *)(ctrl->driverdata);
-       avmcard *card = cinfo->card;
-
-       t1pci_reset(card);
-
-       memset(cinfo->version, 0, sizeof(cinfo->version));
-       ctrl->reseted(ctrl);
-}
-
 static void t1pci_remove_ctr(struct capi_ctr *ctrl)
 {
        avmctrl_info *cinfo = (avmctrl_info *)(ctrl->driverdata);
        avmcard *card = cinfo->card;
 
-       t1pci_reset(card);
+       b1dma_reset(card);
 
        di->detach_ctr(ctrl);
        free_irq(card->irq, card);
@@ -776,210 +93,20 @@ static void t1pci_remove_ctr(struct capi_ctr *ctrl)
 
 /* ------------------------------------------------------------- */
 
-
-void t1pci_register_appl(struct capi_ctr *ctrl,
-                               __u16 appl,
-                               capi_register_params *rp)
-{
-       avmctrl_info *cinfo = (avmctrl_info *)(ctrl->driverdata);
-       avmcard *card = cinfo->card;
-       struct sk_buff *skb;
-       int want = rp->level3cnt;
-       int nconn;
-       void *p;
-
-       if (want > 0) nconn = want;
-       else nconn = ctrl->profile.nbchannel * -want;
-       if (nconn == 0) nconn = ctrl->profile.nbchannel;
-
-       skb = alloc_skb(23, GFP_ATOMIC);
-       if (!skb) {
-               printk(KERN_CRIT "%s: no memory, lost register appl.\n",
-                                       card->name);
-               return;
-       }
-       p = skb->data;
-       _put_byte(&p, 0);
-       _put_byte(&p, 0);
-       _put_byte(&p, SEND_REGISTER);
-       _put_word(&p, appl);
-       _put_word(&p, 1024 * (nconn+1));
-       _put_word(&p, nconn);
-       _put_word(&p, rp->datablkcnt);
-       _put_word(&p, rp->datablklen);
-       skb_put(skb, (__u8 *)p - (__u8 *)skb->data);
-
-       skb_queue_tail(&card->dma->send_queue, skb);
-       t1pci_dispatch_tx(card);
-
-       ctrl->appl_registered(ctrl, appl);
-}
-
-/* ------------------------------------------------------------- */
-
-void t1pci_release_appl(struct capi_ctr *ctrl, __u16 appl)
-{
-       avmctrl_info *cinfo = (avmctrl_info *)(ctrl->driverdata);
-       avmcard *card = cinfo->card;
-       struct sk_buff *skb;
-       void *p;
-
-       skb = alloc_skb(7, GFP_ATOMIC);
-       if (!skb) {
-               printk(KERN_CRIT "%s: no memory, lost release appl.\n",
-                                       card->name);
-               return;
-       }
-       p = skb->data;
-       _put_byte(&p, 0);
-       _put_byte(&p, 0);
-       _put_byte(&p, SEND_RELEASE);
-       _put_word(&p, appl);
-
-       skb_put(skb, (__u8 *)p - (__u8 *)skb->data);
-       skb_queue_tail(&card->dma->send_queue, skb);
-       t1pci_dispatch_tx(card);
-}
-
-/* ------------------------------------------------------------- */
-
-
-static void t1pci_send_message(struct capi_ctr *ctrl, struct sk_buff *skb)
-{
-       avmctrl_info *cinfo = (avmctrl_info *)(ctrl->driverdata);
-       avmcard *card = cinfo->card;
-       skb_queue_tail(&card->dma->send_queue, skb);
-       t1pci_dispatch_tx(card);
-}
-
-/* ------------------------------------------------------------- */
-
-static char *t1pci_procinfo(struct capi_ctr *ctrl)
-{
-       avmctrl_info *cinfo = (avmctrl_info *)(ctrl->driverdata);
-
-       if (!cinfo)
-               return "";
-       sprintf(cinfo->infobuf, "%s %s 0x%x %d 0x%lx",
-               cinfo->cardname[0] ? cinfo->cardname : "-",
-               cinfo->version[VER_DRIVER] ? cinfo->version[VER_DRIVER] : "-",
-               cinfo->card ? cinfo->card->port : 0x0,
-               cinfo->card ? cinfo->card->irq : 0,
-               cinfo->card ? cinfo->card->membase : 0
-               );
-       return cinfo->infobuf;
-}
-
-static int t1pci_read_proc(char *page, char **start, off_t off,
-                       int count, int *eof, struct capi_ctr *ctrl)
-{
-       avmctrl_info *cinfo = (avmctrl_info *)(ctrl->driverdata);
-       avmcard *card = cinfo->card;
-       unsigned long flags;
-       __u8 flag;
-       int len = 0;
-       char *s;
-       __u32 txaddr, txlen, rxaddr, rxlen, csr;
-
-       len += sprintf(page+len, "%-16s %s\n", "name", card->name);
-       len += sprintf(page+len, "%-16s 0x%x\n", "io", card->port);
-       len += sprintf(page+len, "%-16s %d\n", "irq", card->irq);
-       len += sprintf(page+len, "%-16s 0x%lx\n", "membase", card->membase);
-       switch (card->cardtype) {
-       case avm_b1isa: s = "B1 ISA"; break;
-       case avm_b1pci: s = "B1 PCI"; break;
-       case avm_b1pcmcia: s = "B1 PCMCIA"; break;
-       case avm_m1: s = "M1"; break;
-       case avm_m2: s = "M2"; break;
-       case avm_t1isa: s = "T1 ISA (HEMA)"; break;
-       case avm_t1pci: s = "T1 PCI"; break;
-       case avm_c4: s = "C4"; break;
-       default: s = "???"; break;
-       }
-       len += sprintf(page+len, "%-16s %s\n", "type", s);
-       if ((s = cinfo->version[VER_DRIVER]) != 0)
-          len += sprintf(page+len, "%-16s %s\n", "ver_driver", s);
-       if ((s = cinfo->version[VER_CARDTYPE]) != 0)
-          len += sprintf(page+len, "%-16s %s\n", "ver_cardtype", s);
-       if ((s = cinfo->version[VER_SERIAL]) != 0)
-          len += sprintf(page+len, "%-16s %s\n", "ver_serial", s);
-
-       if (card->cardtype != avm_m1) {
-               flag = ((__u8 *)(ctrl->profile.manu))[3];
-               if (flag)
-                       len += sprintf(page+len, "%-16s%s%s%s%s%s%s%s\n",
-                       "protocol",
-                       (flag & 0x01) ? " DSS1" : "",
-                       (flag & 0x02) ? " CT1" : "",
-                       (flag & 0x04) ? " VN3" : "",
-                       (flag & 0x08) ? " NI1" : "",
-                       (flag & 0x10) ? " AUSTEL" : "",
-                       (flag & 0x20) ? " ESS" : "",
-                       (flag & 0x40) ? " 1TR6" : ""
-                       );
-       }
-       if (card->cardtype != avm_m1) {
-               flag = ((__u8 *)(ctrl->profile.manu))[5];
-               if (flag)
-                       len += sprintf(page+len, "%-16s%s%s%s%s\n",
-                       "linetype",
-                       (flag & 0x01) ? " point to point" : "",
-                       (flag & 0x02) ? " point to multipoint" : "",
-                       (flag & 0x08) ? " leased line without D-channel" : "",
-                       (flag & 0x04) ? " leased line with D-channel" : ""
-                       );
-       }
-       len += sprintf(page+len, "%-16s %s\n", "cardname", cinfo->cardname);
-
-       save_flags(flags);
-       cli();
-
-       txaddr = (__u32)phys_to_virt(t1inmeml(card->mbase+0x2c));
-       txaddr -= (__u32)card->dma->sendbuf;
-       txlen  = t1inmeml(card->mbase+0x30);
-
-       rxaddr = (__u32)phys_to_virt(t1inmeml(card->mbase+0x24));
-       rxaddr -= (__u32)card->dma->recvbuf;
-       rxlen  = t1inmeml(card->mbase+0x28);
-
-       csr  = t1inmeml(card->mbase+AMCC_INTCSR);
-
-       restore_flags(flags);
-
-        len += sprintf(page+len, "%-16s 0x%lx\n",
-                               "csr (cached)", (unsigned long)card->csr);
-        len += sprintf(page+len, "%-16s 0x%lx\n",
-                               "csr", (unsigned long)csr);
-        len += sprintf(page+len, "%-16s %lu\n",
-                               "txoff", (unsigned long)txaddr);
-        len += sprintf(page+len, "%-16s %lu\n",
-                               "txlen", (unsigned long)txlen);
-        len += sprintf(page+len, "%-16s %lu\n",
-                               "rxoff", (unsigned long)rxaddr);
-        len += sprintf(page+len, "%-16s %lu\n",
-                               "rxlen", (unsigned long)rxlen);
-
-       if (off+count >= len)
-          *eof = 1;
-       if (len < off)
-           return 0;
-       *start = page + off;
-       return ((count < len-off) ? count : len-off);
-}
-
-/* ------------------------------------------------------------- */
-
 static int t1pci_add_card(struct capi_driver *driver, struct capicardparams *p)
 {
-       unsigned long page_offset, base;
+       unsigned long base, page_offset;
        avmcard *card;
        avmctrl_info *cinfo;
        int retval;
 
+       MOD_INC_USE_COUNT;
+
        card = (avmcard *) kmalloc(sizeof(avmcard), GFP_ATOMIC);
 
        if (!card) {
                printk(KERN_WARNING "%s: no memory.\n", driver->name);
+               MOD_DEC_USE_COUNT;
                return -ENOMEM;
        }
        memset(card, 0, sizeof(avmcard));
@@ -987,6 +114,7 @@ static int t1pci_add_card(struct capi_driver *driver, struct capicardparams *p)
        if (!card->dma) {
                printk(KERN_WARNING "%s: no memory.\n", driver->name);
                kfree(card);
+               MOD_DEC_USE_COUNT;
                return -ENOMEM;
        }
        memset(card->dma, 0, sizeof(avmcard_dmainfo));
@@ -995,6 +123,7 @@ static int t1pci_add_card(struct capi_driver *driver, struct capicardparams *p)
                printk(KERN_WARNING "%s: no memory.\n", driver->name);
                kfree(card->dma);
                kfree(card);
+               MOD_DEC_USE_COUNT;
                return -ENOMEM;
        }
        memset(cinfo, 0, sizeof(avmctrl_info));
@@ -1013,14 +142,26 @@ static int t1pci_add_card(struct capi_driver *driver, struct capicardparams *p)
                kfree(card->ctrlinfo);
                kfree(card->dma);
                kfree(card);
+               MOD_DEC_USE_COUNT;
                return -EBUSY;
        }
 
-        base = card->membase & PAGE_MASK;
+       base = card->membase & PAGE_MASK;
        page_offset = card->membase - base;
        card->mbase = ioremap_nocache(base, page_offset + 64);
+       if (card->mbase) {
+               card->mbase += page_offset;
+       } else {
+               printk(KERN_NOTICE "%s: can't remap memory at 0x%lx\n",
+                                       driver->name, card->membase);
+               kfree(card->ctrlinfo);
+               kfree(card->dma);
+               kfree(card);
+               MOD_DEC_USE_COUNT;
+               return -EIO;
+       }
 
-       t1pci_reset(card);
+       b1dma_reset(card);
 
        if ((retval = t1pci_detect(card)) != 0) {
                printk(KERN_NOTICE "%s: NO card at 0x%x (%d)\n",
@@ -1029,13 +170,14 @@ static int t1pci_add_card(struct capi_driver *driver, struct capicardparams *p)
                kfree(card->ctrlinfo);
                kfree(card->dma);
                kfree(card);
+               MOD_DEC_USE_COUNT;
                return -EIO;
        }
-       t1pci_reset(card);
+       b1dma_reset(card);
 
        request_region(p->port, AVMB1_PORTLEN, card->name);
 
-       retval = request_irq(card->irq, t1pci_interrupt, SA_SHIRQ, card->name, card);
+       retval = request_irq(card->irq, b1dma_interrupt, SA_SHIRQ, card->name, card);
        if (retval) {
                printk(KERN_ERR "%s: unable to get IRQ %d.\n",
                                driver->name, card->irq);
@@ -1044,6 +186,7 @@ static int t1pci_add_card(struct capi_driver *driver, struct capicardparams *p)
                kfree(card->ctrlinfo);
                kfree(card->dma);
                kfree(card);
+               MOD_DEC_USE_COUNT;
                return -EBUSY;
        }
 
@@ -1056,31 +199,52 @@ static int t1pci_add_card(struct capi_driver *driver, struct capicardparams *p)
                kfree(card->ctrlinfo);
                kfree(card->dma);
                kfree(card);
+               MOD_DEC_USE_COUNT;
                return -EBUSY;
        }
        card->cardnr = cinfo->capi_ctrl->cnr;
 
        skb_queue_head_init(&card->dma->send_queue);
 
-       MOD_INC_USE_COUNT;
+       printk(KERN_INFO
+               "%s: AVM T1 PCI at i/o %#x, irq %d, mem %#lx\n",
+               driver->name, card->port, card->irq, card->membase);
 
        return 0;
 }
 
 /* ------------------------------------------------------------- */
 
+static char *t1pci_procinfo(struct capi_ctr *ctrl)
+{
+       avmctrl_info *cinfo = (avmctrl_info *)(ctrl->driverdata);
+
+       if (!cinfo)
+               return "";
+       sprintf(cinfo->infobuf, "%s %s 0x%x %d 0x%lx",
+               cinfo->cardname[0] ? cinfo->cardname : "-",
+               cinfo->version[VER_DRIVER] ? cinfo->version[VER_DRIVER] : "-",
+               cinfo->card ? cinfo->card->port : 0x0,
+               cinfo->card ? cinfo->card->irq : 0,
+               cinfo->card ? cinfo->card->membase : 0
+               );
+       return cinfo->infobuf;
+}
+
+/* ------------------------------------------------------------- */
+
 static struct capi_driver t1pci_driver = {
     "t1pci",
     "0.0",
-    t1pci_load_firmware,
-    t1pci_reset_ctr,
+    b1dma_load_firmware,
+    b1dma_reset_ctr,
     t1pci_remove_ctr,
-    t1pci_register_appl,
-    t1pci_release_appl,
-    t1pci_send_message,
+    b1dma_register_appl,
+    b1dma_release_appl,
+    b1dma_send_message,
 
     t1pci_procinfo,
-    t1pci_read_proc,
+    b1dmactl_read_proc,
     0, /* use standard driver_read_proc */
 
     0, /* no add_card function */
index 850170f6c887cf1e361d6d0922cca869240cd8f5..e425d5d5d3dd25b31ecf46c7a08e726a2bd40c96 100644 (file)
@@ -1,10 +1,10 @@
-/* 
- * $Id: divert_procfs.c,v 1.5 1999/09/14 20:31:01 werner Exp $
+/*
+ * $Id: divert_procfs.c,v 1.6 2000/02/14 19:23:03 werner Exp $
  *
  * Filesystem handling for the diversion supplementary services.
  *
  * Copyright 1998       by Werner Cornelius (werner@isdn4linux.de)
- * 
+ *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
  * the Free Software Foundation; either version 2, or (at your option)
  *
  * You should have received a copy of the GNU General Public License
  * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  *
  * $Log: divert_procfs.c,v $
+ * Revision 1.6  2000/02/14 19:23:03  werner
+ *
+ * Changed handling of proc filesystem tables to a more portable version
+ *
  * Revision 1.5  1999/09/14 20:31:01  werner
  *
  * Removed obsoleted functions for proc fs and synced with new ones.
@@ -44,9 +48,9 @@
 #include <linux/version.h>
 #include <linux/poll.h>
 #ifdef CONFIG_PROC_FS
-  #include <linux/proc_fs.h>
+#include <linux/proc_fs.h>
 #else
-  #include <linux/fs.h>
+#include <linux/fs.h>
 #endif
 #include <linux/isdnif.h>
 #include "isdn_divert.h"
 /*********************************/
 /* Variables for interface queue */
 /*********************************/
-ulong if_used = 0; /* number of interface users */
-static struct divert_info *divert_info_head = NULL; /* head of queue */
-static struct divert_info *divert_info_tail = NULL; /* pointer to last entry */
-static struct wait_queue *rd_queue = 0; /* Queue IO */
+ulong if_used = 0;             /* number of interface users */
+static struct divert_info *divert_info_head = NULL;    /* head of queue */
+static struct divert_info *divert_info_tail = NULL;    /* pointer to last entry */
+static struct wait_queue *rd_queue = 0;                /* Queue IO */
 
 /*********************************/
 /* put an info buffer into queue */
 /*********************************/
-void put_info_buffer(char *cp)
-{ struct divert_info *ib;
-  int flags; 
-  
-  if (if_used <= 0) return;
-  if (!cp) return;
-  if (!*cp) return; 
-  if (!(ib = (struct divert_info *) kmalloc(sizeof(struct divert_info)+strlen(cp), GFP_ATOMIC))) return; /* no memory */
-  strcpy(ib->info_start,cp); /* set output string */
-  ib->next = NULL;
-  save_flags(flags);
-  cli();
-  ib->usage_cnt = if_used; 
-  if (!divert_info_head) 
-    divert_info_head = ib; /* new head */
-  else
-    divert_info_tail->next = ib; /* follows existing messages */
-  divert_info_tail = ib; /* new tail */   
-  restore_flags(flags);
-
-  /* delete old entrys */
-  while (divert_info_head->next)
-   { if ((divert_info_head->usage_cnt <= 0) &&
-         (divert_info_head->next->usage_cnt <= 0))
-       { ib = divert_info_head;
-         divert_info_head = divert_info_head->next;
-         kfree(ib);
-       }
-     else break;
-   } /* divert_info_head->next */  
-  wake_up_interruptible(&(rd_queue));
-} /* put_info_buffer */
+void
+put_info_buffer(char *cp)
+{
+       struct divert_info *ib;
+       int flags;
+
+       if (if_used <= 0)
+               return;
+       if (!cp)
+               return;
+       if (!*cp)
+               return;
+       if (!(ib = (struct divert_info *) kmalloc(sizeof(struct divert_info) + strlen(cp), GFP_ATOMIC)))
+                return;        /* no memory */
+       strcpy(ib->info_start, cp);     /* set output string */
+       ib->next = NULL;
+       save_flags(flags);
+       cli();
+       ib->usage_cnt = if_used;
+       if (!divert_info_head)
+               divert_info_head = ib;  /* new head */
+       else
+               divert_info_tail->next = ib;    /* follows existing messages */
+       divert_info_tail = ib;  /* new tail */
+       restore_flags(flags);
+
+       /* delete old entrys */
+       while (divert_info_head->next) {
+               if ((divert_info_head->usage_cnt <= 0) &&
+                   (divert_info_head->next->usage_cnt <= 0)) {
+                       ib = divert_info_head;
+                       divert_info_head = divert_info_head->next;
+                       kfree(ib);
+               } else
+                       break;
+       }                       /* divert_info_head->next */
+       wake_up_interruptible(&(rd_queue));
+}                              /* put_info_buffer */
 
 /**********************************/
 /* deflection device read routine */
 /**********************************/
-static ssize_t isdn_divert_read(struct file *file, char *buf, size_t count, loff_t *off)
-{ struct divert_info *inf;
-  int len;
-       
-  if (!*((struct divert_info **)file->private_data))
-    { if (file->f_flags & O_NONBLOCK)
-       return -EAGAIN;
-      interruptible_sleep_on(&(rd_queue));
-    }
-  if (!(inf = *((struct divert_info **)file->private_data))) return(0);
-  
-  inf->usage_cnt--; /* new usage count */
-  (struct divert_info **)file->private_data = &inf->next; /* next structure */
-  if ((len = strlen(inf->info_start)) <= count) 
-    { if (copy_to_user(buf, inf->info_start, len))
-       return -EFAULT;
-      file->f_pos += len;
-      return(len);
-    }
-  return(0);
-} /* isdn_divert_read */
+static ssize_t
+isdn_divert_read(struct file *file, char *buf, size_t count, loff_t * off)
+{
+       struct divert_info *inf;
+       int len;
+
+       if (!*((struct divert_info **) file->private_data)) {
+               if (file->f_flags & O_NONBLOCK)
+                       return -EAGAIN;
+               interruptible_sleep_on(&(rd_queue));
+       }
+       if (!(inf = *((struct divert_info **) file->private_data)))
+               return (0);
+
+       inf->usage_cnt--;       /* new usage count */
+       (struct divert_info **) file->private_data = &inf->next;        /* next structure */
+       if ((len = strlen(inf->info_start)) <= count) {
+               if (copy_to_user(buf, inf->info_start, len))
+                       return -EFAULT;
+               file->f_pos += len;
+               return (len);
+       }
+       return (0);
+}                              /* isdn_divert_read */
 
 /**********************************/
 /* deflection device write routine */
 /**********************************/
-static ssize_t isdn_divert_write(struct file *file, const char *buf, size_t count, loff_t *off)
+static ssize_t
+isdn_divert_write(struct file *file, const char *buf, size_t count, loff_t * off)
 {
-  return(-ENODEV);
-} /* isdn_divert_write */
+       return (-ENODEV);
+}                              /* isdn_divert_write */
 
 
 /***************************************/
 /* select routines for various kernels */
 /***************************************/
-static unsigned int isdn_divert_poll(struct file *file, poll_table * wait)
-{ unsigned int mask = 0;
+static unsigned int
+isdn_divert_poll(struct file *file, poll_table * wait)
+{
+       unsigned int mask = 0;
 
-  poll_wait(file, &(rd_queue), wait);
-  /* mask = POLLOUT | POLLWRNORM; */
-  if (*((struct divert_info **)file->private_data)) 
-    { mask |= POLLIN | POLLRDNORM;
-    }
-  return mask;
-} /* isdn_divert_poll */
+       poll_wait(file, &(rd_queue), wait);
+       /* mask = POLLOUT | POLLWRNORM; */
+       if (*((struct divert_info **) file->private_data)) {
+               mask |= POLLIN | POLLRDNORM;
+       }
+       return mask;
+}                              /* isdn_divert_poll */
 
 /****************/
 /* Open routine */
 /****************/
-static int isdn_divert_open(struct inode *ino, struct file *filep)
-{ int flags;
-
-  MOD_INC_USE_COUNT;
-  save_flags(flags);
-  cli();
-  if_used++;
-  if (divert_info_head)
-    (struct divert_info **)filep->private_data = &(divert_info_tail->next);
-   else
-    (struct divert_info **)filep->private_data = &divert_info_head; 
-  restore_flags(flags);
-  /*  start_divert(); */
-  return(0);
-} /* isdn_divert_open */
+static int
+isdn_divert_open(struct inode *ino, struct file *filep)
+{
+       int flags;
+
+       MOD_INC_USE_COUNT;
+       save_flags(flags);
+       cli();
+       if_used++;
+       if (divert_info_head)
+               (struct divert_info **) filep->private_data = &(divert_info_tail->next);
+       else
+               (struct divert_info **) filep->private_data = &divert_info_head;
+       restore_flags(flags);
+       /*  start_divert(); */
+       return (0);
+}                              /* isdn_divert_open */
 
 /*******************/
 /* close routine   */
 /*******************/
-static int isdn_divert_close(struct inode *ino, struct file *filep)
-{ struct divert_info *inf; 
-  int flags;
-
-  save_flags(flags);
-  cli();
-  if_used--;
-  inf = *((struct divert_info **)filep->private_data);
-  while (inf)
-   { inf->usage_cnt--;
-     inf = inf->next;
-   } 
-  restore_flags(flags);
-  if (if_used <= 0)
-   while (divert_info_head)
-    { inf = divert_info_head;
-      divert_info_head = divert_info_head->next;
-      kfree(inf);
-    }
-  MOD_DEC_USE_COUNT;
-  return(0);
-} /* isdn_divert_close */
+static int
+isdn_divert_close(struct inode *ino, struct file *filep)
+{
+       struct divert_info *inf;
+       int flags;
+
+       save_flags(flags);
+       cli();
+       if_used--;
+       inf = *((struct divert_info **) filep->private_data);
+       while (inf) {
+               inf->usage_cnt--;
+               inf = inf->next;
+       }
+       restore_flags(flags);
+       if (if_used <= 0)
+               while (divert_info_head) {
+                       inf = divert_info_head;
+                       divert_info_head = divert_info_head->next;
+                       kfree(inf);
+               }
+       MOD_DEC_USE_COUNT;
+       return (0);
+}                              /* isdn_divert_close */
 
 /*********/
 /* IOCTL */
 /*********/
-static int isdn_divert_ioctl(struct inode *inode, struct file *file, 
-                             uint cmd, ulong arg)
-{ divert_ioctl dioctl;
-  int i, flags;
-  divert_rule *rulep;
-  char *cp;
-
-  if ((i = copy_from_user(&dioctl,(char *) arg, sizeof(dioctl))))
-    return(i); 
-  switch (cmd)
-   { 
-     case IIOCGETVER:
-       dioctl.drv_version = DIVERT_IIOC_VERSION ; /* set version */
-       break;
-
-     case IIOCGETDRV:
-       if ((dioctl.getid.drvid = divert_if.name_to_drv(dioctl.getid.drvnam)) < 0)
-         return(-EINVAL);  
-       break;
-
-     case IIOCGETNAM:
-       cp = divert_if.drv_to_name(dioctl.getid.drvid);
-       if (!cp) return(-EINVAL);
-       if (!*cp) return(-EINVAL);
-       strcpy(dioctl.getid.drvnam,cp);  
-       break;
-
-     case IIOCGETRULE:
-       if (!(rulep = getruleptr(dioctl.getsetrule.ruleidx)))
-         return(-EINVAL);  
-       dioctl.getsetrule.rule = *rulep; /* copy data */
-       break;
-
-     case IIOCMODRULE:
-       if (!(rulep = getruleptr(dioctl.getsetrule.ruleidx)))
-         return(-EINVAL);  
-       save_flags(flags);
-       cli();
-       *rulep = dioctl.getsetrule.rule; /* copy data */
-       restore_flags(flags);
-       return(0); /* no copy required */
-       break;
-
-     case IIOCINSRULE:
-       return(insertrule(dioctl.getsetrule.ruleidx,&dioctl.getsetrule.rule));
-       break;
-
-     case IIOCDELRULE:
-       return(deleterule(dioctl.getsetrule.ruleidx));
-       break;
-
-     case IIOCDODFACT:
-       return(deflect_extern_action(dioctl.fwd_ctrl.subcmd,
-                                    dioctl.fwd_ctrl.callid,
-                                    dioctl.fwd_ctrl.to_nr)); 
-
-     case  IIOCDOCFACT:
-     case  IIOCDOCFDIS:
-     case  IIOCDOCFINT:
-       if (!divert_if.drv_to_name(dioctl.cf_ctrl.drvid)) 
-         return(-EINVAL); /* invalid driver */
-       if ((i = cf_command(dioctl.cf_ctrl.drvid,
-                          (cmd == IIOCDOCFACT) ? 1: (cmd == IIOCDOCFDIS) ? 0:2,
-                          dioctl.cf_ctrl.cfproc,
-                          dioctl.cf_ctrl.msn,  
-                          dioctl.cf_ctrl.service,
-                          dioctl.cf_ctrl.fwd_nr,
-                          &dioctl.cf_ctrl.procid)))
-         return(i);    
-       break;
-   
-     default: 
-       return(-EINVAL);
-   } /* switch cmd */
-  return(copy_to_user((char *) arg, &dioctl, sizeof(dioctl))); /* success */
-} /* isdn_divert_ioctl */
+static int
+isdn_divert_ioctl(struct inode *inode, struct file *file,
+                 uint cmd, ulong arg)
+{
+       divert_ioctl dioctl;
+       int i, flags;
+       divert_rule *rulep;
+       char *cp;
+
+       if ((i = copy_from_user(&dioctl, (char *) arg, sizeof(dioctl))))
+               return (i);
+
+       switch (cmd) {
+               case IIOCGETVER:
+                       dioctl.drv_version = DIVERT_IIOC_VERSION;       /* set version */
+                       break;
+
+               case IIOCGETDRV:
+                       if ((dioctl.getid.drvid = divert_if.name_to_drv(dioctl.getid.drvnam)) < 0)
+                               return (-EINVAL);
+                       break;
+
+               case IIOCGETNAM:
+                       cp = divert_if.drv_to_name(dioctl.getid.drvid);
+                       if (!cp)
+                               return (-EINVAL);
+                       if (!*cp)
+                               return (-EINVAL);
+                       strcpy(dioctl.getid.drvnam, cp);
+                       break;
+
+               case IIOCGETRULE:
+                       if (!(rulep = getruleptr(dioctl.getsetrule.ruleidx)))
+                               return (-EINVAL);
+                       dioctl.getsetrule.rule = *rulep;        /* copy data */
+                       break;
+
+               case IIOCMODRULE:
+                       if (!(rulep = getruleptr(dioctl.getsetrule.ruleidx)))
+                               return (-EINVAL);
+                       save_flags(flags);
+                       cli();
+                       *rulep = dioctl.getsetrule.rule;        /* copy data */
+                       restore_flags(flags);
+                       return (0);     /* no copy required */
+                       break;
+
+               case IIOCINSRULE:
+                       return (insertrule(dioctl.getsetrule.ruleidx, &dioctl.getsetrule.rule));
+                       break;
+
+               case IIOCDELRULE:
+                       return (deleterule(dioctl.getsetrule.ruleidx));
+                       break;
+
+               case IIOCDODFACT:
+                       return (deflect_extern_action(dioctl.fwd_ctrl.subcmd,
+                                                 dioctl.fwd_ctrl.callid,
+                                                dioctl.fwd_ctrl.to_nr));
+
+               case IIOCDOCFACT:
+               case IIOCDOCFDIS:
+               case IIOCDOCFINT:
+                       if (!divert_if.drv_to_name(dioctl.cf_ctrl.drvid))
+                               return (-EINVAL);       /* invalid driver */
+                       if ((i = cf_command(dioctl.cf_ctrl.drvid,
+                                           (cmd == IIOCDOCFACT) ? 1 : (cmd == IIOCDOCFDIS) ? 0 : 2,
+                                           dioctl.cf_ctrl.cfproc,
+                                           dioctl.cf_ctrl.msn,
+                                           dioctl.cf_ctrl.service,
+                                           dioctl.cf_ctrl.fwd_nr,
+                                           &dioctl.cf_ctrl.procid)))
+                               return (i);
+                       break;
+
+               default:
+                       return (-EINVAL);
+       }                       /* switch cmd */
+       return (copy_to_user((char *) arg, &dioctl, sizeof(dioctl)));   /* success */
+}                              /* isdn_divert_ioctl */
 
 
 #ifdef CONFIG_PROC_FS
@@ -282,79 +305,62 @@ static struct file_operations isdn_fops =
        isdn_divert_lseek,
        isdn_divert_read,
        isdn_divert_write,
-       NULL,                          /* isdn_readdir */
-       isdn_divert_poll,              /* isdn_poll */
-       isdn_divert_ioctl,             /* isdn_ioctl */
-       NULL,                          /* isdn_mmap */
+       NULL,                   /* isdn_readdir */
+       isdn_divert_poll,       /* isdn_poll */
+       isdn_divert_ioctl,      /* isdn_ioctl */
+       NULL,                   /* isdn_mmap */
        isdn_divert_open,
-       NULL,                          /* flush */ 
+       NULL,                   /* flush */
        isdn_divert_close,
-       NULL                           /* fsync */
-};
-
-struct inode_operations divert_file_inode_operations = {
-    &isdn_fops,  /* default proc file-ops */
-    NULL,       /* create      */
-    NULL,       /* lookup      */
-    NULL,       /* link                */
-    NULL,       /* unlink      */
-    NULL,       /* symlink     */
-    NULL,       /* mkdir       */
-    NULL,       /* rmdir          */
-    NULL,       /* mknod          */
-    NULL,          /* rename      */
-    NULL,          /* readlink    */
-    NULL,          /* follow_link */
-    NULL,          /* readpage    */
-    NULL,          /* writepage   */
-    NULL,          /* bmap        */
-    NULL,          /* truncate    */
-    NULL           /* permission  */
+       NULL                    /* fsync */
 };
 
+struct inode_operations divert_file_inode_operations;
 
 /****************************/
 /* isdn subdir in /proc/net */
 /****************************/
 static struct proc_dir_entry *isdn_proc_entry = NULL;
 static struct proc_dir_entry *isdn_divert_entry = NULL;
-#endif CONFIG_PROC_FS
+#endif /* CONFIG_PROC_FS */
 
 /***************************************************************************/
 /* divert_dev_init must be called before the proc filesystem may be used   */
 /***************************************************************************/
-int divert_dev_init(void)
-{ int i;
+int
+divert_dev_init(void)
+{
 
 
 #ifdef CONFIG_PROC_FS
-  isdn_proc_entry = create_proc_entry("isdn", S_IFDIR | S_IRUGO | S_IXUGO ,proc_net);
-  if (!isdn_proc_entry) 
-    return(-1);
-  isdn_divert_entry = create_proc_entry("divert",S_IFREG | S_IRUGO,isdn_proc_entry); 
-  if (!isdn_divert_entry) 
-   {
-     remove_proc_entry("isdn",proc_net);
-     return(-1);
-   }
-  isdn_divert_entry->ops = &divert_file_inode_operations;
-#endif CONFIG_PROC_FS
-
-  return(0);
-} /* divert_dev_init */
+       isdn_proc_entry = create_proc_entry("isdn", S_IFDIR | S_IRUGO | S_IXUGO, proc_net);
+       if (!isdn_proc_entry)
+               return (-1);
+       isdn_divert_entry = create_proc_entry("divert", S_IFREG | S_IRUGO, isdn_proc_entry);
+       if (!isdn_divert_entry) {
+               remove_proc_entry("isdn", proc_net);
+               return (-1);
+       }
+       memset(&divert_file_inode_operations, 0, sizeof(struct inode_operations));
+       divert_file_inode_operations.default_file_ops = &isdn_fops;
+       isdn_divert_entry->ops = &divert_file_inode_operations;
+#endif /* CONFIG_PROC_FS */
+
+       return (0);
+}                              /* divert_dev_init */
 
 /***************************************************************************/
 /* divert_dev_deinit must be called before leaving isdn when included as   */
 /* a module.                                                               */
 /***************************************************************************/
-int divert_dev_deinit(void)
-{ int i;
+int
+divert_dev_deinit(void)
+{
 
 #ifdef CONFIG_PROC_FS
-  remove_proc_entry("divert",isdn_proc_entry);
-  remove_proc_entry("isdn",proc_net);
-#endif CONFIG_PROC_FS
-
-  return(0);
-} /* divert_dev_deinit */
+       remove_proc_entry("divert", isdn_proc_entry);
+       remove_proc_entry("isdn", proc_net);
+#endif /* CONFIG_PROC_FS */
 
+       return (0);
+}                              /* divert_dev_deinit */
index c2d1724e572eb519f7653cffe138e70c8032a67f..7e013a71bd2d38f6ff3b759889e20c810c17450a 100644 (file)
@@ -1,10 +1,10 @@
-/* $Id: eicon.h,v 1.18 1999/11/25 11:43:27 armin Exp $
+/* $Id: eicon.h,v 1.19 2000/01/23 21:21:23 armin Exp $
  *
- * ISDN low-level module for Eicon.Diehl active ISDN-Cards.
+ * ISDN low-level module for Eicon active ISDN-Cards.
  *
  * Copyright 1998    by Fritz Elfert (fritz@isdn4linux.de)
- * Copyright 1998,99 by Armin Schindler (mac@melware.de) 
- * Copyright 1999    Cytronics & Melware (info@melware.de)
+ * Copyright 1998-2000  by Armin Schindler (mac@melware.de) 
+ * Copyright 1999,2000  Cytronics & Melware (info@melware.de)
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 
  *
  * $Log: eicon.h,v $
+ * Revision 1.19  2000/01/23 21:21:23  armin
+ * Added new trace capability and some updates.
+ * DIVA Server BRI now supports data for ISDNLOG.
+ *
  * Revision 1.18  1999/11/25 11:43:27  armin
  * Fixed statectrl and connect message.
  * X.75 fix and HDLC/transparent with autoconnect.
@@ -263,7 +267,7 @@ typedef struct {
 
 /* Macro for delay via schedule() */
 #define SLEEP(j) {                     \
-  current->state = TASK_INTERRUPTIBLE; \
+  current->state = TASK_UNINTERRUPTIBLE; \
   schedule_timeout(j);                 \
 }
 
@@ -282,6 +286,8 @@ typedef struct {
 #define XLOG_ERR_UNKNOWN        (18)
 #define XLOG_OK                  (0)
 
+#define TRACE_OK                 (1)
+
 typedef struct {
   __u8 Id      __attribute__ ((packed));
   __u8 uX      __attribute__ ((packed));
@@ -697,6 +703,7 @@ extern int eicon_info(char *, int , void *);
 
 extern ulong DebugVar;
 extern void eicon_log(eicon_card * card, int level, const char *fmt, ...);
+extern void eicon_putstatus(eicon_card * card, char * buf);
 
 #endif  /* __KERNEL__ */
 
index 9ffbd9bdbed376656d50679786b848a2d34cc9b3..420d73f6ea8f18c415f2c5105bd6099caf0acc2a 100644 (file)
@@ -1,10 +1,10 @@
-/* $Id: eicon_dsp.h,v 1.4 1999/07/25 15:12:02 armin Exp $
+/* $Id: eicon_dsp.h,v 1.5 2000/01/23 21:21:23 armin Exp $
  *
- * ISDN lowlevel-module for Eicon.Diehl active cards.
+ * ISDN lowlevel-module for Eicon active cards.
  *        DSP definitions
  *
- * Copyright 1999    by Armin Schindler (mac@melware.de)
- * Copyright 1999    Cytronics & Melware (info@melware.de)
+ * Copyright 1999,2000  by Armin Schindler (mac@melware.de)
+ * Copyright 1999,2000  Cytronics & Melware (info@melware.de)
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  *
  * $Log: eicon_dsp.h,v $
+ * Revision 1.5  2000/01/23 21:21:23  armin
+ * Added new trace capability and some updates.
+ * DIVA Server BRI now supports data for ISDNLOG.
+ *
  * Revision 1.4  1999/07/25 15:12:02  armin
  * fix of some debug logs.
  * enabled ISA-cards option.
index 1758297fe2ed7b7d97170c8a5fa980e6e2cd5374..9cef520bc5271eb07130ec245cc5b16bd6587cb2 100644 (file)
@@ -1,10 +1,10 @@
-/* $Id: eicon_idi.c,v 1.28 2000/01/20 19:55:34 keil Exp $
+/* $Id: eicon_idi.c,v 1.33 2000/03/06 15:45:17 armin Exp $
  *
- * ISDN lowlevel-module for Eicon.Diehl active cards.
+ * ISDN lowlevel-module for Eicon active cards.
  *        IDI interface 
  *
- * Copyright 1998,99 by Armin Schindler (mac@melware.de)
- * Copyright 1999    Cytronics & Melware (info@melware.de)
+ * Copyright 1998-2000  by Armin Schindler (mac@melware.de)
+ * Copyright 1999,2000  Cytronics & Melware (info@melware.de)
  *
  * Thanks to   Deutsche Mailbox Saar-Lor-Lux GmbH
  *             for sponsoring and testing fax
  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 
  *
  * $Log: eicon_idi.c,v $
+ * Revision 1.33  2000/03/06 15:45:17  armin
+ * Fixed incomplete number handling with BRI PtP connection.
+ *
+ * Revision 1.32  2000/03/04 17:04:21  armin
+ * Fix of statemachine, B-connect before D-connect,
+ * thanks to Helmut Adams <adams@ipcon.de>
+ * Minor change in send-data packet handling.
+ *
+ * Revision 1.31  2000/02/22 16:26:40  armin
+ * Fixed membase error message.
+ * Fixed missing log buffer struct.
+ *
+ * Revision 1.30  2000/02/16 16:08:46  armin
+ * Fixed virtual channel handling of IDI.
+ *
+ * Revision 1.29  2000/01/23 21:21:23  armin
+ * Added new trace capability and some updates.
+ * DIVA Server BRI now supports data for ISDNLOG.
+ *
  * Revision 1.28  2000/01/20 19:55:34  keil
  * Add FAX Class 1 support
  *
 
 #undef EICON_FULL_SERVICE_OKTETT
 
-char *eicon_idi_revision = "$Revision: 1.28 $";
+char *eicon_idi_revision = "$Revision: 1.33 $";
 
 eicon_manifbuf *manbuf;
 
@@ -251,10 +270,10 @@ idi_assign_req(eicon_REQ *reqbuf, int signet, eicon_chan *chan)
 }
 
 int
-idi_put_req(eicon_REQ *reqbuf, int rq, int signet)
+idi_put_req(eicon_REQ *reqbuf, int rq, int signet, int Ch)
 {
        reqbuf->Req = rq;
-       reqbuf->ReqCh = 0;
+       reqbuf->ReqCh = Ch;
        reqbuf->ReqId = 1;
        reqbuf->XBuffer.length = 1;
        reqbuf->XBuffer.P[0] = 0;
@@ -364,34 +383,34 @@ idi_do_req(eicon_card *card, eicon_chan *chan, int cmd, int layer)
                        break;
                case REMOVE:
                case REMOVE|0x700:
-                       idi_put_req(reqbuf, REMOVE, layer);
+                       idi_put_req(reqbuf, REMOVE, layer, 0);
                        break;
                case INDICATE_REQ:
-                       idi_put_req(reqbuf, INDICATE_REQ, 0);
+                       idi_put_req(reqbuf, INDICATE_REQ, 0, 0);
                        break;
                case HANGUP:
-                       idi_put_req(reqbuf, HANGUP, 0);
+                       idi_put_req(reqbuf, HANGUP, 0, 0);
                        break;
                case REJECT:
-                       idi_put_req(reqbuf, REJECT, 0);
+                       idi_put_req(reqbuf, REJECT, 0 ,0);
                        break;
                case CALL_ALERT:
-                       idi_put_req(reqbuf, CALL_ALERT, 0);
+                       idi_put_req(reqbuf, CALL_ALERT, 0, 0);
                        break;
                case CALL_RES:
                        idi_call_res_req(reqbuf, chan);
                        break;
                case IDI_N_CONNECT|0x700:
-                       idi_put_req(reqbuf, IDI_N_CONNECT, 1);
+                       idi_put_req(reqbuf, IDI_N_CONNECT, 1, 0);
                        break;
                case IDI_N_CONNECT_ACK|0x700:
-                       idi_put_req(reqbuf, IDI_N_CONNECT_ACK, 1);
+                       idi_put_req(reqbuf, IDI_N_CONNECT_ACK, 1, 0);
                        break;
                case IDI_N_DISC|0x700:
-                       idi_put_req(reqbuf, IDI_N_DISC, 1);
+                       idi_put_req(reqbuf, IDI_N_DISC, 1, chan->e.IndCh);
                        break;
                case IDI_N_DISC_ACK|0x700:
-                       idi_put_req(reqbuf, IDI_N_DISC_ACK, 1);
+                       idi_put_req(reqbuf, IDI_N_DISC_ACK, 1, chan->e.IndCh);
                        break;
                default:
                        eicon_log(card, 1, "idi_req: Ch%d: Unknown request\n", chan->No);
@@ -809,6 +828,11 @@ idi_IndParse(eicon_card *ccard, eicon_chan *chan, idi_ind_message *message, unsi
                                        message->osa[i] = buffer[pos++];
                                eicon_log(ccard, 2, "idi_inf: Ch%d: OSA=%s\n", chan->No, message->osa);
                                break;
+                       case CAD:
+                               pos += wlen;
+                               eicon_log(ccard, 2, "idi_inf: Ch%d: Connected Address in ind, len:%x\n", 
+                                       chan->No, wlen);
+                               break;
                        case BC:
                                if (wlen > sizeof(message->bc)) {
                                        pos += wlen;
@@ -1202,7 +1226,7 @@ idi_send_edata(eicon_card *card, eicon_chan *chan)
        reqbuf = (eicon_REQ *)skb_put(skb, sizeof(eicon_t30_s) + sizeof(eicon_REQ));
 
        reqbuf->Req = IDI_N_EDATA;
-       reqbuf->ReqCh = 0;
+       reqbuf->ReqCh = chan->e.IndCh;
        reqbuf->ReqId = 1;
 
        reqbuf->XBuffer.length = idi_fill_in_T30(chan, reqbuf->XBuffer.P);
@@ -2201,7 +2225,7 @@ idi_send_udata(eicon_card *card, eicon_chan *chan, int UReq, u_char *buffer, int
        reqbuf = (eicon_REQ *)skb_put(skb, 1 + len + sizeof(eicon_REQ));
 
        reqbuf->Req = IDI_N_UDATA;
-       reqbuf->ReqCh = 0;
+       reqbuf->ReqCh = chan->e.IndCh;
        reqbuf->ReqId = 1;
 
        reqbuf->XBuffer.length = len + 1;
@@ -2305,6 +2329,51 @@ idi_parse_udata(eicon_card *ccard, eicon_chan *chan, unsigned char *buffer, int
        }
 }
 
+void
+eicon_parse_trace(eicon_card *ccard, unsigned char *buffer, int len)
+{
+       int i,j,n;
+       int buflen = len * 3 + 30;
+       char *p;
+       struct trace_s {
+               unsigned long time;
+               unsigned short size;
+               unsigned short code;
+               unsigned char data[1];
+       } *q;
+
+       if (!(p = kmalloc(buflen, GFP_ATOMIC))) {
+               eicon_log(ccard, 1, "idi_err: Ch??: could not allocate trace buffer\n");
+               return;
+       }
+       memset(p, 0, buflen);
+       q = (struct trace_s *)buffer;
+
+       if (DebugVar & 512) {
+               if ((q->code == 3) || (q->code == 4)) {
+                       n = (short) *(q->data);
+                       if (n) {
+                               j = sprintf(p, "DTRC:");
+                               for (i = 0; i < n; i++) {
+                                       j += sprintf(p + j, "%02x ", q->data[i+2]);
+                               }
+                               j += sprintf(p + j, "\n");
+                       }
+               }
+       } else {
+               j = sprintf(p, "XLOG: %lx %04x %04x ",
+                       q->time, q->size, q->code);
+
+               for (i = 0; i < q->size; i++) {
+                       j += sprintf(p + j, "%02x ", q->data[i]);
+               }
+               j += sprintf(p + j, "\n");
+       }
+       if (strlen(p))
+               eicon_putstatus(ccard, p);
+       kfree(p);
+}
+
 void
 idi_handle_ind(eicon_card *ccard, struct sk_buff *skb)
 {
@@ -2331,12 +2400,12 @@ idi_handle_ind(eicon_card *ccard, struct sk_buff *skb)
                return;
        }
        
-       if (ind->Ind != 8)
+       if ((ind->Ind != 8) && (ind->Ind != 0xc))
                dlev = 144;
        else
                dlev = 128;
 
-               eicon_log(ccard, dlev, "idi_hdl: Ch%d: Ind=%d Id=%x Ch=%d MInd=%d MLen=%d Len=%d\n", chan->No,
+               eicon_log(ccard, dlev, "idi_hdl: Ch%d: Ind=%x Id=%x Ch=%x MInd=%x MLen=%x Len=%x\n", chan->No,
                ind->Ind,ind->IndId,ind->IndCh,ind->MInd,ind->MLength,ind->RBuffer.length);
 
        free_buff = 1;
@@ -2454,15 +2523,7 @@ idi_handle_ind(eicon_card *ccard, struct sk_buff *skb)
                                                break;
                                        case 3: /* incomplete number */
                                                eicon_log(ccard, 8, "idi_req: Ch%d: Incomplete Number\n", chan->No);
-                                               switch(ccard->type) {
-                                                       case EICON_CTYPE_MAESTRAP:
-                                                       case EICON_CTYPE_S2M:
-                                                               /* TODO (other protocols) */
-                                                               chan->fsm_state = EICON_STATE_ICALLW;
-                                                               break;
-                                                       default:
-                                                               idi_do_req(ccard, chan, HANGUP, 0);
-                                               }
+                                               chan->fsm_state = EICON_STATE_ICALLW;
                                                break;
                                }
                                break;
@@ -2499,8 +2560,10 @@ idi_handle_ind(eicon_card *ccard, struct sk_buff *skb)
                                                        /* On most incoming calls we use automatic connect */
                                                        /* idi_do_req(ccard, chan, IDI_N_CONNECT, 1); */
                                        }
-                               } else
-                                       idi_hangup(ccard, chan);
+                               } else {
+                                       if (chan->fsm_state != EICON_STATE_ACTIVE)
+                                               idi_hangup(ccard, chan);
+                               }
                                break;
                        case CALL_CON:
                                eicon_log(ccard, 8, "idi_ind: Ch%d: Call_Con\n", chan->No);
@@ -2541,8 +2604,12 @@ idi_handle_ind(eicon_card *ccard, struct sk_buff *skb)
 
                if (chan->No == ccard->nchannels) {
                        /* Management Indication */
-                       idi_IndParse(ccard, chan, &message, ind->RBuffer.P, ind->RBuffer.length);
-                       chan->fsm_state = 1;
+                       if (ind->Ind == 0x04) { /* Trace_Ind */
+                               eicon_parse_trace(ccard, ind->RBuffer.P, ind->RBuffer.length);
+                       } else {
+                               idi_IndParse(ccard, chan, &message, ind->RBuffer.P, ind->RBuffer.length);
+                               chan->fsm_state = 1;
+                       }
                } 
                else
                switch(ind->Ind) {
@@ -2581,6 +2648,7 @@ idi_handle_ind(eicon_card *ccard, struct sk_buff *skb)
                                break; 
                        case IDI_N_CONNECT:
                                eicon_log(ccard, 16,"idi_ind: Ch%d: N_Connect\n", chan->No);
+                               chan->e.IndCh = ind->IndCh;
                                if (chan->e.B2Id) idi_do_req(ccard, chan, IDI_N_CONNECT_ACK, 1);
                                if (chan->l2prot == ISDN_PROTO_L2_FAX) {
                                        break;
@@ -2611,6 +2679,7 @@ idi_handle_ind(eicon_card *ccard, struct sk_buff *skb)
                                        idi_fax_hangup(ccard, chan);
                                }
 #endif
+                               chan->e.IndCh = 0;
                                save_flags(flags);
                                cli();
                                chan->queued = 0;
@@ -2640,7 +2709,7 @@ idi_handle_ind(eicon_card *ccard, struct sk_buff *skb)
 #endif
                                break; 
                        case IDI_N_DATA_ACK:
-                               eicon_log(ccard, 16, "idi_ind: Ch%d: N_DATA_ACK\n", chan->No);
+                               eicon_log(ccard, 128, "idi_ind: Ch%d: N_DATA_ACK\n", chan->No);
                                break;
                        case IDI_N_DATA:
                                skb_pull(skb, sizeof(eicon_IND) - 1);
@@ -2690,7 +2759,7 @@ idi_handle_ack_ok(eicon_card *ccard, eicon_chan *chan, eicon_RC *ack)
        /* Management Interface */      
        if (chan->No == ccard->nchannels) {
                /* Managementinterface: changing state */
-               if (chan->e.Req == 0x04)
+               if (chan->e.Req != 0x02)
                        chan->fsm_state = 1;
        }
 
@@ -2721,6 +2790,11 @@ idi_handle_ack_ok(eicon_card *ccard, eicon_chan *chan, eicon_RC *ack)
        } else {
        /* Network layer */
                switch(chan->e.Req & 0x0f) {
+                       case IDI_N_CONNECT:
+                               chan->e.IndCh = ack->RcCh;
+                               eicon_log(ccard, 16, "idi_ack: Ch%d: RC OK Id=%x Ch=%d (ref:%d)\n", chan->No,
+                                       ack->RcId, ack->RcCh, ack->Reference);
+                               break;
                        case IDI_N_MDATA:
                        case IDI_N_DATA:
                                if ((chan->e.Req & 0x0f) == IDI_N_DATA) {
@@ -2857,11 +2931,14 @@ idi_handle_ack(eicon_card *ccard, struct sk_buff *skb)
                                                dCh, ack->Rc, ack->RcId, ack->RcCh);
                                        break;
                                default:
-                                       eicon_log(ccard, 1, "eicon_err: Ch%d: Ack Not OK !!: Rc=%d Id=%x Ch=%d Req=%d\n",
-                                               dCh, ack->Rc, ack->RcId, ack->RcCh, chan->e.Req);
+                                       if (dCh != ccard->nchannels)
+                                               eicon_log(ccard, 1, "eicon_err: Ch%d: Ack Not OK !!: Rc=%d Id=%x Ch=%d Req=%d\n",
+                                                       dCh, ack->Rc, ack->RcId, ack->RcCh, chan->e.Req);
                        }
                        if (dCh == ccard->nchannels) { /* Management */
                                chan->fsm_state = 2;
+                               eicon_log(ccard, 8, "eicon_err: Ch%d: Ack Not OK !!: Rc=%d Id=%x Ch=%d Req=%d\n",
+                                       dCh, ack->Rc, ack->RcId, ack->RcCh, chan->e.Req);
                        } else if (dCh >= 0) {
                                        /* any other channel */
                                        /* card reports error: we hangup */
@@ -2937,13 +3014,15 @@ idi_send_data(eicon_card *card, eicon_chan *chan, int ack, struct sk_buff *skb,
 
                reqbuf = (eicon_REQ *)skb_put(xmit_skb, plen + sizeof(eicon_REQ));
                if (((len - offset) > 270) &&
+                       (chan->l2prot != ISDN_PROTO_L2_MODEM) &&
+                       (chan->l2prot != ISDN_PROTO_L2_FAX) &&
                        (chan->l2prot != ISDN_PROTO_L2_TRANS)) {
                        reqbuf->Req = IDI_N_MDATA;
                } else {
                        reqbuf->Req = IDI_N_DATA;
-                       if (ack) reqbuf->Req |= N_D_BIT;
+                       /* if (ack) reqbuf->Req |= N_D_BIT; */
                }       
-               reqbuf->ReqCh = 0;
+               reqbuf->ReqCh = chan->e.IndCh;
                reqbuf->ReqId = 1;
                memcpy(&reqbuf->XBuffer.P, skb->data + offset, plen);
                reqbuf->XBuffer.length = plen;
@@ -3061,38 +3140,36 @@ eicon_idi_manage(eicon_card *card, eicon_manifbuf *mb)
 
         chan = &(card->bch[card->nchannels]);
 
-       if (chan->e.D3Id)
-               return -EBUSY;
-       chan->e.D3Id = 1;
-       while((skb2 = skb_dequeue(&chan->e.X)))
-               dev_kfree_skb(skb2);
-       chan->e.busy = 0;
+       if (!(chan->e.D3Id)) {
+               chan->e.D3Id = 1;
+               while((skb2 = skb_dequeue(&chan->e.X)))
+                       dev_kfree_skb(skb2);
+               chan->e.busy = 0;
  
-       if ((ret = eicon_idi_manage_assign(card))) {
-               chan->e.D3Id = 0;
-               return(ret); 
-       }
+               if ((ret = eicon_idi_manage_assign(card))) {
+                       chan->e.D3Id = 0;
+                       return(ret); 
+               }
 
-        timeout = jiffies + 50;
-        while (timeout > jiffies) {
-                if (chan->e.B2Id) break;
-                SLEEP(10);
-        }
-        if (!chan->e.B2Id) {
-               chan->e.D3Id = 0;
-               return -EIO;
+               timeout = jiffies + 50;
+               while (timeout > jiffies) {
+                       if (chan->e.B2Id) break;
+                       SLEEP(10);
+               }
+               if (!chan->e.B2Id) {
+                       chan->e.D3Id = 0;
+                       return -EIO;
+               }
        }
 
        chan->fsm_state = 0;
 
        if (!(manbuf = kmalloc(sizeof(eicon_manifbuf), GFP_KERNEL))) {
                        eicon_log(card, 1, "idi_err: alloc_manifbuf failed\n");
-               chan->e.D3Id = 0;
                return -ENOMEM;
        }
        if (copy_from_user(manbuf, mb, sizeof(eicon_manifbuf))) {
                kfree(manbuf);
-               chan->e.D3Id = 0;
                return -EFAULT;
        }
 
@@ -3106,7 +3183,6 @@ eicon_idi_manage(eicon_card *card, eicon_manifbuf *mb)
                if (skb2) 
                        dev_kfree_skb(skb2);
                kfree(manbuf);
-               chan->e.D3Id = 0;
                 return -ENOMEM;
         }
 
@@ -3143,25 +3219,14 @@ eicon_idi_manage(eicon_card *card, eicon_manifbuf *mb)
                 SLEEP(10);
         }
         if ((!chan->fsm_state) || (chan->fsm_state == 2)) {
-               eicon_idi_manage_remove(card);
                kfree(manbuf);
-               chan->e.D3Id = 0;
                return -EIO;
        }
-
-       if ((ret = eicon_idi_manage_remove(card))) {
-               kfree(manbuf);
-               chan->e.D3Id = 0;
-               return(ret);
-       }
-
        if (copy_to_user(mb, manbuf, sizeof(eicon_manifbuf))) {
                kfree(manbuf);
-               chan->e.D3Id = 0;
                return -EFAULT;
        }
 
        kfree(manbuf);
-       chan->e.D3Id = 0;
   return(0);
 }
index 2ab4bdd165dcb704849926a57092f2932d6997aa..2fe6167a4347238833f541951a7dd590cd99d01b 100644 (file)
@@ -1,10 +1,10 @@
-/* $Id: eicon_idi.h,v 1.8 1999/11/25 11:43:27 armin Exp $
+/* $Id: eicon_idi.h,v 1.9 2000/01/23 21:21:23 armin Exp $
  *
- * ISDN lowlevel-module for the Eicon.Diehl active cards.
+ * ISDN lowlevel-module for the Eicon active cards.
  * IDI-Interface
  *
- * Copyright 1998,99 by Armin Schindler (mac@melware.de)
- * Copyright 1999    Cytronics & Melware (info@melware.de)
+ * Copyright 1998-2000  by Armin Schindler (mac@melware.de)
+ * Copyright 1999,2000  Cytronics & Melware (info@melware.de)
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 
  *
  * $Log: eicon_idi.h,v $
+ * Revision 1.9  2000/01/23 21:21:23  armin
+ * Added new trace capability and some updates.
+ * DIVA Server BRI now supports data for ISDNLOG.
+ *
  * Revision 1.8  1999/11/25 11:43:27  armin
  * Fixed statectrl and connect message.
  * X.75 fix and HDLC/transparent with autoconnect.
index fac393f83c08274027148a86149891c8a0922434..4f4180ed6effcb2b6925cdd6f4c50445b6279ae8 100644 (file)
@@ -1,12 +1,12 @@
-/* $Id: eicon_io.c,v 1.9 1999/11/18 20:55:25 armin Exp $
+/* $Id: eicon_io.c,v 1.10 2000/01/23 21:21:23 armin Exp $
  *
- * ISDN low-level module for Eicon.Diehl active ISDN-Cards.
+ * ISDN low-level module for Eicon active ISDN-Cards.
  * Code for communicating with hardware.
  *
- * Copyright 1999    by Armin Schindler (mac@melware.de)
- * Copyright 1999    Cytronics & Melware (info@melware.de)
+ * Copyright 1999,2000  by Armin Schindler (mac@melware.de)
+ * Copyright 1999,2000  Cytronics & Melware (info@melware.de)
  *
- * Thanks to   Eicon Technology Diehl GmbH & Co. oHG for 
+ * Thanks to   Eicon Technology GmbH & Co. oHG for 
  *             documents, informations and hardware. 
  *
  * This program is free software; you can redistribute it and/or modify
  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 
  *
  * $Log: eicon_io.c,v $
+ * Revision 1.10  2000/01/23 21:21:23  armin
+ * Added new trace capability and some updates.
+ * DIVA Server BRI now supports data for ISDNLOG.
+ *
  * Revision 1.9  1999/11/18 20:55:25  armin
  * Ready_Int fix of ISA cards.
  *
index e86adca225e5542e8499a37c6342ad324ad1c0ca..8a7f0d099febb94c0f33347c98e813f5bf7dceab 100644 (file)
@@ -1,11 +1,11 @@
-/* $Id: eicon_isa.c,v 1.12 1999/11/27 12:56:19 armin Exp $
+/* $Id: eicon_isa.c,v 1.14 2000/02/22 16:26:40 armin Exp $
  *
- * ISDN low-level module for Eicon.Diehl active ISDN-Cards.
+ * ISDN low-level module for Eicon active ISDN-Cards.
  * Hardware-specific code for old ISA cards.
  *
- * Copyright 1998    by Fritz Elfert (fritz@isdn4linux.de)
- * Copyright 1998,99 by Armin Schindler (mac@melware.de)
- * Copyright 1999    Cytronics & Melware (info@melware.de)
+ * Copyright 1998      by Fritz Elfert (fritz@isdn4linux.de)
+ * Copyright 1998-2000 by Armin Schindler (mac@melware.de)
+ * Copyright 1999,2000 Cytronics & Melware (info@melware.de)
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 
  *
  * $Log: eicon_isa.c,v $
+ * Revision 1.14  2000/02/22 16:26:40  armin
+ * Fixed membase error message.
+ * Fixed missing log buffer struct.
+ *
+ * Revision 1.13  2000/01/23 21:21:23  armin
+ * Added new trace capability and some updates.
+ * DIVA Server BRI now supports data for ISDNLOG.
+ *
  * Revision 1.12  1999/11/27 12:56:19  armin
  * Forgot some iomem changes for last ioremap compat.
  *
@@ -79,7 +87,7 @@
 #define release_shmem release_region
 #define request_shmem request_region
 
-char *eicon_isa_revision = "$Revision: 1.12 $";
+char *eicon_isa_revision = "$Revision: 1.14 $";
 
 #undef EICON_MCA_DEBUG
 
@@ -141,6 +149,9 @@ eicon_isa_find_card(int Mem, int Irq, char * Id)
        if (!strlen(Id))
                return -1;
 
+       if (Mem == -1)
+               return -1;
+
        /* Check for valid membase address */
        if ((Mem < 0x0c0000) ||
            (Mem > 0x0fc000) ||
index 18048de3f665860ef63fd29c3a79e97b5c27f8b3..b53adfcbf66ae577333d80d47ff40189d394fbf3 100644 (file)
@@ -1,10 +1,10 @@
-/* $Id: eicon_isa.h,v 1.7 1999/11/18 21:14:30 armin Exp $
+/* $Id: eicon_isa.h,v 1.8 2000/01/23 21:21:23 armin Exp $
  *
- * ISDN low-level module for Eicon.Diehl active ISDN-Cards.
+ * ISDN low-level module for Eicon active ISDN-Cards.
  *
- * Copyright 1998    by Fritz Elfert (fritz@isdn4linux.de)
- * Copyright 1998,99 by Armin Schindler (mac@melware.de)
- * Copyright 1999    Cytronics & Melware (info@melware.de)
+ * Copyright 1998      by Fritz Elfert (fritz@isdn4linux.de)
+ * Copyright 1998-2000 by Armin Schindler (mac@melware.de)
+ * Copyright 1999,2000 Cytronics & Melware (info@melware.de)
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 
  *
  * $Log: eicon_isa.h,v $
+ * Revision 1.8  2000/01/23 21:21:23  armin
+ * Added new trace capability and some updates.
+ * DIVA Server BRI now supports data for ISDNLOG.
+ *
  * Revision 1.7  1999/11/18 21:14:30  armin
  * New ISA memory mapped IO
  *
index a75a5c31ac0637b7c710745c89763ea80b539db0..37cb64be41838944f19edb9a636ae1a2e8855252 100644 (file)
@@ -1,12 +1,12 @@
-/* $Id: eicon_mod.c,v 1.23 2000/01/20 19:55:34 keil Exp $
+/* $Id: eicon_mod.c,v 1.25 2000/02/22 16:26:40 armin Exp $
  *
- * ISDN lowlevel-module for Eicon.Diehl active cards.
+ * ISDN lowlevel-module for Eicon active cards.
  * 
- * Copyright 1997    by Fritz Elfert (fritz@isdn4linux.de)
- * Copyright 1998,99 by Armin Schindler (mac@melware.de) 
- * Copyright 1999    Cytronics & Melware (info@melware.de)
+ * Copyright 1997      by Fritz Elfert (fritz@isdn4linux.de)
+ * Copyright 1998-2000 by Armin Schindler (mac@melware.de) 
+ * Copyright 1999,2000 Cytronics & Melware (info@melware.de)
  * 
- * Thanks to    Eicon Technology Diehl GmbH & Co. oHG for
+ * Thanks to    Eicon Technology GmbH & Co. oHG for
  *              documents, informations and hardware.
  *
  *              Deutsche Telekom AG for S2M support.
  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 
  *
  * $Log: eicon_mod.c,v $
+ * Revision 1.25  2000/02/22 16:26:40  armin
+ * Fixed membase error message.
+ * Fixed missing log buffer struct.
+ *
+ * Revision 1.24  2000/01/23 21:21:23  armin
+ * Added new trace capability and some updates.
+ * DIVA Server BRI now supports data for ISDNLOG.
+ *
  * Revision 1.23  2000/01/20 19:55:34  keil
  * Add FAX Class 1 support
  *
 static eicon_card *cards = (eicon_card *) NULL;   /* glob. var , contains
                                                      start of card-list   */
 
-static char *eicon_revision = "$Revision: 1.23 $";
+static char *eicon_revision = "$Revision: 1.25 $";
 
 extern char *eicon_pci_revision;
 extern char *eicon_isa_revision;
@@ -157,7 +165,7 @@ static int   irq          = -1;
 #endif
 static char *id           = "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0";
 
-MODULE_DESCRIPTION(             "Driver for Eicon.Diehl active ISDN cards");
+MODULE_DESCRIPTION(             "Driver for Eicon active ISDN cards");
 MODULE_AUTHOR(                  "Armin Schindler");
 MODULE_SUPPORTED_DEVICE(        "ISDN subsystem");
 MODULE_PARM_DESC(id,                   "ID-String of first card");
@@ -882,8 +890,10 @@ eicon_putstatus(eicon_card * card, char * buf)
        u_char *p;
        struct sk_buff *skb;
 
-       if (!card)
-               return;
+       if (!card) {
+               if (!(card = cards))
+                       return;
+       }
 
        save_flags(flags);
        cli();
index 954b9dba282a5eee19ba54366e72cf4db64c3cdb..c9bbb8048c5b66809ecbdc527f7d6a3996091e05 100644 (file)
@@ -1,12 +1,12 @@
-/* $Id: eicon_pci.c,v 1.10 1999/08/22 20:26:49 calle Exp $
+/* $Id: eicon_pci.c,v 1.11 2000/01/23 21:21:23 armin Exp $
  *
- * ISDN low-level module for Eicon.Diehl active ISDN-Cards.
+ * ISDN low-level module for Eicon active ISDN-Cards.
  * Hardware-specific code for PCI cards.
  *
- * Copyright 1998,99 by Armin Schindler (mac@melware.de)
- * Copyright 1999    Cytronics & Melware (info@melware.de)
+ * Copyright 1998-2000 by Armin Schindler (mac@melware.de)
+ * Copyright 1999,2000 Cytronics & Melware (info@melware.de)
  *
- * Thanks to   Eicon Technology Diehl GmbH & Co. oHG for 
+ * Thanks to   Eicon Technology GmbH & Co. oHG for 
  *             documents, informations and hardware. 
  *
  *             Deutsche Telekom AG for S2M support.
  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 
  *
  * $Log: eicon_pci.c,v $
+ * Revision 1.11  2000/01/23 21:21:23  armin
+ * Added new trace capability and some updates.
+ * DIVA Server BRI now supports data for ISDNLOG.
+ *
  * Revision 1.10  1999/08/22 20:26:49  calle
  * backported changes from kernel 2.3.14:
  * - several #include "config.h" gone, others come.
@@ -77,7 +81,7 @@
 #include "eicon_pci.h"
 
 
-char *eicon_pci_revision = "$Revision: 1.10 $";
+char *eicon_pci_revision = "$Revision: 1.11 $";
 
 #if CONFIG_PCI          /* intire stuff is only for PCI */
 
index a23faade2ba84e7472b2c3970bfe34e0f4b4289c..384cc422c536aef74197043d54858840aee9ecfe 100644 (file)
@@ -1,9 +1,9 @@
-/* $Id: eicon_pci.h,v 1.3 1999/03/29 11:19:51 armin Exp $
+/* $Id: eicon_pci.h,v 1.4 2000/01/23 21:21:23 armin Exp $
  *
- * ISDN low-level module for Eicon.Diehl active ISDN-Cards (PCI part).
+ * ISDN low-level module for Eicon active ISDN-Cards (PCI part).
  *
- * Copyright 1998,99 by Armin Schindler (mac@melware.de)
- * Copyright 1999    Cytronics & Melware (info@melware.de)
+ * Copyright 1998-2000 by Armin Schindler (mac@melware.de)
+ * Copyright 1999,2000 Cytronics & Melware (info@melware.de)
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 
  *
  * $Log: eicon_pci.h,v $
+ * Revision 1.4  2000/01/23 21:21:23  armin
+ * Added new trace capability and some updates.
+ * DIVA Server BRI now supports data for ISDNLOG.
+ *
  * Revision 1.3  1999/03/29 11:19:51  armin
  * I/O stuff now in seperate file (eicon_io.c)
  * Old ISA type cards (S,SX,SCOM,Quadro,S2M) implemented.
index eee955b83c4b863248ee83b018b7de83641b1a7d..b60313e51d4ef083438bac3f9ac8f5341649e7f5 100644 (file)
@@ -1,10 +1,13 @@
-/* $Id: config.c,v 2.43 2000/01/20 19:49:36 keil Exp $
+/* $Id: config.c,v 2.44 2000/02/26 00:35:12 keil Exp $
 
  * Author       Karsten Keil (keil@isdn4linux.de)
  *              based on the teles driver from Jan den Ouden
  *
  *
  * $Log: config.c,v $
+ * Revision 2.44  2000/02/26 00:35:12  keil
+ * Fix skb freeing in interrupt context
+ *
  * Revision 2.43  2000/01/20 19:49:36  keil
  * Support teles 13.3c vendor version 2.1
  *
@@ -548,9 +551,9 @@ HiSaxVersion(void))
 
        printk(KERN_INFO "HiSax: Linux Driver for passive ISDN cards\n");
 #ifdef MODULE
-       printk(KERN_INFO "HiSax: Version 3.3d (module)\n");
+       printk(KERN_INFO "HiSax: Version 3.3e (module)\n");
 #else
-       printk(KERN_INFO "HiSax: Version 3.3d (kernel)\n");
+       printk(KERN_INFO "HiSax: Version 3.3e (kernel)\n");
 #endif
        strcpy(tmp, l1_revision);
        printk(KERN_INFO "HiSax: Layer1 Revision %s\n", HiSax_getrev(tmp));
index 19ac85242895200e0f6e91218024abf3f2d2fa8f..3008ecfd8d9a4b385a4b13663be5f1010fb9cea0 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: hfc_pci.c,v 1.25 1999/12/19 13:09:42 keil Exp $
+/* $Id: hfc_pci.c,v 1.27 2000/02/26 00:35:12 keil Exp $
 
  * hfc_pci.c     low level driver for CCD´s hfc-pci based cards
  *
  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  *
  * $Log: hfc_pci.c,v $
+ * Revision 1.27  2000/02/26 00:35:12  keil
+ * Fix skb freeing in interrupt context
+ *
+ * Revision 1.26  2000/02/09 20:22:55  werner
+ *
+ * Updated PCI-ID table
+ *
  * Revision 1.25  1999/12/19 13:09:42  keil
  * changed TASK_INTERRUPTIBLE into TASK_UNINTERRUPTIBLE for
  * signal proof delays
 
 extern const char *CardType[];
 
-static const char *hfcpci_revision = "$Revision: 1.25 $";
+static const char *hfcpci_revision = "$Revision: 1.27 $";
 
 /* table entry in the PCI devices list */
 typedef struct {
@@ -151,6 +158,7 @@ static const PCI_ENTRY id_list[] =
        {0x1051, 0x0100, "Motorola MC145575", "MC145575"},
        {0x1397, 0xB100, "Seyeon", "B100"},
        {0x15B0, 0x2BD0, "Zoltrix", "2BD0"},
+       {0x114f, 0x71,   "Digi intl.","Digicom"}, 
        {0, 0, NULL, NULL},
 };
 
index b0eea570676f370e62af3c1e49aba34ec2f001f5..8175c5d614340a2c9ad012f8722202d934ae5033 100644 (file)
@@ -1,8 +1,11 @@
-/* $Id: hisax.h,v 2.40 2000/01/20 19:51:46 keil Exp $
+/* $Id: hisax.h,v 2.41 2000/02/26 00:35:13 keil Exp $
 
  *   Basic declarations, defines and prototypes
  *
  * $Log: hisax.h,v $
+ * Revision 2.41  2000/02/26 00:35:13  keil
+ * Fix skb freeing in interrupt context
+ *
  * Revision 2.40  2000/01/20 19:51:46  keil
  * Fix AddTimer message
  * Change CONFIG defines
 #include <linux/tty.h>
 #include <linux/serial_reg.h>
 
-#undef ERROR_STATISTIC
+#define ERROR_STATISTIC
 
 #define REQUEST                0
 #define CONFIRM                1
index 9fa10e326dd9dfb6e65f7258468331362585c7ab..2b0451a0af3e3e8d3fee592113675b8e19ed5aba 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: l3dss1.c,v 2.22 2000/01/20 19:44:20 keil Exp $
+/* $Id: l3dss1.c,v 2.23 2000/02/26 01:38:14 keil Exp $
 
  * EURO/DSS1 D-channel protocol
  *
@@ -13,6 +13,9 @@
  *              Fritz Elfert
  *
  * $Log: l3dss1.c,v $
+ * Revision 2.23  2000/02/26 01:38:14  keil
+ * Fixes for V.110 encoding LLC from Jens Jakobsen
+ *
  * Revision 2.22  2000/01/20 19:44:20  keil
  * Fixed uninitialiesed location
  * Fixed redirecting number IE in Setup
 #include <linux/config.h>
 
 extern char *HiSax_getrev(const char *revision);
-const char *dss1_revision = "$Revision: 2.22 $";
+const char *dss1_revision = "$Revision: 2.23 $";
 
 #define EXT_BEARER_CAPS 1
 
@@ -1045,7 +1048,8 @@ u_char *
 EncodeASyncParams(u_char * p, u_char si2)
 {                              // 7c 06 88  90 21 42 00 bb
 
-       p[0] = p[1] = 0;
+       p[0] = 0;
+       p[1] = 0x40;            // Intermediate rate: 16 kbit/s jj 2000.02.19
        p[2] = 0x80;
        if (si2 & 32)           // 7 data bits
 
@@ -1059,7 +1063,7 @@ EncodeASyncParams(u_char * p, u_char si2)
                p[2] += 96;
        else                    // 1 stop bit
 
-               p[2] = 32;
+               p[2] += 32;
 
        if (si2 & 8)            // even parity
 
index b83fe66e1e7f58c8e6db5d6e7e2b273244946c69..167ea322721bc725153b12dbf433de197af24dad 100644 (file)
@@ -13,7 +13,7 @@ b7aa7f97b2374967a4aca7c52991142c  isdnl3.c
 a23fbf8879c1432b04640b8b04bdf419  tei.c
 ce248e56c2e1326012d0b25f92bbf99b  callc.c
 bf9605b36429898f7be6630034e83230  cert.c
-233960fa9fc46aaffcaa883b5b59cf4e  l3dss1.c
+6ce0a184127be1a44747e2017ed24ad9  l3dss1.c
 a3a570781f828b6d59e6b231653133de  l3_1tr6.c
 8188deeb4a1b34c574cd51638cd214d0  elsa.c
 a3c2b8e9d2c623658888b5f1d4317c2a  diva.c
@@ -23,9 +23,9 @@ a3c2b8e9d2c623658888b5f1d4317c2a  diva.c
 Version: 2.6.3i
 Charset: noconv
 
-iQCVAwUBOIdqVzpxHvX/mS9tAQGaWQP+Pj0oVxbhusXnlNOQ+FV6YOGj1HGMXPsO
-C/9555qSbvcKg64OO8VdU1LWq/RCsAwBkJ3eSizF5LbWD8lhCHUpkNlzEv4fIaHe
-fAA9zLnC8Vk4h/YLwUNfZxezYvf22NGSydXGZH4VvLAigF0OGRlKaewsR61KZ/Fh
-4GnVqcxYaH8=
-=eINS
+iQCVAwUBONEHHTpxHvX/mS9tAQG/pAP/UyLx23V9mOgiYaId1Gm6xthyM8TP4bfE
+ov4cNmUHQtHINLXtkAP+eacw/kCiiYhdxBIrNaUC+KQkyiFPOs8frx6espxTfDte
+VZDhKDY5NYch2n3OKPLX26pNNJeu7DELMpFR6vvGByokv1RRYVs2wBk0Q5dnfPaq
+WsW0HeL/vBA=
+=fSCb
 -----END PGP SIGNATURE-----
index 2c84bbcaf1f442974a7dfe4c397b1d2bbcfb318f..171aeb07d72fb96566f736f49b71bd40c75ede8f 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: teles3.c,v 2.14 1999/12/23 15:09:32 keil Exp $
+/* $Id: teles3.c,v 2.15 2000/02/03 16:40:10 keil Exp $
 
  * teles3.c     low level stuff for Teles 16.3 & PNP isdn cards
  *
@@ -11,6 +11,9 @@
  *              Beat Doebeli
  *
  * $Log: teles3.c,v $
+ * Revision 2.15  2000/02/03 16:40:10  keil
+ * Fix teles pcmcia
+ *
  * Revision 2.14  1999/12/23 15:09:32  keil
  * change email
  *
@@ -91,7 +94,7 @@
 #include "isdnl1.h"
 
 extern const char *CardType[];
-const char *teles3_revision = "$Revision: 2.14 $";
+const char *teles3_revision = "$Revision: 2.15 $";
 
 #define byteout(addr,val) outb(val,addr)
 #define bytein(addr) inb(addr)
@@ -228,7 +231,7 @@ void
 release_io_teles3(struct IsdnCardState *cs)
 {
        if (cs->typ == ISDN_CTYPE_TELESPCMCIA) {
-               release_region(cs->hw.teles3.hscx[0], 97);
+               release_region(cs->hw.teles3.hscx[1], 96);
        } else {
                if (cs->hw.teles3.cfg_reg) {
                        if (cs->typ == ISDN_CTYPE_COMPAQ_ISA) {
@@ -370,15 +373,15 @@ setup_teles3(struct IsdnCard *card))
        cs->hw.teles3.hscxfifo[0] = cs->hw.teles3.hscx[0] + 0x3e;
        cs->hw.teles3.hscxfifo[1] = cs->hw.teles3.hscx[1] + 0x3e;
        if (cs->typ == ISDN_CTYPE_TELESPCMCIA) {
-               if (check_region((cs->hw.teles3.hscx[0]), 97)) {
+               if (check_region((cs->hw.teles3.hscx[1]), 96 )) {
                        printk(KERN_WARNING
                               "HiSax: %s ports %x-%x already in use\n",
                               CardType[cs->typ],
-                              cs->hw.teles3.hscx[0],
-                              cs->hw.teles3.hscx[0] + 96);
+                              cs->hw.teles3.hscx[1],
+                              cs->hw.teles3.hscx[1] + 96);
                        return (0);
                } else
-                       request_region(cs->hw.teles3.hscx[0], 97, "HiSax Teles PCMCIA");
+                       request_region(cs->hw.teles3.hscx[1], 96, "HiSax Teles PCMCIA");
        } else {
                if (cs->hw.teles3.cfg_reg) {
                        if (cs->typ == ISDN_CTYPE_COMPAQ_ISA) {
index 6b3ef9970941bee63da12b8e5f5883519df15b39..282a5247f624918efe5f9821c741a7ca57fa73f6 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: isdn_common.c,v 1.97 2000/01/23 18:45:37 keil Exp $
+/* $Id: isdn_common.c,v 1.100 2000/03/03 16:37:11 kai Exp $
 
  * Linux ISDN subsystem, common used functions (linklevel).
  *
  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  *
  * $Log: isdn_common.c,v $
+ * Revision 1.100  2000/03/03 16:37:11  kai
+ * incorporated some cosmetic changes from the official kernel tree back
+ * into CVS
+ *
+ * Revision 1.99  2000/02/26 01:00:52  keil
+ * changes from 2.3.47
+ *
+ * Revision 1.98  2000/02/16 14:56:27  paul
+ * translated ISDN_MODEM_ANZREG to ISDN_MODEM_NUMREG for english speakers
+ *
  * Revision 1.97  2000/01/23 18:45:37  keil
  * Change EAZ mapping to forbit the use of cards (insert a "-" for the MSN)
  *
 
 isdn_dev *dev = (isdn_dev *) 0;
 
-static char *isdn_revision = "$Revision: 1.97 $";
+static char *isdn_revision = "$Revision: 1.100 $";
 
 extern char *isdn_net_revision;
 extern char *isdn_tty_revision;
@@ -1792,15 +1802,15 @@ isdn_ioctl(struct inode *inode, struct file *file, uint cmd, ulong arg)
                                        int i;
 
                                        if ((ret = verify_area(VERIFY_WRITE, (void *) arg,
-                                       (ISDN_MODEM_ANZREG + ISDN_MSNLEN + ISDN_LMSNLEN)
+                                       (ISDN_MODEM_NUMREG + ISDN_MSNLEN + ISDN_LMSNLEN)
                                                   * ISDN_MAX_CHANNELS)))
                                                return ret;
 
                                        for (i = 0; i < ISDN_MAX_CHANNELS; i++) {
                                                if (copy_to_user(p, dev->mdm.info[i].emu.profile,
-                                                     ISDN_MODEM_ANZREG))
+                                                     ISDN_MODEM_NUMREG))
                                                        return -EFAULT;
-                                               p += ISDN_MODEM_ANZREG;
+                                               p += ISDN_MODEM_NUMREG;
                                                if (copy_to_user(p, dev->mdm.info[i].emu.pmsn, ISDN_MSNLEN))
                                                        return -EFAULT;
                                                p += ISDN_MSNLEN;
@@ -1808,7 +1818,7 @@ isdn_ioctl(struct inode *inode, struct file *file, uint cmd, ulong arg)
                                                        return -EFAULT;
                                                p += ISDN_LMSNLEN;
                                        }
-                                       return (ISDN_MODEM_ANZREG + ISDN_MSNLEN + ISDN_LMSNLEN) * ISDN_MAX_CHANNELS;
+                                       return (ISDN_MODEM_NUMREG + ISDN_MSNLEN + ISDN_LMSNLEN) * ISDN_MAX_CHANNELS;
                                } else
                                        return -EINVAL;
                                break;
@@ -1819,15 +1829,15 @@ isdn_ioctl(struct inode *inode, struct file *file, uint cmd, ulong arg)
                                        int i;
 
                                        if ((ret = verify_area(VERIFY_READ, (void *) arg,
-                                       (ISDN_MODEM_ANZREG + ISDN_MSNLEN)
+                                       (ISDN_MODEM_NUMREG + ISDN_MSNLEN)
                                                   * ISDN_MAX_CHANNELS)))
                                                return ret;
 
                                        for (i = 0; i < ISDN_MAX_CHANNELS; i++) {
                                                if (copy_from_user(dev->mdm.info[i].emu.profile, p,
-                                                    ISDN_MODEM_ANZREG))
+                                                    ISDN_MODEM_NUMREG))
                                                        return -EFAULT;
-                                               p += ISDN_MODEM_ANZREG;
+                                               p += ISDN_MODEM_NUMREG;
                                                if (copy_from_user(dev->mdm.info[i].emu.pmsn, p, ISDN_MSNLEN))
                                                        return -EFAULT;
                                                p += ISDN_MSNLEN;
@@ -2061,17 +2071,13 @@ isdn_close(struct inode *ino, struct file *filep)
 
 static struct file_operations isdn_fops =
 {
-       isdn_lseek,
-       isdn_read,
-       isdn_write,
-       NULL,                   /* isdn_readdir */
-       isdn_poll,              /* isdn_poll */
-       isdn_ioctl,             /* isdn_ioctl */
-       NULL,                   /* isdn_mmap */
-       isdn_open,
-       NULL,                   /* flush */
-       isdn_close,
-       NULL                    /* fsync */
+       llseek:         isdn_lseek,
+       read:           isdn_read,
+       write:          isdn_write,
+       poll:           isdn_poll,
+       ioctl:          isdn_ioctl,
+       open:           isdn_open,
+       release:        isdn_close,
 };
 
 char *
@@ -2570,6 +2576,7 @@ isdn_getrev(const char *revision)
        return rev;
 }
 
+
 /*
  * Allocate and initialize all data, register modem-devices
  */
index d23eee32211b5fa3945cfebb4109cbe23906d7ae..d4e7c7f14a5d6d5d79ff38987847cca9efc89db8 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: isdn_net.c,v 1.103 2000/01/23 18:45:37 keil Exp $
+/* $Id: isdn_net.c,v 1.114 2000/03/16 16:37:41 kai Exp $
 
  * Linux ISDN subsystem, network interfaces and related functions (linklevel).
  *
  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  *
  * $Log: isdn_net.c,v $
+ * Revision 1.114  2000/03/16 16:37:41  kai
+ * Allow phone numbers starting with "*" as outgoing numbers for
+ * networking interface. Some PBX's need this to allow dialing internal
+ * numbers (mine, for example ;-)
+ *
+ * Revision 1.113  2000/03/16 15:46:37  kai
+ * a little bugfix and cosmetic changes
+ *
+ * Revision 1.112  2000/03/04 16:20:42  detabc
+ * copy frames before rewriting frame's saddr
+ *
+ * Revision 1.111  2000/02/28 22:28:24  he
+ * moved tx_timeout warning messages in old (2.2.x) branch where it really only
+ * indicates problems.
+ *
+ * Revision 1.110  2000/02/26 01:00:53  keil
+ * changes from 2.3.47
+ *
+ * Revision 1.109  2000/02/25 11:29:17  paul
+ * changed chargetime to ulong from int (after about 20 days the "chargetime of
+ * ipppX is now 1234" message displays a negative number on alpha).
+ *
+ * Revision 1.108  2000/02/15 12:54:01  kai
+ * set TX timeout back to 2 secs for 2.2.x, just to be safe
+ *
+ * Revision 1.107  2000/02/13 09:52:05  kai
+ * increased TX_TIMEOUT to 20sec
+ *
+ * Revision 1.106  2000/02/12 19:26:55  kai
+ * adopted to latest 2.3 softnet changes.
+ *
+ * tested with PPP and MPPP, it works here.
+ * can somebody check raw-ip?
+ *
+ * also changed std2kern, stddiff for bash-1 compatibility,
+ * hope this doesn't break anything.
+ *
+ * Revision 1.105  2000/02/12 11:43:26  he
+ * SOFTNET related changes, first try. Compatible with linux 2.2.x, but
+ * not tested for kernels with softnet (>= 2.3.43) yet.
+ *
+ * Revision 1.104  2000/02/06 21:49:59  detabc
+ * add rewriting of socket's and frame's saddr for udp-ipv4 dynip-connections.
+ * Include checksum-recompute of ip- and udp-header's.
+ *
  * Revision 1.103  2000/01/23 18:45:37  keil
  * Change EAZ mapping to forbit the use of cards (insert a "-" for the MSN)
  *
 #endif
 
 
-#ifndef ISDN_NEW_TBUSY
-#define ISDN_NEW_TBUSY
-#endif
-#ifdef ISDN_NEW_TBUSY
 /*
  * Outline of new tbusy handling: 
  *
  */
 
 /*
- * Tell upper layers that the network device is ready to xmit more frames.
+ * About SOFTNET:
+ * Most of the changes were pretty obvious and basically done by HE already.
+ *
+ * One problem of the isdn net device code is that is uses struct net_device
+ * for masters and slaves. However, only master interface are registered to 
+ * the network layer, and therefore, it only makes sense to call netif_* 
+ * functions on them.
+ *
+ * --KG
  */
-static void __inline__ isdn_net_dev_xon(struct device * dev)
-{
-       dev->tbusy = 0;
-       mark_bh(NET_BH);
-}
 
-static void __inline__ isdn_net_lp_xon(isdn_net_local * lp)
+/* 
+ * Find out if the netdevice has been ifup-ed yet.
+ * For slaves, look at the corresponding master.
+ */
+static int __inline__ isdn_net_started(isdn_net_dev *n)
 {
-       lp->netdev->dev.tbusy = 0;
-       if(lp->master) lp->master->tbusy = 0;
-       mark_bh(NET_BH);
+       isdn_net_local *lp = n->local;
+       struct device *dev;
+       
+       if (lp->master) 
+               dev = lp->master;
+       else
+               dev = &n->dev;
+       return dev->start;
 }
 
 /*
- * Ask upper layers to temporarily cease passing us more xmit frames.
+ * wake up the network -> net_device queue.
+ * For slaves, wake the corresponding master interface.
  */
-static void __inline__ isdn_net_dev_xoff(struct device * dev)
+static void __inline__ isdn_net_lp_xon(isdn_net_local * lp)
 {
-       dev->tbusy = 1;
+       if (lp->master) 
+               netif_wake_queue(lp->master);
+       else
+               netif_wake_queue(&lp->netdev->dev);
 }
-#endif
+
+/* For 2.2.x we leave the transmitter busy timeout at 2 secs, just 
+ * to be safe.
+ * For 2.3.x we push it up to 20 secs, because call establishment
+ * (in particular callback) may take such a long time, and we 
+ * don't want confusing messages in the log. However, there is a slight
+ * possibility that this large timeout will break other things like MPPP,
+ * which might rely on the tx timeout. If so, we'll find out this way...
+ */
+
+#define ISDN_NET_TX_TIMEOUT (2*HZ)
 
 /* Prototypes */
 
@@ -483,7 +550,7 @@ int isdn_net_force_dial_lp(isdn_net_local *);
 static int isdn_net_start_xmit(struct sk_buff *, struct device *);
 static int isdn_net_xmit(struct device *, isdn_net_local *, struct sk_buff *);
 
-char *isdn_net_revision = "$Revision: 1.103 $";
+char *isdn_net_revision = "$Revision: 1.114 $";
 
  /*
   * Code for raw-networking over ISDN
@@ -522,14 +589,9 @@ isdn_net_reset(struct device *dev)
 #endif
        ulong flags;
 
+       /* not sure if the cli() is needed at all --KG */
        save_flags(flags);
        cli();                  /* Avoid glitch on writes to CMD regs */
-       dev->interrupt = 0;
-#ifdef ISDN_NEW_TBUSY
-       isdn_net_dev_xon(dev);
-#else
-       dev->tbusy = 0;
-#endif
 #ifdef CONFIG_ISDN_X25
        if( cprot && cprot -> pops && dops )
                cprot -> pops -> restart ( cprot, dev, dops );
@@ -545,8 +607,12 @@ isdn_net_open(struct device *dev)
        struct device *p;
        struct in_device *in_dev;
 
+       /* moved here from isdn_net_reset, because only the master has an
+          interface associated which is supposed to be started. BTW:
+          we need to call netif_start_queue, not netif_wake_queue here */
+       netif_start_queue(dev);
+
        isdn_net_reset(dev);
-       dev->start = 1;
        /* Fill in the MAC-level header (not needed, but for compatibility... */
        for (i = 0; i < ETH_ALEN - sizeof(u32); i++)
                dev->dev_addr[i] = 0xfc;
@@ -564,7 +630,6 @@ isdn_net_open(struct device *dev)
        if ((p = (((isdn_net_local *) dev->priv)->slave))) {
                while (p) {
                        isdn_net_reset(p);
-                       p->start = 1;
                        p = (((isdn_net_local *) p->priv)->slave);
                }
        }
@@ -682,7 +747,7 @@ isdn_net_autohup()
                                                        isdn_net_hangup(&p->dev);
                                                } else if (jiffies - l->chargetime > l->chargeint) {
                                                        printk(KERN_DEBUG
-                                                              "isdn_net: %s: chtime = %d, chint = %d\n",
+                                                              "isdn_net: %s: chtime = %lu, chint = %d\n",
                                                               l->name, l->chargetime, l->chargeint);
                                                        isdn_net_hangup(&p->dev);
                                                }
@@ -743,19 +808,11 @@ isdn_net_stat_callback(int idx, isdn_ctrl *c)
                                                        mdev = &lp->netdev->dev;
                                                if (!isdn_net_send_skb(mdev, lp, lp->sav_skb)) {
                                                        lp->sav_skb = NULL;
-#ifndef ISDN_NEW_TBUSY
-                                                       mark_bh(NET_BH);
-#endif
                                                } else {
                                                        return 1;
                                                }
                                        }
-#ifdef ISDN_NEW_TBUSY
                                        isdn_net_lp_xon(lp);
-#else
-                                       if (test_and_clear_bit(0, (void *) &(p->dev.tbusy)))
-                                               mark_bh(NET_BH);
-#endif
                                }
                                return 1;
                        case ISDN_STAT_DCONN:
@@ -831,7 +888,7 @@ isdn_net_stat_callback(int idx, isdn_ctrl *c)
                                                 * we correct the timestamp here.
                                                 */
                                                lp->chargetime = jiffies;
-                                               printk(KERN_DEBUG "isdn_net: chargetime of %s now %d\n",
+                                               printk(KERN_DEBUG "isdn_net: chargetime of %s now %lu\n",
                                                lp->name, lp->chargetime);
 
                                                /* reset dial-timeout */
@@ -854,18 +911,7 @@ isdn_net_stat_callback(int idx, isdn_ctrl *c)
                                                        if (!(isdn_net_xmit(&p->dev, lp, lp->first_skb)))
                                                                lp->first_skb = NULL;
                                                }
-#ifdef ISDN_NEW_TBUSY
                                                if(! lp->first_skb) isdn_net_lp_xon(lp);
-#else
-                                               else {
-                                                       /*
-                                                        * dev.tbusy is usually cleared implicitly by isdn_net_xmit(,,lp->first_skb).
-                                                        * With an empty lp->first_skb, we need to do this ourselves
-                                                        */
-                                                       lp->netdev->dev.tbusy = 0;
-                                                       mark_bh(NET_BH);
-                                               }
-#endif /* ISDN_NEW_TBUSY */
                                                return 1;
                                }
                                break;
@@ -889,7 +935,7 @@ isdn_net_stat_callback(int idx, isdn_ctrl *c)
                                if (lp->hupflags & ISDN_WAITCHARGE)
                                        lp->hupflags |= ISDN_HAVECHARGE;
                                lp->chargetime = jiffies;
-                               printk(KERN_DEBUG "isdn_net: Got CINF chargetime of %s now %d\n",
+                               printk(KERN_DEBUG "isdn_net: Got CINF chargetime of %s now %lu\n",
                                       lp->name, lp->chargetime);
                                return 1;
                }
@@ -897,20 +943,6 @@ isdn_net_stat_callback(int idx, isdn_ctrl *c)
        return 0;
 }
 
-/*
- * Check, if a number contains wildcard-characters, in which case it
- * is for incoming purposes only.
- */
-static int
-isdn_net_checkwild(char *num)
-{
-       return ((strchr(num, '?')) ||
-               (strchr(num, '*')) ||
-               (strchr(num, '[')) ||
-               (strchr(num, ']')) ||
-               (strchr(num, '^')));
-}
-
 /*
  * Perform dialout for net-interfaces and timeout-handling for
  * D-Channel-up and B-Channel-up Messages.
@@ -1322,13 +1354,7 @@ isdn_net_log_skb(struct sk_buff * skb, isdn_net_local * lp)
  *
  * Return: 0 on success, !0 on failure.
  */
-#ifndef ISDN_NEW_TBUSY
-/*
- * Side-effects: ndev->tbusy is cleared on success.
- */
-#endif
-int
-isdn_net_send_skb
+int isdn_net_send_skb
                (struct device *ndev, isdn_net_local * lp,struct sk_buff *skb)
 {
        int ret;
@@ -1337,17 +1363,11 @@ isdn_net_send_skb
        ret = isdn_writebuf_skb_stub(lp->isdn_device, lp->isdn_channel, 1, skb);
        if (ret == len) {
                lp->transcount += len;
-#ifndef ISDN_NEW_TBUSY
-               clear_bit(0, (void *) &(ndev->tbusy));
-#endif
                return 0;
        }
        if (ret < 0) {
                dev_kfree_skb(skb);
                lp->stats.tx_errors++;
-#ifndef ISDN_NEW_TBUSY
-               clear_bit(0, (void *) &(ndev->tbusy));
-#endif
                return 0;
        }
        return 1;
@@ -1393,11 +1413,7 @@ isdn_net_xmit(struct device *ndev, isdn_net_local * lp, struct sk_buff *skb)
                        if (lp->srobin == ndev)
                                ret = isdn_net_send_skb(ndev, lp, skb);
                        else
-#ifdef ISDN_NEW_TBUSY
                                ret = isdn_net_start_xmit(skb, lp->srobin);
-#else
-                               ret = ndev->tbusy = isdn_net_start_xmit(skb, lp->srobin);
-#endif
                        lp->srobin = (slp->slave) ? slp->slave : ndev;
                        slp = (isdn_net_local *) (lp->srobin->priv);
                        if (!((slp->flags & ISDN_NET_CONNECTED) && (slp->dialstate == 0)))
@@ -1439,6 +1455,8 @@ isdn_net_adjust_hdr(struct sk_buff *skb, struct device *dev)
        }
 }
 
+
+
 /*
  * Try sending a packet.
  * If this interface isn't connected to a ISDN-Channel, find a free channel,
@@ -1451,19 +1469,24 @@ isdn_net_start_xmit(struct sk_buff *skb, struct device *ndev)
 #ifdef CONFIG_ISDN_X25
        struct concap_proto * cprot = lp -> netdev -> cprot;
 #endif
+       /* some comment as with the softnet TX timeout
+          when this happens, it's a bug in the HL card driver
+          and should be fixed there, so we can supposedly get rid of 
+          this here at all. 
+          I added a debugging message to find out if it ever occurs --KG
+       */
+
        if (ndev->tbusy) {
-               if (jiffies - ndev->trans_start < (2 * HZ))
+               if (jiffies - ndev->trans_start < ISDN_NET_TX_TIMEOUT)
                        return 1;
-               if (!lp->dialstate)
+               if (!lp->dialstate){
                        lp->stats.tx_errors++;
+                       printk(KERN_WARNING "isdn_tx_timeout dev %s dialstate %d\n",
+                               ndev->name, lp->dialstate);
+               }
                ndev->trans_start = jiffies;
-#ifdef ISDN_NEW_TBUSY
-               isdn_net_dev_xon(ndev);
-#endif
+               netif_wake_queue(ndev);
        }
-#ifndef ISDN_NEW_TBUSY
-       ndev->tbusy = 1; /* left instead of obsolete test_and_set_bit() */
-#endif
 #ifdef CONFIG_ISDN_X25
 /* At this point hard_start_xmit() passes control to the encapsulation
    protocol (if present).
@@ -1478,9 +1501,7 @@ isdn_net_start_xmit(struct sk_buff *skb, struct device *ndev)
 */
        if( cprot ) {
                int ret = cprot -> pops -> encap_and_xmit ( cprot , skb);
-#ifdef ISDN_NEW_TBUSY
-               if(ret) isdn_net_dev_xoff(ndev);
-#endif
+               if(ret) netif_stop_queue(ndev);
                return ret;
        } else
 #endif
@@ -1500,9 +1521,6 @@ isdn_net_start_xmit(struct sk_buff *skb, struct device *ndev)
                        if (!(ISDN_NET_DIALMODE(*lp) == ISDN_NET_DM_AUTO)) {
                                isdn_net_unreachable(ndev, skb, "dial rejected: interface not in dialmode `auto'");
                                dev_kfree_skb(skb);
-#ifndef ISDN_NEW_TBUSY
-                               ndev->tbusy = 0;
-#endif
                                return 0;
                        }
                        if (lp->phone[1]) {
@@ -1518,9 +1536,6 @@ isdn_net_start_xmit(struct sk_buff *skb, struct device *ndev)
                                        if(jiffies < lp->dialwait_timer) {
                                                isdn_net_unreachable(ndev, skb, "dial rejected: retry-time not reached");
                                                dev_kfree_skb(skb);
-#ifndef ISDN_NEW_TBUSY
-                                               ndev->tbusy = 0;
-#endif
                                                restore_flags(flags);
                                                return 0;
                                        } else
@@ -1549,9 +1564,6 @@ isdn_net_start_xmit(struct sk_buff *skb, struct device *ndev)
                                        isdn_net_unreachable(ndev, skb,
                                                           "No channel");
                                        dev_kfree_skb(skb);
-#ifndef ISDN_NEW_TBUSY
-                                       ndev->tbusy = 0;
-#endif
                                        return 0;
                                }
                                /* Log packet, which triggered dialing */
@@ -1571,9 +1583,7 @@ isdn_net_start_xmit(struct sk_buff *skb, struct device *ndev)
                                        }
                                        restore_flags(flags);
                                        isdn_net_dial();        /* Initiate dialing */
-#ifdef ISDN_NEW_TBUSY
-                                       isdn_net_dev_xoff(ndev);
-#endif
+                                       netif_stop_queue(ndev);
                                        return 1;       /* let upper layer requeue skb packet */
                                }
 #endif
@@ -1587,9 +1597,6 @@ isdn_net_start_xmit(struct sk_buff *skb, struct device *ndev)
                                }
                                lp->first_skb = skb;
                                /* Initiate dialing */
-#ifndef ISDN_NEW_TBUSY
-                               ndev->tbusy = 0;
-#endif
                                restore_flags(flags);
                                isdn_net_dial();
                                return 0;
@@ -1597,9 +1604,6 @@ isdn_net_start_xmit(struct sk_buff *skb, struct device *ndev)
                                isdn_net_unreachable(ndev, skb,
                                                     "No phone number");
                                dev_kfree_skb(skb);
-#ifndef ISDN_NEW_TBUSY
-                               ndev->tbusy = 0;
-#endif
                                return 0;
                        }
                } else {
@@ -1610,24 +1614,16 @@ isdn_net_start_xmit(struct sk_buff *skb, struct device *ndev)
                                int ret;
                                if (lp->first_skb) {
                                        if (isdn_net_xmit(ndev, lp, lp->first_skb)){
-#ifdef ISDN_NEW_TBUSY
-                                               isdn_net_dev_xoff(ndev);
-#endif
+                                               netif_stop_queue(ndev);
                                                return 1;
 }
                                        lp->first_skb = NULL;
                                }
                                ret = (isdn_net_xmit(ndev, lp, skb));
-#ifdef ISDN_NEW_TBUSY
-                               if(ret) isdn_net_dev_xoff(ndev);
-#endif
+                               if(ret) netif_stop_queue(ndev);
                                return ret;
                        } else
-#ifdef ISDN_NEW_TBUSY
-                               isdn_net_dev_xoff(ndev);
-#else
-                               ndev->tbusy = 1;
-#endif
+                               netif_stop_queue(ndev);
                }
        }
        return 1;
@@ -1649,7 +1645,7 @@ isdn_net_close(struct device *dev)
 #ifdef CONFIG_ISDN_X25
        if( cprot && cprot -> pops ) cprot -> pops -> close( cprot );
 #endif
-       dev->tbusy = 1;
+       netif_stop_queue(dev);
        dev->start = 0;
        if ((p = (((isdn_net_local *) dev->priv)->slave))) {
                /* If this interface has slaves, stop them also */
@@ -1661,8 +1657,6 @@ isdn_net_close(struct device *dev)
                                cprot -> pops -> close( cprot );
 #endif
                        isdn_net_hangup(p);
-                       p->tbusy = 1;
-                       p->start = 0;
                        p = (((isdn_net_local *) p->priv)->slave);
                }
        }
@@ -2403,7 +2397,7 @@ isdn_net_find_icall(int di, int ch, int idx, setup_parm setup)
                                 * Is the interface up?
                                 * If not, reject the call actively.
                                 */
-                               if (!p->dev.start) {
+                               if (!isdn_net_started(p)) {
                                        restore_flags(flags);
                                        printk(KERN_INFO "%s: incoming call, interface down -> rejected\n",
                                               lp->name);
@@ -2671,9 +2665,6 @@ isdn_net_new(char *name, struct device *master)
                        p = (((isdn_net_local *) p->priv)->slave);
                }
                ((isdn_net_local *) q->priv)->slave = &(netdev->dev);
-               q->interrupt = 0;
-               q->tbusy = 0;
-               q->start = master->start;
        } else {
                /* Device shall be a master */
                if (register_netdev(&netdev->dev) != 0) {
@@ -2746,7 +2737,7 @@ isdn_net_newslave(char *parm)
                if (n->local->master)
                        return NULL;
                /* Master must not be started yet */
-               if (n->dev.start)
+               if (isdn_net_started(n)) 
                        return NULL;
                return (isdn_net_new(newname, &(n->dev)));
        }
@@ -2789,9 +2780,8 @@ isdn_net_setcfg(isdn_net_ioctl_cfg * cfg)
 #ifdef CONFIG_ISDN_X25
                        struct concap_proto * cprot = p -> cprot;
 #endif
-                       if (p->dev.start) {
-                               printk(KERN_WARNING
-                               "%s: cannot change encap when if is up\n",
+                       if (isdn_net_started(p)) {
+                               printk(KERN_WARNING "%s: cannot change encap when if is up\n",
                                       lp->name);
                                return -EBUSY;
                        }
@@ -3051,8 +3041,6 @@ isdn_net_addphone(isdn_net_ioctl_phone * phone)
        isdn_net_dev *p = isdn_net_findif(phone->name);
        isdn_net_phone *n;
 
-       if (isdn_net_checkwild(phone->phone) && (phone->outgoing & 1))
-               return -EINVAL;
        if (p) {
                if (!(n = (isdn_net_phone *) kmalloc(sizeof(isdn_net_phone), GFP_KERNEL)))
                        return -ENOMEM;
@@ -3225,14 +3213,8 @@ isdn_net_realrm(isdn_net_dev * p, isdn_net_dev * q)
 
        save_flags(flags);
        cli();
-       if (p->local->master) {
-               /* If it's a slave, it may be removed even if it is busy. However
-                * it has to be hung up first.
-                */
-               isdn_net_hangup(&p->dev);
-               p->dev.start = 0;
-       }
-       if (p->dev.start) {
+
+       if (isdn_net_started(p)) {
                restore_flags(flags);
                return -EBUSY;
        }
index 5b12c224974f1501298ecdfc2eb8da72711b95ca..acc3641ef0a0a3ee30522a53ea440dc6d2996354 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: isdn_ppp.c,v 1.61 1999/11/20 22:14:14 detabc Exp $
+/* $Id: isdn_ppp.c,v 1.63 2000/03/16 15:46:37 kai Exp $
  *
  * Linux ISDN subsystem, functions for synchronous PPP (linklevel).
  *
  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  *
  * $Log: isdn_ppp.c,v $
+ * Revision 1.63  2000/03/16 15:46:37  kai
+ * a little bugfix and cosmetic changes
+ *
+ * Revision 1.62  2000/02/12 19:26:55  kai
+ * adopted to latest 2.3 softnet changes.
+ *
+ * tested with PPP and MPPP, it works here.
+ * can somebody check raw-ip?
+ *
+ * also changed std2kern, stddiff for bash-1 compatibility,
+ * hope this doesn't break anything.
+ *
  * Revision 1.61  1999/11/20 22:14:14  detabc
  * added channel dial-skip in case of external use
  * (isdn phone or another isdn device) on the same NTBA.
@@ -322,7 +334,7 @@ static int isdn_ppp_fill_mpqueue(isdn_net_dev *, struct sk_buff **skb,
 static void isdn_ppp_free_mpqueue(isdn_net_dev *);
 #endif
 
-char *isdn_ppp_revision = "$Revision: 1.61 $";
+char *isdn_ppp_revision = "$Revision: 1.63 $";
 
 static struct ippp_struct *ippp_table[ISDN_MAX_CHANNELS];
 
@@ -716,7 +728,7 @@ isdn_ppp_ioctl(int min, struct file *file, unsigned int cmd, unsigned long arg)
                case PPPIOCGIFNAME:
                        if(!lp)
                                return -EINVAL;
-                       if ((r = set_arg((void *) arg, lp->name,strlen(lp->name))))
+                       if ((r = set_arg((void *) arg, lp->name, strlen(lp->name))))
                                return r;
                        break;
                case PPPIOCGMPFLAGS:    /* get configuration flags */
@@ -738,8 +750,8 @@ isdn_ppp_ioctl(int min, struct file *file, unsigned int cmd, unsigned long arg)
                        }
                        if (val & SC_ENABLE_IP && !(is->pppcfg & SC_ENABLE_IP) && (is->state & IPPP_CONNECT)) {
                                if (lp) {
-                                       lp->netdev->dev.tbusy = 0;
-                                       mark_bh(NET_BH);        /* OK .. we are ready to send buffers */
+                                       /* OK .. we are ready to send buffers */
+                                       netif_wake_queue(&lp->netdev->dev);
                                }
                        }
                        is->pppcfg = val;
@@ -1508,7 +1520,7 @@ isdn_ppp_xmit(struct sk_buff *skb, struct device *netdev)
                        break;
                default:
                        dev_kfree_skb(skb);
-                       printk(KERN_ERR "isdn_ppp: skipped frame with unsupported protocoll: %#x.\n", skb->protocol);
+                       printk(KERN_ERR "isdn_ppp: skipped frame with unsupported protocol: %#x.\n", skb->protocol);
                        return 0;
        }
 
@@ -1516,7 +1528,7 @@ isdn_ppp_xmit(struct sk_buff *skb, struct device *netdev)
 
        if (lp->sav_skb) {      /* find a non-busy device */
                isdn_net_local *nlp = lp->next;
-               while (lp->sav_skb) {
+               while (nlp->sav_skb) {
                        if (lp == nlp)
                                return 1;
                        nlp = nd->queue = nd->queue->next;
@@ -1942,12 +1954,14 @@ isdn_ppp_cleanup_mpqueue(isdn_net_dev * dev, long min_sqno)
 #ifdef CONFIG_ISDN_PPP_VJ
        int toss = 0;
 #endif
-/* z.z einfaches aussortieren gammeliger pakete. Fuer die Zukunft:
-   eventuell, solange vorne kein B-paket ist und sqno<=min_sqno: auch rauswerfen
-   wenn sqno<min_sqno und Luecken vorhanden sind: auch weg (die koennen nicht mehr gefuellt werden)
-   bei paketen groesser min_sqno: ueber mp_mrru: wenn summe ueber pktlen der rumhaengenden Pakete
-   groesser als mrru ist: raus damit , Pakete muessen allerdings zusammenhaengen sonst koennte
-   ja ein Paket mit B und eins mit E dazwischenpassen */
+       /* currently we just discard ancient packets. 
+          To do: 
+          Maybe, as long as there's no B-packet in front and sqno <= min_sqno: discard.
+          If sqno < min_sqno and there are gaps: discard (the gaps won't be filled anyway).
+          Packets with sqno > min_sqno: Larger than mp_mrru: If sum of all pktlen of pending
+          packets large than mrru: discard - packets need to be consecutive, though, if not 
+          there could be an B and an E-packet in between.
+       */
 
        struct mpqueue *ql,
        *q = dev->mp_last;
index b1a17ecd827af427b909fda63d83bf685957756d..ef4c43d1245ad6a253b0cf01d45ee3e66c56837c 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: isdn_tty.c,v 1.82 2000/01/23 18:45:37 keil Exp $
+/* $Id: isdn_tty.c,v 1.84 2000/02/16 15:10:14 paul Exp $
 
  * Linux ISDN subsystem, tty functions and AT-command emulator (linklevel).
  *
  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  *
  * $Log: isdn_tty.c,v $
+ * Revision 1.84  2000/02/16 15:10:14  paul
+ * If a ttyI has no open FDs, don't connect incoming calls to it.
+ * (Hangup on close of last FD is still to be done.)
+ *
+ * Revision 1.83  2000/02/16 14:59:33  paul
+ * translated ISDN_MODEM_ANZREG to ISDN_MODEM_NUMREG for english speakers;
+ * used defines for result codes;
+ * fixed RING ... RUNG problem (no empty lines in between).
+ *
  * Revision 1.82  2000/01/23 18:45:37  keil
  * Change EAZ mapping to forbit the use of cards (insert a "-" for the MSN)
  *
@@ -379,7 +388,7 @@ static int bit2si[8] =
 static int si2bit[8] =
 {4, 1, 4, 4, 4, 4, 4, 4};
 
-char *isdn_tty_revision = "$Revision: 1.82 $";
+char *isdn_tty_revision = "$Revision: 1.84 $";
 
 
 /* isdn_tty_try_read() is called from within isdn_tty_rcv_skb()
@@ -901,7 +910,7 @@ static void
 isdn_tty_modem_do_ncarrier(unsigned long data)
 {
        modem_info *info = (modem_info *) data;
-       isdn_tty_modem_result(3, info);
+       isdn_tty_modem_result(RESULT_NO_CARRIER, info);
 }
 
 /* Next routine is called, whenever the DTR-signal is raised.
@@ -986,7 +995,7 @@ isdn_tty_dial(char *n, modem_info * info, atemu * m)
        i = isdn_get_free_channel(usg, l2, m->mdmreg[REG_L3PROT], -1, -1, m->msn);
        if (i < 0) {
                restore_flags(flags);
-               isdn_tty_modem_result(6, info);
+               isdn_tty_modem_result(RESULT_NO_DIALTONE, info);
        } else {
                info->isdn_driver = dev->drvmap[i];
                info->isdn_channel = dev->chanmap[i];
@@ -1056,8 +1065,7 @@ isdn_tty_modem_hup(modem_info * info, int local)
        if (info->online) {
                info->last_lhup = local;
                info->online = 0;
-               /* NO CARRIER message */
-               isdn_tty_modem_result(3, info);
+               isdn_tty_modem_result(RESULT_NO_CARRIER, info);
        }
 #ifdef CONFIG_ISDN_AUDIO
        info->vonline = 0;
@@ -1086,7 +1094,7 @@ isdn_tty_modem_hup(modem_info * info, int local)
 #endif
        if ((info->msr & UART_MSR_RI) &&
                (info->emu.mdmreg[REG_RUNG] & BIT_RUNG))
-               isdn_tty_modem_result(12, info);
+               isdn_tty_modem_result(RESULT_RUNG, info);
        info->msr &= ~(UART_MSR_DCD | UART_MSR_RI);
        info->lsr |= UART_LSR_TEMT;
        if (info->isdn_driver >= 0) {
@@ -1197,7 +1205,7 @@ isdn_tty_resume(char *id, modem_info * info, atemu * m)
        i = isdn_get_free_channel(usg, l2, m->mdmreg[REG_L3PROT], -1, -1, m->msn);
        if (i < 0) {
                restore_flags(flags);
-               isdn_tty_modem_result(6, info);
+               isdn_tty_modem_result(RESULT_NO_DIALTONE, info);
        } else {
                info->isdn_driver = dev->drvmap[i];
                info->isdn_channel = dev->chanmap[i];
@@ -1265,7 +1273,7 @@ isdn_tty_send_msg(modem_info * info, atemu * m, char *msg)
 
        l = strlen(msg);
        if (!l) {
-               isdn_tty_modem_result(4, info);
+               isdn_tty_modem_result(RESULT_ERROR, info);
                return;
        }
        for (j = 7; j >= 0; j--)
@@ -1291,7 +1299,7 @@ isdn_tty_send_msg(modem_info * info, atemu * m, char *msg)
        i = isdn_get_free_channel(usg, l2, m->mdmreg[REG_L3PROT], -1, -1, m->msn);
        if (i < 0) {
                restore_flags(flags);
-               isdn_tty_modem_result(6, info);
+               isdn_tty_modem_result(RESULT_NO_DIALTONE, info);
        } else {
                info->isdn_driver = dev->drvmap[i];
                info->isdn_channel = dev->chanmap[i];
@@ -1589,7 +1597,7 @@ isdn_tty_write(struct tty_struct *tty, int from_user, const u_char * buf, int co
 #ifdef ISDN_DEBUG_MODEM_HUP
                                printk(KERN_DEBUG "Mhup in isdn_tty_write\n");
 #endif
-                               isdn_tty_modem_result(3, info);
+                               isdn_tty_modem_result(RESULT_NO_CARRIER, info);
                                isdn_tty_modem_hup(info, 1);
                        } else
                                c = isdn_tty_edit_at(buf, c, info, from_user);
@@ -2322,7 +2330,7 @@ isdn_tty_modem_reset_regs(modem_info * info, int force)
 {
        atemu *m = &info->emu;
        if ((m->mdmreg[REG_DTRR] & BIT_DTRR) || force) {
-               memcpy(m->mdmreg, m->profile, ISDN_MODEM_ANZREG);
+               memcpy(m->mdmreg, m->profile, ISDN_MODEM_NUMREG);
                memcpy(m->msn, m->pmsn, ISDN_MSNLEN);
                memcpy(m->lmsn, m->plmsn, ISDN_LMSNLEN);
                info->xmit_size = m->mdmreg[REG_PSIZE] * 16;
@@ -2339,7 +2347,7 @@ isdn_tty_modem_reset_regs(modem_info * info, int force)
 static void
 modem_write_profile(atemu * m)
 {
-       memcpy(m->profile, m->mdmreg, ISDN_MODEM_ANZREG);
+       memcpy(m->profile, m->mdmreg, ISDN_MODEM_NUMREG);
        memcpy(m->pmsn, m->msn, ISDN_MSNLEN);
        memcpy(m->plmsn, m->lmsn, ISDN_LMSNLEN);
        if (dev->profd)
@@ -2448,6 +2456,13 @@ isdn_tty_modem_init(void)
        return 0;
 }
 
+
+/*
+ * isdn_tty_match_icall(char *MSN, atemu *tty_emulator, int dev_idx)
+ *      match the MSN against the MSNs (glob patterns) defined for tty_emulator,
+ *      and return 0 for match, 1 for no match, 2 if MSN could match if longer.
+ */
+
 static int
 isdn_tty_match_icall(char *cid, atemu *emu, int di)
 {
@@ -2513,15 +2528,14 @@ isdn_tty_find_icall(int di, int ch, setup_parm setup)
        int idx;
        int si1;
        int si2;
-       char nr[32];
+       char *nr;
        ulong flags;
 
        if (!setup.phone[0]) {
-               nr[0] = '0';
-               nr[1] = '\0';
+               nr = "0";
                printk(KERN_INFO "isdn_tty: Incoming call without OAD, assuming '0'\n");
        } else
-               strcpy(nr, setup.phone);
+               nr = setup.phone;
        si1 = (int) setup.si1;
        si2 = (int) setup.si2;
        if (!setup.eazmsn[0]) {
@@ -2538,6 +2552,8 @@ isdn_tty_find_icall(int di, int ch, setup_parm setup)
        for (i = 0; i < ISDN_MAX_CHANNELS; i++) {
                modem_info *info = &dev->mdm.info[i];
 
+                if (info->count == 0)
+                    continue;
                if ((info->emu.mdmreg[REG_SI1] & si2bit[si1]) &&  /* SI1 is matching */
                    (info->emu.mdmreg[REG_SI2] == si2)) {         /* SI2 is matching */
                        idx = isdn_dc2minor(di, ch);
@@ -2575,7 +2591,7 @@ isdn_tty_find_icall(int di, int ch, setup_parm setup)
                                        printk(KERN_INFO "isdn_tty: call from %s, -> RING on ttyI%d\n", nr,
                                               info->line);
                                        info->msr |= UART_MSR_RI;
-                                       isdn_tty_modem_result(2, info);
+                                       isdn_tty_modem_result(RESULT_RING, info);
                                        isdn_timer_ctrl(ISDN_TIMER_MODEMRING, 1);
                                        return 1;
                                }
@@ -2661,9 +2677,9 @@ isdn_tty_stat_callback(int i, isdn_ctrl *c)
 #endif
                                if (TTY_IS_ACTIVE(info)) {
                                        if (info->dialing == 1) 
-                                               isdn_tty_modem_result(7, info);
+                                               isdn_tty_modem_result(RESULT_BUSY, info);
                                        if (info->dialing > 1) 
-                                               isdn_tty_modem_result(3, info);
+                                               isdn_tty_modem_result(RESULT_NO_CARRIER, info);
                                        info->dialing = 0;
 #ifdef ISDN_DEBUG_MODEM_HUP
                                        printk(KERN_DEBUG "Mhup in ISDN_STAT_DHUP\n");
@@ -2692,12 +2708,12 @@ isdn_tty_stat_callback(int i, isdn_ctrl *c)
                                        if (USG_MODEM(dev->usage[i])) {
                                                if (info->emu.mdmreg[REG_L2PROT] == ISDN_PROTO_L2_MODEM) {
                                                        strcpy(info->emu.connmsg, c->parm.num);
-                                                       isdn_tty_modem_result(1, info);
+                                                       isdn_tty_modem_result(RESULT_CONNECT, info);
                                                } else
-                                                       isdn_tty_modem_result(5, info);
+                                                       isdn_tty_modem_result(RESULT_CONNECT64000, info);
                                        }
                                        if (USG_VOICE(dev->usage[i]))
-                                               isdn_tty_modem_result(11, info);
+                                               isdn_tty_modem_result(RESULT_VCON, info);
                                        return 1;
                                }
                                break;
@@ -2723,7 +2739,7 @@ isdn_tty_stat_callback(int i, isdn_ctrl *c)
                                                info->last_l2 = -1;
                                                info->last_si = 0;
                                                sprintf(info->last_cause, "0000");
-                                               isdn_tty_modem_result(6, info);
+                                               isdn_tty_modem_result(RESULT_NO_DIALTONE, info);
                                        }
                                        isdn_tty_modem_hup(info, 0);
                                        return 1;
@@ -2938,6 +2954,7 @@ isdn_tty_check_esc(const u_char * p, u_char plus, int count, int *pluscount,
  * For CONNECT-messages also switch to online-mode.
  * For RING-message handle auto-ATA if register 0 != 0
  */
+
 static void
 isdn_tty_modem_result(int code, modem_info * info)
 {
@@ -2950,14 +2967,13 @@ isdn_tty_modem_result(int code, modem_info * info)
        char s[ISDN_MSNLEN+10];
 
        switch (code) {
-               case 2:
-                       m->mdmreg[REG_RINGCNT]++;       /* RING */
+               case RESULT_RING:
+                       m->mdmreg[REG_RINGCNT]++;
                        if (m->mdmreg[REG_RINGCNT] == m->mdmreg[REG_RINGATA])
                                /* Automatically accept incoming call */
                                isdn_tty_cmd_ATA(info);
                        break;
-               case 3:
-                       /* NO CARRIER */
+               case RESULT_NO_CARRIER:
 #ifdef ISDN_DEBUG_MODEM_HUP
                        printk(KERN_DEBUG "modem_result: NO CARRIER %d %d\n",
                               (info->flags & ISDN_ASYNC_CLOSING),
@@ -2992,13 +3008,13 @@ isdn_tty_modem_result(int code, modem_info * info)
                        }
 #endif
                        break;
-               case 1:
-               case 5:
+               case RESULT_CONNECT:
+               case RESULT_CONNECT64000:
                        sprintf(info->last_cause, "0000");
                        if (!info->online)
                                info->online = 2;
                        break;
-               case 11:
+               case RESULT_VCON:
 #ifdef ISDN_DEBUG_MODEM_VOICE
                        printk(KERN_DEBUG "res3: send VCON on ttyI%d\n",
                               info->line);
@@ -3007,27 +3023,30 @@ isdn_tty_modem_result(int code, modem_info * info)
                        if (!info->online)
                                info->online = 1;
                        break;
-       }
+       } /* switch(code) */
+
        if (m->mdmreg[REG_RESP] & BIT_RESP) {
                /* Show results */
-               isdn_tty_at_cout("\r\n", info);
                if (m->mdmreg[REG_RESPNUM] & BIT_RESPNUM) {
-                       /* Show numeric results */
-                       sprintf(s, "%d", code);
+                       /* Show numeric results only */
+                       sprintf(s, "\r\n%d\r\n", code);
                        isdn_tty_at_cout(s, info);
                } else {
-                       if ((code == 2) &&
-                               (m->mdmreg[REG_RUNG] & BIT_RUNG) &&
-                               (m->mdmreg[REG_RINGCNT] > 1))
-                               return;
-                       if ((code == 2) && (!(m->mdmreg[REG_CIDONCE] & BIT_CIDONCE))) {
-                               isdn_tty_at_cout("CALLER NUMBER: ", info);
-                               isdn_tty_at_cout(dev->num[info->drv_index], info);
-                               isdn_tty_at_cout("\r\n", info);
+                       if (code == RESULT_RING) {
+                           /* return if "show RUNG" and ringcounter>1 */
+                           if ((m->mdmreg[REG_RUNG] & BIT_RUNG) &&
+                                   (m->mdmreg[REG_RINGCNT] > 1))
+                                               return;
+                           /* print CID, _before_ _every_ ring */
+                           if (!(m->mdmreg[REG_CIDONCE] & BIT_CIDONCE)) {
+                                   isdn_tty_at_cout("\r\nCALLER NUMBER: ", info);
+                                   isdn_tty_at_cout(dev->num[info->drv_index], info);
+                           }
                        }
+                       isdn_tty_at_cout("\r\n", info);
                        isdn_tty_at_cout(msg[code], info);
                        switch (code) {
-                               case 1:
+                               case RESULT_CONNECT:
                                        switch (m->mdmreg[REG_L2PROT]) {
                                                case ISDN_PROTO_L2_MODEM:
                                                        isdn_tty_at_cout(" ", info);
@@ -3035,13 +3054,13 @@ isdn_tty_modem_result(int code, modem_info * info)
                                                        break;
                                        }
                                        break;
-                               case 2:
+                               case RESULT_RING:
                                        /* Append CPN, if enabled */
                                        if ((m->mdmreg[REG_CPN] & BIT_CPN)) {
                                                sprintf(s, "/%s", m->cpn);
                                                isdn_tty_at_cout(s, info);
                                        }
-                                       /* Print CID only once, _after_ 1.st RING */
+                                       /* Print CID only once, _after_ 1st RING */
                                        if ((m->mdmreg[REG_CIDONCE] & BIT_CIDONCE) &&
                                            (m->mdmreg[REG_RINGCNT] == 1)) {
                                                isdn_tty_at_cout("\r\n", info);
@@ -3049,10 +3068,10 @@ isdn_tty_modem_result(int code, modem_info * info)
                                                isdn_tty_at_cout(dev->num[info->drv_index], info);
                                        }
                                        break;
-                               case 3:
-                               case 6:
-                               case 7:
-                               case 8:
+                               case RESULT_NO_CARRIER:
+                               case RESULT_NO_DIALTONE:
+                               case RESULT_BUSY:
+                               case RESULT_NO_ANSWER:
                                        m->mdmreg[REG_RINGCNT] = 0;
                                        /* Append Cause-Message if enabled */
                                        if (m->mdmreg[REG_RESPXT] & BIT_RESPXT) {
@@ -3060,7 +3079,7 @@ isdn_tty_modem_result(int code, modem_info * info)
                                                isdn_tty_at_cout(s, info);
                                        }
                                        break;
-                               case 5:
+                               case RESULT_CONNECT64000:
                                        /* Append Protocol to CONNECT message */
                                        switch (m->mdmreg[REG_L2PROT]) {
                                                case ISDN_PROTO_L2_X75I:
@@ -3088,10 +3107,10 @@ isdn_tty_modem_result(int code, modem_info * info)
                                        }
                                        break;
                        }
+                       isdn_tty_at_cout("\r\n", info);
                }
-               isdn_tty_at_cout("\r\n", info);
        }
-       if (code == 3) {
+       if (code == RESULT_NO_CARRIER) {
                save_flags(flags);
                cli();
                if ((info->flags & ISDN_ASYNC_CLOSING) || (!info->tty)) {
@@ -3109,6 +3128,7 @@ isdn_tty_modem_result(int code, modem_info * info)
        }
 }
 
+
 /*
  * Display a modem-register-value.
  */
@@ -3161,8 +3181,8 @@ isdn_tty_getdial(char *p, char *q,int cnt)
        *q = 0;
 }
 
-#define PARSE_ERROR { isdn_tty_modem_result(4, info); return; }
-#define PARSE_ERROR1 { isdn_tty_modem_result(4, info); return 1; }
+#define PARSE_ERROR { isdn_tty_modem_result(RESULT_ERROR, info); return; }
+#define PARSE_ERROR1 { isdn_tty_modem_result(RESULT_ERROR, info); return 1; }
 
 static void
 isdn_tty_report(modem_info * info)
@@ -3330,8 +3350,8 @@ isdn_tty_cmd_ATand(char **p, modem_info * info)
                        /* &L -Set Numbers to listen on */
                        p[0]++;
                        i = 0;
-                       while ((strchr("0123456789,-*[]?;", *p[0])) &&
-                              (i < ISDN_LMSNLEN) && *p[0])
+                       while (*p[0] && (strchr("0123456789,-*[]?;", *p[0])) &&
+                              (i < ISDN_LMSNLEN))
                                m->lmsn[i++] = *p[0]++;
                        m->lmsn[i] = '\0';
                        break;
@@ -3382,7 +3402,7 @@ isdn_tty_cmd_ATand(char **p, modem_info * info)
                        /* &V - Show registers */
                        p[0]++;
                        isdn_tty_at_cout("\r\n", info);
-                       for (i = 0; i < ISDN_MODEM_ANZREG; i++) {
+                       for (i = 0; i < ISDN_MODEM_NUMREG; i++) {
                                sprintf(rb, "S%02d=%03d%s", i,
                                        m->mdmreg[i], ((i + 1) % 10) ? " " : "\r\n");
                                isdn_tty_at_cout(rb, info);
@@ -3487,7 +3507,7 @@ isdn_tty_cmd_ATS(char **p, modem_info * info)
        int bval;
 
        mreg = isdn_getnum(p);
-       if (mreg < 0 || mreg >= ISDN_MODEM_ANZREG)
+       if (mreg < 0 || mreg >= ISDN_MODEM_NUMREG)
                PARSE_ERROR1;
        switch (*p[0]) {
                case '=':
@@ -3590,7 +3610,7 @@ isdn_tty_cmd_ATA(modem_info * info)
                isdn_command(&cmd);
                isdn_timer_ctrl(ISDN_TIMER_CARRIER, 1);
        } else
-               isdn_tty_modem_result(8, info);
+               isdn_tty_modem_result(RESULT_NO_ANSWER, info);
 }
 
 #ifdef CONFIG_ISDN_AUDIO
@@ -3780,7 +3800,7 @@ isdn_tty_cmd_PLUSV(char **p, modem_info * info)
                        if (!m->vpar[0])
                                PARSE_ERROR1;
                        if (info->online != 1) {
-                               isdn_tty_modem_result(8, info);
+                               isdn_tty_modem_result(RESULT_NO_ANSWER, info);
                                return 1;
                        }
                        info->dtmf_state = isdn_audio_dtmf_init(info->dtmf_state);
@@ -3804,7 +3824,7 @@ isdn_tty_cmd_PLUSV(char **p, modem_info * info)
                        printk(KERN_DEBUG "AT: +VRX\n");
 #endif
                        info->vonline |= 1;
-                       isdn_tty_modem_result(1, info);
+                       isdn_tty_modem_result(RESULT_CONNECT, info);
                        return 0;
                        break;
                case 4:
@@ -3894,7 +3914,7 @@ isdn_tty_cmd_PLUSV(char **p, modem_info * info)
                        if (!m->vpar[0])
                                PARSE_ERROR1;
                        if (info->online != 1) {
-                               isdn_tty_modem_result(8, info);
+                               isdn_tty_modem_result(RESULT_NO_ANSWER, info);
                                return 1;
                        }
                        info->dtmf_state = isdn_audio_dtmf_init(info->dtmf_state);
@@ -3914,7 +3934,7 @@ isdn_tty_cmd_PLUSV(char **p, modem_info * info)
 #endif
                        m->lastDLE = 0;
                        info->vonline |= 2;
-                       isdn_tty_modem_result(1, info);
+                       isdn_tty_modem_result(RESULT_CONNECT, info);
                        return 0;
                        break;
                case 7:
@@ -3999,13 +4019,13 @@ isdn_tty_parse_at(modem_info * info)
                                if (info->msr & UART_MSR_DCD)
                                        PARSE_ERROR;
                                if (info->msr & UART_MSR_RI) {
-                                       isdn_tty_modem_result(3, info);
+                                       isdn_tty_modem_result(RESULT_NO_CARRIER, info);
                                        return;
                                }
                                isdn_tty_getdial(++p, ds, sizeof ds);
                                p += strlen(p);
                                if (!strlen(m->msn))
-                                       isdn_tty_modem_result(10, info);
+                                       isdn_tty_modem_result(RESULT_NO_MSN_EAZ, info);
                                else if (strlen(ds))
                                        isdn_tty_dial(ds, info, m);
                                else
@@ -4077,9 +4097,9 @@ isdn_tty_parse_at(modem_info * info)
                                p++;
                                if (info->msr & UART_MSR_DCD)
                                        /* if B-Channel is up */
-                                       isdn_tty_modem_result((m->mdmreg[REG_L2PROT] == ISDN_PROTO_L2_MODEM) ? 1:5, info);
+                                       isdn_tty_modem_result((m->mdmreg[REG_L2PROT] == ISDN_PROTO_L2_MODEM) ? RESULT_CONNECT:RESULT_CONNECT64000, info);
                                else
-                                       isdn_tty_modem_result(3, info);
+                                       isdn_tty_modem_result(RESULT_NO_CARRIER, info);
                                return;
                        case 'Q':
                                /* Q - Turn Emulator messages on/off */
@@ -4172,7 +4192,7 @@ isdn_tty_parse_at(modem_info * info)
 #ifdef CONFIG_ISDN_AUDIO
        if (!info->vonline)
 #endif
-               isdn_tty_modem_result(0, info);
+               isdn_tty_modem_result(RESULT_OK, info);
 }
 
 /* Need own toupper() because standard-toupper is not available
@@ -4283,7 +4303,7 @@ isdn_tty_modem_escape(void)
                                            ((jiffies - info->emu.lastplus) > PLUSWAIT2)) {
                                                info->emu.pluscount = 0;
                                                info->online = 0;
-                                               isdn_tty_modem_result(0, info);
+                                               isdn_tty_modem_result(RESULT_OK, info);
                                        }
                                }
                        }
@@ -4305,7 +4325,7 @@ isdn_tty_modem_ring(void)
                modem_info *info = &dev->mdm.info[i];
                if (info->msr & UART_MSR_RI) {
                        ton = 1;
-                       isdn_tty_modem_result(2, info);
+                       isdn_tty_modem_result(RESULT_RING, info);
                }
        }
        isdn_timer_ctrl(ISDN_TIMER_MODEMRING, ton);
@@ -4347,7 +4367,7 @@ isdn_tty_carrier_timeout(void)
                if (info->dialing) {
                        if (info->emu.carrierwait++ > info->emu.mdmreg[REG_WAITC]) {
                                info->dialing = 0;
-                               isdn_tty_modem_result(3, info);
+                               isdn_tty_modem_result(RESULT_NO_CARRIER, info);
                                isdn_tty_modem_hup(info, 1);
                        }
                        else
index ff7e479f0cd12dac347b50625b9270c4fd68df29..ed9190cfef72eb2d0912535ae672d5af79ea3cfb 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: isdn_tty.h,v 1.18 2000/01/20 19:55:33 keil Exp $
+/* $Id: isdn_tty.h,v 1.19 2000/02/16 14:59:33 paul Exp $
 
  * header for Linux ISDN subsystem, tty related functions (linklevel).
  *
  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  *
  * $Log: isdn_tty.h,v $
+ * Revision 1.19  2000/02/16 14:59:33  paul
+ * translated ISDN_MODEM_ANZREG to ISDN_MODEM_NUMREG for english speakers;
+ * used defines for result codes;
+ * fixed RING ... RUNG problem (no empty lines in between).
+ *
  * Revision 1.18  2000/01/20 19:55:33  keil
  * Add FAX Class 1 support
  *
  * Definition of some special Registers of AT-Emulator
  */
 #define REG_RINGATA   0
-#define REG_RINGCNT   1
+#define REG_RINGCNT   1  /* ring counter register */
 #define REG_ESC       2
 #define REG_CR        3
 #define REG_LF        4
 
 #define REG_WAITC     7
 
-#define REG_RESP     12
-#define BIT_RESP      1
-#define REG_RESPNUM  12
-#define BIT_RESPNUM   2
+#define REG_RESP     12  /* show response messages register */
+#define BIT_RESP      1  /* show response messages bit      */
+#define REG_RESPNUM  12  /* show numeric responses register */
+#define BIT_RESPNUM   2  /* show numeric responses bit      */
 #define REG_ECHO     12
 #define BIT_ECHO      4
 #define REG_DCD      12
 #define BIT_RESPXT    8
 #define REG_CIDONCE  13
 #define BIT_CIDONCE  16
-#define REG_RUNG     13
-#define BIT_RUNG     64
+#define REG_RUNG     13  /* show RUNG message register      */
+#define BIT_RUNG     64  /* show RUNG message bit           */
 #define REG_DISPLAY  13
 #define BIT_DISPLAY 128
 
 #define BIT_CPN       1
 #define BIT_CPNFCON   2
 
+/* defines for result codes */
+#define RESULT_OK              0
+#define RESULT_CONNECT         1
+#define RESULT_RING            2
+#define RESULT_NO_CARRIER      3
+#define RESULT_ERROR           4
+#define RESULT_CONNECT64000    5
+#define RESULT_NO_DIALTONE     6
+#define RESULT_BUSY            7
+#define RESULT_NO_ANSWER       8
+#define RESULT_RINGING         9
+#define RESULT_NO_MSN_EAZ      10
+#define RESULT_VCON            11
+#define RESULT_RUNG            12
+
 #define TTY_IS_FCLASS1(info) \
        ((info->emu.mdmreg[REG_L2PROT] == ISDN_PROTO_L2_FAX) && \
         (info->emu.mdmreg[REG_L3PROT] == ISDN_PROTO_L3_FCLASS1))
index a3ac19caf09bd2918e09465a2d96186db2bd1396..22863e208419469bd988a08172e45bf0bc7264f4 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: isdn_v110.c,v 1.3 1999/10/30 09:49:28 keil Exp $
+/* $Id: isdn_v110.c,v 1.4 2000/03/16 16:34:12 kai Exp $
 
  * Linux ISDN subsystem, V.110 related functions (linklevel).
  *
  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  *
  * $Log: isdn_v110.c,v $
+ * Revision 1.4  2000/03/16 16:34:12  kai
+ * some translation work
+ *
+ * there shouldn't be any German comments lurking around anymore ;-)
+ *
  * Revision 1.3  1999/10/30 09:49:28  keil
  * Reinit of v110 structs
  *
 
 #undef ISDN_V110_DEBUG
 
-char *isdn_v110_revision = "$Revision: 1.3 $";
+char *isdn_v110_revision = "$Revision: 1.4 $";
 
 #define V110_38400 255
 #define V110_19200  15
 #define V110_9600    3
 
-/* Die folgenden Daten sind fertig kodierte Matrizen, jeweils
-   als online und offline matrix für 9600, 19200 und 38400
+/* 
+ * The following data are precoded matrices, online and offline matrix 
+ * for 9600, 19200 und 38400, respectively
  */
 static unsigned char V110_OnMatrix_9600[] =
 {0xfc, 0xfc, 0xfc, 0xfc, 0xff, 0xff, 0xff, 0xfd, 0xff, 0xff,
@@ -74,13 +80,12 @@ static unsigned char V110_OnMatrix_38400[] =
 static unsigned char V110_OffMatrix_38400[] =
 {0x00, 0xff, 0xff, 0xff, 0xff, 0xfd, 0xff, 0xff, 0xff, 0xff};
 
-
-/* FlipBits dreht die Reihenfolge von jeweils keylen bits in einem byte um.
  Aus der Bitreihenfolge 76543210 werden bei keylen=4 die bits 45670123,
-   bei keylen=2 die bits 67452301. Dies ist notwendig, weil die reihenfolge
  auf der isdn-leitung falsch herum ist.
+/* 
+ * FlipBits reorders sequences of keylen bits in one byte.
* E.g. source order 7654321 will be converted to 45670123 when keylen = 4,
+ * and to 67452301 when keylen = 2. This is necessary because ordering on
* the isdn line is the the other way.
  */
-
 static __inline unsigned char
 FlipBits(unsigned char c, int keylen)
 {
@@ -164,8 +169,9 @@ isdn_v110_close(isdn_v110_stream * v)
 }
 
 
-/* ValidHeaderBytes prüft, wieviele bytes in v->decodebuf gültig sind */
-
+/* 
+ * ValidHeaderBytes return the number of valid bytes in v->decodebuf 
+ */
 static int
 ValidHeaderBytes(isdn_v110_stream * v)
 {
@@ -176,8 +182,9 @@ ValidHeaderBytes(isdn_v110_stream * v)
        return i;
 }
 
-/* SyncHeader schiebt den decodebuf pointer auf den nächsten gültigen header */
-
+/* 
+ * SyncHeader moves the decodebuf ptr to the next valid header 
+ */
 static void
 SyncHeader(isdn_v110_stream * v)
 {
@@ -214,68 +221,60 @@ DecodeMatrix(isdn_v110_stream * v, unsigned char *m, int len, unsigned char *buf
        int dbit = v->dbit;
        unsigned char b = v->b;
 
-       while (line < len) {    /* sind schon alle matrizenzeilen abgearbeitet? */
-               if ((line % 10) == 0) { /* die 0. zeile der matrix ist immer null ! */
-                       if (m[line] != 0x00) {  /* nicht 0 ? dann fehler! */
+       while (line < len) {    /* Are we done with all lines of the matrix? */
+               if ((line % 10) == 0) { /* the 0. line of the matrix is always 0 ! */
+                       if (m[line] != 0x00) {  /* not 0 ? -> error! */
 #ifdef ISDN_V110_DEBUG
                                printk(KERN_DEBUG "isdn_v110: DecodeMatrix, V110 Bad Header\n");
+                               /* returning now is not the right thing, though :-( */
 #endif
-
-/*
-  dann einen return zu machen, ist auch irgendwie nicht das richtige! :-(
-  v->introducer = 0; v->dbit = 1; v->b = 0;
-  return buflen;                                                                                                     anzahl schon erzeugter daten zurückgeben!
-  */
-                       }
-                       line++; /* sonst die nächste matrixzeile nehmen */
+                       } 
+                       line++; /* next line of matrix */
                        continue;
-               } else if ((line % 10) == 5) {  /* in zeile 5 stehen nur e-bits ! */
-                       if ((m[line] & 0x70) != 0x30) { /* 011 muß am anfang stehen! */
+               } else if ((line % 10) == 5) {  /* in line 5 there's only e-bits ! */
+                       if ((m[line] & 0x70) != 0x30) { /* 011 has to be at the beginning! */
 #ifdef ISDN_V110_DEBUG
                                printk(KERN_DEBUG "isdn_v110: DecodeMatrix, V110 Bad 5th line\n");
+                               /* returning now is not the right thing, though :-( */
 #endif
-/* dann einen return zu machen, ist auch irgendwie nicht das richtige! :-(
-   v->introducer = 0; v->dbit = 1; v->b = 0;
-   return buflen;
- */
                        }
-                       line++; /* alles klar, nächste zeile */
+                       line++; /* next line */
                        continue;
                } else if (!introducer) {       /* every byte starts with 10 (stopbit, startbit) */
-                       introducer = (m[line] & mbit) ? 0 : 1;  /* aktuelles bit der matrix */
+                       introducer = (m[line] & mbit) ? 0 : 1;  /* current bit of the matrix */
                      next_byte:
-                       if (mbit > 2) { /* war es das letzte bit dieser matrixzeile ? */
-                               mbit >>= 1;     /* nein, nimm das nächste in dieser zeile */
+                       if (mbit > 2) { /* was it the last bit in this line ? */
+                               mbit >>= 1;     /* no -> take next */
                                continue;
-                       }       /* sonst links in der nächsten zeile anfangen */
+                       }       /* otherwise start with leftmost bit in the next line */
                        mbit = 64;
                        line++;
                        continue;
-               } else {        /* sonst müssen wir ein datenbit setzen */
-                       if (m[line] & mbit)     /* war das bit in der matrix gesetzt ? */
-                               b |= dbit;      /* ja, dann setz es auch im datenbyte  */
+               } else {        /* otherwise we need to set a data bit */
+                       if (m[line] & mbit)     /* was that bit set in the matrix ? */
+                               b |= dbit;      /* yes -> set it in the data byte */
                        else
-                               b &= dbit - 1;  /* nein, lösch bit im datenbyte */
-                       if (dbit < 128) /* haben wir schon ein ganzes byte voll ? */
-                               dbit <<= 1;     /* nein, auf zum nächsten datenbit */
-                       else {  /* ein ganzes datenbyte ist voll */
-                               buf[buflen++] = b;      /* byte in den output buffer kopieren */
-                               introducer = b = 0;     /* Init der Introsequenz und des datenbytes */
-                               dbit = 1;       /* als nächstes suchen wir das nullte bit */
+                               b &= dbit - 1;  /* no -> clear it in the data byte */
+                       if (dbit < 128) /* is that data byte done ? */
+                               dbit <<= 1;     /* no, got the next bit */
+                       else {  /* data byte is done */
+                               buf[buflen++] = b;      /* copy byte into the output buffer */
+                               introducer = b = 0;     /* init of the intro sequence and of the data byte */
+                               dbit = 1;       /* next we look for the 0th bit */
                        }
-                       goto next_byte; /* suche das nächste bit in der matrix */
+                       goto next_byte; /* look for next bit in the matrix */
                }
        }
        v->introducer = introducer;
        v->dbit = dbit;
        v->b = b;
-       return buflen;          /* return anzahl der bytes im output buffer */
+       return buflen;          /* return number of bytes in the output buffer */
 }
 
-/* DecodeStream erhält vom input stream V110 kodierte Daten, die zu den
-   V110 frames zusammengepackt werden müssen. Die Daten können an diese
-   Schnittstelle so Ã¼bergeben werden, wie sie von der Leitung kommen, ohne
-   darauf achten zu müssen, das frames usw. eingehalten werden.
+/* 
+ * DecodeStream receives V.110 coded data from the input stream. It recovers the 
+ * original frames.
+ * The input stream doesn't need to be framed
  */
 struct sk_buff *
 isdn_v110_decode(isdn_v110_stream * v, struct sk_buff *skb)
@@ -314,8 +313,8 @@ isdn_v110_decode(isdn_v110_stream * v, struct sk_buff *skb)
                dev_kfree_skb(skb);
                return NULL;    /* no, try later      */
        }
-       if (ValidHeaderBytes(v) != v->nbytes) { /* ist es ein ungültiger header ? */
-               SyncHeader(v);  /* nein, such einen header */
+       if (ValidHeaderBytes(v) != v->nbytes) { /* is that a valid header? */
+               SyncHeader(v);  /* no -> look for header */
                goto ReSync;
        }
        len = (v->decodelen - (v->decodelen % (10 * v->nbytes))) / v->nbytes;
@@ -357,15 +356,15 @@ EncodeMatrix(unsigned char *buf, int len, unsigned char *m, int mlen)
        int introducer = 3;
        int ibit[] = {0, 1, 1};
 
-       while ((i < len) && (line < mlen)) {    /* solange noch input da ist */
-               switch (line % 10) {    /* in welcher matrixzeile sind wir ? */
+       while ((i < len) && (line < mlen)) {    /* while we still have input data */
+               switch (line % 10) {    /* in which line of the matrix are we? */
                        case 0:
-                               m[line++] = 0x00;       /* zeile 0 ist immer 0 */
-                               mbit = 128;     /* und es geht mit dem 7. bit weiter */
+                               m[line++] = 0x00;       /* line 0 is always 0 */
+                               mbit = 128;     /* go on with the 7th bit */
                                break;
                        case 5:
-                               m[line++] = 0xbf;       /* zeile 5 ist immer 10111111 */
-                               mbit = 128;     /* und es geht mit dem 7. bit weiter */
+                               m[line++] = 0xbf;       /* line 5 is always 10111111 */
+                               mbit = 128;     /* go on with the 7th bit */
                                break;
                }
                if (line >= mlen) {
@@ -373,41 +372,41 @@ EncodeMatrix(unsigned char *buf, int len, unsigned char *m, int mlen)
                        return line;
                }
        next_bit:
-               switch (mbit) { /* ganz linkes oder rechtes bit ? */
+               switch (mbit) { /* leftmost or rightmost bit ? */
                        case 1:
-                               line++; /* ganz rechts ! dann in die nächste */
+                               line++; /* rightmost -> go to next line */
                                if (line >= mlen) {
                                        printk(KERN_WARNING "isdn_v110 (EncodeMatrix): buffer full!\n");
                                        return line;
                                }
                        case 128:
-                               m[line] = 128;  /* ganz links byte auf 1000000 setzen */
-                               mbit = 64;      /* aktuelles bit in der matrixzeile */
+                               m[line] = 128;  /* leftmost -> set byte to 1000000 */
+                               mbit = 64;      /* current bit in the matrix line */
                                continue;
                }
-               if (introducer) {       /* 110 sequenz setzen ? */
-                       introducer--;   /* ein digit weniger setzen */
-                       m[line] |= ibit[introducer] ? mbit : 0; /* entsprechendes bit setzen */
-                       mbit >>= 1;     /* bit der matrixzeile >> 1 */
-                       goto next_bit;  /* und dort weiter machen */
-               }               /* else datenbits in die matrix packen! */
-               m[line] |= (buf[i] & dbit) ? mbit : 0;  /* datenbit in matrix setzen */
-               if (dbit == 128) {      /* war es das letzte datenbit ? */
-                       dbit = 1;       /* dann mach beim nächsten weiter */
-                       i++;    /* nächste datenbyte des input buffers */
-                       if (i < len)    /* war es schon das letzte ? */
-                               introducer = 3; /* nein, schreib den introducer 110 */
-                       else {  /* war das letzte datenbyte ! */
-                               m[line] |= (mbit - 1) & 0xfe;   /* setz restliche bits der zeile auf 1 */
+               if (introducer) {       /* set 110 sequence ? */
+                       introducer--;   /* set on digit less */
+                       m[line] |= ibit[introducer] ? mbit : 0; /* set corresponding bit */
+                       mbit >>= 1;     /* bit of matrix line  >> 1 */
+                       goto next_bit;  /* and go on there */
+               }               /* else push data bits into the matrix! */
+               m[line] |= (buf[i] & dbit) ? mbit : 0;  /* set data bit in matrix */
+               if (dbit == 128) {      /* was it the last one? */
+                       dbit = 1;       /* then go on with first bit of  */
+                       i++;            /* next byte in input buffer */
+                       if (i < len)    /* input buffer done ? */
+                               introducer = 3; /* no, write introducer 110 */
+                       else {  /* input buffer done ! */
+                               m[line] |= (mbit - 1) & 0xfe;   /* set remaining bits in line to 1 */
                                break;
                        }
-               } else          /* nicht das letzte datenbit */
-                       dbit <<= 1;     /* dann gehe zum nächsten datenbit */
-               mbit >>= 1;     /* und setz bit der matrix weiter */
+               } else          /* not the last data bit */
+                       dbit <<= 1;     /* then go to next data bit */
+               mbit >>= 1;     /* go to next bit of matrix */
                goto next_bit;
 
        }
-       /* evtl. noch restliche zeilen in der matrix generieren... */
+       /* if necessary, generate remaining lines of the matrix... */
        if ((line) && ((line + 10) < mlen))
                switch (++line % 10) {
                        case 1:
@@ -429,7 +428,7 @@ EncodeMatrix(unsigned char *buf, int len, unsigned char *m, int mlen)
                        case 9:
                                m[line++] = 0xfe;
                }
-       return line;            /* soviele matrixzeilen sind es */
+       return line;            /* that's how many lines we have */
 }
 
 /*
@@ -517,7 +516,7 @@ isdn_v110_encode(isdn_v110_stream * v, struct sk_buff *skb)
                return nskb;
        }
        mlen = EncodeMatrix(skb->data, rlen, v110buf, size);
-       /* jetzt noch jeweils 2 oder 4 bits auf den output stream verteilen! */
+       /* now distribute 2 or 4 bits each to the output stream! */
        rbuf = skb_put(nskb, size);
        olen = 0;
        sval1 = 8 - v->nbits;
index 4bb6948498430d2f151fbac55c5d34af196770fa..de6f9f6e1664c580125e913b59ef125f84eda606 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: isdn_v110.h,v 1.2 1999/10/30 09:49:28 keil Exp $
+/* $Id: isdn_v110.h,v 1.3 2000/03/16 16:34:12 kai Exp $
 
  * Linux ISDN subsystem, V.110 related functions (linklevel).
  *
  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  *
  * $Log: isdn_v110.h,v $
+ * Revision 1.3  2000/03/16 16:34:12  kai
+ * some translation work
+ *
+ * there shouldn't be any German comments lurking around anymore ;-)
+ *
  * Revision 1.2  1999/10/30 09:49:28  keil
  * Reinit of v110 structs
  *
 #ifndef _isdn_v110_h_
 #define _isdn_v110_h_
 
-/* isdn_v110_encode erhält len Nettodaten in buf, kodiert diese und liefert
-   das Ergebnis wieder in buf. Wieviele Bytes kodiert wurden wird als
-   return zurück gegeben. Diese Daten können dann 1:1 auf die Leitung
-   gegeben werden.
-*/
+/* 
+ * isdn_v110_encode will take raw data and encode it using V.110 
+ */
 extern struct sk_buff *isdn_v110_encode(isdn_v110_stream *, struct sk_buff *);
 
-/* isdn_v110_decode erhält vom input stream V110 kodierte Daten, die zu den
-   V110 frames zusammengepackt werden müssen. Die Daten können an diese
-   Schnittstelle so Ã¼bergeben werden, wie sie von der Leitung kommen, ohne
-   darauf achten zu müssen, das frames usw. eingehalten werden.
+/* 
+ * isdn_v110_decode receives V.110 coded data from the stream and rebuilds
+ * frames from them. The source stream doesn't need to be framed.
  */
 extern struct sk_buff *isdn_v110_decode(isdn_v110_stream *, struct sk_buff *);
 
index 029dc187e28fedbc479708b4485c7afd72be9693..ac6136a7febf3f16f7634098f5cd20fd74859445 100644 (file)
@@ -346,8 +346,8 @@ int dmfe_probe(struct device *dev)
                        continue;
 
                /* read PCI IO base address and IRQ to check */
-               pci_read_config_dword(net_dev, PCI_BASE_ADDRESS_0, &pci_iobase);
-               pci_read_config_byte(net_dev, PCI_INTERRUPT_LINE, &pci_irqline);
+               pci_iobase = net_dev->base_address[0];
+               pci_irqline = net_dev->irq;
                pci_iobase &= ~0x7f;    /* mask off bit0~6 */
 
                /* Enable Master/IO access, Disable memory access */
@@ -360,7 +360,7 @@ int dmfe_probe(struct device *dev)
                pci_write_config_byte(net_dev, PCI_LATENCY_TIMER, 0x80);
 
                /* Read Chip revesion */
-               pci_read_config_dword(net_dev, 8, &dev_rev);
+               pci_read_config_dword(net_dev, PCI_REVISION_ID, &dev_rev);
 
                /* IO range check */
                if (check_region(pci_iobase, CHK_IO_SIZE(pci_id, dev_rev))) {
@@ -570,9 +570,8 @@ static int dmfe_start_xmit(struct sk_buff *skb, struct device *dev)
        }
        /* No Tx resource check, it never happen normally */
        if (db->tx_queue_cnt >= TX_FREE_DESC_CNT) {
-               dev_kfree_skb(skb);
                dev->tbusy = 1;
-               return -EBUSY;
+               return 1;
        }
        /* transmit this packet */
        txptr = db->tx_insert_ptr;
index 4585db2dc2459f4763687d2e201e7f21ba22e155..7c53c81127fa973e4ceab350a72191405a89295f 100644 (file)
@@ -6,7 +6,7 @@
  * Status:       Experimental.
  * Author:       Dag Brattli <dagb@cs.uit.no>
  * Created at:   Sun Aug  3 13:49:59 1997
- * Modified at:   Fri Jan 14 21:07:20 2000
+ * Modified at:   Sat Mar 11 07:41:54 2000
  * Modified by:   Dag Brattli <dagb@cs.uit.no>
  * Sources:      serial.c by Linus Torvalds 
  * 
@@ -943,10 +943,14 @@ static int irport_net_ioctl(struct device *dev, struct ifreq *rq, int cmd)
        
        switch (cmd) {
        case SIOCSBANDWIDTH: /* Set bandwidth */
+               if (!capable(CAP_NET_ADMIN))
+                       return -EPERM;
                irda_task_execute(self, __irport_change_speed, NULL, NULL, 
                                  (void *) irq->ifr_baudrate);
                break;
        case SIOCSDONGLE: /* Set dongle */
+               if (!capable(CAP_NET_ADMIN))
+                       return -EPERM;
                /* Initialize dongle */
                dongle = irda_device_dongle_init(dev, irq->ifr_dongle);
                if (!dongle)
@@ -967,12 +971,16 @@ static int irport_net_ioctl(struct device *dev, struct ifreq *rq, int cmd)
                                  NULL);        
                break;
        case SIOCSMEDIABUSY: /* Set media busy */
+               if (!capable(CAP_NET_ADMIN))
+                       return -EPERM;
                irda_device_set_media_busy(self->netdev, TRUE);
                break;
        case SIOCGRECEIVING: /* Check if we are receiving right now */
                irq->ifr_receiving = irport_is_receiving(self);
                break;
        case SIOCSDTRRTS:
+               if (!capable(CAP_NET_ADMIN))
+                       return -EPERM;
                irport_set_dtr_rts(dev, irq->ifr_dtr, irq->ifr_rts);
                break;
        default:
index fad95bb8c348dd3186b7eaff85ad5e2cfc85a6e0..4557fea380b0df7b57c55c09a632d556fb3df7d9 100644 (file)
@@ -6,7 +6,7 @@
  * Status:        Experimental.
  * Author:        Dag Brattli <dagb@cs.uit.no>
  * Created at:    Tue Dec  9 21:18:38 1997
- * Modified at:   Fri Jan 14 21:02:27 2000
+ * Modified at:   Sat Mar 11 07:43:30 2000
  * Modified by:   Dag Brattli <dagb@cs.uit.no>
  * Sources:       slip.c by Laurence Culhane,   <loz@holmes.demon.co.uk>
  *                          Fred N. van Kempen, <waltje@uwalt.nl.mugnet.org>
@@ -34,6 +34,7 @@
 
 #include <asm/segment.h>
 #include <asm/uaccess.h>
+#include <asm/termios.h>
 
 #include <net/irda/irda.h>
 #include <net/irda/irtty.h>
@@ -325,7 +326,7 @@ static void irtty_stop_receiver(struct irtty_cb *self, int stop)
 {
        struct termios old_termios;
        int cflag;
-
+       
        old_termios = *(self->tty->termios);
        cflag = self->tty->termios->c_cflag;
        
@@ -562,6 +563,8 @@ static void irtty_receive_buf(struct tty_struct *tty, const unsigned char *cp,
 {
        struct irtty_cb *self = (struct irtty_cb *) tty->disc_data;
 
+       IRDA_DEBUG(2, __FUNCTION__ "(%ld)\n", jiffies);
+
        if (!self || !self->netdev) {
                IRDA_DEBUG(0, __FUNCTION__ "(), not ready yet!\n");
                return;
@@ -711,8 +714,6 @@ static void irtty_write_wakeup(struct tty_struct *tty)
 
                self->tx_buff.data += actual;
                self->tx_buff.len  -= actual;
-
-               self->stats.tx_packets++;                     
        } else {                
                /* 
                 *  Now serial buffer is almost free & we can start 
@@ -734,6 +735,7 @@ static void irtty_write_wakeup(struct tty_struct *tty)
                        /* Tell network layer that we want more frames */
                        mark_bh(NET_BH);
                }
+               self->stats.tx_packets++;
        }
 }
 
@@ -972,10 +974,14 @@ static int irtty_net_ioctl(struct device *dev, struct ifreq *rq, int cmd)
        
        switch (cmd) {
        case SIOCSBANDWIDTH: /* Set bandwidth */
+               if (!capable(CAP_NET_ADMIN))
+                       return -EPERM;
                irda_task_execute(self, irtty_change_speed, NULL, NULL, 
                                  (void *) irq->ifr_baudrate);
                break;
        case SIOCSDONGLE: /* Set dongle */
+               if (!capable(CAP_NET_ADMIN))
+                       return -EPERM;
                /* Initialize dongle */
                dongle = irda_device_dongle_init(dev, irq->ifr_dongle);
                if (!dongle)
@@ -996,15 +1002,21 @@ static int irtty_net_ioctl(struct device *dev, struct ifreq *rq, int cmd)
                                  NULL);        
                break;
        case SIOCSMEDIABUSY: /* Set media busy */
+               if (!capable(CAP_NET_ADMIN))
+                       return -EPERM;
                irda_device_set_media_busy(self->netdev, TRUE);
                break;
        case SIOCGRECEIVING: /* Check if we are receiving right now */
                irq->ifr_receiving = irtty_is_receiving(self);
                break;
        case SIOCSDTRRTS:
+               if (!capable(CAP_NET_ADMIN))
+                       return -EPERM;
                irtty_set_dtr_rts(dev, irq->ifr_dtr, irq->ifr_rts);
                break;
        case SIOCSMODE:
+               if (!capable(CAP_NET_ADMIN))
+                       return -EPERM;
                irtty_set_mode(dev, irq->ifr_mode);
                break;
        default:
index 3a264f41017ac46a6cc0f54b7caa251a6993ce2b..f06c55d5a72259cc147dcd0425c464bc45585b88 100644 (file)
@@ -6,7 +6,7 @@
  * Status:        Stable.
  * Author:        Dag Brattli <dagb@cs.uit.no>
  * Created at:    Sat Nov  7 21:43:15 1998
- * Modified at:   Wed Jan 26 13:00:29 2000
+ * Modified at:   Fri Mar 10 11:53:26 2000
  * Modified by:   Dag Brattli <dagb@cs.uit.no>
  * 
  *     Copyright (c) 1998-2000 Dag Brattli <dagb@cs.uit.no>
@@ -1969,9 +1969,13 @@ static int nsc_ircc_net_ioctl(struct device *dev, struct ifreq *rq, int cmd)
        
        switch (cmd) {
        case SIOCSBANDWIDTH: /* Set bandwidth */
+               if (!capable(CAP_NET_ADMIN))
+                       return -EPERM;
                nsc_ircc_change_speed(self, irq->ifr_baudrate);
                break;
        case SIOCSMEDIABUSY: /* Set media busy */
+               if (!capable(CAP_NET_ADMIN))
+                       return -EPERM;
                irda_device_set_media_busy(self->netdev, TRUE);
                break;
        case SIOCGRECEIVING: /* Check if we are receiving right now */
index abf1685b0bb36381a2fdd5fd91c05f7e0f76c79f..b5f7752481b9d615b357169915d27f6084676299 100644 (file)
@@ -612,11 +612,15 @@ static int toshoboe_net_ioctl(struct device *dev, struct ifreq *rq, int cmd)
        
        switch (cmd) {
        case SIOCSBANDWIDTH: /* Set bandwidth */
+               if (!capable(CAP_NET_ADMIN))
+                       return -EPERM;
                /* toshoboe_setbaud(self, irq->ifr_baudrate); */
                 /* Just change speed once - inserted by Paul Bristow */
                self->new_speed = irq->ifr_baudrate;
                break;
        case SIOCSMEDIABUSY: /* Set media busy */
+               if (!capable(CAP_NET_ADMIN))
+                       return -EPERM;
                irda_device_set_media_busy(self->netdev, TRUE);
                break;
        case SIOCGRECEIVING: /* Check if we are receiving right now */
index 9ff16f1983afdf3eaf946b5141f7ada9a395c2e8..025c975cad0f2d4a1034754ac10606fbfbc5d909 100644 (file)
@@ -6,7 +6,7 @@
  * Status:        Experimental.
  * Author:        Paul VanderSpek
  * Created at:    Wed Nov  4 11:46:16 1998
- * Modified at:   Tue Jan 11 13:09:48 2000
+ * Modified at:   Fri Mar 10 11:53:53 2000
  * Modified by:   Dag Brattli <dagb@cs.uit.no>
  * 
  *     Copyright (c) 1998-2000 Dag Brattli <dagb@cs.uit.no>
@@ -1348,9 +1348,13 @@ static int w83977af_net_ioctl(struct device *dev, struct ifreq *rq, int cmd)
        
        switch (cmd) {
        case SIOCSBANDWIDTH: /* Set bandwidth */
+               if (!capable(CAP_NET_ADMIN))
+                       return -EPERM;
                w83977af_change_speed(self, irq->ifr_baudrate);
                break;
        case SIOCSMEDIABUSY: /* Set media busy */
+               if (!capable(CAP_NET_ADMIN))
+                       return -EPERM;
                irda_device_set_media_busy(self->netdev, TRUE);
                break;
        case SIOCGRECEIVING: /* Check if we are receiving right now */
index bd59802d71dc303dc510ae77e2b62270ab0ad7a9..2281e57b667c538ac753f35be76cdba5d5d3b680 100644 (file)
  *
  *  6/8/99  - Official Release 0.2.0   
  *            Merged into the kernel code 
- *  
- *  1/10/00 - Added Spinlocks for smp.
  *
+ *  3/10/00 - Enabled FDX and fixed bugs produced thereafter.
+ *           Put in smp code 
  *  To Do:
- *     IPv6 Multicast 
- *     
+ *
  *  If Problems do Occur
  *  Most problems can be rectified by either closing and opening the interface
  *  (ifconfig down and up) or rmmod and insmod'ing the driver (a bit difficult
@@ -85,7 +84,7 @@
  */
 
 static char *version = 
-"Olympic.c v0.2.1 1/10/00 - Peter De Schrijver & Mike Phillips" ; 
+"Olympic.c v0.4.0 3/10/00 - Peter De Schrijver & Mike Phillips" ; 
 
 static char *open_maj_error[]  = {"No error", "Lobe Media Test", "Physical Insertion",
                                   "Address Verification", "Neighbor Notification (Ring Poll)",
@@ -397,7 +396,7 @@ static int olympic_open(struct device *dev)
 #if OLYMPIC_NETWORK_MONITOR
                writew(ntohs(OPEN_ADAPTER_ENABLE_FDX | OPEN_ADAPTER_PASS_ADC_MAC | OPEN_ADAPTER_PASS_ATT_MAC | OPEN_ADAPTER_PASS_BEACON),init_srb+8);
 #else
-               writew(OPEN_ADAPTER_ENABLE_FDX,init_srb+8);
+               writew(ntohs(OPEN_ADAPTER_ENABLE_FDX),init_srb+8);
 #endif         
 
                if (olympic_priv->olympic_laa[0]) {
@@ -755,7 +754,7 @@ static void olympic_interrupt(int irq, void *dev_id, struct pt_regs *regs)
        if (!(sisr & SISR_MI)) /* Interrupt isn't for us */ 
                return ;
 
-       spin_lock(&olympic_priv->olympic_lock) ; 
+       spin_lock(&olympic_priv->olympic_lock);
 
        if (dev->interrupt) 
                printk(KERN_WARNING "%s: Re-entering interrupt \n",dev->name) ; 
@@ -835,7 +834,9 @@ static void olympic_interrupt(int irq, void *dev_id, struct pt_regs *regs)
        dev->interrupt = 0 ;  
 
        writel(SISR_MI,olympic_mmio+SISR_MASK_SUM);
+
        spin_unlock(&olympic_priv->olympic_lock) ; 
+
 }      
 
 static int olympic_xmit(struct sk_buff *skb, struct device *dev) 
@@ -844,13 +845,12 @@ static int olympic_xmit(struct sk_buff *skb, struct device *dev)
        __u8 *olympic_mmio=olympic_priv->olympic_mmio;
        unsigned long flags ; 
 
-       spin_lock_irqsave(&olympic_priv->olympic_lock, flags) ; 
-
        if (test_and_set_bit(0, (void*)&dev->tbusy) != 0) {
-               spin_unlock_irqrestore(&olympic_priv->olympic_lock,flags) ; 
                return 1;
        }
 
+       spin_lock_irqsave(&olympic_priv->olympic_lock, flags) ; 
+
        if(olympic_priv->free_tx_ring_entries) {
                olympic_priv->olympic_tx_ring[olympic_priv->tx_ring_free].buffer=virt_to_bus(skb->data);
                olympic_priv->olympic_tx_ring[olympic_priv->tx_ring_free].status_length=skb->len | (0x80000000);
@@ -864,13 +864,12 @@ static int olympic_xmit(struct sk_buff *skb, struct device *dev)
                writew((((readw(olympic_mmio+TXENQ_1)) & 0x8000) ^ 0x8000) | 1,olympic_mmio+TXENQ_1);
 
                dev->tbusy=0;           
-               spin_unlock_irqrestore(&olympic_priv->olympic_lock,flags) ; 
+               spin_unlock_irqrestore(&olympic_priv->olympic_lock, flags) ; 
                return 0;
        } else {
-               spin_unlock_irqrestore(&olympic_priv->olympic_lock,flags) ; 
+               spin_unlock_irqrestore(&olympic_priv->olympic_lock, flags) ; 
                return 1;
-       } 
-
+       }       
 }
        
 
@@ -951,9 +950,9 @@ static void olympic_set_rx_mode(struct device *dev)
        options = olympic_priv->olympic_copy_all_options; 
 
        if (dev->flags&IFF_PROMISC)  
-               options |= (3<<5) ; /* All LLC and MAC frames, all through the main rx channel */  
+               options |= 0x61 ; 
        else
-               options &= ~(3<<5) ; 
+               options &= ~0x61 ; 
 
        if (dev->mc_count) {  
                set_mc_list = 1 ; 
@@ -1228,7 +1227,7 @@ static void olympic_arb_cmd(struct device *dev)
        __u16 lan_status = 0, lan_status_diff  ; /* Initialize to stop compiler warning */
        __u8 fdx_prot_error ; 
        __u16 next_ptr;
-
+       int i ; 
 #if OLYMPIC_NETWORK_MONITOR
        struct trh_hdr *mac_hdr ; 
 #endif
@@ -1288,7 +1287,7 @@ static void olympic_arb_cmd(struct device *dev)
 
                /* Is the ASB free ? */         
                
-               if (!(readl(olympic_priv->olympic_mmio + SISR) & SISR_ASB_FREE)) {
+               if (readb(asb_block + 2) != 0xff) { 
                        olympic_priv->asb_queued = 1 ; 
                        writel(LISR_ASB_FREE_REQ,olympic_priv->olympic_mmio+LISR_SUM); 
                        return ;        
@@ -1307,7 +1306,7 @@ static void olympic_arb_cmd(struct device *dev)
                return ;        
                
        } else if (readb(arb_block) == ARB_LAN_CHANGE_STATUS) { /* Lan.change.status */
-               lan_status = readw(arb_block+6);
+               lan_status = ntohs(readw(arb_block+6)) ;
                fdx_prot_error = readb(arb_block+8) ; 
                
                /* Issue ARB Free */
@@ -1335,11 +1334,20 @@ static void olympic_arb_cmd(struct device *dev)
                        dev->tbusy = 1 ;
                        dev->interrupt = 1 ; 
                        dev->start = 0 ; 
+       
                        olympic_priv->srb = readw(olympic_priv->olympic_lap + LAPWWO) ; 
+                       olympic_priv->rx_status_last_received++;
+                       olympic_priv->rx_status_last_received&=OLYMPIC_RX_RING_SIZE-1;
+                       for(i=0;i<OLYMPIC_RX_RING_SIZE;i++) {
+                               dev_kfree_skb(olympic_priv->rx_ring_skb[olympic_priv->rx_status_last_received]);
+                               olympic_priv->rx_status_last_received++;
+                               olympic_priv->rx_status_last_received&=OLYMPIC_RX_RING_SIZE-1;
+                       }
+
                        free_irq(dev->irq,dev);
                        
                        printk(KERN_WARNING "%s: Adapter has been closed \n", dev->name) ; 
-       
+                       MOD_DEC_USE_COUNT ; 
                } /* If serious error */
                
                if (olympic_priv->olympic_message_level) { 
index 089a3f49abcce4e3102a56fd1feda65d051c6573..1faa955397b9d80d6702fcaca2fb5d9185190653 100644 (file)
@@ -244,7 +244,7 @@ struct olympic_private {
        __u8 *olympic_mmio;
        __u8 *olympic_lap;
 
-       spinlock_t      olympic_lock ; 
+       spinlock_t olympic_lock ; 
 
        volatile int srb_queued;    /* True if an SRB is still posted */        
        struct wait_queue *srb_wait;
@@ -282,7 +282,7 @@ struct olympic_parameters_table {
        
        __u8  phys_addr[4] ; 
        __u8  up_node_addr[6] ; 
-       __u8  up_phys_addr[6] ; 
+       __u8  up_phys_addr[4] ; 
        __u8  poll_addr[6] ; 
        __u16 reserved ; 
        __u16 acc_priority ; 
index b9ab897d99e123b9e4fad0ad3891505e0682572c..ca38ee3df509b3de2c169d1185313185ecff6a27 100644 (file)
@@ -131,9 +131,7 @@ static char *AdapterName;
 
 static int AdapterNum = 0;
 
-#ifdef MODULE
 static int rate[SKTR_MAX_ADAPTERS]     = { SPEED_16,  };
-#endif
 
 /* Use 0 for production, 1 for verification, 2 for debug, and
  * 3 for very verbose debug.
index b64f34eb7e91cf2596da8e5599885edc1cacac4a..4ffe8e136045634eda009587054c9c883b4bff37 100644 (file)
@@ -484,10 +484,10 @@ extern void scsi_unregister_module(int, void *);
 #ifdef CONFIG_SCSI_PLUTO_MODULE
 #define SD_EXTRA_DEVS 40
 #else
-#define SD_EXTRA_DEVS 16
+#define SD_EXTRA_DEVS 21
 #endif
-#define ST_EXTRA_DEVS 2
-#define SR_EXTRA_DEVS 4
+#define ST_EXTRA_DEVS 3
+#define SR_EXTRA_DEVS 8
 #define SG_EXTRA_DEVS (SD_EXTRA_DEVS + SR_EXTRA_DEVS + ST_EXTRA_DEVS)
 
 #endif
index 5ccf0c8be8b6dfdb0d7fb6d76bd345bb6d86bb76..fab3f1d9a490da19fbd55498f6c7c2bd68931cc6 100644 (file)
@@ -2,14 +2,14 @@
  *
  *                    Linux MegaRAID device driver
  *
- * Copyright 1998 American Megatrends Inc.
+ * Copyright 1999 American Megatrends Inc.
  *
  *              This program is free software; you can redistribute it and/or
  *              modify it under the terms of the GNU General Public License
  *              as published by the Free Software Foundation; either version
  *              2 of the License, or (at your option) any later version.
  *
- * Version : 1.04
+ * Version : 1.07b
  * 
  * Description: Linux device driver for AMI MegaRAID controller
  *
  *    The addtional 32 bit field for 64bit address in the newly defined
  *      mailbox64 structure is set to 0 at this point.
  *
+ * Version 1.05
+ *    Changed the queing implementation for handling SCBs and completed
+ *      commands.
+ *    Added spinlocks in the interrupt service routine to enable the dirver
+ *      function in the SMP environment.
+ *    Fixed the problem of unnecessary aborts in the abort entry point, which
+ *      also enables the driver to handle large amount of I/O requests for
+ *      long duration of time.
+ *
+ * Version 1.07
+ *    Removed the usage of uaccess.h file for kernel versions less than
+ *    2.0.36, as this file is not present in those versions.
+ *
+ * Version 1.07b
+ *    The MegaRAID 466 cards with 3.00 firmware lockup and seem to very
+ *    occasionally hang. We check such cards and report them. You can
+ *    get firmware upgrades to flash the board to 3.10 for free.
+ *
  * BUGS:
  *     Some older 2.1 kernels (eg. 2.1.90) have a bug in pci.c that
  *     fails to detect the controller as a pci device on the system.
 #define CRLFSTR "\n"
 #define IOCTL_CMD_NEW  0x81
 
-#define MEGARAID_VERSION "v1.04 (August 16, 1999)"
+#define MEGARAID_VERSION "v107 (December 22, 1999)"
+
 
 #include <linux/config.h>
 #include <linux/version.h>
@@ -145,8 +164,6 @@ MODULE_DESCRIPTION ("AMI MegaRAID driver");
 #include <linux/types.h>
 #include <linux/errno.h>
 #include <linux/kernel.h>
-#include <linux/sched.h>
-#include <linux/malloc.h>
 #include <linux/ioport.h>
 #include <linux/fcntl.h>
 #include <linux/delay.h>
@@ -169,7 +186,9 @@ MODULE_DESCRIPTION ("AMI MegaRAID driver");
 
 #include <asm/io.h>
 #include <asm/irq.h>
+#if LINUX_VERSION_CODE > 0x020024
 #include <asm/uaccess.h>
+#endif
 
 #include "sd.h"
 #include "scsi.h"
@@ -209,31 +228,6 @@ typedef struct {
 #define MAX_SERBUF 160
 #define COM_BASE 0x2f8
 
-#define ENQUEUE(obj,type,list,next) \
-{ type **node; long cpuflag; \
-  spin_lock_irqsave(&mega_lock,cpuflag);\
-  for(node=&(list); *node; node=(type **)&(*node)->##next); \
-  (*node) = obj; \
-  (*node)->##next = NULL; \
-  spin_unlock_irqrestore(&mega_lock,cpuflag);\
-}
-
-/* a non-locking version (if we already have the lock) */
-#define ENQUEUE_NL(obj,type,list,next) \
-{ type **node; \
-  for(node=&(list); *node; node=(type **)&(*node)->##next); \
-  (*node) = obj; \
-  (*node)->##next = NULL; \
-}
-
-#define DEQUEUE(obj,type,list,next) \
-{ long cpuflag; \
-  spin_lock_irqsave(&mega_lock,cpuflag);\
-  if ((obj=list) != NULL) {\
-    list = (type *)(list)->##next; \
-  } \
-  spin_unlock_irqrestore(&mega_lock,cpuflag);\
-};
 
 u32 RDINDOOR (mega_host_config * megaCfg)
 {
@@ -265,19 +259,67 @@ static int megaIssueCmd (mega_host_config * megaCfg,
                         u_char * mboxData,
                         mega_scb * scb,
                         int intr);
-static int build_sglist (mega_host_config * megaCfg, mega_scb * scb,
+static int mega_build_sglist (mega_host_config * megaCfg, mega_scb * scb,
                         u32 * buffer, u32 * length);
 
 static int mega_busyWaitMbox(mega_host_config *);
 static void mega_runpendq (mega_host_config *);
-static void mega_rundoneq (void);
+static void mega_rundoneq (mega_host_config *);
 static void mega_cmd_done (mega_host_config *, mega_scb *, int);
 static mega_scb *mega_ioctl (mega_host_config * megaCfg, Scsi_Cmnd * SCpnt);
-static inline void freeSgList(mega_host_config *megaCfg);
+static inline void mega_freeSgList(mega_host_config *megaCfg);
 static void mega_Convert8ldTo40ld(  mega_RAIDINQ  *inquiry,
                                     mega_Enquiry3 *enquiry3,
                                     megaRaidProductInfo *productInfo );
 
+
+
+
+#if LINUX_VERSION_CODE > 0x020100
+#  include <asm/spinlock.h>
+#  include <linux/smp.h>
+#  define cpuid smp_processor_id()
+#  if LINUX_VERSION_CODE < 0x020195
+#    define DRIVER_LOCK_T unsigned long cpu_flags = 0;
+#    define DRIVER_LOCK_INIT(p) \
+       spin_lock_init(&p->mega_lock);
+#    define DRIVER_LOCK(p) \
+       if(!p->cpu_lock_count[cpuid]) { \
+         spin_lock_irqsave(&p->mega_lock, cpu_flags); \
+         p->cpu_lock_count[cpuid]++; \
+       } else { \
+         p->cpu_lock_count[cpuid]++; \
+       }
+#    define DRIVER_UNLOCK(p) \
+       if(--p->cpu_lock_count[cpuid] == 0) \
+         spin_unlock_irqrestore(&p->mega_lock, cpu_flags);
+#    define IO_LOCK(p)   spin_lock_irqsave(&io_request_lock,cpu_flags);
+#    define IO_UNLOCK(p) spin_unlock_irqrestore(&io_request_lock,cpu_flags);
+#  else
+#    define DRIVER_LOCK_T
+#    define DRIVER_LOCK_INIT(p)
+#    define DRIVER_LOCK(p)
+#    define DRIVER_UNLOCK(p)
+#    define IO_LOCK_T unsigned long io_flags = 0;
+#    define IO_LOCK spin_lock_irqsave(&io_request_lock,io_flags);
+#    define IO_UNLOCK spin_unlock_irqrestore(&io_request_lock,io_flags);
+#  endif
+#else
+#  define cpuid 0
+#  define DRIVER_LOCK_T long cpu_flags;
+#  define DRIVER_LOCK_INIT(p)
+#  define DRIVER_LOCK(p) \
+       save_flags(cpu_flags); \
+       cli();
+#  define DRIVER_UNLOCK(p) \
+       restore_flags(cpu_flags);
+#  define IO_LOCK_T unsigned long io_flags = 0;
+#  define IO_LOCK(p)   DRIVER_LOCK(p)
+#  define IO_UNLOCK(p) DRIVER_UNLOCK(p)
+#  define le32_to_cpu(x) (x)
+#  define cpu_to_le32(x) (x)
+#endif
+
 /* set SERDEBUG to 1 to enable serial debugging */
 #define SERDEBUG 0
 #if SERDEBUG
@@ -297,6 +339,7 @@ static int ser_printk (const char *fmt,...);
 /*  Use "megaraid=skipXX" as LILO option to prohibit driver from scanning
     XX scsi id on each channel.  Used for Madrona motherboard, where SAF_TE
     processor id cannot be scanned */
+
 static char *megaraid;
 #if LINUX_VERSION_CODE > 0x20100
 #ifdef MODULE
@@ -314,13 +357,10 @@ static u32 maxCmdTime = 0;
 
 static mega_scb *pLastScb = NULL;
 
-/* Queue of pending/completed SCBs */
-static Scsi_Cmnd *qCompleted = NULL;
 
 #if SERDEBUG
 volatile static spinlock_t serial_lock;
 #endif
-volatile static spinlock_t mega_lock;
 
 struct proc_dir_entry proc_scsi_megaraid =
 {
@@ -386,7 +426,7 @@ static int ser_printk (const char *fmt,...)
 #define TRACE(A)
 #endif
 
-void callDone (Scsi_Cmnd * SCpnt)
+static void callDone (Scsi_Cmnd * SCpnt)
 {
   if (SCpnt->result) {
     TRACE (("*** %.08lx %.02x <%d.%d.%d> = %x\n", SCpnt->serial_number,
@@ -406,37 +446,66 @@ void callDone (Scsi_Cmnd * SCpnt)
  * Free a SCB structure
  *=======================
  */
-static void freeSCB (mega_host_config *megaCfg, mega_scb * pScb)
+static void mega_freeSCB (mega_host_config *megaCfg, mega_scb * pScb)
 {
-  mega_scb **ppScb;
+
+  mega_scb *pScbtmp;
+
+  if ((pScb == NULL) || (pScb->idx >= 0xFE)) {
+    return ;
+  }
 
   /* Unlink from pending queue */
-  for(ppScb=&megaCfg->qPending; *ppScb; ppScb=&(*ppScb)->next) {
-    if (*ppScb == pScb) {
-       *ppScb = pScb->next;
+
+  if(pScb == megaCfg->qPendingH) {
+    if(megaCfg->qPendingH == megaCfg->qPendingT ) 
+      megaCfg->qPendingH = megaCfg->qPendingT = NULL;
+    else {
+      megaCfg->qPendingH = megaCfg->qPendingH->next;
+    }
+    megaCfg->qPcnt--;
+  }
+  else {
+    for(pScbtmp=megaCfg->qPendingH; pScbtmp; pScbtmp=pScbtmp->next) {
+      if (pScbtmp->next == pScb) {
+        pScbtmp->next = pScb->next;
+        if(pScb == megaCfg->qPendingT) {
+          megaCfg->qPendingT = pScbtmp;
+        }
+        megaCfg->qPcnt--;
        break;
     }
   }
+  }
 
-  /* Link back into list */
+  /* Link back into free list */
   pScb->state = SCB_FREE;
   pScb->SCpnt = NULL;
 
-  pScb->next     = megaCfg->qFree;
-  megaCfg->qFree = pScb;
+  if(megaCfg->qFreeH == (mega_scb *) NULL ) {
+    megaCfg->qFreeH = megaCfg->qFreeT = pScb;
+  }
+  else {
+    megaCfg->qFreeT->next  = pScb;
+    megaCfg->qFreeT = pScb;
+  }
+  megaCfg->qFreeT->next = NULL;
+  megaCfg->qFcnt++;
+
 }
 
 /*===========================
  * Allocate a SCB structure
  *===========================
  */
-static mega_scb * allocateSCB (mega_host_config * megaCfg, Scsi_Cmnd * SCpnt)
+static mega_scb * mega_allocateSCB (mega_host_config * megaCfg, Scsi_Cmnd * SCpnt)
 {
   mega_scb *pScb;
 
   /* Unlink command from Free List */
-  if ((pScb = megaCfg->qFree) != NULL) {
-    megaCfg->qFree = pScb->next;
+  if ((pScb = megaCfg->qFreeH) != NULL) {
+    megaCfg->qFreeH = pScb->next;
+    megaCfg->qFcnt--;
     
     pScb->isrcount = jiffies;
     pScb->next  = NULL;
@@ -455,62 +524,72 @@ static mega_scb * allocateSCB (mega_host_config * megaCfg, Scsi_Cmnd * SCpnt)
  * Initialize SCB structures
  *================================================
  */
-static int initSCB (mega_host_config * megaCfg)
+static int mega_initSCB (mega_host_config * megaCfg)
 {
   int idx;
 
-  megaCfg->qFree = NULL;
+  megaCfg->qFreeH = NULL;
+  megaCfg->qFcnt = 0;
+#if DEBUG
+if(megaCfg->max_cmds >= MAX_COMMANDS) {
+printk("megaraid:ctlr max cmds = %x : MAX_CMDS = %x", megaCfg->max_cmds, MAX_COMMANDS);
+}
+#endif
+
   for (idx = megaCfg->max_cmds-1; idx >= 0; idx--) {
     megaCfg->scbList[idx].idx    = idx;
     megaCfg->scbList[idx].sgList = kmalloc(sizeof(mega_sglist) * MAX_SGLIST,
                                           GFP_ATOMIC | GFP_DMA);
     if (megaCfg->scbList[idx].sgList == NULL) {
       printk(KERN_WARNING "Can't allocate sglist for id %d\n",idx);
-      freeSgList(megaCfg);
+      mega_freeSgList(megaCfg);
       return -1;
     }
     
     if (idx < MAX_COMMANDS) {
       /* Link to free list */
-      freeSCB(megaCfg, &megaCfg->scbList[idx]);
+      mega_freeSCB(megaCfg, &megaCfg->scbList[idx]);
     }
   }
   return 0;
 }
 
 /* Run through the list of completed requests */
-static void mega_rundoneq ()
+static void mega_rundoneq (mega_host_config *megaCfg)
 {
   Scsi_Cmnd *SCpnt;
 
-  while (1) {
-    DEQUEUE (SCpnt, Scsi_Cmnd, qCompleted, host_scribble);
-    if (SCpnt == NULL)
-      return;
+  while ((SCpnt = megaCfg->qCompletedH) != NULL) {
+    megaCfg->qCompletedH = (Scsi_Cmnd *)SCpnt->host_scribble;
+    megaCfg->qCcnt--;
 
+    SCpnt->host_scribble = (unsigned char *) NULL ; // XC : sep 14
     /* Callback */
     callDone (SCpnt);
   }
+  megaCfg->qCompletedH = megaCfg->qCompletedT = NULL;
 }
 
 /*
-  Runs through the list of pending requests
-  Assumes that mega_lock spin_lock has been acquired.
-*/
* Runs through the list of pending requests
* Assumes that mega_lock spin_lock has been acquired.
+ */
 static void mega_runpendq(mega_host_config *megaCfg)
 {
   mega_scb *pScb;
 
   /* Issue any pending commands to the card */
-  for(pScb=megaCfg->qPending; pScb; pScb=pScb->next) {
+  for(pScb=megaCfg->qPendingH; pScb; pScb=pScb->next) {
     if (pScb->state == SCB_ACTIVE) {
-      megaIssueCmd(megaCfg, pScb->mboxData, pScb, 1);
+      if(megaIssueCmd(megaCfg, pScb->mboxData, pScb, 1))
+       return;
     }
   }
 }
 
 /* Add command to the list of completed requests */
-static void mega_cmd_done (mega_host_config * megaCfg, mega_scb * pScb, 
+static void
+mega_cmd_done (mega_host_config * megaCfg, mega_scb * pScb, 
                           int status)
 {
   int islogical;
@@ -524,7 +603,6 @@ static void mega_cmd_done (mega_host_config * megaCfg, mega_scb * pScb,
   }
 
   SCpnt = pScb->SCpnt;
-  /*freeSCB(megaCfg, pScb);*/ /*delay this to the end of this func.*/
   pthru = &pScb->pthru;
   mbox = (mega_mailbox *) &pScb->mboxData;
 
@@ -533,7 +611,7 @@ static void mega_cmd_done (mega_host_config * megaCfg, mega_scb * pScb,
        TRACE(("pScb->idx = ",pScb->idx));
        TRACE(("pScb->state = ",pScb->state));
        TRACE(("pScb->state = ",pScb->state));
-       printk("Problem...!\n");
+       printk("megaraid:Problem...!\n");
        while(1);
   }
 
@@ -588,10 +666,18 @@ else{
   /* not IOCTL_CMD_NEW SCB, freeSCB()*/
   /* For IOCTL_CMD_NEW SCB, delay freeSCB() in megaraid_queue()
    * after copy data back to user space*/
-     freeSCB(megaCfg, pScb);
+     mega_freeSCB(megaCfg, pScb);
 
   /* Add Scsi_Command to end of completed queue */
-  ENQUEUE_NL(SCpnt, Scsi_Cmnd, qCompleted, host_scribble);
+    if( megaCfg->qCompletedH == NULL ) {
+      megaCfg->qCompletedH = megaCfg->qCompletedT = SCpnt;
+    }
+    else {
+      megaCfg->qCompletedT->host_scribble = (unsigned char *) SCpnt;
+      megaCfg->qCompletedT = SCpnt;
+   }
+   megaCfg->qCompletedT->host_scribble = (unsigned char *) NULL;
+   megaCfg->qCcnt++;
 }
 
 /*-------------------------------------------------------------------
@@ -631,13 +717,11 @@ static mega_scb * mega_build_cmd (mega_host_config * megaCfg,
 
   if ( islogical ) {
        lun = (SCpnt->target * 8) + lun;
-#if 1
         if ( lun > FC_MAX_LOGICAL_DRIVES ){
             SCpnt->result = (DID_BAD_TARGET << 16);
             callDone (SCpnt);
             return NULL;
         }
-#endif
   }
   /*-----------------------------------------------------
    *
@@ -661,7 +745,7 @@ static mega_scb * mega_build_cmd (mega_host_config * megaCfg,
     case READ_CAPACITY:
     case INQUIRY:
       /* Allocate a SCB and initialize passthru */
-      if ((pScb = allocateSCB (megaCfg, SCpnt)) == NULL) {
+      if ((pScb = mega_allocateSCB (megaCfg, SCpnt)) == NULL) {
        SCpnt->result = (DID_ERROR << 16);
        callDone (SCpnt);
        return NULL;
@@ -692,7 +776,7 @@ static mega_scb * mega_build_cmd (mega_host_config * megaCfg,
     case READ_10:
     case WRITE_10:
       /* Allocate a SCB and initialize mailbox */
-      if ((pScb = allocateSCB (megaCfg, SCpnt)) == NULL) {
+      if ((pScb = mega_allocateSCB (megaCfg, SCpnt)) == NULL) {
        SCpnt->result = (DID_ERROR << 16);
        callDone (SCpnt);
        return NULL;
@@ -728,7 +812,7 @@ static mega_scb * mega_build_cmd (mega_host_config * megaCfg,
       }
 
       /* Calculate Scatter-Gather info */
-      mbox->numsgelements = build_sglist (megaCfg, pScb,
+      mbox->numsgelements = mega_build_sglist (megaCfg, pScb,
                                          (u32 *) & mbox->xferaddr,
                                          (u32 *) & seg);
 
@@ -747,7 +831,7 @@ static mega_scb * mega_build_cmd (mega_host_config * megaCfg,
    *-----------------------------------------------------*/
   else {
     /* Allocate a SCB and initialize passthru */
-    if ((pScb = allocateSCB (megaCfg, SCpnt)) == NULL) {
+    if ((pScb = mega_allocateSCB (megaCfg, SCpnt)) == NULL) {
       SCpnt->result = (DID_ERROR << 16);
       callDone (SCpnt);
       return NULL;
@@ -768,7 +852,7 @@ static mega_scb * mega_build_cmd (mega_host_config * megaCfg,
     pthru->cdblen = SCpnt->cmd_len;
     memcpy (pthru->cdb, SCpnt->cmnd, SCpnt->cmd_len);
 
-    pthru->numsgelements = build_sglist (megaCfg, pScb,
+    pthru->numsgelements = mega_build_sglist (megaCfg, pScb,
                                         (u32 *) & pthru->dataxferaddr,
                                         (u32 *) & pthru->dataxferlen);
 
@@ -795,20 +879,12 @@ static mega_scb * mega_ioctl (mega_host_config * megaCfg, Scsi_Cmnd * SCpnt)
   unsigned char *data = (unsigned char *)SCpnt->request_buffer;
   int i;
 
-  if ((pScb = allocateSCB (megaCfg, SCpnt)) == NULL) {
+  if ((pScb = mega_allocateSCB (megaCfg, SCpnt)) == NULL) {
     SCpnt->result = (DID_ERROR << 16);
     callDone (SCpnt);
     return NULL;
   }
 
-#if 0
-  printk("\nBUF: ");
-  for (i=0;i<18;i++) {
-     printk(" %x",data[i]);
-  }
-  printk("......\n");
-#endif
-
   mboxdata = (u8 *) & pScb->mboxData;
   mbox = (mega_ioctl_mbox *) & pScb->mboxData;
   mailbox = (mega_mailbox *) & pScb->mboxData;
@@ -831,7 +907,7 @@ static mega_scb * mega_ioctl (mega_host_config * megaCfg, Scsi_Cmnd * SCpnt)
     mailbox->cmd = MEGA_MBOXCMD_PASSTHRU;
     mailbox->xferaddr = virt_to_bus (pthru);
 
-    pthru->numsgelements = build_sglist (megaCfg, pScb,
+    pthru->numsgelements = mega_build_sglist (megaCfg, pScb,
                                         (u32 *) & pthru->dataxferaddr,
                                         (u32 *) & pthru->dataxferlen);
 
@@ -843,6 +919,14 @@ static mega_scb * mega_ioctl (mega_host_config * megaCfg, Scsi_Cmnd * SCpnt)
   }
   /* else normal (nonpassthru) command */
 
+#if LINUX_VERSION_CODE > 0x020024
+/*
+ * usage of the function copy from user is used in case of data more than
+ * 4KB.  This is used only with adapters which supports more than 8 logical
+ * drives.  This feature is disabled on kernels earlier or same as 2.0.36
+ * as the uaccess.h file is not available with those kernels.
+ */
+
   if (SCpnt->cmnd[0] == IOCTL_CMD_NEW) { 
             /* use external data area for large xfers  */
      /* If cmnd[0] is set to IOCTL_CMD_NEW then *
@@ -868,6 +952,7 @@ static mega_scb * mega_ioctl (mega_host_config * megaCfg, Scsi_Cmnd * SCpnt)
       copy_from_user(kern_area,user_area,xfer_size);
       pScb->kern_area = kern_area;
   }
+#endif
 
   mbox->cmd = data[0];
   mbox->channel = data[1];
@@ -890,7 +975,7 @@ static mega_scb * mega_ioctl (mega_host_config * megaCfg, Scsi_Cmnd * SCpnt)
   } 
   else {
 
-      mbox->numsgelements = build_sglist (megaCfg, pScb,
+      mbox->numsgelements = mega_build_sglist (megaCfg, pScb,
                                      (u32 *) & mbox->xferaddr,
                                      (u32 *) & seg);
 
@@ -918,32 +1003,36 @@ static void showMbox(mega_scb *pScb)
 }
 #endif
 
+#if DEBUG
+static unsigned int cum_time = 0;
+static unsigned int cum_time_cnt = 0;
+#endif
+
 /*--------------------------------------------------------------------
  * Interrupt service routine
  *--------------------------------------------------------------------*/
 static void megaraid_isr (int irq, void *devp, struct pt_regs *regs)
 {
+#if LINUX_VERSION_CODE >= 0x20100
+  IO_LOCK_T
+#endif
   mega_host_config    *megaCfg;
   u_char byte, idx, sIdx, tmpBox[MAILBOX_SIZE];
-  u32 dword;
+  u32 dword=0;
   mega_mailbox *mbox;
   mega_scb *pScb;
-  long flags;
-  int qCnt, qStatus;
+  u_char qCnt, qStatus;
+  u_char            completed[MAX_FIRMWARE_STATUS];
+  Scsi_Cmnd *SCpnt;
 
   megaCfg = (mega_host_config *) devp;
   mbox = (mega_mailbox *)tmpBox;
 
-#if LINUX_VERSION_CODE >= 0x20100
-  spin_lock_irqsave (&io_request_lock, flags);
-#endif
-
-  while (megaCfg->host->irq == irq) {
-
-    spin_lock_irqsave (&mega_lock, flags);
+  if (megaCfg->host->irq == irq) {
 
     if (megaCfg->flag & IN_ISR) {
       TRACE (("ISR called reentrantly!!\n"));
+      printk ("ISR called reentrantly!!\n");
     }
 
     megaCfg->flag |= IN_ISR;
@@ -952,48 +1041,67 @@ static void megaraid_isr (int irq, void *devp, struct pt_regs *regs)
        printk(KERN_WARNING "Error: mailbox busy in isr!\n");
     }
 
-
     /* Check if a valid interrupt is pending */
     if (megaCfg->flag & BOARD_QUARTZ) {
       dword = RDOUTDOOR (megaCfg);
       if (dword != 0x10001234) {
        /* Spurious interrupt */
        megaCfg->flag &= ~IN_ISR;
-       spin_unlock_irqrestore (&mega_lock, flags);
-       break;
+       return;
       }
-      WROUTDOOR (megaCfg, dword);
-
-      /* Copy to temp location */
-      memcpy(tmpBox, (mega_mailbox *)megaCfg->mbox, MAILBOX_SIZE);
-
-      /* Acknowledge interrupt */
-      WRINDOOR (megaCfg, virt_to_bus (megaCfg->mbox) | 0x2);
-      while (RDINDOOR (megaCfg) & 0x02);
     }
     else {
       byte = READ_PORT (megaCfg->host->io_port, INTR_PORT);
       if ((byte & VALID_INTR_BYTE) == 0) {
        /* Spurious interrupt */
        megaCfg->flag &= ~IN_ISR;
-       spin_unlock_irqrestore (&mega_lock, flags);
-       break;
+       return;
       }
       WRITE_PORT (megaCfg->host->io_port, INTR_PORT, byte);
+    }
 
-      /* Copy to temp location */
-      memcpy(tmpBox, (mega_mailbox *)megaCfg->mbox, MAILBOX_SIZE);
+    for(idx=0;idx<MAX_FIRMWARE_STATUS;idx++ ) completed[idx] = 0;
 
+#if LINUX_VERSION_CODE >= 0x20100
+    IO_LOCK;
+#endif
+
+    qCnt = 0xff;
+    while ((qCnt = megaCfg->mbox->numstatus) == 0xFF) 
+      ;
+
+    qStatus = 0xff;
+    while ((qStatus = megaCfg->mbox->status) == 0xFF)
+      ;
+
+    /* Get list of completed requests */
+    for (idx = 0; idx<qCnt; idx++) {
+      while ((sIdx = megaCfg->mbox->completed[idx]) == 0xFF) {
+       printk("p");
+      }
+      completed[idx] = sIdx;
+      sIdx = 0xFF;
+    }
+
+    if (megaCfg->flag & BOARD_QUARTZ) {
+      WROUTDOOR (megaCfg, dword);
       /* Acknowledge interrupt */
+      WRINDOOR (megaCfg, virt_to_bus (megaCfg->mbox) | 0x2);
+      while (RDINDOOR (megaCfg) & 0x02);
+    }
+    else {
       CLEAR_INTR (megaCfg->host->io_port);
     }
 
-    qCnt = mbox->numstatus;
-    qStatus = mbox->status;
+#if DEBUG
+    if(qCnt >= MAX_FIRMWARE_STATUS) {
+      printk("megaraid_isr: cmplt=%d ", qCnt);
+    }
+#endif
 
     for (idx = 0; idx < qCnt; idx++) {
-      sIdx = mbox->completed[idx];
-      if (sIdx > 0) {
+      sIdx = completed[idx];
+      if ((sIdx > 0) && (sIdx <= MAX_COMMANDS)) {
        pScb = &megaCfg->scbList[sIdx - 1];
 
        /* ASSERT(pScb->state == SCB_ISSUED); */
@@ -1001,12 +1109,30 @@ static void megaraid_isr (int irq, void *devp, struct pt_regs *regs)
 #if DEBUG
        if (((jiffies) - pScb->isrcount) > maxCmdTime) {
          maxCmdTime = (jiffies) - pScb->isrcount;
-         printk("cmd time = %u\n", maxCmdTime);
+         printk("megaraid_isr : cmd time = %u\n", maxCmdTime);
        }
 #endif
-
+/*
+ * Assuming that the scsi command, for which an abort request was received
+ * earlier has completed.
+ */
        if (pScb->state == SCB_ABORTED) {
-         printk("Received aborted SCB! %u\n", (int)((jiffies)-pScb->isrcount));
+          SCpnt = pScb->SCpnt;
+       }
+       if (pScb->state == SCB_RESET) {
+          SCpnt = pScb->SCpnt;
+         mega_freeSCB (megaCfg, pScb);
+         SCpnt->result = (DID_RESET << 16) ;
+          if( megaCfg->qCompletedH == NULL ) {
+            megaCfg->qCompletedH = megaCfg->qCompletedT = SCpnt;
+          }
+          else {
+            megaCfg->qCompletedT->host_scribble = (unsigned char *) SCpnt;
+            megaCfg->qCompletedT = SCpnt;
+          }
+          megaCfg->qCompletedT->host_scribble = (unsigned char *) NULL;
+          megaCfg->qCcnt++;
+          continue;
        }
 
         if (*(pScb->SCpnt->cmnd)==IOCTL_CMD_NEW) 
@@ -1017,24 +1143,23 @@ static void megaraid_isr (int irq, void *devp, struct pt_regs *regs)
        mega_cmd_done(megaCfg, pScb, qStatus);
 
       }
-
+      else {
+        printk("megaraid: wrong cmd id completed from firmware:id=%x\n",sIdx);
+       for(;;);
+      }
     }
-    spin_unlock_irqrestore (&mega_lock, flags);
-
-    megaCfg->flag &= ~IN_ISR;
 
-    mega_rundoneq();
+    mega_rundoneq(megaCfg);
 
+    megaCfg->flag &= ~IN_ISR;
     /* Loop through any pending requests */
-    spin_lock_irqsave(&mega_lock, flags);
     mega_runpendq(megaCfg);
-    spin_unlock_irqrestore(&mega_lock,flags);
+#if LINUX_VERSION_CODE >= 0x20100
+    IO_UNLOCK;
+#endif
 
   }
 
-#if LINUX_VERSION_CODE >= 0x20100
-  spin_unlock_irqrestore (&io_request_lock, flags);
-#endif
 }
 
 /*==================================================*/
@@ -1078,7 +1203,6 @@ static int megaIssueCmd (mega_host_config * megaCfg,
   mega_mailbox *mbox = (mega_mailbox *) megaCfg->mbox;
   u_char byte;
   u32 cmdDone;
-  Scsi_Cmnd *SCpnt;
   u32 phys_mbox;
   u8 retval=-1;
 
@@ -1087,18 +1211,12 @@ static int megaIssueCmd (mega_host_config * megaCfg,
 
   phys_mbox = virt_to_bus (megaCfg->mbox);
 
-#if 0
-  if (intr && mbox->busy) {
-    return 0;
-  }
-#endif
-
 #if DEBUG
   showMbox(pScb);
 #endif
 
   /* Wait until mailbox is free */
-  while (mega_busyWaitMbox (megaCfg)) {
+  if (mega_busyWaitMbox (megaCfg)) {
     printk("Blocked mailbox......!!\n");
     udelay(1000);
 
@@ -1108,14 +1226,10 @@ static int megaIssueCmd (mega_host_config * megaCfg,
     
     /* Abort command */
     if (pScb == NULL) {
-       printk("NULL pScb in megaIssue\n");
        TRACE(("NULL pScb in megaIssue\n"));
+       printk("NULL pScb in megaIssue\n");
     }
-    SCpnt = pScb->SCpnt;
-    freeSCB(megaCfg, pScb);
-
-    SCpnt->result = (DID_ABORT << 16);
-    callDone(SCpnt);
+    mega_cmd_done (megaCfg, pScb, 0x08);
     return -1;
   }
 
@@ -1154,7 +1268,6 @@ static int megaIssueCmd (mega_host_config * megaCfg,
 
       if (pScb) {
        mega_cmd_done (megaCfg, pScb, mbox->status);
-       mega_rundoneq ();
       }
 
       WRINDOOR (megaCfg, phys_mbox | 0x2);
@@ -1168,26 +1281,25 @@ static int megaIssueCmd (mega_host_config * megaCfg,
       while (!((byte = READ_PORT (megaCfg->host->io_port, INTR_PORT)) & INTR_VALID));
       WRITE_PORT (megaCfg->host->io_port, INTR_PORT, byte);
 
-
       ENABLE_INTR (megaCfg->host->io_port);
       CLEAR_INTR (megaCfg->host->io_port);
 
       if (pScb) {
        mega_cmd_done (megaCfg, pScb, mbox->status);
-       mega_rundoneq ();
       }
       else {
        TRACE (("Error: NULL pScb!\n"));
       }
-
     }
     enable_irq(megaCfg->host->irq);
     retval=mbox->status;
   }
+#if DEBUG
   while (mega_busyWaitMbox (megaCfg)) {
     printk("Blocked mailbox on exit......!\n");
     udelay(1000);
   }
+#endif
 
   return retval;
 }
@@ -1195,7 +1307,7 @@ static int megaIssueCmd (mega_host_config * megaCfg,
 /*-------------------------------------------------------------------
  * Copies data to SGLIST
  *-------------------------------------------------------------------*/
-static int build_sglist (mega_host_config * megaCfg, mega_scb * scb,
+static int mega_build_sglist (mega_host_config * megaCfg, mega_scb * scb,
              u32 * buffer, u32 * length)
 {
   struct scatterlist *sgList;
@@ -1254,9 +1366,7 @@ static int mega_register_mailbox (mega_host_config * megaCfg, u32 paddr)
   paddr = (paddr + 4 + 16) & 0xfffffff0;
 
   /* Register mailbox area with the firmware */
-  if (megaCfg->flag & BOARD_QUARTZ) {
-  }
-  else {
+  if (!(megaCfg->flag & BOARD_QUARTZ)) {
     WRITE_PORT (megaCfg->host->io_port, MBOX_PORT0, paddr & 0xFF);
     WRITE_PORT (megaCfg->host->io_port, MBOX_PORT1, (paddr >> 8) & 0xFF);
     WRITE_PORT (megaCfg->host->io_port, MBOX_PORT2, (paddr >> 16) & 0xFF);
@@ -1314,8 +1424,6 @@ static int mega_i_query_adapter (mega_host_config * megaCfg)
   u32 paddr;
   u8 retval;
 
-  spin_lock_init (&mega_lock);
-
   /* Initialize adapter inquiry mailbox*/
   paddr = virt_to_bus (megaCfg->mega_buffer);
   mbox = (mega_mailbox *) mboxData;
@@ -1375,28 +1483,17 @@ static int mega_i_query_adapter (mega_host_config * megaCfg)
     /*(megaCfg->flag & BOARD_40LD)?FC_MAX_TARGETS_PER_CHANNEL:MAX_TARGET+1;*/ 
   megaCfg->host->max_lun =              /* max lun */
     (megaCfg->flag & BOARD_40LD) ? FC_MAX_LOGICAL_DRIVES : MAX_LOGICAL_DRIVES; 
+  megaCfg->host->cmd_per_lun = MAX_CMD_PER_LUN;
 
   megaCfg->numldrv = enquiry3Pnt->numLDrv;
   megaCfg->max_cmds = megaCfg->productInfo.MaxConcCmds;
+  if(megaCfg->max_cmds > MAX_COMMANDS) megaCfg->max_cmds = MAX_COMMANDS - 1;
 
-#if 0 
-  int i;
-  printk (KERN_DEBUG "---- Logical drive info from enquiry3 struct----\n");
-  for (i = 0; i < megaCfg->numldrv; i++) {
-    printk ("%d: size: %d prop: %x state: %x\n", i,
-           enquiry3Pnt->lDrvSize[i],
-           enquiry3Pnt->lDrvProp[i],
-           enquiry3Pnt->lDrvState[i]);
-  }
+  megaCfg->host->can_queue   = megaCfg->max_cmds;
 
-  printk (KERN_DEBUG "---- Physical drive info ----\n");
-  for (i = 0; i < FC_MAX_PHYSICAL_DEVICES; i++) {
-    if (i && !(i % 8))
-      printk ("\n");
-    printk ("%d: %x   ", i, enquiry3Pnt->pDrvState[i]);
+  if (megaCfg->host->can_queue >= MAX_COMMANDS) {
+    megaCfg->host->can_queue = MAX_COMMANDS-1;
   }
-  printk ("\n");
-#endif
 
 #ifdef HP                      /* use HP firmware and bios version encoding */
   sprintf (megaCfg->fwVer, "%c%d%d.%d%d",
@@ -1443,7 +1540,7 @@ int megaraid_proc_info (char *buffer, char **start, off_t offset,
   return 0;
 }
 
-int findCard (Scsi_Host_Template * pHostTmpl,
+int mega_findCard (Scsi_Host_Template * pHostTmpl,
          u16 pciVendor, u16 pciDev,
          long flag)
 {
@@ -1456,10 +1553,6 @@ int findCard (Scsi_Host_Template * pHostTmpl,
 
 #if LINUX_VERSION_CODE < 0x20100
   while (!pcibios_find_device (pciVendor, pciDev, pciIdx, &pciBus, &pciDevFun)) {
-
-#if 0
-  } /* keep auto-indenters happy */
-#endif
 #else
   
   struct pci_dev *pdev = pci_devices;
@@ -1470,10 +1563,14 @@ int findCard (Scsi_Host_Template * pHostTmpl,
 #endif
     if ((flag & BOARD_QUARTZ) && (skip_id == -1)) {
       u16 magic;
+#if LINUX_VERSION_CODE < 0x20100
       pcibios_read_config_word (pciBus, pciDevFun,
                                PCI_CONF_AMISIG,
                                &magic);
-      if (magic != AMI_SIGNATURE) {
+#else
+      pci_read_config_word (pdev, PCI_CONF_AMISIG, &magic);
+#endif
+      if ((magic != AMI_SIGNATURE) && (magic != AMI_SIGNATURE_471) ){
         pciIdx++;
        continue;               /* not an AMI board */
       }
@@ -1518,8 +1615,15 @@ int findCard (Scsi_Host_Template * pHostTmpl,
            host->host_no, (u_int) megaBase, megaIrq);
 
     /* Copy resource info into structure */
-    megaCfg->qPending = NULL;
-    megaCfg->qFree    = NULL;
+    megaCfg->qCompletedH = NULL;
+    megaCfg->qCompletedT = NULL;
+    megaCfg->qPendingH = NULL;
+    megaCfg->qPendingT = NULL;
+    megaCfg->qFreeH    = NULL;
+    megaCfg->qFreeT    = NULL;
+    megaCfg->qFcnt = 0;
+    megaCfg->qPcnt = 0;
+    megaCfg->qCcnt = 0;
     megaCfg->flag = flag;
     megaCfg->host = host;
     megaCfg->base = megaBase;
@@ -1549,10 +1653,43 @@ int findCard (Scsi_Host_Template * pHostTmpl,
 
     mega_register_mailbox (megaCfg, virt_to_bus ((void *) &megaCfg->mailbox64));
     mega_i_query_adapter (megaCfg);
-    
+   
+    if (flag == BOARD_QUARTZ) {
+      /* Check to see if this is a Dell PERC RAID controller model 466 */
+      u16 subsysid, subsysvid;
+#if LINUX_VERSION_CODE < 0x20100
+      pcibios_read_config_word (pciBus, pciDevFun,
+                               PCI_SUBSYSTEM_VENDOR_ID,
+                               &subsysvid);
+      pcibios_read_config_word (pciBus, pciDevFun,
+                               PCI_SUBSYSTEM_ID,
+                               &subsysid);
+#else
+      pci_read_config_word (pdev, PCI_SUBSYSTEM_VENDOR_ID, &subsysvid);
+      pci_read_config_word (pdev, PCI_SUBSYSTEM_ID, &subsysid);
+#endif
+      if ( (subsysid == 0x1111) && (subsysvid == 0x1111) &&
+           (!strcmp(megaCfg->fwVer,"3.00") || !strcmp(megaCfg->fwVer,"3.01"))) {
+       printk(KERN_WARNING
+"megaraid: Your card is a Dell PERC 2/SC RAID controller with firmware\n"
+"megaraid: 3.00 or 3.01.  This driver is known to have corruption issues\n"
+"megaraid: with those firmware versions on this specific card.  In order\n"
+"megaraid: to protect your data, please upgrade your firmware to version\n"
+"megaraid: 3.10 or later, available from the Dell Technical Support web\n"
+"megaraid: site at\n"
+"http://support.dell.com/us/en/filelib/download/index.asp?fileid=2489\n");
+       megaraid_release (host);
+#ifdef MODULE  
+       continue;
+#else
+       while(1) schedule_timeout(1 * HZ);
+#endif 
+      }
+    }
+
     /* Initialize SCBs */
-    if (initSCB (megaCfg)) {
-      scsi_unregister (host);
+    if (mega_initSCB (megaCfg)) {
+      megaraid_release (host);
       continue;
     }
 
@@ -1589,9 +1726,9 @@ int megaraid_detect (Scsi_Host_Template * pHostTmpl)
 
   printk ("megaraid: " MEGARAID_VERSION CRLFSTR);
 
-  count += findCard (pHostTmpl, 0x101E, 0x9010, 0);
-  count += findCard (pHostTmpl, 0x101E, 0x9060, 0);
-  count += findCard (pHostTmpl, 0x8086, 0x1960, BOARD_QUARTZ);
+  count += mega_findCard (pHostTmpl, 0x101E, 0x9010, 0);
+  count += mega_findCard (pHostTmpl, 0x101E, 0x9060, 0);
+  count += mega_findCard (pHostTmpl, 0x8086, 0x1960, BOARD_QUARTZ);
 
   return count;
 }
@@ -1626,13 +1763,13 @@ int megaraid_release (struct Scsi_Host *pSHost)
     release_region (megaCfg->host->io_port, 16);
   }
 
-  freeSgList(megaCfg);
+  mega_freeSgList(megaCfg);
   scsi_unregister (pSHost);
 
   return 0;
 }
 
-static inline void freeSgList(mega_host_config *megaCfg)
+static inline void mega_freeSgList(mega_host_config *megaCfg)
 {
   int i;
 
@@ -1678,13 +1815,12 @@ const char * megaraid_info (struct Scsi_Host *pSHost)
  *-----------------------------------------------------------------*/
 int megaraid_queue (Scsi_Cmnd * SCpnt, void (*pktComp) (Scsi_Cmnd *))
 {
+  DRIVER_LOCK_T
   mega_host_config *megaCfg;
   mega_scb *pScb;
-  long flags;
-
-  spin_lock_irqsave(&mega_lock,flags);
 
   megaCfg = (mega_host_config *) SCpnt->host->hostdata;
+  DRIVER_LOCK(megaCfg);
 
   if (!(megaCfg->flag & (1L << SCpnt->channel))) {
     if (SCpnt->channel < SCpnt->host->max_channel)
@@ -1702,33 +1838,56 @@ int megaraid_queue (Scsi_Cmnd * SCpnt, void (*pktComp) (Scsi_Cmnd *))
   /* If driver in abort or reset.. cancel this command */
   if (megaCfg->flag & IN_ABORT) {
     SCpnt->result = (DID_ABORT << 16);
-    ENQUEUE_NL(SCpnt, Scsi_Cmnd, qCompleted, host_scribble);
+    /* Add Scsi_Command to end of completed queue */
+    if( megaCfg->qCompletedH == NULL ) {
+      megaCfg->qCompletedH = megaCfg->qCompletedT = SCpnt;
+    }
+    else {
+      megaCfg->qCompletedT->host_scribble = (unsigned char *) SCpnt;
+      megaCfg->qCompletedT = SCpnt;
+    }
+    megaCfg->qCompletedT->host_scribble = (unsigned char *) NULL;
+    megaCfg->qCcnt++;
 
-    spin_unlock_irqrestore(&mega_lock,flags);
+    DRIVER_UNLOCK(megaCfg);
     return 0;
   }
   else if (megaCfg->flag & IN_RESET) {
     SCpnt->result = (DID_RESET << 16);
-    ENQUEUE_NL(SCpnt, Scsi_Cmnd, qCompleted, host_scribble);
+    /* Add Scsi_Command to end of completed queue */
+    if( megaCfg->qCompletedH == NULL ) {
+      megaCfg->qCompletedH = megaCfg->qCompletedT = SCpnt;
+    }
+    else {
+      megaCfg->qCompletedT->host_scribble = (unsigned char *) SCpnt;
+      megaCfg->qCompletedT = SCpnt;
+    }
+    megaCfg->qCompletedT->host_scribble = (unsigned char *) NULL;
+    megaCfg->qCcnt++;
 
-    spin_unlock_irqrestore(&mega_lock,flags);
+    DRIVER_UNLOCK(megaCfg);
     return 0;
   }
 
+  megaCfg->flag |= IN_QUEUE;
   /* Allocate and build a SCB request */
   if ((pScb = mega_build_cmd (megaCfg, SCpnt)) != NULL) {
               /*build SCpnt for IOCTL_CMD_NEW cmd in mega_ioctl()*/
     /* Add SCB to the head of the pending queue */
-    ENQUEUE_NL (pScb, mega_scb, megaCfg->qPending, next);
-
-    /* Issue any pending command to the card if not in ISR */
-    if (!(megaCfg->flag & IN_ISR)) {
-      mega_runpendq(megaCfg);
+    /* Add SCB to the head of the pending queue */
+    if( megaCfg->qPendingH == NULL ) {
+      megaCfg->qPendingH = megaCfg->qPendingT = pScb;
     }
     else {
-      printk("IRQ pend...\n");
+      megaCfg->qPendingT->next = pScb;
+      megaCfg->qPendingT = pScb;
     }
+    megaCfg->qPendingT->next = NULL;
+    megaCfg->qPcnt++;
 
+      mega_runpendq(megaCfg);
+
+#if LINUX_VERSION_CODE > 0x020024
     if ( SCpnt->cmnd[0]==IOCTL_CMD_NEW )
     {  /* user data from external user buffer */
           char *user_area;
@@ -1744,12 +1903,13 @@ int megaraid_queue (Scsi_Cmnd * SCpnt, void (*pktComp) (Scsi_Cmnd *))
 
           kfree(pScb->kern_area);
 
-          freeSCB(megaCfg, pScb);
+          mega_freeSCB(megaCfg, pScb);
     }
-
+#endif
   }
 
-  spin_unlock_irqrestore(&mega_lock,flags);
+  megaCfg->flag &= ~IN_QUEUE;
+  DRIVER_UNLOCK(megaCfg);
 
   return 0;
 }
@@ -1787,78 +1947,92 @@ int megaraid_command (Scsi_Cmnd * SCpnt)
 /*---------------------------------------------------------------------
  * Abort a previous SCSI request
  *---------------------------------------------------------------------*/
-int megaraid_abort (Scsi_Cmnd * SCpnt)
+int
+megaraid_abort (Scsi_Cmnd * SCpnt)
 {
   mega_host_config *megaCfg;
-  int   rc, idx;
-  long  flags;
+  int   rc; //, idx;
   mega_scb *pScb;
 
-  rc = SCSI_ABORT_SUCCESS;
-
-  spin_lock_irqsave (&mega_lock, flags);
+  rc = SCSI_ABORT_NOT_RUNNING;
 
   megaCfg = (mega_host_config *) SCpnt->host->hostdata;
 
   megaCfg->flag |= IN_ABORT;
 
-  for(pScb=megaCfg->qPending; pScb; pScb=pScb->next) {
+  for(pScb=megaCfg->qPendingH; pScb; pScb=pScb->next) {
     if (pScb->SCpnt == SCpnt) {
       /* Found an aborting command */
 #if DEBUG
       showMbox(pScb);
 #endif
 
-      printk("Abort: %d %u\n", 
-            SCpnt->timeout_per_command,
-            (uint)((jiffies) - pScb->isrcount));
+/*
+ * If the command is queued to be issued to the firmware, abort the scsi cmd,
+ * If the command is already aborted in a previous call to the _abort entry
+ *  point, return SCSI_ABORT_SNOOZE, suggesting a reset.
+ * If the command is issued to the firmware, which might complete after
+ *  some time, we will mark the scb as aborted, and return to the mid layer, 
+ *  that abort could not be done.
+ *  In the ISR, when this command actually completes, we will perform a normal
+ *  completion.
+ *
+ * Oct 27, 1999
+ */
 
       switch(pScb->state) {
       case SCB_ABORTED: /* Already aborted */
        rc = SCSI_ABORT_SNOOZE;
        break;
       case SCB_ISSUED: /* Waiting on ISR result */
-       rc = SCSI_ABORT_PENDING;
+       rc = SCSI_ABORT_NOT_RUNNING;
        pScb->state = SCB_ABORTED;
        break;
+      case SCB_ACTIVE: /* still on the pending queue */
+       mega_freeSCB (megaCfg, pScb);
+       SCpnt->result = (DID_ABORT << 16) ;
+        if( megaCfg->qCompletedH == NULL ) {
+          megaCfg->qCompletedH = megaCfg->qCompletedT = SCpnt;
+        }
+        else {
+          megaCfg->qCompletedT->host_scribble = (unsigned char *) SCpnt;
+          megaCfg->qCompletedT = SCpnt;
+        }
+        megaCfg->qCompletedT->host_scribble = (unsigned char *) NULL;
+        megaCfg->qCcnt++;
+       rc = SCSI_ABORT_SUCCESS;
+        break;
+      default:
+        printk("megaraid_abort: unknown command state!!\n");
+        rc = SCSI_ABORT_NOT_RUNNING;
+       break;
       }
+      break;
     }
   }
 
-#if 0
-  TRACE (("ABORT!!! %.08lx %.02x <%d.%d.%d>\n",
-         SCpnt->serial_number, SCpnt->cmnd[0], SCpnt->channel, SCpnt->target,
-         SCpnt->lun));
-  for(pScb=megaCfg->qPending; pScb; pScb=pScb->next) {
-    if (pScb->SCpnt == SCpnt) { 
-      ser_printk("** %d<%x>  %c\n", pScb->SCpnt->pid, pScb->idx+1,
-                pScb->state == SCB_ACTIVE ? 'A' : 'I');
+  megaCfg->flag &= ~IN_ABORT;
+
 #if DEBUG
-      showMbox(pScb);
-#endif
-    }
-  }
+if(megaCfg->flag & IN_QUEUE)  printk("ma:flag is in queue\n");
+if(megaCfg->qCompletedH == NULL) printk("ma:qchead == null\n");
 #endif
-
-  /*
-   * Walk list of SCBs for any that are still outstanding
-   */
-  for (idx = 0; idx < megaCfg->max_cmds; idx++) {
-    if (megaCfg->scbList[idx].state != SCB_FREE) {
-      if (megaCfg->scbList[idx].SCpnt == SCpnt) {
-       freeSCB (megaCfg, &megaCfg->scbList[idx]);
-
-       SCpnt->result = (DID_ABORT << 16) | (SUGGEST_RETRY << 24);
-       ENQUEUE_NL(SCpnt, Scsi_Cmnd, qCompleted, host_scribble);
-      }
-    }
-  }
   
-  megaCfg->flag &= ~IN_ABORT;
-
-  spin_unlock_irqrestore (&mega_lock, flags);
-
-  mega_rundoneq();
+/*
+ * This is required here to complete any completed requests to be communicated
+ * over to the mid layer.
+ * Calling just mega_rundoneq() did not work.
+ */
+if(megaCfg->qCompletedH) {
+  SCpnt = megaCfg->qCompletedH;
+  megaCfg->qCompletedH = (Scsi_Cmnd *)SCpnt->host_scribble;
+  megaCfg->qCcnt--;
+
+  SCpnt->host_scribble = (unsigned char *) NULL ;
+  /* Callback */
+  callDone (SCpnt);
+}
+  mega_rundoneq(megaCfg);
 
   return rc;
 }
@@ -1870,14 +2044,18 @@ int megaraid_reset (Scsi_Cmnd * SCpnt, unsigned int rstflags)
 {
   mega_host_config *megaCfg;
   int idx;
-  long flags;
-
-  spin_lock_irqsave (&mega_lock, flags);
+  int rc;
+  mega_scb *pScb;
 
+  rc = SCSI_RESET_NOT_RUNNING;
   megaCfg = (mega_host_config *) SCpnt->host->hostdata;
 
   megaCfg->flag |= IN_RESET;
 
+  printk ("megaraid_RESET: %.08lx cmd=%.02x <c=%d.t=%d.l=%d>, flag = %x\n",
+       SCpnt->serial_number, SCpnt->cmnd[0], SCpnt->channel, SCpnt->target,
+         SCpnt->lun, rstflags);
+
   TRACE (("RESET: %.08lx %.02x <%d.%d.%d>\n",
        SCpnt->serial_number, SCpnt->cmnd[0], SCpnt->channel, SCpnt->target,
          SCpnt->lun));
@@ -1888,20 +2066,18 @@ int megaraid_reset (Scsi_Cmnd * SCpnt, unsigned int rstflags)
   for (idx = 0; idx < megaCfg->max_cmds; idx++) {
     if (megaCfg->scbList[idx].state != SCB_FREE) {
       SCpnt = megaCfg->scbList[idx].SCpnt;
+      pScb = &megaCfg->scbList[idx];
       if (SCpnt != NULL) {
-       freeSCB (megaCfg, &megaCfg->scbList[idx]);
-       SCpnt->result = (DID_RESET << 16) | (SUGGEST_RETRY << 24);
-       ENQUEUE_NL(SCpnt, Scsi_Cmnd, qCompleted, host_scribble);
+        pScb->state = SCB_RESET;
+        break;
       }
     }
   }
 
   megaCfg->flag &= ~IN_RESET;
 
-  spin_unlock_irqrestore (&mega_lock, flags);
-
-  mega_rundoneq();
-  return SCSI_RESET_PUNT;
+  mega_rundoneq(megaCfg);
+  return rc;
 }
 
 /*-------------------------------------------------------------
@@ -1947,4 +2123,3 @@ Scsi_Host_Template driver_template = MEGARAID;
 
 #include "scsi_module.c"
 #endif
-
index 83fe02785b4719e92cd2f4d7f051ac69c4bb27ef..5fd1744d8c9fe67be0a40761e748b8b9d4750909 100644 (file)
@@ -8,6 +8,7 @@
 #define IN_ISR                  0x80000000L
 #define IN_ABORT                0x40000000L
 #define IN_RESET                0x20000000L
+#define IN_QUEUE                0x10000000L
 #define BOARD_QUARTZ            0x08000000L
 #define BOARD_40LD              0x04000000L
 
 
 #define MEGA_CMD_TIMEOUT        10
 
-#define MAX_SGLIST              17
-#define MAX_COMMANDS            250
+/* Feel free to fiddle with these.. max values are:
+   SGLIST     0..26
+   COMMANDS   0..253
+   CMDPERLUN  0..63
+*/
+#define MAX_SGLIST              0x1A
+#define MAX_COMMANDS            127
 #define MAX_CMD_PER_LUN         63
+#define MAX_FIRMWARE_STATUS     46
 
 #define MAX_LOGICAL_DRIVES      8
 #define MAX_CHANNEL             5
 #define PCI_CONF_IRQ_OFFSET        0x3c
 #define PCI_CONF_AMISIG            0xa0
 #define AMI_SIGNATURE              0x3344
+#define AMI_SIGNATURE_471          0xCCCC
 
 #if LINUX_VERSION_CODE < 0x20100
 #define MEGARAID \
@@ -505,7 +513,7 @@ typedef struct mega_passthru {
     u32 dataxferlen;
 } mega_passthru;
 
-typedef struct _mega_mailbox {
+struct _mega_mailbox {
     /* 0x0 */ u8 cmd;
     /* 0x1 */ u8 cmdid;
     /* 0x2 */ u16 numsectors;
@@ -520,8 +528,9 @@ typedef struct _mega_mailbox {
     /* 0x12 */ u8 completed[46];
     u8 mraid_poll;
     u8 mraid_ack;
-    u8 pad[16];
-} mega_mailbox;
+    u8 pad[16]; /* for alignment purposes */
+}__attribute__((packed));
+typedef struct _mega_mailbox mega_mailbox;
 
 typedef struct {
     u32 xferSegment;      /* for 64-bit controllers */
@@ -575,8 +584,16 @@ typedef struct _mega_host_config {
     u32 flag;
     u32 base;
  
-    mega_scb *qFree;
-    mega_scb *qPending;
+    mega_scb *qFreeH;
+    mega_scb *qFreeT;
+    mega_scb *qPendingH;
+    mega_scb *qPendingT;
+    
+    Scsi_Cmnd *qCompletedH;
+    Scsi_Cmnd *qCompletedT;
+    u32 qFcnt;
+    u32 qPcnt;
+    u32 qCcnt;
 
     u32 nReads[FC_MAX_LOGICAL_DRIVES];
     u32 nWrites[FC_MAX_LOGICAL_DRIVES];
index e6d093c2f32da60d59e53d6d570de8247fa7bd60..fc01ed729a04d01ac17dd3d5a30c538d8e1ce15f 100644 (file)
@@ -270,6 +270,7 @@ static struct dev_info device_list[] =
                                                 * SCSI code to reset bus.*/
 {"QUANTUM","LPS525S","3110", BLIST_NOLUN},      /* Locks sometimes if polled for lun != 0 */
 {"QUANTUM","PD1225S","3110", BLIST_NOLUN},      /* Locks sometimes if polled for lun != 0 */
+{"QUANTUM","FIREBALL ST4.3S","0F0C",BLIST_NOLUN},/* Locks sometimes if polled for lun != 0 */
 {"MEDIAVIS","CDR-H93MV","1.31", BLIST_NOLUN},   /* Locks up if polled for lun != 0 */
 {"SANKYO", "CP525","6.64", BLIST_NOLUN},        /* causes failed REQ SENSE, extra reset */
 {"HP", "C1750A", "3226", BLIST_NOLUN},          /* scanjet iic */
@@ -281,6 +282,7 @@ static struct dev_info device_list[] =
 {"YAMAHA","CRW6416S","1.0c", BLIST_NOLUN},     /* Locks up if polled for lun != 0 */
 {"MITSUMI", "CD-R CR-2201CS", "6119", BLIST_NOLUN}, /* Locks up if polled for lun != 0 */
 {"RELISYS", "Scorpio", "*", BLIST_NOLUN},      /* responds to all LUN */
+{"MICROTEK", "ScanMaker II", "5.61", BLIST_NOLUN}, /* responds to all LUN */
 
 /*
  * Other types of devices that have special flags.
index 5fee0c18ae1a000bc211596b84d96b6646c1ea21..0f39820f583b04b0e1a1e26cb4c603a588d5868c 100644 (file)
@@ -539,7 +539,6 @@ static inline struct dquot *find_best_free(void)
 struct dquot *get_empty_dquot(void)
 {
        struct dquot *dquot;
-       int count;
 
 repeat:
        dquot = find_best_free();
@@ -569,10 +568,9 @@ pressure:
        /*
         * Try pruning the dcache to free up some dquots ...
         */
-//     printk(KERN_DEBUG "get_empty_dquot: pruning %d\n", count);
        if (prune_dcache(0, 128))
        {
-               free_inode_memory(count);
+               free_inode_memory(10);
                goto repeat;
        }
 
@@ -1584,7 +1582,7 @@ asmlinkage int sys_quotactl(int cmd, const char *special, int id, caddr_t addr)
                        break;
                case Q_GETQUOTA:
                        if (((type == USRQUOTA && current->euid != id) ||
-                            (type == GRPQUOTA && in_group_p(id))) &&
+                            (type == GRPQUOTA && !in_egroup_p(id))) &&
                            !capable(CAP_SYS_RESOURCE))
                                goto out;
                        break;
index a28f746d9ad9533647b6340f6bd72cb63ddc2406..401d2969ce464b36a4df4e6ac7e73de155dccfad 100644 (file)
@@ -690,6 +690,15 @@ repeat:
                return 1;
        }
 
+       /* if nfsd_server is zero, NFSD_MAXFH will be zero too, so
+        * find_fhe() will NEVER find the file handle NOR an empty space,
+        * and expire_slot will not be able to expire any file handle,
+        * because NFSD_MAXFH is zero ... */
+
+       if (nfsd_nservers <= 0) {
+               return 0;
+       }
+
        expire_slot(cache);
        goto repeat;
 }
index 4c4110416c17d37c21a86f7a35997c017871ace6..96344af3e04c85bc3a2aeea028692ccf453cd116 100644 (file)
 #define ASIZ_task_parent_exec_id       0x00000004
 #define AOFF_task_self_exec_id 0x000005a0
 #define ASIZ_task_self_exec_id 0x00000004
+#define AOFF_task_oom_kill_try 0x000005a4
+#define ASIZ_task_oom_kill_try 0x00000004
 #define AOFF_mm_mmap   0x00000000
 #define ASIZ_mm_mmap   0x00000004
 #define AOFF_mm_mmap_avl       0x00000004
 #define AOFF_task_mm   0x00000668
 #define ASIZ_task_mm   0x00000004
 #define AOFF_task_sigmask_lock 0x0000066c
-#define ASIZ_task_sigmask_lock 0x00000008
-#define AOFF_task_sig  0x00000674
+#define ASIZ_task_sigmask_lock 0x00000001
+#define AOFF_task_sig  0x00000670
 #define ASIZ_task_sig  0x00000004
-#define AOFF_task_signal       0x00000678
+#define AOFF_task_signal       0x00000674
 #define ASIZ_task_signal       0x00000008
-#define AOFF_task_blocked      0x00000680
+#define AOFF_task_blocked      0x0000067c
 #define ASIZ_task_blocked      0x00000008
-#define AOFF_task_sigqueue     0x00000688
+#define AOFF_task_sigqueue     0x00000684
 #define ASIZ_task_sigqueue     0x00000004
-#define AOFF_task_sigqueue_tail        0x0000068c
+#define AOFF_task_sigqueue_tail        0x00000688
 #define ASIZ_task_sigqueue_tail        0x00000004
-#define AOFF_task_sas_ss_sp    0x00000690
+#define AOFF_task_sas_ss_sp    0x0000068c
 #define ASIZ_task_sas_ss_sp    0x00000004
-#define AOFF_task_sas_ss_size  0x00000694
+#define AOFF_task_sas_ss_size  0x00000690
 #define ASIZ_task_sas_ss_size  0x00000004
-#define AOFF_task_parent_exec_id       0x00000698
+#define AOFF_task_parent_exec_id       0x00000694
 #define ASIZ_task_parent_exec_id       0x00000004
-#define AOFF_task_self_exec_id 0x0000069c
+#define AOFF_task_self_exec_id 0x00000698
 #define ASIZ_task_self_exec_id 0x00000004
+#define AOFF_task_oom_kill_try 0x0000069c
+#define ASIZ_task_oom_kill_try 0x00000004
 #define AOFF_mm_mmap   0x00000000
 #define ASIZ_mm_mmap   0x00000004
 #define AOFF_mm_mmap_avl       0x00000004
index b49f3868c49caace4ba06dd7a8bae6189a79f788..902d19e6852b782abbaa6f1064e814d2de935674 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: pgtable.h,v 1.78.2.1 1999/08/07 10:52:48 davem Exp $ */
+/* $Id: pgtable.h,v 1.78.2.2 2000/02/27 04:44:44 davem Exp $ */
 #ifndef _SPARC_PGTABLE_H
 #define _SPARC_PGTABLE_H
 
index 2a7da55ba06bdc941ea7db1a808aeef104a476c5..8577ae2b4b6ce1c7b3b86d981e40f2b6b0de7512 100644 (file)
@@ -57,8 +57,13 @@ typedef struct { volatile unsigned int lock; } rwlock_t;
 
 #include <asm/psr.h>
 
-/* Define this to use the verbose/debugging versions in arch/sparc/lib/debuglocks.c */
-#define SPIN_LOCK_DEBUG
+/*
+ * Define this to use the verbose/debugging versions in
+ * arch/sparc/lib/debuglocks.c
+ *
+ * Be sure to make check_asm whenever changing this option.
+ */
+#undef SPIN_LOCK_DEBUG
 
 #ifdef SPIN_LOCK_DEBUG
 struct _spinlock_debug {
@@ -141,9 +146,13 @@ do {       unsigned long flags; \
 typedef unsigned char spinlock_t;
 #define SPIN_LOCK_UNLOCKED     0
 
-#define spin_lock_init(lock)   (*(lock) = 0)
+#define spin_lock_init(lock)   (*((unsigned char *)(lock)) = 0)
 #define spin_is_locked(lock)    (*((volatile unsigned char *)(lock)) != 0)
-#define spin_unlock_wait(lock) do { barrier(); } while(*(volatile unsigned char *)lock)
+
+#define spin_unlock_wait(lock) \
+do { \
+       barrier(); \
+} while(*((volatile unsigned char *)lock))
 
 extern __inline__ void spin_lock(spinlock_t *lock)
 {
@@ -152,7 +161,7 @@ extern __inline__ void spin_lock(spinlock_t *lock)
        orcc    %%g2, 0x0, %%g0
        bne,a   2f
         ldub   [%0], %%g2
-       .text   2
+       .subsection     2
 2:     orcc    %%g2, 0x0, %%g0
        bne,a   2b
         ldub   [%0], %%g2
@@ -178,77 +187,13 @@ extern __inline__ void spin_unlock(spinlock_t *lock)
        __asm__ __volatile__("stb %%g0, [%0]" : : "r" (lock) : "memory");
 }
 
-extern __inline__ void spin_lock_irq(spinlock_t *lock)
-{
-       __asm__ __volatile__("
-       rd      %%psr, %%g2
-       or      %%g2, %0, %%g2
-       wr      %%g2, 0x0, %%psr
-       nop; nop; nop;
-1:     ldstub  [%1], %%g2
-       orcc    %%g2, 0x0, %%g0
-       bne,a   2f
-        ldub   [%1], %%g2
-       .text   2
-2:     orcc    %%g2, 0x0, %%g0
-       bne,a   2b
-        ldub   [%1], %%g2
-       b,a     1b
-       .previous
-"      : /* No outputs */
-       : "i" (PSR_PIL), "r" (lock)
-       : "g2", "memory", "cc");
-}
-
-extern __inline__ void spin_unlock_irq(spinlock_t *lock)
-{
-       __asm__ __volatile__("
-       rd      %%psr, %%g2
-       andn    %%g2, %1, %%g2
-       stb     %%g0, [%0]
-       wr      %%g2, 0x0, %%psr
-       nop; nop; nop;
-"      : /* No outputs. */
-       : "r" (lock), "i" (PSR_PIL)
-       : "g2", "memory");
-}
+#define spin_lock_irqsave(lock, flags) \
+       do { __save_and_cli(flags); spin_lock(lock); } while (0)
+#define spin_unlock_irqrestore(lock, flags) \
+       do { spin_unlock(lock); __restore_flags(flags); } while (0)
 
-#define spin_lock_irqsave(__lock, flags)       \
-do {                                           \
-       register spinlock_t *__lp asm("g1");    \
-       __lp = (__lock);                        \
-       __asm__ __volatile__(                   \
-       "rd     %%psr, %0\n\t"                  \
-       "or     %0, %1, %%g2\n\t"               \
-       "wr     %%g2, 0x0, %%psr\n\t"           \
-       "nop; nop; nop;\n"                      \
-       "1:\n\t"                                \
-       "ldstub [%2], %%g2\n\t"                 \
-       "orcc   %%g2, 0x0, %%g0\n\t"            \
-       "bne,a  2f\n\t"                         \
-       " ldub  [%2], %%g2\n\t"                 \
-       ".text  2\n"                            \
-       "2:\n\t"                                \
-       "orcc   %%g2, 0x0, %%g0\n\t"            \
-       "bne,a  2b\n\t"                         \
-       " ldub  [%2], %%g2\n\t"                 \
-       "b,a    1b\n\t"                         \
-       ".previous\n"                           \
-       : "=r" (flags)                          \
-       : "i" (PSR_PIL), "r" (__lp)             \
-       : "g2", "memory", "cc");                \
-} while(0)
-
-extern __inline__ void spin_unlock_irqrestore(spinlock_t *lock, unsigned long flags)
-{
-       __asm__ __volatile__("
-       stb     %%g0, [%0]
-       wr      %1, 0x0, %%psr
-       nop; nop; nop;
-"      : /* No outputs. */
-       : "r" (lock), "r" (flags)
-       : "memory", "cc");
-}
+#define spin_lock_irq(lock)    do { __cli(); spin_lock(lock); } while (0)
+#define spin_unlock_irq(lock)  do { spin_unlock(lock); __sti(); } while (0)
 
 /* Read-write spinlocks, allowing multiple readers
  * but only one writer.
@@ -290,7 +235,7 @@ extern __inline__ void _read_lock(rwlock_t *rw)
         ldstub [%%g1 + 3], %%g2
 "      : /* no outputs */
        : "r" (lp)
-       : "g2", "g4", "g7", "memory", "cc");
+       : "g2", "g4", "memory", "cc");
 }
 
 #define read_lock(lock) \
@@ -310,7 +255,7 @@ extern __inline__ void _read_unlock(rwlock_t *rw)
         ldstub [%%g1 + 3], %%g2
 "      : /* no outputs */
        : "r" (lp)
-       : "g2", "g4", "g7", "memory", "cc");
+       : "g2", "g4", "memory", "cc");
 }
 
 #define read_unlock(lock) \
@@ -330,7 +275,7 @@ extern __inline__ void write_lock(rwlock_t *rw)
         ldstub [%%g1 + 3], %%g2
 "      : /* no outputs */
        : "r" (lp)
-       : "g2", "g4", "g7", "memory", "cc");
+       : "g2", "g4", "memory", "cc");
 }
 
 #define write_unlock(rw)       do { (rw)->lock = 0; } while(0)
index 6b562006e4db6e5bfa31c54e53413222170f8792..51a8010857db58099f43b372eb4adb05167e3e8d 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: vaddrs.h,v 1.22 1999/04/20 13:22:55 anton Exp $ */
+/* $Id: vaddrs.h,v 1.22.2.1 2000/03/05 19:26:24 davem Exp $ */
 #ifndef _SPARC_VADDRS_H
 #define _SPARC_VADDRS_H
 
index 4bb5a543cc5bde0e66b942e46914f18e915724ed..bd2b87f3517c3ffc30557f4d48ea61dd39a775de 100644 (file)
 #define ASIZ_task_parent_exec_id       0x00000004
 #define AOFF_task_self_exec_id 0x0000082c
 #define ASIZ_task_self_exec_id 0x00000004
-#define ASIZ_task      0x00000830
+#define AOFF_task_oom_kill_try 0x00000830
+#define ASIZ_task_oom_kill_try 0x00000004
+#define ASIZ_task      0x00000840
 #define AOFF_mm_mmap   0x00000000
 #define ASIZ_mm_mmap   0x00000008
 #define AOFF_mm_mmap_avl       0x00000008
 #define ASIZ_task_parent_exec_id       0x00000004
 #define AOFF_task_self_exec_id 0x00000a1c
 #define ASIZ_task_self_exec_id 0x00000004
-#define ASIZ_task      0x00000a20
+#define AOFF_task_oom_kill_try 0x00000a20
+#define ASIZ_task_oom_kill_try 0x00000004
+#define ASIZ_task      0x00000a30
 #define AOFF_mm_mmap   0x00000000
 #define ASIZ_mm_mmap   0x00000008
 #define AOFF_mm_mmap_avl       0x00000008
 #define ASIZ_task_parent_exec_id       0x00000004
 #define AOFF_task_self_exec_id 0x00000a24
 #define ASIZ_task_self_exec_id 0x00000004
+#define AOFF_task_oom_kill_try 0x00000a28
+#define ASIZ_task_oom_kill_try 0x00000004
 #define ASIZ_task      0x00000a30
 #define AOFF_mm_mmap   0x00000000
 #define ASIZ_mm_mmap   0x00000008
index 055e17c818a3ebb93130a3f1551e9a7a6f9897a2..84708eacc97a25c652e1ab745ece8010356c50ae 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: floppy.h,v 1.18.2.3 2000/01/09 18:29:32 ecd Exp $
+/* $Id: floppy.h,v 1.18.2.4 2000/02/27 04:44:47 davem Exp $
  * asm-sparc64/floppy.h: Sparc specific parts of the Floppy driver.
  *
  * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu)
index 1d6ff0815cfbcdf2317bf07a224346156bb42b82..cca3d1303f30f135b7883f3d4a12ad894caa2580 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: pgtable.h,v 1.103.2.2 1999/12/05 07:24:45 davem Exp $
+/* $Id: pgtable.h,v 1.103.2.3 2000/02/27 04:44:47 davem Exp $
  * pgtable.h: SpitFire page table operations.
  *
  * Copyright 1996,1997 David S. Miller (davem@caip.rutgers.edu)
index b08d979e69938277e4009cd449b25b30d4b719cd..fca555443d0869629fff9ba672db1fb768737016 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: system.h,v 1.50 1999/05/08 03:03:22 davem Exp $ */
+/* $Id: system.h,v 1.50.2.1 2000/03/06 22:30:28 davem Exp $ */
 #ifndef __SPARC64_SYSTEM_H
 #define __SPARC64_SYSTEM_H
 
index 2ef651e19ad8ef158658f61606622ddc5c0eb562..20f07460ba0f9f1250eb3601cb6e7c6f5a80ac0e 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: isdn.h,v 1.88 2000/01/20 19:59:43 keil Exp $
+/* $Id: isdn.h,v 1.95 2000/03/04 16:20:42 detabc Exp $
  *
  * Main header for the Linux ISDN subsystem (linklevel).
  *
  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 
  *
  * $Log: isdn.h,v $
+ * Revision 1.95  2000/03/04 16:20:42  detabc
+ * copy frames before rewriting frame's saddr
+ *
+ * Revision 1.94  2000/02/26 00:29:40  keil
+ * more softnet changes
+ *
+ * Revision 1.93  2000/02/25 11:29:17  paul
+ * changed chargetime to ulong from int (after about 20 days the "chargetime of
+ * ipppX is now 1234" message displays a negative number on alpha).
+ *
+ * Revision 1.92  2000/02/17 13:15:56  keil
+ * fix backward compatibility for 2.2
+ *
+ * Revision 1.91  2000/02/16 14:56:27  paul
+ * translated ISDN_MODEM_ANZREG to ISDN_MODEM_NUMREG for english speakers
+ *
+ * Revision 1.90  2000/02/06 21:50:00  detabc
+ * add rewriting of socket's and frame's saddr for udp-ipv4 dynip-connections.
+ * Include checksum-recompute of ip- and udp-header's.
+ *
+ * Revision 1.89  2000/02/05 22:11:33  detabc
+ * Add rewriting of socket's and frame's saddr adressfield for
+ * dynip-connections.  Only for tcp/ipv4 and switchable per interface.
+ * Include checksum-recompute of ip- and tcp-header's.
+ *
  * Revision 1.88  2000/01/20 19:59:43  keil
  * Add FAX Class 1 support
  *
 #undef CONFIG_ISDN_WITH_ABC_CONN_ERROR
 #undef CONFIG_ISDN_WITH_ABC_RAWIPCOMPRESS
 #undef CONFIG_ISDN_WITH_ABC_FRAME_LIMIT
+#undef CONFIG_ISDN_WITH_ABC_IPV4_RW_SOCKADDR 
+#undef CONFIG_ISDN_WITH_ABC_IPV4_RWUDP_SOCKADDR 
 
 
 /* New ioctl-codes */
 #define ISDN_USAGE_EXCLUSIVE 64 /* This bit is set, if channel is exclusive */
 #define ISDN_USAGE_OUTGOING 128 /* This bit is set, if channel is outgoing  */
 
-#define ISDN_MODEM_ANZREG    24        /* Number of Modem-Registers        */
+#define ISDN_MODEM_NUMREG    24        /* Number of Modem-Registers        */
 #define ISDN_LMSNLEN         255 /* Length of tty's Listen-MSN string */
 #define ISDN_CMSGLEN        50  /* Length of CONNECT-Message to add for Modem */
 
@@ -536,6 +563,7 @@ typedef struct {
 #  include <linux/concap.h>
 #endif
 
+
 #include <linux/isdnif.h>
 
 #define ISDN_DRVIOCTL_MASK       0x7f  /* Mask for Device-ioctl */
@@ -657,7 +685,7 @@ typedef struct isdn_net_local_s {
                                        /*   0 = Transparent                */
   int                    huptimer;     /* Timeout-counter for auto-hangup  */
   int                    charge;       /* Counter for charging units       */
-  int                    chargetime;   /* Timer for Charging info          */
+  ulong                  chargetime;   /* Timer for Charging info          */
   int                    hupflags;     /* Flags for charge-unit-hangup:    */
                                       /* bit0: chargeint is invalid       */
                                       /* bit1: Getting charge-interval    */
@@ -762,8 +790,8 @@ typedef struct isdn_audio_skb {
 
 /* Private data of AT-command-interpreter */
 typedef struct atemu {
-       u_char       profile[ISDN_MODEM_ANZREG]; /* Modem-Regs. Profile 0              */
-       u_char       mdmreg[ISDN_MODEM_ANZREG];  /* Modem-Registers                    */
+       u_char       profile[ISDN_MODEM_NUMREG]; /* Modem-Regs. Profile 0              */
+       u_char       mdmreg[ISDN_MODEM_NUMREG];  /* Modem-Registers                    */
        char         pmsn[ISDN_MSNLEN];          /* EAZ/MSNs Profile 0                 */
        char         msn[ISDN_MSNLEN];           /* EAZ/MSN                            */
        char         plmsn[ISDN_LMSNLEN];        /* Listening MSNs Profile 0           */
@@ -975,5 +1003,32 @@ extern isdn_dev *dev;
 /* Utility-Macros */
 #define MIN(a,b) ((a<b)?a:b)
 #define MAX(a,b) ((a>b)?a:b)
+/*
+ * Tell upper layers that the network device is ready to xmit more frames.
+ */
+static void __inline__ netif_wake_queue(struct device * dev)
+{
+       dev->tbusy = 0;
+       mark_bh(NET_BH);
+}
+
+/*
+ * called during net_device open()
+ */
+static void __inline__ netif_start_queue(struct device * dev)
+{
+       dev->tbusy = 0;
+       /* actually, we never use the interrupt flag at all */
+       dev->interrupt = 0;
+       dev->start = 1;
+}
+
+/*
+ * Ask upper layers to temporarily cease passing us more xmit frames.
+ */
+static void __inline__ netif_stop_queue(struct device * dev)
+{
+       dev->tbusy = 1;
+}
 #endif /* __KERNEL__ */
 #endif /* isdn_h */
index 5778d2ebb97f1b2438c12a470813de1fed62d152..b10f304a5ac66ffd9c2f41341245075a0e3a6db8 100644 (file)
@@ -1,11 +1,15 @@
 /*
- * $Id: kernelcapi.h,v 1.4 1999/09/10 17:24:19 calle Exp $
+ * $Id: kernelcapi.h,v 1.5 2000/01/28 16:45:40 calle Exp $
  * 
  * Kernel CAPI 2.0 Interface for Linux
  * 
  * (c) Copyright 1997 by Carsten Paeth (calle@calle.in-berlin.de)
  * 
  * $Log: kernelcapi.h,v $
+ * Revision 1.5  2000/01/28 16:45:40  calle
+ * new manufacturer command KCAPI_CMD_ADDCARD (generic addcard),
+ * will search named driver and call the add_card function if one exist.
+ *
  * Revision 1.4  1999/09/10 17:24:19  calle
  * Changes for proposed standard for CAPI2.0:
  * - AK148 "Linux Exention"
@@ -57,8 +61,17 @@ typedef struct kcapi_flagdef {
        int flag;
 } kcapi_flagdef;
 
+typedef struct kcapi_carddef {
+       char            driver[32];
+       unsigned int    port;
+       unsigned        irq;
+       unsigned int    membase;
+       int             cardnr;
+} kcapi_carddef;
+
 /* new ioctls >= 10 */
 #define KCAPI_CMD_TRACE                10
+#define KCAPI_CMD_ADDCARD      11      /* add card to named driver */
 
 /* 
  * flag > 2 => trace also data
index 242126f4fcc7b620cbba16cfbe7bd54c13904e0f..9598a1684e1e451b478166a1187d0c36dd7c6926 100644 (file)
--- a/ipc/sem.c
+++ b/ipc/sem.c
@@ -521,16 +521,14 @@ asmlinkage int sys_semctl (int semid, int semnum, int cmd, union semun arg)
                break;
        case IPC_SET:
                buf = arg.buf;
-               err = copy_from_user (&tbuf, buf, sizeof (*buf));
-               if (err)
-                       err = -EFAULT;
+               err = -EFAULT;
+               if(copy_from_user (&tbuf, buf, sizeof (*buf)))
+                       goto out;
                break;
        }
 
        err = -EIDRM;
-       if (semary[id] == IPC_UNUSED || semary[id] == IPC_NOID)
-               goto out;
-       if (sma->sem_perm.seq != (unsigned int) semid / SEMMNI)
+       if ((sma != semary[id]) || (sma->sem_perm.seq != (unsigned int) semid / SEMMNI))
                goto out;
 
        switch (cmd) {
@@ -540,8 +538,9 @@ asmlinkage int sys_semctl (int semid, int semnum, int cmd, union semun arg)
                        goto out;
                for (i = 0; i < sma->sem_nsems; i++)
                        sem_io[i] = sma->sem_base[i].semval;
+               err = -EFAULT;
                if (copy_to_user (array, sem_io, nsems*sizeof(ushort)))
-                       err = -EFAULT;
+                       goto out;
                break;
        case SETVAL:
                err = -EACCES;
@@ -575,8 +574,9 @@ asmlinkage int sys_semctl (int semid, int semnum, int cmd, union semun arg)
                tbuf.sem_otime  = sma->sem_otime;
                tbuf.sem_ctime  = sma->sem_ctime;
                tbuf.sem_nsems  = sma->sem_nsems;
+               err = -EFAULT;
                if (copy_to_user (buf, &tbuf, sizeof(*buf)))
-                       err = -EFAULT;
+                       goto out;
                break;
        case SETALL:
                err = -EACCES;
@@ -601,6 +601,25 @@ out:
        return err;
 }
 
+
+static struct sem_undo* freeundos(struct sem_undo* un)
+{
+       struct sem_undo* u;
+       struct sem_undo** up;
+
+       for (up = &current->semundo;(u=*up);up=&u->proc_next) {
+               if(un==u) {
+                       un=u->proc_next;
+                       *up=un;
+                       kfree(u);
+                       return un;
+               }
+       }
+       printk ("freeundos undo list error id=%d\n", un->semid);
+       return un->proc_next;
+}
+
+
 asmlinkage int sys_semop (int semid, struct sembuf *tsops, unsigned nsops)
 {
        int id, size, error = -EINVAL;
@@ -647,9 +666,15 @@ asmlinkage int sys_semop (int semid, struct sembuf *tsops, unsigned nsops)
                /* Make sure we have an undo structure
                 * for this process and this semaphore set.
                 */
-               for (un = current->semundo; un; un = un->proc_next)
-                       if (un->semid == semid)
+               un = current->semundo;
+               while(un != NULL) {
+                       if(un->semid==semid)
                                break;
+                       if(un->semid==-1)
+                               un=freeundos(un);
+                       else
+                       un=un->proc_next;
+               }
                if (!un) {
                        size = sizeof(struct sem_undo) + sizeof(short)*sma->sem_nsems;
                        un = (struct sem_undo *) kmalloc(size, GFP_ATOMIC);
index e7f894e8ecf36ba72b2b8bde23672b07edcceef6..e2eda9ef5173639af97850ae40c8ec6781214f54 100644 (file)
@@ -16,6 +16,7 @@
  *     X.25 001        Jonathan Naylor Started coding.
  *     X.25 002        Jonathan Naylor Centralised disconnect handling.
  *                                     New timer architecture.
+ *     2000-11-03      Henner Eisen    MSG_EOR handling more POSIX compliant.
  */
 
 #include <linux/config.h>
@@ -854,7 +855,7 @@ static int x25_sendmsg(struct socket *sock, struct msghdr *msg, int len, struct
        unsigned char *asmptr;
        int size, qbit = 0;
 
-       if (msg->msg_flags & ~(MSG_DONTWAIT | MSG_OOB))
+       if (msg->msg_flags & ~(MSG_DONTWAIT | MSG_OOB | MSG_EOR))
                return -EINVAL;
 
        if (sk->zapped)
@@ -1036,6 +1037,9 @@ static int x25_recvmsg(struct socket *sock, struct msghdr *msg, int size, int fl
                msg->msg_flags |= MSG_TRUNC;
        }
 
+       /* Currently, each datagram always contains a complete record */ 
+       msg->msg_flags |= MSG_EOR;
+
        skb_copy_datagram_iovec(skb, 0, msg->msg_iov, copied);
 
        if (sx25 != NULL) {
index df6cd6402d72de84e6a2cf3a29557ce321758453..ef2d731bf6131df97573c2d9b7c06a8756933237 100644 (file)
@@ -85,13 +85,14 @@ static int x25_t20timer_pending(struct x25_neigh *neigh)
 void x25_link_control(struct sk_buff *skb, struct x25_neigh *neigh, unsigned short frametype)
 {
        struct sk_buff *skbn;
+       int confirm;
 
        switch (frametype) {
                case X25_RESTART_REQUEST:
+                       confirm = !x25_t20timer_pending(neigh);
                        x25_stop_t20timer(neigh);
-                       if (!x25_t20timer_pending(neigh))
-                               x25_transmit_restart_confirmation(neigh);
                        neigh->state = X25_LINK_STATE_3;
+                       if (confirm) x25_transmit_restart_confirmation(neigh);
                        break;
 
                case X25_RESTART_CONFIRMATION: