aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/isdn
diff options
context:
space:
mode:
authorAndrea Bastoni <bastoni@cs.unc.edu>2010-05-30 19:16:45 -0400
committerAndrea Bastoni <bastoni@cs.unc.edu>2010-05-30 19:16:45 -0400
commitada47b5fe13d89735805b566185f4885f5a3f750 (patch)
tree644b88f8a71896307d71438e9b3af49126ffb22b /drivers/isdn
parent43e98717ad40a4ae64545b5ba047c7b86aa44f4f (diff)
parent3280f21d43ee541f97f8cda5792150d2dbec20d5 (diff)
Merge branch 'wip-2.6.34' into old-private-masterarchived-private-master
Diffstat (limited to 'drivers/isdn')
-rw-r--r--drivers/isdn/Kconfig43
-rw-r--r--drivers/isdn/act2000/Kconfig4
-rw-r--r--drivers/isdn/act2000/module.c1
-rw-r--r--drivers/isdn/capi/Kconfig20
-rw-r--r--drivers/isdn/capi/capi.c1203
-rw-r--r--drivers/isdn/capi/capidrv.c105
-rw-r--r--drivers/isdn/capi/capifs.c127
-rw-r--r--drivers/isdn/capi/capifs.h21
-rw-r--r--drivers/isdn/capi/capilib.c1
-rw-r--r--drivers/isdn/capi/capiutil.c1
-rw-r--r--drivers/isdn/capi/kcapi.c818
-rw-r--r--drivers/isdn/capi/kcapi.h13
-rw-r--r--drivers/isdn/capi/kcapi_proc.c41
-rw-r--r--drivers/isdn/divert/divert_procfs.c1
-rw-r--r--drivers/isdn/divert/isdn_divert.c1
-rw-r--r--drivers/isdn/gigaset/Kconfig25
-rw-r--r--drivers/isdn/gigaset/Makefile5
-rw-r--r--drivers/isdn/gigaset/asyncdata.c666
-rw-r--r--drivers/isdn/gigaset/bas-gigaset.c99
-rw-r--r--drivers/isdn/gigaset/capi.c2273
-rw-r--r--drivers/isdn/gigaset/common.c175
-rw-r--r--drivers/isdn/gigaset/dummyll.c76
-rw-r--r--drivers/isdn/gigaset/ev-layer.c651
-rw-r--r--drivers/isdn/gigaset/gigaset.h193
-rw-r--r--drivers/isdn/gigaset/i4l.c621
-rw-r--r--drivers/isdn/gigaset/interface.c51
-rw-r--r--drivers/isdn/gigaset/isocdata.c230
-rw-r--r--drivers/isdn/gigaset/proc.c5
-rw-r--r--drivers/isdn/gigaset/ser-gigaset.c58
-rw-r--r--drivers/isdn/gigaset/usb-gigaset.c77
-rw-r--r--drivers/isdn/hardware/avm/avm_cs.c7
-rw-r--r--drivers/isdn/hardware/avm/avmcard.h6
-rw-r--r--drivers/isdn/hardware/avm/b1.c55
-rw-r--r--drivers/isdn/hardware/avm/b1dma.c72
-rw-r--r--drivers/isdn/hardware/avm/b1isa.c2
-rw-r--r--drivers/isdn/hardware/avm/b1pci.c4
-rw-r--r--drivers/isdn/hardware/avm/b1pcmcia.c2
-rw-r--r--drivers/isdn/hardware/avm/c4.c54
-rw-r--r--drivers/isdn/hardware/avm/t1isa.c3
-rw-r--r--drivers/isdn/hardware/avm/t1pci.c2
-rw-r--r--drivers/isdn/hardware/eicon/capimain.c41
-rw-r--r--drivers/isdn/hardware/eicon/di.c2
-rw-r--r--drivers/isdn/hardware/eicon/diva_didd.c45
-rw-r--r--drivers/isdn/hardware/eicon/divasi.c48
-rw-r--r--drivers/isdn/hardware/eicon/divasproc.c198
-rw-r--r--drivers/isdn/hardware/eicon/maintidi.c4
-rw-r--r--drivers/isdn/hardware/eicon/message.c35
-rw-r--r--drivers/isdn/hardware/mISDN/avmfritz.c1
-rw-r--r--drivers/isdn/hardware/mISDN/hfcmulti.c11
-rw-r--r--drivers/isdn/hardware/mISDN/hfcpci.c1
-rw-r--r--drivers/isdn/hardware/mISDN/hfcsusb.c3
-rw-r--r--drivers/isdn/hardware/mISDN/hfcsusb.h2
-rw-r--r--drivers/isdn/hardware/mISDN/mISDNinfineon.c2
-rw-r--r--drivers/isdn/hardware/mISDN/mISDNipac.c1
-rw-r--r--drivers/isdn/hardware/mISDN/mISDNisar.c7
-rw-r--r--drivers/isdn/hardware/mISDN/netjet.c1
-rw-r--r--drivers/isdn/hardware/mISDN/speedfax.c2
-rw-r--r--drivers/isdn/hardware/mISDN/w6692.c3
-rw-r--r--drivers/isdn/hisax/Kconfig18
-rw-r--r--drivers/isdn/hisax/amd7930_fn.c1
-rw-r--r--drivers/isdn/hisax/avm_pci.c7
-rw-r--r--drivers/isdn/hisax/avma1_cs.c43
-rw-r--r--drivers/isdn/hisax/bkm_a4t.c2
-rw-r--r--drivers/isdn/hisax/bkm_a8.c2
-rw-r--r--drivers/isdn/hisax/callc.c1
-rw-r--r--drivers/isdn/hisax/config.c1
-rw-r--r--drivers/isdn/hisax/diva.c14
-rw-r--r--drivers/isdn/hisax/elsa.c9
-rw-r--r--drivers/isdn/hisax/elsa_cs.c60
-rw-r--r--drivers/isdn/hisax/elsa_ser.c1
-rw-r--r--drivers/isdn/hisax/enternow_pci.c2
-rw-r--r--drivers/isdn/hisax/fsm.c1
-rw-r--r--drivers/isdn/hisax/gazel.c8
-rw-r--r--drivers/isdn/hisax/hfc4s8s_l1.c1
-rw-r--r--drivers/isdn/hisax/hfc_2bds0.c1
-rw-r--r--drivers/isdn/hisax/hfc_2bs0.c1
-rw-r--r--drivers/isdn/hisax/hfc_pci.c2
-rw-r--r--drivers/isdn/hisax/hfc_sx.c1
-rw-r--r--drivers/isdn/hisax/hfc_usb.c3
-rw-r--r--drivers/isdn/hisax/hisax.h23
-rw-r--r--drivers/isdn/hisax/hisax_isac.c1
-rw-r--r--drivers/isdn/hisax/hscx.c1
-rw-r--r--drivers/isdn/hisax/icc.c1
-rw-r--r--drivers/isdn/hisax/ipacx.c1
-rw-r--r--drivers/isdn/hisax/isac.c1
-rw-r--r--drivers/isdn/hisax/isar.c3
-rw-r--r--drivers/isdn/hisax/isdnl1.c1
-rw-r--r--drivers/isdn/hisax/isdnl2.c1
-rw-r--r--drivers/isdn/hisax/isdnl3.c1
-rw-r--r--drivers/isdn/hisax/jade.c1
-rw-r--r--drivers/isdn/hisax/l3dss1.c1
-rw-r--r--drivers/isdn/hisax/l3ni1.c1
-rw-r--r--drivers/isdn/hisax/netjet.c1
-rw-r--r--drivers/isdn/hisax/niccy.c6
-rw-r--r--drivers/isdn/hisax/nj_s.c2
-rw-r--r--drivers/isdn/hisax/nj_u.c2
-rw-r--r--drivers/isdn/hisax/sedlbauer.c6
-rw-r--r--drivers/isdn/hisax/sedlbauer_cs.c78
-rw-r--r--drivers/isdn/hisax/st5481_b.c2
-rw-r--r--drivers/isdn/hisax/st5481_d.c2
-rw-r--r--drivers/isdn/hisax/tei.c1
-rw-r--r--drivers/isdn/hisax/teles_cs.c52
-rw-r--r--drivers/isdn/hisax/telespci.c2
-rw-r--r--drivers/isdn/hisax/w6692.c3
-rw-r--r--drivers/isdn/hysdn/Kconfig4
-rw-r--r--drivers/isdn/hysdn/hycapi.c57
-rw-r--r--drivers/isdn/hysdn/hysdn_boot.c2
-rw-r--r--drivers/isdn/hysdn/hysdn_procconf.c1
-rw-r--r--drivers/isdn/hysdn/hysdn_proclog.c1
-rw-r--r--drivers/isdn/i4l/Kconfig7
-rw-r--r--drivers/isdn/i4l/isdn_audio.c1
-rw-r--r--drivers/isdn/i4l/isdn_common.c3
-rw-r--r--drivers/isdn/i4l/isdn_net.c3
-rw-r--r--drivers/isdn/i4l/isdn_ppp.c7
-rw-r--r--drivers/isdn/i4l/isdn_tty.c1
-rw-r--r--drivers/isdn/i4l/isdn_ttyfax.c2
-rw-r--r--drivers/isdn/i4l/isdn_x25iface.c1
-rw-r--r--drivers/isdn/icn/Kconfig4
-rw-r--r--drivers/isdn/icn/icn.c1
-rw-r--r--drivers/isdn/isdnloop/isdnloop.c1
-rw-r--r--drivers/isdn/mISDN/clock.c1
-rw-r--r--drivers/isdn/mISDN/core.c1
-rw-r--r--drivers/isdn/mISDN/dsp_cmx.c1
-rw-r--r--drivers/isdn/mISDN/dsp_core.c7
-rw-r--r--drivers/isdn/mISDN/dsp_pipeline.c1
-rw-r--r--drivers/isdn/mISDN/dsp_tones.c1
-rw-r--r--drivers/isdn/mISDN/hwchannel.c1
-rw-r--r--drivers/isdn/mISDN/l1oip_core.c7
-rw-r--r--drivers/isdn/mISDN/layer1.c1
-rw-r--r--drivers/isdn/mISDN/layer2.c1
-rw-r--r--drivers/isdn/mISDN/socket.c6
-rw-r--r--drivers/isdn/mISDN/stack.c1
-rw-r--r--drivers/isdn/mISDN/tei.c3
-rw-r--r--drivers/isdn/mISDN/timerdev.c1
-rw-r--r--drivers/isdn/pcbit/Kconfig4
-rw-r--r--drivers/isdn/pcbit/callbacks.c1
-rw-r--r--drivers/isdn/pcbit/edss1.c1
-rw-r--r--drivers/isdn/sc/Kconfig4
-rw-r--r--drivers/isdn/sc/hardware.h2
-rw-r--r--drivers/isdn/sc/init.c1
140 files changed, 5622 insertions, 3112 deletions
diff --git a/drivers/isdn/Kconfig b/drivers/isdn/Kconfig
index 022a19452953..4fb601670de3 100644
--- a/drivers/isdn/Kconfig
+++ b/drivers/isdn/Kconfig
@@ -7,15 +7,14 @@ menuconfig ISDN
7 depends on NET 7 depends on NET
8 depends on !S390 8 depends on !S390
9 ---help--- 9 ---help---
10 ISDN ("Integrated Services Digital Networks", called RNIS in France) 10 ISDN ("Integrated Services Digital Network", called RNIS in France)
11 is a special type of fully digital telephone service; it's mostly 11 is a fully digital telephone service that can be used for voice and
12 used to connect to your Internet service provider (with SLIP or 12 data connections. If your computer is equipped with an ISDN
13 PPP). The main advantage is that the speed is higher than ordinary 13 adapter you can use it to connect to your Internet service provider
14 modem/telephone connections, and that you can have voice 14 (with SLIP or PPP) faster than via a conventional telephone modem
15 conversations while downloading stuff. It only works if your 15 (though still much slower than with DSL) or to make and accept
16 computer is equipped with an ISDN card and both you and your service 16 voice calls (eg. turning your PC into a software answering machine
17 provider purchased an ISDN line from the phone company. For 17 or PABX).
18 details, read <http://www.alumni.caltech.edu/~dank/isdn/> on the WWW.
19 18
20 Select this option if you want your kernel to support ISDN. 19 Select this option if you want your kernel to support ISDN.
21 20
@@ -39,17 +38,22 @@ menuconfig ISDN_I4L
39 It is still available, though, for use with adapters that are not 38 It is still available, though, for use with adapters that are not
40 supported by the new CAPI subsystem yet. 39 supported by the new CAPI subsystem yet.
41 40
42source "drivers/isdn/mISDN/Kconfig"
43
44source "drivers/isdn/i4l/Kconfig" 41source "drivers/isdn/i4l/Kconfig"
45 42
46menuconfig ISDN_CAPI 43menuconfig ISDN_CAPI
47 tristate "CAPI 2.0 subsystem" 44 tristate "CAPI 2.0 subsystem"
48 help 45 help
49 This provides the CAPI (Common ISDN Application Programming 46 This provides CAPI (the Common ISDN Application Programming
50 Interface, a standard making it easy for programs to access ISDN 47 Interface) Version 2.0, a standard making it easy for programs to
51 hardware, see <http://www.capi.org/>. This is needed for AVM's set 48 access ISDN hardware in a device independent way. (For details see
52 of active ISDN controllers like B1, T1, M1. 49 <http://www.capi.org/>.) CAPI supports making and accepting voice
50 and data connections, controlling call options and protocols,
51 as well as ISDN supplementary services like call forwarding or
52 three-party conferences (if supported by the specific hardware
53 driver).
54
55 Select this option and the appropriate hardware driver below if
56 you have an ISDN adapter supported by the CAPI subsystem.
53 57
54if ISDN_CAPI 58if ISDN_CAPI
55 59
@@ -61,4 +65,13 @@ endif # ISDN_CAPI
61 65
62source "drivers/isdn/gigaset/Kconfig" 66source "drivers/isdn/gigaset/Kconfig"
63 67
68source "drivers/isdn/hysdn/Kconfig"
69
70source "drivers/isdn/mISDN/Kconfig"
71
72config ISDN_HDLC
73 tristate
74 select CRC_CCITT
75 select BITREVERSE
76
64endif # ISDN 77endif # ISDN
diff --git a/drivers/isdn/act2000/Kconfig b/drivers/isdn/act2000/Kconfig
index 3fc1a5434ef7..fa2673fc69c2 100644
--- a/drivers/isdn/act2000/Kconfig
+++ b/drivers/isdn/act2000/Kconfig
@@ -1,6 +1,3 @@
1#
2# Config.in for IBM Active 2000 ISDN driver
3#
4config ISDN_DRV_ACT2000 1config ISDN_DRV_ACT2000
5 tristate "IBM Active 2000 support" 2 tristate "IBM Active 2000 support"
6 depends on ISA 3 depends on ISA
@@ -10,4 +7,3 @@ config ISDN_DRV_ACT2000
10 into the card using a utility which is part of the latest 7 into the card using a utility which is part of the latest
11 isdn4k-utils package. Please read the file 8 isdn4k-utils package. Please read the file
12 <file:Documentation/isdn/README.act2000> for more information. 9 <file:Documentation/isdn/README.act2000> for more information.
13
diff --git a/drivers/isdn/act2000/module.c b/drivers/isdn/act2000/module.c
index f774e12bb64d..05ed72c4cf59 100644
--- a/drivers/isdn/act2000/module.c
+++ b/drivers/isdn/act2000/module.c
@@ -16,6 +16,7 @@
16#include "act2000_isa.h" 16#include "act2000_isa.h"
17#include "capi.h" 17#include "capi.h"
18#include <linux/module.h> 18#include <linux/module.h>
19#include <linux/slab.h>
19#include <linux/init.h> 20#include <linux/init.h>
20 21
21static unsigned short act2000_isa_ports[] = 22static unsigned short act2000_isa_ports[] =
diff --git a/drivers/isdn/capi/Kconfig b/drivers/isdn/capi/Kconfig
index e1afd60924fb..a168e8a891be 100644
--- a/drivers/isdn/capi/Kconfig
+++ b/drivers/isdn/capi/Kconfig
@@ -1,6 +1,3 @@
1#
2# Config.in for the CAPI subsystem
3#
4config ISDN_DRV_AVMB1_VERBOSE_REASON 1config ISDN_DRV_AVMB1_VERBOSE_REASON
5 bool "Verbose reason code reporting" 2 bool "Verbose reason code reporting"
6 default y 3 default y
@@ -20,8 +17,7 @@ config CAPI_TRACE
20 If unsure, say Y. 17 If unsure, say Y.
21 18
22config ISDN_CAPI_MIDDLEWARE 19config ISDN_CAPI_MIDDLEWARE
23 bool "CAPI2.0 Middleware support (EXPERIMENTAL)" 20 bool "CAPI2.0 Middleware support"
24 depends on EXPERIMENTAL
25 help 21 help
26 This option will enhance the capabilities of the /dev/capi20 22 This option will enhance the capabilities of the /dev/capi20
27 interface. It will provide a means of moving a data connection, 23 interface. It will provide a means of moving a data connection,
@@ -38,18 +34,19 @@ config ISDN_CAPI_CAPI20
38 Y/M here. 34 Y/M here.
39 35
40config ISDN_CAPI_CAPIFS_BOOL 36config ISDN_CAPI_CAPIFS_BOOL
41 bool "CAPI2.0 filesystem support" 37 bool "CAPI2.0 filesystem support (DEPRECATED)"
42 depends on ISDN_CAPI_MIDDLEWARE && ISDN_CAPI_CAPI20 38 depends on ISDN_CAPI_MIDDLEWARE && ISDN_CAPI_CAPI20
39 help
40 This option provides a special file system, similar to /dev/pts with
41 device nodes for the special ttys established by using the
42 middleware extension above.
43 You no longer need this, udev fully replaces it. This feature is
44 scheduled for removal.
43 45
44config ISDN_CAPI_CAPIFS 46config ISDN_CAPI_CAPIFS
45 tristate 47 tristate
46 depends on ISDN_CAPI_CAPIFS_BOOL 48 depends on ISDN_CAPI_CAPIFS_BOOL
47 default ISDN_CAPI_CAPI20 49 default ISDN_CAPI_CAPI20
48 help
49 This option provides a special file system, similar to /dev/pts with
50 device nodes for the special ttys established by using the
51 middleware extension above. If you want to use pppd with
52 pppdcapiplugin to dial up to your ISP, say Y here.
53 50
54config ISDN_CAPI_CAPIDRV 51config ISDN_CAPI_CAPIDRV
55 tristate "CAPI2.0 capidrv interface support" 52 tristate "CAPI2.0 capidrv interface support"
@@ -59,4 +56,3 @@ config ISDN_CAPI_CAPIDRV
59 the legacy isdn4linux link layer. If you have a card which is 56 the legacy isdn4linux link layer. If you have a card which is
60 supported by a CAPI driver, but still want to use old features like 57 supported by a CAPI driver, but still want to use old features like
61 ippp interfaces or ttyI emulation, say Y/M here. 58 ippp interfaces or ttyI emulation, say Y/M here.
62
diff --git a/drivers/isdn/capi/capi.c b/drivers/isdn/capi/capi.c
index 65bf91e16a42..ee5837522f5a 100644
--- a/drivers/isdn/capi/capi.c
+++ b/drivers/isdn/capi/capi.c
@@ -23,16 +23,13 @@
23#include <linux/smp_lock.h> 23#include <linux/smp_lock.h>
24#include <linux/timer.h> 24#include <linux/timer.h>
25#include <linux/wait.h> 25#include <linux/wait.h>
26#ifdef CONFIG_ISDN_CAPI_MIDDLEWARE
27#include <linux/tty.h> 26#include <linux/tty.h>
28#ifdef CONFIG_PPP
29#include <linux/netdevice.h> 27#include <linux/netdevice.h>
30#include <linux/ppp_defs.h> 28#include <linux/ppp_defs.h>
31#include <linux/if_ppp.h> 29#include <linux/if_ppp.h>
32#endif /* CONFIG_PPP */
33#endif /* CONFIG_ISDN_CAPI_MIDDLEWARE */
34#include <linux/skbuff.h> 30#include <linux/skbuff.h>
35#include <linux/proc_fs.h> 31#include <linux/proc_fs.h>
32#include <linux/seq_file.h>
36#include <linux/poll.h> 33#include <linux/poll.h>
37#include <linux/capi.h> 34#include <linux/capi.h>
38#include <linux/kernelcapi.h> 35#include <linux/kernelcapi.h>
@@ -41,35 +38,29 @@
41#include <linux/moduleparam.h> 38#include <linux/moduleparam.h>
42#include <linux/isdn/capiutil.h> 39#include <linux/isdn/capiutil.h>
43#include <linux/isdn/capicmd.h> 40#include <linux/isdn/capicmd.h>
44#if defined(CONFIG_ISDN_CAPI_CAPIFS) || defined(CONFIG_ISDN_CAPI_CAPIFS_MODULE)
45#include "capifs.h"
46#endif
47 41
48static char *revision = "$Revision: 1.1.2.7 $"; 42#include "capifs.h"
49 43
50MODULE_DESCRIPTION("CAPI4Linux: Userspace /dev/capi20 interface"); 44MODULE_DESCRIPTION("CAPI4Linux: Userspace /dev/capi20 interface");
51MODULE_AUTHOR("Carsten Paeth"); 45MODULE_AUTHOR("Carsten Paeth");
52MODULE_LICENSE("GPL"); 46MODULE_LICENSE("GPL");
53 47
54#undef _DEBUG_REFCOUNT /* alloc/free and open/close debug */
55#undef _DEBUG_TTYFUNCS /* call to tty_driver */ 48#undef _DEBUG_TTYFUNCS /* call to tty_driver */
56#undef _DEBUG_DATAFLOW /* data flow */ 49#undef _DEBUG_DATAFLOW /* data flow */
57 50
58/* -------- driver information -------------------------------------- */ 51/* -------- driver information -------------------------------------- */
59 52
60static struct class *capi_class; 53static struct class *capi_class;
61
62static int capi_major = 68; /* allocated */ 54static int capi_major = 68; /* allocated */
55
56module_param_named(major, capi_major, uint, 0);
57
63#ifdef CONFIG_ISDN_CAPI_MIDDLEWARE 58#ifdef CONFIG_ISDN_CAPI_MIDDLEWARE
64#define CAPINC_NR_PORTS 32 59#define CAPINC_NR_PORTS 32
65#define CAPINC_MAX_PORTS 256 60#define CAPINC_MAX_PORTS 256
66static int capi_ttymajor = 191; 61
67static int capi_ttyminors = CAPINC_NR_PORTS; 62static int capi_ttyminors = CAPINC_NR_PORTS;
68#endif /* CONFIG_ISDN_CAPI_MIDDLEWARE */
69 63
70module_param_named(major, capi_major, uint, 0);
71#ifdef CONFIG_ISDN_CAPI_MIDDLEWARE
72module_param_named(ttymajor, capi_ttymajor, uint, 0);
73module_param_named(ttyminors, capi_ttyminors, uint, 0); 64module_param_named(ttyminors, capi_ttyminors, uint, 0);
74#endif /* CONFIG_ISDN_CAPI_MIDDLEWARE */ 65#endif /* CONFIG_ISDN_CAPI_MIDDLEWARE */
75 66
@@ -83,53 +74,43 @@ module_param_named(ttyminors, capi_ttyminors, uint, 0);
83 74
84struct capidev; 75struct capidev;
85struct capincci; 76struct capincci;
86#ifdef CONFIG_ISDN_CAPI_MIDDLEWARE
87struct capiminor; 77struct capiminor;
88 78
89struct datahandle_queue { 79struct ackqueue_entry {
90 struct list_head list; 80 struct list_head list;
91 u16 datahandle; 81 u16 datahandle;
92}; 82};
93 83
94struct capiminor { 84struct capiminor {
95 struct list_head list; 85 struct kref kref;
96 struct capincci *nccip; 86
97 unsigned int minor; 87 unsigned int minor;
88 struct dentry *capifs_dentry;
98 89
99 struct capi20_appl *ap; 90 struct capi20_appl *ap;
100 u32 ncci; 91 u32 ncci;
101 u16 datahandle; 92 atomic_t datahandle;
102 u16 msgid; 93 atomic_t msgid;
103 94
104 struct tty_struct *tty; 95 struct tty_port port;
105 int ttyinstop; 96 int ttyinstop;
106 int ttyoutstop; 97 int ttyoutstop;
107 struct sk_buff *ttyskb;
108 atomic_t ttyopencount;
109 98
110 struct sk_buff_head inqueue; 99 struct sk_buff_head inqueue;
111 int inbytes; 100
112 struct sk_buff_head outqueue; 101 struct sk_buff_head outqueue;
113 int outbytes; 102 int outbytes;
103 struct sk_buff *outskb;
104 spinlock_t outlock;
114 105
115 /* transmit path */ 106 /* transmit path */
116 struct list_head ackqueue; 107 struct list_head ackqueue;
117 int nack; 108 int nack;
118 spinlock_t ackqlock; 109 spinlock_t ackqlock;
119}; 110};
120#endif /* CONFIG_ISDN_CAPI_MIDDLEWARE */
121
122/* FIXME: The following lock is a sledgehammer-workaround to a
123 * locking issue with the capiminor (and maybe other) data structure(s).
124 * Access to this data is done in a racy way and crashes the machine with
125 * a FritzCard DSL driver; sooner or later. This is a workaround
126 * which trades scalability vs stability, so it doesn't crash the kernel anymore.
127 * The correct (and scalable) fix for the issue seems to require
128 * an API change to the drivers... . */
129static DEFINE_SPINLOCK(workaround_lock);
130 111
131struct capincci { 112struct capincci {
132 struct capincci *next; 113 struct list_head list;
133 u32 ncci; 114 u32 ncci;
134 struct capidev *cdev; 115 struct capidev *cdev;
135#ifdef CONFIG_ISDN_CAPI_MIDDLEWARE 116#ifdef CONFIG_ISDN_CAPI_MIDDLEWARE
@@ -146,28 +127,28 @@ struct capidev {
146 struct sk_buff_head recvqueue; 127 struct sk_buff_head recvqueue;
147 wait_queue_head_t recvwait; 128 wait_queue_head_t recvwait;
148 129
149 struct capincci *nccis; 130 struct list_head nccis;
150 131
151 struct mutex ncci_list_mtx; 132 struct mutex lock;
152}; 133};
153 134
154/* -------- global variables ---------------------------------------- */ 135/* -------- global variables ---------------------------------------- */
155 136
156static DEFINE_RWLOCK(capidev_list_lock); 137static DEFINE_MUTEX(capidev_list_lock);
157static LIST_HEAD(capidev_list); 138static LIST_HEAD(capidev_list);
158 139
159#ifdef CONFIG_ISDN_CAPI_MIDDLEWARE 140#ifdef CONFIG_ISDN_CAPI_MIDDLEWARE
160static DEFINE_RWLOCK(capiminor_list_lock);
161static LIST_HEAD(capiminor_list);
162#endif /* CONFIG_ISDN_CAPI_MIDDLEWARE */
163 141
164#ifdef CONFIG_ISDN_CAPI_MIDDLEWARE 142static DEFINE_SPINLOCK(capiminors_lock);
143static struct capiminor **capiminors;
144
145static struct tty_driver *capinc_tty_driver;
146
165/* -------- datahandles --------------------------------------------- */ 147/* -------- datahandles --------------------------------------------- */
166 148
167static int capincci_add_ack(struct capiminor *mp, u16 datahandle) 149static int capiminor_add_ack(struct capiminor *mp, u16 datahandle)
168{ 150{
169 struct datahandle_queue *n; 151 struct ackqueue_entry *n;
170 unsigned long flags;
171 152
172 n = kmalloc(sizeof(*n), GFP_ATOMIC); 153 n = kmalloc(sizeof(*n), GFP_ATOMIC);
173 if (unlikely(!n)) { 154 if (unlikely(!n)) {
@@ -176,253 +157,246 @@ static int capincci_add_ack(struct capiminor *mp, u16 datahandle)
176 } 157 }
177 n->datahandle = datahandle; 158 n->datahandle = datahandle;
178 INIT_LIST_HEAD(&n->list); 159 INIT_LIST_HEAD(&n->list);
179 spin_lock_irqsave(&mp->ackqlock, flags); 160 spin_lock_bh(&mp->ackqlock);
180 list_add_tail(&n->list, &mp->ackqueue); 161 list_add_tail(&n->list, &mp->ackqueue);
181 mp->nack++; 162 mp->nack++;
182 spin_unlock_irqrestore(&mp->ackqlock, flags); 163 spin_unlock_bh(&mp->ackqlock);
183 return 0; 164 return 0;
184} 165}
185 166
186static int capiminor_del_ack(struct capiminor *mp, u16 datahandle) 167static int capiminor_del_ack(struct capiminor *mp, u16 datahandle)
187{ 168{
188 struct datahandle_queue *p, *tmp; 169 struct ackqueue_entry *p, *tmp;
189 unsigned long flags;
190 170
191 spin_lock_irqsave(&mp->ackqlock, flags); 171 spin_lock_bh(&mp->ackqlock);
192 list_for_each_entry_safe(p, tmp, &mp->ackqueue, list) { 172 list_for_each_entry_safe(p, tmp, &mp->ackqueue, list) {
193 if (p->datahandle == datahandle) { 173 if (p->datahandle == datahandle) {
194 list_del(&p->list); 174 list_del(&p->list);
195 kfree(p);
196 mp->nack--; 175 mp->nack--;
197 spin_unlock_irqrestore(&mp->ackqlock, flags); 176 spin_unlock_bh(&mp->ackqlock);
177 kfree(p);
198 return 0; 178 return 0;
199 } 179 }
200 } 180 }
201 spin_unlock_irqrestore(&mp->ackqlock, flags); 181 spin_unlock_bh(&mp->ackqlock);
202 return -1; 182 return -1;
203} 183}
204 184
205static void capiminor_del_all_ack(struct capiminor *mp) 185static void capiminor_del_all_ack(struct capiminor *mp)
206{ 186{
207 struct datahandle_queue *p, *tmp; 187 struct ackqueue_entry *p, *tmp;
208 unsigned long flags;
209 188
210 spin_lock_irqsave(&mp->ackqlock, flags);
211 list_for_each_entry_safe(p, tmp, &mp->ackqueue, list) { 189 list_for_each_entry_safe(p, tmp, &mp->ackqueue, list) {
212 list_del(&p->list); 190 list_del(&p->list);
213 kfree(p); 191 kfree(p);
214 mp->nack--; 192 mp->nack--;
215 } 193 }
216 spin_unlock_irqrestore(&mp->ackqlock, flags);
217} 194}
218 195
219 196
220/* -------- struct capiminor ---------------------------------------- */ 197/* -------- struct capiminor ---------------------------------------- */
221 198
199static const struct tty_port_operations capiminor_port_ops; /* we have none */
200
222static struct capiminor *capiminor_alloc(struct capi20_appl *ap, u32 ncci) 201static struct capiminor *capiminor_alloc(struct capi20_appl *ap, u32 ncci)
223{ 202{
224 struct capiminor *mp, *p; 203 struct capiminor *mp;
225 unsigned int minor = 0; 204 struct device *dev;
226 unsigned long flags; 205 unsigned int minor;
227 206
228 mp = kzalloc(sizeof(*mp), GFP_ATOMIC); 207 mp = kzalloc(sizeof(*mp), GFP_KERNEL);
229 if (!mp) { 208 if (!mp) {
230 printk(KERN_ERR "capi: can't alloc capiminor\n"); 209 printk(KERN_ERR "capi: can't alloc capiminor\n");
231 return NULL; 210 return NULL;
232 } 211 }
233 212
213 kref_init(&mp->kref);
214
234 mp->ap = ap; 215 mp->ap = ap;
235 mp->ncci = ncci; 216 mp->ncci = ncci;
236 mp->msgid = 0;
237 atomic_set(&mp->ttyopencount,0);
238 INIT_LIST_HEAD(&mp->ackqueue); 217 INIT_LIST_HEAD(&mp->ackqueue);
239 spin_lock_init(&mp->ackqlock); 218 spin_lock_init(&mp->ackqlock);
240 219
241 skb_queue_head_init(&mp->inqueue); 220 skb_queue_head_init(&mp->inqueue);
242 skb_queue_head_init(&mp->outqueue); 221 skb_queue_head_init(&mp->outqueue);
222 spin_lock_init(&mp->outlock);
243 223
244 /* Allocate the least unused minor number. 224 tty_port_init(&mp->port);
245 */ 225 mp->port.ops = &capiminor_port_ops;
246 write_lock_irqsave(&capiminor_list_lock, flags); 226
247 if (list_empty(&capiminor_list)) 227 /* Allocate the least unused minor number. */
248 list_add(&mp->list, &capiminor_list); 228 spin_lock(&capiminors_lock);
249 else { 229 for (minor = 0; minor < capi_ttyminors; minor++)
250 list_for_each_entry(p, &capiminor_list, list) { 230 if (!capiminors[minor]) {
251 if (p->minor > minor) 231 capiminors[minor] = mp;
252 break; 232 break;
253 minor++;
254 }
255
256 if (minor < capi_ttyminors) {
257 mp->minor = minor;
258 list_add(&mp->list, p->list.prev);
259 } 233 }
260 } 234 spin_unlock(&capiminors_lock);
261 write_unlock_irqrestore(&capiminor_list_lock, flags);
262 235
263 if (!(minor < capi_ttyminors)) { 236 if (minor == capi_ttyminors) {
264 printk(KERN_NOTICE "capi: out of minors\n"); 237 printk(KERN_NOTICE "capi: out of minors\n");
265 kfree(mp); 238 goto err_out1;
266 return NULL;
267 } 239 }
268 240
241 mp->minor = minor;
242
243 dev = tty_register_device(capinc_tty_driver, minor, NULL);
244 if (IS_ERR(dev))
245 goto err_out2;
246
269 return mp; 247 return mp;
248
249err_out2:
250 spin_lock(&capiminors_lock);
251 capiminors[minor] = NULL;
252 spin_unlock(&capiminors_lock);
253
254err_out1:
255 kfree(mp);
256 return NULL;
270} 257}
271 258
272static void capiminor_free(struct capiminor *mp) 259static void capiminor_destroy(struct kref *kref)
273{ 260{
274 unsigned long flags; 261 struct capiminor *mp = container_of(kref, struct capiminor, kref);
275
276 write_lock_irqsave(&capiminor_list_lock, flags);
277 list_del(&mp->list);
278 write_unlock_irqrestore(&capiminor_list_lock, flags);
279 262
280 kfree_skb(mp->ttyskb); 263 kfree_skb(mp->outskb);
281 mp->ttyskb = NULL;
282 skb_queue_purge(&mp->inqueue); 264 skb_queue_purge(&mp->inqueue);
283 skb_queue_purge(&mp->outqueue); 265 skb_queue_purge(&mp->outqueue);
284 capiminor_del_all_ack(mp); 266 capiminor_del_all_ack(mp);
285 kfree(mp); 267 kfree(mp);
286} 268}
287 269
288static struct capiminor *capiminor_find(unsigned int minor) 270static struct capiminor *capiminor_get(unsigned int minor)
289{ 271{
290 struct list_head *l; 272 struct capiminor *mp;
291 struct capiminor *p = NULL;
292 273
293 read_lock(&capiminor_list_lock); 274 spin_lock(&capiminors_lock);
294 list_for_each(l, &capiminor_list) { 275 mp = capiminors[minor];
295 p = list_entry(l, struct capiminor, list); 276 if (mp)
296 if (p->minor == minor) 277 kref_get(&mp->kref);
297 break; 278 spin_unlock(&capiminors_lock);
298 }
299 read_unlock(&capiminor_list_lock);
300 if (l == &capiminor_list)
301 return NULL;
302 279
303 return p; 280 return mp;
281}
282
283static inline void capiminor_put(struct capiminor *mp)
284{
285 kref_put(&mp->kref, capiminor_destroy);
286}
287
288static void capiminor_free(struct capiminor *mp)
289{
290 tty_unregister_device(capinc_tty_driver, mp->minor);
291
292 spin_lock(&capiminors_lock);
293 capiminors[mp->minor] = NULL;
294 spin_unlock(&capiminors_lock);
295
296 capiminor_put(mp);
304} 297}
305#endif /* CONFIG_ISDN_CAPI_MIDDLEWARE */
306 298
307/* -------- struct capincci ----------------------------------------- */ 299/* -------- struct capincci ----------------------------------------- */
308 300
309static struct capincci *capincci_alloc(struct capidev *cdev, u32 ncci) 301static void capincci_alloc_minor(struct capidev *cdev, struct capincci *np)
310{ 302{
311 struct capincci *np, **pp; 303 struct capiminor *mp;
312#ifdef CONFIG_ISDN_CAPI_MIDDLEWARE 304 dev_t device;
313 struct capiminor *mp = NULL;
314#endif /* CONFIG_ISDN_CAPI_MIDDLEWARE */
315 305
316 np = kzalloc(sizeof(*np), GFP_ATOMIC); 306 if (!(cdev->userflags & CAPIFLAG_HIGHJACKING))
317 if (!np) 307 return;
318 return NULL; 308
319 np->ncci = ncci; 309 mp = np->minorp = capiminor_alloc(&cdev->ap, np->ncci);
320 np->cdev = cdev;
321#ifdef CONFIG_ISDN_CAPI_MIDDLEWARE
322 mp = NULL;
323 if (cdev->userflags & CAPIFLAG_HIGHJACKING)
324 mp = np->minorp = capiminor_alloc(&cdev->ap, ncci);
325 if (mp) { 310 if (mp) {
326 mp->nccip = np; 311 device = MKDEV(capinc_tty_driver->major, mp->minor);
327#ifdef _DEBUG_REFCOUNT 312 mp->capifs_dentry = capifs_new_ncci(mp->minor, device);
328 printk(KERN_DEBUG "set mp->nccip\n");
329#endif
330#if defined(CONFIG_ISDN_CAPI_CAPIFS) || defined(CONFIG_ISDN_CAPI_CAPIFS_MODULE)
331 capifs_new_ncci(mp->minor, MKDEV(capi_ttymajor, mp->minor));
332#endif
333 } 313 }
334#endif /* CONFIG_ISDN_CAPI_MIDDLEWARE */
335 for (pp=&cdev->nccis; *pp; pp = &(*pp)->next)
336 ;
337 *pp = np;
338 return np;
339} 314}
340 315
341static void capincci_free(struct capidev *cdev, u32 ncci) 316static void capincci_free_minor(struct capincci *np)
342{ 317{
343 struct capincci *np, **pp; 318 struct capiminor *mp = np->minorp;
344#ifdef CONFIG_ISDN_CAPI_MIDDLEWARE 319 struct tty_struct *tty;
345 struct capiminor *mp;
346#endif /* CONFIG_ISDN_CAPI_MIDDLEWARE */
347 320
348 pp=&cdev->nccis; 321 if (mp) {
349 while (*pp) { 322 capifs_free_ncci(mp->capifs_dentry);
350 np = *pp; 323
351 if (ncci == 0xffffffff || np->ncci == ncci) { 324 tty = tty_port_tty_get(&mp->port);
352 *pp = (*pp)->next; 325 if (tty) {
353#ifdef CONFIG_ISDN_CAPI_MIDDLEWARE 326 tty_vhangup(tty);
354 if ((mp = np->minorp) != NULL) { 327 tty_kref_put(tty);
355#if defined(CONFIG_ISDN_CAPI_CAPIFS) || defined(CONFIG_ISDN_CAPI_CAPIFS_MODULE)
356 capifs_free_ncci(mp->minor);
357#endif
358 if (mp->tty) {
359 mp->nccip = NULL;
360#ifdef _DEBUG_REFCOUNT
361 printk(KERN_DEBUG "reset mp->nccip\n");
362#endif
363 tty_hangup(mp->tty);
364 } else {
365 capiminor_free(mp);
366 }
367 }
368#endif /* CONFIG_ISDN_CAPI_MIDDLEWARE */
369 kfree(np);
370 if (*pp == NULL) return;
371 } else {
372 pp = &(*pp)->next;
373 } 328 }
329
330 capiminor_free(mp);
374 } 331 }
375} 332}
376 333
377static struct capincci *capincci_find(struct capidev *cdev, u32 ncci) 334static inline unsigned int capincci_minor_opencount(struct capincci *np)
378{ 335{
379 struct capincci *p; 336 struct capiminor *mp = np->minorp;
337 unsigned int count = 0;
338 struct tty_struct *tty;
380 339
381 for (p=cdev->nccis; p ; p = p->next) { 340 if (mp) {
382 if (p->ncci == ncci) 341 tty = tty_port_tty_get(&mp->port);
383 break; 342 if (tty) {
343 count = tty->count;
344 tty_kref_put(tty);
345 }
384 } 346 }
385 return p; 347 return count;
386} 348}
387 349
388/* -------- struct capidev ------------------------------------------ */ 350#else /* !CONFIG_ISDN_CAPI_MIDDLEWARE */
351
352static inline void
353capincci_alloc_minor(struct capidev *cdev, struct capincci *np) { }
354static inline void capincci_free_minor(struct capincci *np) { }
389 355
390static struct capidev *capidev_alloc(void) 356static inline unsigned int capincci_minor_opencount(struct capincci *np)
391{ 357{
392 struct capidev *cdev; 358 return 0;
393 unsigned long flags; 359}
394 360
395 cdev = kzalloc(sizeof(*cdev), GFP_KERNEL); 361#endif /* !CONFIG_ISDN_CAPI_MIDDLEWARE */
396 if (!cdev) 362
363static struct capincci *capincci_alloc(struct capidev *cdev, u32 ncci)
364{
365 struct capincci *np;
366
367 np = kzalloc(sizeof(*np), GFP_KERNEL);
368 if (!np)
397 return NULL; 369 return NULL;
370 np->ncci = ncci;
371 np->cdev = cdev;
398 372
399 mutex_init(&cdev->ncci_list_mtx); 373 capincci_alloc_minor(cdev, np);
400 skb_queue_head_init(&cdev->recvqueue); 374
401 init_waitqueue_head(&cdev->recvwait); 375 list_add_tail(&np->list, &cdev->nccis);
402 write_lock_irqsave(&capidev_list_lock, flags); 376
403 list_add_tail(&cdev->list, &capidev_list); 377 return np;
404 write_unlock_irqrestore(&capidev_list_lock, flags);
405 return cdev;
406} 378}
407 379
408static void capidev_free(struct capidev *cdev) 380static void capincci_free(struct capidev *cdev, u32 ncci)
409{ 381{
410 unsigned long flags; 382 struct capincci *np, *tmp;
411 383
412 if (cdev->ap.applid) { 384 list_for_each_entry_safe(np, tmp, &cdev->nccis, list)
413 capi20_release(&cdev->ap); 385 if (ncci == 0xffffffff || np->ncci == ncci) {
414 cdev->ap.applid = 0; 386 capincci_free_minor(np);
415 } 387 list_del(&np->list);
416 skb_queue_purge(&cdev->recvqueue); 388 kfree(np);
389 }
390}
417 391
418 mutex_lock(&cdev->ncci_list_mtx); 392static struct capincci *capincci_find(struct capidev *cdev, u32 ncci)
419 capincci_free(cdev, 0xffffffff); 393{
420 mutex_unlock(&cdev->ncci_list_mtx); 394 struct capincci *np;
421 395
422 write_lock_irqsave(&capidev_list_lock, flags); 396 list_for_each_entry(np, &cdev->nccis, list)
423 list_del(&cdev->list); 397 if (np->ncci == ncci)
424 write_unlock_irqrestore(&capidev_list_lock, flags); 398 return np;
425 kfree(cdev); 399 return NULL;
426} 400}
427 401
428#ifdef CONFIG_ISDN_CAPI_MIDDLEWARE 402#ifdef CONFIG_ISDN_CAPI_MIDDLEWARE
@@ -432,7 +406,7 @@ static struct sk_buff *
432gen_data_b3_resp_for(struct capiminor *mp, struct sk_buff *skb) 406gen_data_b3_resp_for(struct capiminor *mp, struct sk_buff *skb)
433{ 407{
434 struct sk_buff *nskb; 408 struct sk_buff *nskb;
435 nskb = alloc_skb(CAPI_DATA_B3_RESP_LEN, GFP_ATOMIC); 409 nskb = alloc_skb(CAPI_DATA_B3_RESP_LEN, GFP_KERNEL);
436 if (nskb) { 410 if (nskb) {
437 u16 datahandle = CAPIMSG_U16(skb->data,CAPIMSG_BASELEN+4+4+2); 411 u16 datahandle = CAPIMSG_U16(skb->data,CAPIMSG_BASELEN+4+4+2);
438 unsigned char *s = skb_put(nskb, CAPI_DATA_B3_RESP_LEN); 412 unsigned char *s = skb_put(nskb, CAPI_DATA_B3_RESP_LEN);
@@ -440,7 +414,7 @@ gen_data_b3_resp_for(struct capiminor *mp, struct sk_buff *skb)
440 capimsg_setu16(s, 2, mp->ap->applid); 414 capimsg_setu16(s, 2, mp->ap->applid);
441 capimsg_setu8 (s, 4, CAPI_DATA_B3); 415 capimsg_setu8 (s, 4, CAPI_DATA_B3);
442 capimsg_setu8 (s, 5, CAPI_RESP); 416 capimsg_setu8 (s, 5, CAPI_RESP);
443 capimsg_setu16(s, 6, mp->msgid++); 417 capimsg_setu16(s, 6, atomic_inc_return(&mp->msgid));
444 capimsg_setu32(s, 8, mp->ncci); 418 capimsg_setu32(s, 8, mp->ncci);
445 capimsg_setu16(s, 12, datahandle); 419 capimsg_setu16(s, 12, datahandle);
446 } 420 }
@@ -449,122 +423,156 @@ gen_data_b3_resp_for(struct capiminor *mp, struct sk_buff *skb)
449 423
450static int handle_recv_skb(struct capiminor *mp, struct sk_buff *skb) 424static int handle_recv_skb(struct capiminor *mp, struct sk_buff *skb)
451{ 425{
426 unsigned int datalen = skb->len - CAPIMSG_LEN(skb->data);
427 struct tty_struct *tty;
452 struct sk_buff *nskb; 428 struct sk_buff *nskb;
453 int datalen;
454 u16 errcode, datahandle; 429 u16 errcode, datahandle;
455 struct tty_ldisc *ld; 430 struct tty_ldisc *ld;
456 431 int ret = -1;
457 datalen = skb->len - CAPIMSG_LEN(skb->data); 432
458 if (mp->tty == NULL) 433 tty = tty_port_tty_get(&mp->port);
459 { 434 if (!tty) {
460#ifdef _DEBUG_DATAFLOW 435#ifdef _DEBUG_DATAFLOW
461 printk(KERN_DEBUG "capi: currently no receiver\n"); 436 printk(KERN_DEBUG "capi: currently no receiver\n");
462#endif 437#endif
463 return -1; 438 return -1;
464 } 439 }
465 440
466 ld = tty_ldisc_ref(mp->tty); 441 ld = tty_ldisc_ref(tty);
467 if (ld == NULL) 442 if (!ld) {
468 return -1; 443 /* fatal error, do not requeue */
444 ret = 0;
445 kfree_skb(skb);
446 goto deref_tty;
447 }
448
469 if (ld->ops->receive_buf == NULL) { 449 if (ld->ops->receive_buf == NULL) {
470#if defined(_DEBUG_DATAFLOW) || defined(_DEBUG_TTYFUNCS) 450#if defined(_DEBUG_DATAFLOW) || defined(_DEBUG_TTYFUNCS)
471 printk(KERN_DEBUG "capi: ldisc has no receive_buf function\n"); 451 printk(KERN_DEBUG "capi: ldisc has no receive_buf function\n");
472#endif 452#endif
473 goto bad; 453 /* fatal error, do not requeue */
454 goto free_skb;
474 } 455 }
475 if (mp->ttyinstop) { 456 if (mp->ttyinstop) {
476#if defined(_DEBUG_DATAFLOW) || defined(_DEBUG_TTYFUNCS) 457#if defined(_DEBUG_DATAFLOW) || defined(_DEBUG_TTYFUNCS)
477 printk(KERN_DEBUG "capi: recv tty throttled\n"); 458 printk(KERN_DEBUG "capi: recv tty throttled\n");
478#endif 459#endif
479 goto bad; 460 goto deref_ldisc;
480 } 461 }
481 if (mp->tty->receive_room < datalen) { 462
463 if (tty->receive_room < datalen) {
482#if defined(_DEBUG_DATAFLOW) || defined(_DEBUG_TTYFUNCS) 464#if defined(_DEBUG_DATAFLOW) || defined(_DEBUG_TTYFUNCS)
483 printk(KERN_DEBUG "capi: no room in tty\n"); 465 printk(KERN_DEBUG "capi: no room in tty\n");
484#endif 466#endif
485 goto bad; 467 goto deref_ldisc;
486 } 468 }
487 if ((nskb = gen_data_b3_resp_for(mp, skb)) == NULL) { 469
470 nskb = gen_data_b3_resp_for(mp, skb);
471 if (!nskb) {
488 printk(KERN_ERR "capi: gen_data_b3_resp failed\n"); 472 printk(KERN_ERR "capi: gen_data_b3_resp failed\n");
489 goto bad; 473 goto deref_ldisc;
490 } 474 }
491 datahandle = CAPIMSG_U16(skb->data,CAPIMSG_BASELEN+4); 475
476 datahandle = CAPIMSG_U16(skb->data, CAPIMSG_BASELEN + 4);
477
492 errcode = capi20_put_message(mp->ap, nskb); 478 errcode = capi20_put_message(mp->ap, nskb);
493 if (errcode != CAPI_NOERROR) { 479
480 if (errcode == CAPI_NOERROR) {
481 skb_pull(skb, CAPIMSG_LEN(skb->data));
482#ifdef _DEBUG_DATAFLOW
483 printk(KERN_DEBUG "capi: DATA_B3_RESP %u len=%d => ldisc\n",
484 datahandle, skb->len);
485#endif
486 ld->ops->receive_buf(tty, skb->data, NULL, skb->len);
487 } else {
494 printk(KERN_ERR "capi: send DATA_B3_RESP failed=%x\n", 488 printk(KERN_ERR "capi: send DATA_B3_RESP failed=%x\n",
495 errcode); 489 errcode);
496 kfree_skb(nskb); 490 kfree_skb(nskb);
497 goto bad; 491
492 if (errcode == CAPI_SENDQUEUEFULL)
493 goto deref_ldisc;
498 } 494 }
499 (void)skb_pull(skb, CAPIMSG_LEN(skb->data)); 495
500#ifdef _DEBUG_DATAFLOW 496free_skb:
501 printk(KERN_DEBUG "capi: DATA_B3_RESP %u len=%d => ldisc\n", 497 ret = 0;
502 datahandle, skb->len);
503#endif
504 ld->ops->receive_buf(mp->tty, skb->data, NULL, skb->len);
505 kfree_skb(skb); 498 kfree_skb(skb);
499
500deref_ldisc:
506 tty_ldisc_deref(ld); 501 tty_ldisc_deref(ld);
507 return 0; 502
508bad: 503deref_tty:
509 tty_ldisc_deref(ld); 504 tty_kref_put(tty);
510 return -1; 505 return ret;
511} 506}
512 507
513static void handle_minor_recv(struct capiminor *mp) 508static void handle_minor_recv(struct capiminor *mp)
514{ 509{
515 struct sk_buff *skb; 510 struct sk_buff *skb;
516 while ((skb = skb_dequeue(&mp->inqueue)) != NULL) { 511
517 unsigned int len = skb->len; 512 while ((skb = skb_dequeue(&mp->inqueue)) != NULL)
518 mp->inbytes -= len;
519 if (handle_recv_skb(mp, skb) < 0) { 513 if (handle_recv_skb(mp, skb) < 0) {
520 skb_queue_head(&mp->inqueue, skb); 514 skb_queue_head(&mp->inqueue, skb);
521 mp->inbytes += len;
522 return; 515 return;
523 } 516 }
524 }
525} 517}
526 518
527static int handle_minor_send(struct capiminor *mp) 519static void handle_minor_send(struct capiminor *mp)
528{ 520{
521 struct tty_struct *tty;
529 struct sk_buff *skb; 522 struct sk_buff *skb;
530 u16 len; 523 u16 len;
531 int count = 0;
532 u16 errcode; 524 u16 errcode;
533 u16 datahandle; 525 u16 datahandle;
534 526
535 if (mp->tty && mp->ttyoutstop) { 527 tty = tty_port_tty_get(&mp->port);
528 if (!tty)
529 return;
530
531 if (mp->ttyoutstop) {
536#if defined(_DEBUG_DATAFLOW) || defined(_DEBUG_TTYFUNCS) 532#if defined(_DEBUG_DATAFLOW) || defined(_DEBUG_TTYFUNCS)
537 printk(KERN_DEBUG "capi: send: tty stopped\n"); 533 printk(KERN_DEBUG "capi: send: tty stopped\n");
538#endif 534#endif
539 return 0; 535 tty_kref_put(tty);
536 return;
540 } 537 }
541 538
542 while ((skb = skb_dequeue(&mp->outqueue)) != NULL) { 539 while (1) {
543 datahandle = mp->datahandle; 540 spin_lock_bh(&mp->outlock);
541 skb = __skb_dequeue(&mp->outqueue);
542 if (!skb) {
543 spin_unlock_bh(&mp->outlock);
544 break;
545 }
544 len = (u16)skb->len; 546 len = (u16)skb->len;
547 mp->outbytes -= len;
548 spin_unlock_bh(&mp->outlock);
549
550 datahandle = atomic_inc_return(&mp->datahandle);
545 skb_push(skb, CAPI_DATA_B3_REQ_LEN); 551 skb_push(skb, CAPI_DATA_B3_REQ_LEN);
546 memset(skb->data, 0, CAPI_DATA_B3_REQ_LEN); 552 memset(skb->data, 0, CAPI_DATA_B3_REQ_LEN);
547 capimsg_setu16(skb->data, 0, CAPI_DATA_B3_REQ_LEN); 553 capimsg_setu16(skb->data, 0, CAPI_DATA_B3_REQ_LEN);
548 capimsg_setu16(skb->data, 2, mp->ap->applid); 554 capimsg_setu16(skb->data, 2, mp->ap->applid);
549 capimsg_setu8 (skb->data, 4, CAPI_DATA_B3); 555 capimsg_setu8 (skb->data, 4, CAPI_DATA_B3);
550 capimsg_setu8 (skb->data, 5, CAPI_REQ); 556 capimsg_setu8 (skb->data, 5, CAPI_REQ);
551 capimsg_setu16(skb->data, 6, mp->msgid++); 557 capimsg_setu16(skb->data, 6, atomic_inc_return(&mp->msgid));
552 capimsg_setu32(skb->data, 8, mp->ncci); /* NCCI */ 558 capimsg_setu32(skb->data, 8, mp->ncci); /* NCCI */
553 capimsg_setu32(skb->data, 12, (u32)(long)skb->data);/* Data32 */ 559 capimsg_setu32(skb->data, 12, (u32)(long)skb->data);/* Data32 */
554 capimsg_setu16(skb->data, 16, len); /* Data length */ 560 capimsg_setu16(skb->data, 16, len); /* Data length */
555 capimsg_setu16(skb->data, 18, datahandle); 561 capimsg_setu16(skb->data, 18, datahandle);
556 capimsg_setu16(skb->data, 20, 0); /* Flags */ 562 capimsg_setu16(skb->data, 20, 0); /* Flags */
557 563
558 if (capincci_add_ack(mp, datahandle) < 0) { 564 if (capiminor_add_ack(mp, datahandle) < 0) {
559 skb_pull(skb, CAPI_DATA_B3_REQ_LEN); 565 skb_pull(skb, CAPI_DATA_B3_REQ_LEN);
560 skb_queue_head(&mp->outqueue, skb); 566
561 return count; 567 spin_lock_bh(&mp->outlock);
568 __skb_queue_head(&mp->outqueue, skb);
569 mp->outbytes += len;
570 spin_unlock_bh(&mp->outlock);
571
572 break;
562 } 573 }
563 errcode = capi20_put_message(mp->ap, skb); 574 errcode = capi20_put_message(mp->ap, skb);
564 if (errcode == CAPI_NOERROR) { 575 if (errcode == CAPI_NOERROR) {
565 mp->datahandle++;
566 count++;
567 mp->outbytes -= len;
568#ifdef _DEBUG_DATAFLOW 576#ifdef _DEBUG_DATAFLOW
569 printk(KERN_DEBUG "capi: DATA_B3_REQ %u len=%u\n", 577 printk(KERN_DEBUG "capi: DATA_B3_REQ %u len=%u\n",
570 datahandle, len); 578 datahandle, len);
@@ -575,16 +583,20 @@ static int handle_minor_send(struct capiminor *mp)
575 583
576 if (errcode == CAPI_SENDQUEUEFULL) { 584 if (errcode == CAPI_SENDQUEUEFULL) {
577 skb_pull(skb, CAPI_DATA_B3_REQ_LEN); 585 skb_pull(skb, CAPI_DATA_B3_REQ_LEN);
578 skb_queue_head(&mp->outqueue, skb); 586
587 spin_lock_bh(&mp->outlock);
588 __skb_queue_head(&mp->outqueue, skb);
589 mp->outbytes += len;
590 spin_unlock_bh(&mp->outlock);
591
579 break; 592 break;
580 } 593 }
581 594
582 /* ups, drop packet */ 595 /* ups, drop packet */
583 printk(KERN_ERR "capi: put_message = %x\n", errcode); 596 printk(KERN_ERR "capi: put_message = %x\n", errcode);
584 mp->outbytes -= len;
585 kfree_skb(skb); 597 kfree_skb(skb);
586 } 598 }
587 return count; 599 tty_kref_put(tty);
588} 600}
589 601
590#endif /* CONFIG_ISDN_CAPI_MIDDLEWARE */ 602#endif /* CONFIG_ISDN_CAPI_MIDDLEWARE */
@@ -594,65 +606,56 @@ static void capi_recv_message(struct capi20_appl *ap, struct sk_buff *skb)
594{ 606{
595 struct capidev *cdev = ap->private; 607 struct capidev *cdev = ap->private;
596#ifdef CONFIG_ISDN_CAPI_MIDDLEWARE 608#ifdef CONFIG_ISDN_CAPI_MIDDLEWARE
609 struct tty_struct *tty;
597 struct capiminor *mp; 610 struct capiminor *mp;
598 u16 datahandle; 611 u16 datahandle;
599#endif /* CONFIG_ISDN_CAPI_MIDDLEWARE */ 612#endif /* CONFIG_ISDN_CAPI_MIDDLEWARE */
600 struct capincci *np; 613 struct capincci *np;
601 u32 ncci; 614
602 unsigned long flags; 615 mutex_lock(&cdev->lock);
603 616
604 if (CAPIMSG_CMD(skb->data) == CAPI_CONNECT_B3_CONF) { 617 if (CAPIMSG_CMD(skb->data) == CAPI_CONNECT_B3_CONF) {
605 u16 info = CAPIMSG_U16(skb->data, 12); // Info field 618 u16 info = CAPIMSG_U16(skb->data, 12); // Info field
606 if ((info & 0xff00) == 0) { 619 if ((info & 0xff00) == 0)
607 mutex_lock(&cdev->ncci_list_mtx);
608 capincci_alloc(cdev, CAPIMSG_NCCI(skb->data)); 620 capincci_alloc(cdev, CAPIMSG_NCCI(skb->data));
609 mutex_unlock(&cdev->ncci_list_mtx);
610 }
611 } 621 }
612 if (CAPIMSG_CMD(skb->data) == CAPI_CONNECT_B3_IND) { 622 if (CAPIMSG_CMD(skb->data) == CAPI_CONNECT_B3_IND)
613 mutex_lock(&cdev->ncci_list_mtx);
614 capincci_alloc(cdev, CAPIMSG_NCCI(skb->data)); 623 capincci_alloc(cdev, CAPIMSG_NCCI(skb->data));
615 mutex_unlock(&cdev->ncci_list_mtx); 624
616 }
617 spin_lock_irqsave(&workaround_lock, flags);
618 if (CAPIMSG_COMMAND(skb->data) != CAPI_DATA_B3) { 625 if (CAPIMSG_COMMAND(skb->data) != CAPI_DATA_B3) {
619 skb_queue_tail(&cdev->recvqueue, skb); 626 skb_queue_tail(&cdev->recvqueue, skb);
620 wake_up_interruptible(&cdev->recvwait); 627 wake_up_interruptible(&cdev->recvwait);
621 spin_unlock_irqrestore(&workaround_lock, flags); 628 goto unlock_out;
622 return;
623 } 629 }
624 ncci = CAPIMSG_CONTROL(skb->data); 630
625 for (np = cdev->nccis; np && np->ncci != ncci; np = np->next) 631 np = capincci_find(cdev, CAPIMSG_CONTROL(skb->data));
626 ;
627 if (!np) { 632 if (!np) {
628 printk(KERN_ERR "BUG: capi_signal: ncci not found\n"); 633 printk(KERN_ERR "BUG: capi_signal: ncci not found\n");
629 skb_queue_tail(&cdev->recvqueue, skb); 634 skb_queue_tail(&cdev->recvqueue, skb);
630 wake_up_interruptible(&cdev->recvwait); 635 wake_up_interruptible(&cdev->recvwait);
631 spin_unlock_irqrestore(&workaround_lock, flags); 636 goto unlock_out;
632 return;
633 } 637 }
638
634#ifndef CONFIG_ISDN_CAPI_MIDDLEWARE 639#ifndef CONFIG_ISDN_CAPI_MIDDLEWARE
635 skb_queue_tail(&cdev->recvqueue, skb); 640 skb_queue_tail(&cdev->recvqueue, skb);
636 wake_up_interruptible(&cdev->recvwait); 641 wake_up_interruptible(&cdev->recvwait);
642
637#else /* CONFIG_ISDN_CAPI_MIDDLEWARE */ 643#else /* CONFIG_ISDN_CAPI_MIDDLEWARE */
644
638 mp = np->minorp; 645 mp = np->minorp;
639 if (!mp) { 646 if (!mp) {
640 skb_queue_tail(&cdev->recvqueue, skb); 647 skb_queue_tail(&cdev->recvqueue, skb);
641 wake_up_interruptible(&cdev->recvwait); 648 wake_up_interruptible(&cdev->recvwait);
642 spin_unlock_irqrestore(&workaround_lock, flags); 649 goto unlock_out;
643 return;
644 } 650 }
645
646
647 if (CAPIMSG_SUBCOMMAND(skb->data) == CAPI_IND) { 651 if (CAPIMSG_SUBCOMMAND(skb->data) == CAPI_IND) {
648
649 datahandle = CAPIMSG_U16(skb->data, CAPIMSG_BASELEN+4+4+2); 652 datahandle = CAPIMSG_U16(skb->data, CAPIMSG_BASELEN+4+4+2);
650#ifdef _DEBUG_DATAFLOW 653#ifdef _DEBUG_DATAFLOW
651 printk(KERN_DEBUG "capi_signal: DATA_B3_IND %u len=%d\n", 654 printk(KERN_DEBUG "capi_signal: DATA_B3_IND %u len=%d\n",
652 datahandle, skb->len-CAPIMSG_LEN(skb->data)); 655 datahandle, skb->len-CAPIMSG_LEN(skb->data));
653#endif 656#endif
654 skb_queue_tail(&mp->inqueue, skb); 657 skb_queue_tail(&mp->inqueue, skb);
655 mp->inbytes += skb->len; 658
656 handle_minor_recv(mp); 659 handle_minor_recv(mp);
657 660
658 } else if (CAPIMSG_SUBCOMMAND(skb->data) == CAPI_CONF) { 661 } else if (CAPIMSG_SUBCOMMAND(skb->data) == CAPI_CONF) {
@@ -664,10 +667,13 @@ static void capi_recv_message(struct capi20_appl *ap, struct sk_buff *skb)
664 CAPIMSG_U16(skb->data, CAPIMSG_BASELEN+4+2)); 667 CAPIMSG_U16(skb->data, CAPIMSG_BASELEN+4+2));
665#endif 668#endif
666 kfree_skb(skb); 669 kfree_skb(skb);
667 (void)capiminor_del_ack(mp, datahandle); 670 capiminor_del_ack(mp, datahandle);
668 if (mp->tty) 671 tty = tty_port_tty_get(&mp->port);
669 tty_wakeup(mp->tty); 672 if (tty) {
670 (void)handle_minor_send(mp); 673 tty_wakeup(tty);
674 tty_kref_put(tty);
675 }
676 handle_minor_send(mp);
671 677
672 } else { 678 } else {
673 /* ups, let capi application handle it :-) */ 679 /* ups, let capi application handle it :-) */
@@ -675,7 +681,9 @@ static void capi_recv_message(struct capi20_appl *ap, struct sk_buff *skb)
675 wake_up_interruptible(&cdev->recvwait); 681 wake_up_interruptible(&cdev->recvwait);
676 } 682 }
677#endif /* CONFIG_ISDN_CAPI_MIDDLEWARE */ 683#endif /* CONFIG_ISDN_CAPI_MIDDLEWARE */
678 spin_unlock_irqrestore(&workaround_lock, flags); 684
685unlock_out:
686 mutex_unlock(&cdev->lock);
679} 687}
680 688
681/* -------- file_operations for capidev ----------------------------- */ 689/* -------- file_operations for capidev ----------------------------- */
@@ -686,24 +694,19 @@ capi_read(struct file *file, char __user *buf, size_t count, loff_t *ppos)
686 struct capidev *cdev = (struct capidev *)file->private_data; 694 struct capidev *cdev = (struct capidev *)file->private_data;
687 struct sk_buff *skb; 695 struct sk_buff *skb;
688 size_t copied; 696 size_t copied;
697 int err;
689 698
690 if (!cdev->ap.applid) 699 if (!cdev->ap.applid)
691 return -ENODEV; 700 return -ENODEV;
692 701
693 if ((skb = skb_dequeue(&cdev->recvqueue)) == NULL) { 702 skb = skb_dequeue(&cdev->recvqueue);
694 703 if (!skb) {
695 if (file->f_flags & O_NONBLOCK) 704 if (file->f_flags & O_NONBLOCK)
696 return -EAGAIN; 705 return -EAGAIN;
697 706 err = wait_event_interruptible(cdev->recvwait,
698 for (;;) { 707 (skb = skb_dequeue(&cdev->recvqueue)));
699 interruptible_sleep_on(&cdev->recvwait); 708 if (err)
700 if ((skb = skb_dequeue(&cdev->recvqueue)) != NULL) 709 return err;
701 break;
702 if (signal_pending(current))
703 break;
704 }
705 if (skb == NULL)
706 return -ERESTARTNOHAND;
707 } 710 }
708 if (skb->len > count) { 711 if (skb->len > count) {
709 skb_queue_head(&cdev->recvqueue, skb); 712 skb_queue_head(&cdev->recvqueue, skb);
@@ -753,9 +756,9 @@ capi_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos
753 CAPIMSG_SETAPPID(skb->data, cdev->ap.applid); 756 CAPIMSG_SETAPPID(skb->data, cdev->ap.applid);
754 757
755 if (CAPIMSG_CMD(skb->data) == CAPI_DISCONNECT_B3_RESP) { 758 if (CAPIMSG_CMD(skb->data) == CAPI_DISCONNECT_B3_RESP) {
756 mutex_lock(&cdev->ncci_list_mtx); 759 mutex_lock(&cdev->lock);
757 capincci_free(cdev, CAPIMSG_NCCI(skb->data)); 760 capincci_free(cdev, CAPIMSG_NCCI(skb->data));
758 mutex_unlock(&cdev->ncci_list_mtx); 761 mutex_unlock(&cdev->lock);
759 } 762 }
760 763
761 cdev->errcode = capi20_put_message(&cdev->ap, skb); 764 cdev->errcode = capi20_put_message(&cdev->ap, skb);
@@ -788,30 +791,35 @@ capi_ioctl(struct inode *inode, struct file *file,
788 unsigned int cmd, unsigned long arg) 791 unsigned int cmd, unsigned long arg)
789{ 792{
790 struct capidev *cdev = file->private_data; 793 struct capidev *cdev = file->private_data;
791 struct capi20_appl *ap = &cdev->ap;
792 capi_ioctl_struct data; 794 capi_ioctl_struct data;
793 int retval = -EINVAL; 795 int retval = -EINVAL;
794 void __user *argp = (void __user *)arg; 796 void __user *argp = (void __user *)arg;
795 797
796 switch (cmd) { 798 switch (cmd) {
797 case CAPI_REGISTER: 799 case CAPI_REGISTER:
798 { 800 mutex_lock(&cdev->lock);
799 if (ap->applid)
800 return -EEXIST;
801 801
802 if (copy_from_user(&cdev->ap.rparam, argp, 802 if (cdev->ap.applid) {
803 sizeof(struct capi_register_params))) 803 retval = -EEXIST;
804 return -EFAULT; 804 goto register_out;
805 805 }
806 cdev->ap.private = cdev; 806 if (copy_from_user(&cdev->ap.rparam, argp,
807 cdev->ap.recv_message = capi_recv_message; 807 sizeof(struct capi_register_params))) {
808 cdev->errcode = capi20_register(ap); 808 retval = -EFAULT;
809 if (cdev->errcode) { 809 goto register_out;
810 ap->applid = 0; 810 }
811 return -EIO; 811 cdev->ap.private = cdev;
812 } 812 cdev->ap.recv_message = capi_recv_message;
813 cdev->errcode = capi20_register(&cdev->ap);
814 retval = (int)cdev->ap.applid;
815 if (cdev->errcode) {
816 cdev->ap.applid = 0;
817 retval = -EIO;
813 } 818 }
814 return (int)ap->applid; 819
820register_out:
821 mutex_unlock(&cdev->lock);
822 return retval;
815 823
816 case CAPI_GET_VERSION: 824 case CAPI_GET_VERSION:
817 { 825 {
@@ -910,101 +918,104 @@ capi_ioctl(struct inode *inode, struct file *file,
910 return 0; 918 return 0;
911 919
912 case CAPI_SET_FLAGS: 920 case CAPI_SET_FLAGS:
913 case CAPI_CLR_FLAGS: 921 case CAPI_CLR_FLAGS: {
914 { 922 unsigned userflags;
915 unsigned userflags; 923
916 if (copy_from_user(&userflags, argp, 924 if (copy_from_user(&userflags, argp, sizeof(userflags)))
917 sizeof(userflags))) 925 return -EFAULT;
918 return -EFAULT;
919 if (cmd == CAPI_SET_FLAGS)
920 cdev->userflags |= userflags;
921 else
922 cdev->userflags &= ~userflags;
923 }
924 return 0;
925 926
927 mutex_lock(&cdev->lock);
928 if (cmd == CAPI_SET_FLAGS)
929 cdev->userflags |= userflags;
930 else
931 cdev->userflags &= ~userflags;
932 mutex_unlock(&cdev->lock);
933 return 0;
934 }
926 case CAPI_GET_FLAGS: 935 case CAPI_GET_FLAGS:
927 if (copy_to_user(argp, &cdev->userflags, 936 if (copy_to_user(argp, &cdev->userflags,
928 sizeof(cdev->userflags))) 937 sizeof(cdev->userflags)))
929 return -EFAULT; 938 return -EFAULT;
930 return 0; 939 return 0;
931 940
932 case CAPI_NCCI_OPENCOUNT: 941 case CAPI_NCCI_OPENCOUNT: {
933 { 942 struct capincci *nccip;
934 struct capincci *nccip; 943 unsigned ncci;
935#ifdef CONFIG_ISDN_CAPI_MIDDLEWARE 944 int count = 0;
936 struct capiminor *mp;
937#endif /* CONFIG_ISDN_CAPI_MIDDLEWARE */
938 unsigned ncci;
939 int count = 0;
940 if (copy_from_user(&ncci, argp, sizeof(ncci)))
941 return -EFAULT;
942 945
943 mutex_lock(&cdev->ncci_list_mtx); 946 if (copy_from_user(&ncci, argp, sizeof(ncci)))
944 if ((nccip = capincci_find(cdev, (u32) ncci)) == NULL) { 947 return -EFAULT;
945 mutex_unlock(&cdev->ncci_list_mtx); 948
946 return 0; 949 mutex_lock(&cdev->lock);
947 } 950 nccip = capincci_find(cdev, (u32)ncci);
948#ifdef CONFIG_ISDN_CAPI_MIDDLEWARE 951 if (nccip)
949 if ((mp = nccip->minorp) != NULL) { 952 count = capincci_minor_opencount(nccip);
950 count += atomic_read(&mp->ttyopencount); 953 mutex_unlock(&cdev->lock);
951 } 954 return count;
952#endif /* CONFIG_ISDN_CAPI_MIDDLEWARE */ 955 }
953 mutex_unlock(&cdev->ncci_list_mtx);
954 return count;
955 }
956 return 0;
957 956
958#ifdef CONFIG_ISDN_CAPI_MIDDLEWARE 957#ifdef CONFIG_ISDN_CAPI_MIDDLEWARE
959 case CAPI_NCCI_GETUNIT: 958 case CAPI_NCCI_GETUNIT: {
960 { 959 struct capincci *nccip;
961 struct capincci *nccip; 960 struct capiminor *mp;
962 struct capiminor *mp; 961 unsigned ncci;
963 unsigned ncci; 962 int unit = -ESRCH;
964 int unit = 0; 963
965 if (copy_from_user(&ncci, argp, 964 if (copy_from_user(&ncci, argp, sizeof(ncci)))
966 sizeof(ncci))) 965 return -EFAULT;
967 return -EFAULT; 966
968 mutex_lock(&cdev->ncci_list_mtx); 967 mutex_lock(&cdev->lock);
969 nccip = capincci_find(cdev, (u32) ncci); 968 nccip = capincci_find(cdev, (u32)ncci);
970 if (!nccip || (mp = nccip->minorp) == NULL) { 969 if (nccip) {
971 mutex_unlock(&cdev->ncci_list_mtx); 970 mp = nccip->minorp;
972 return -ESRCH; 971 if (mp)
973 } 972 unit = mp->minor;
974 unit = mp->minor;
975 mutex_unlock(&cdev->ncci_list_mtx);
976 return unit;
977 } 973 }
978 return 0; 974 mutex_unlock(&cdev->lock);
975 return unit;
976 }
979#endif /* CONFIG_ISDN_CAPI_MIDDLEWARE */ 977#endif /* CONFIG_ISDN_CAPI_MIDDLEWARE */
978
979 default:
980 return -EINVAL;
980 } 981 }
981 return -EINVAL;
982} 982}
983 983
984static int 984static int capi_open(struct inode *inode, struct file *file)
985capi_open(struct inode *inode, struct file *file)
986{ 985{
987 int ret; 986 struct capidev *cdev;
988 987
989 lock_kernel(); 988 cdev = kzalloc(sizeof(*cdev), GFP_KERNEL);
990 if (file->private_data) 989 if (!cdev)
991 ret = -EEXIST; 990 return -ENOMEM;
992 else if ((file->private_data = capidev_alloc()) == NULL) 991
993 ret = -ENOMEM; 992 mutex_init(&cdev->lock);
994 else 993 skb_queue_head_init(&cdev->recvqueue);
995 ret = nonseekable_open(inode, file); 994 init_waitqueue_head(&cdev->recvwait);
996 unlock_kernel(); 995 INIT_LIST_HEAD(&cdev->nccis);
997 return ret; 996 file->private_data = cdev;
997
998 mutex_lock(&capidev_list_lock);
999 list_add_tail(&cdev->list, &capidev_list);
1000 mutex_unlock(&capidev_list_lock);
1001
1002 return nonseekable_open(inode, file);
998} 1003}
999 1004
1000static int 1005static int capi_release(struct inode *inode, struct file *file)
1001capi_release(struct inode *inode, struct file *file)
1002{ 1006{
1003 struct capidev *cdev = (struct capidev *)file->private_data; 1007 struct capidev *cdev = file->private_data;
1004 1008
1005 capidev_free(cdev); 1009 mutex_lock(&capidev_list_lock);
1006 file->private_data = NULL; 1010 list_del(&cdev->list);
1007 1011 mutex_unlock(&capidev_list_lock);
1012
1013 if (cdev->ap.applid)
1014 capi20_release(&cdev->ap);
1015 skb_queue_purge(&cdev->recvqueue);
1016 capincci_free(cdev, 0xffffffff);
1017
1018 kfree(cdev);
1008 return 0; 1019 return 0;
1009} 1020}
1010 1021
@@ -1023,182 +1034,159 @@ static const struct file_operations capi_fops =
1023#ifdef CONFIG_ISDN_CAPI_MIDDLEWARE 1034#ifdef CONFIG_ISDN_CAPI_MIDDLEWARE
1024/* -------- tty_operations for capincci ----------------------------- */ 1035/* -------- tty_operations for capincci ----------------------------- */
1025 1036
1026static int capinc_tty_open(struct tty_struct * tty, struct file * file) 1037static int
1038capinc_tty_install(struct tty_driver *driver, struct tty_struct *tty)
1027{ 1039{
1028 struct capiminor *mp; 1040 int idx = tty->index;
1029 unsigned long flags; 1041 struct capiminor *mp = capiminor_get(idx);
1042 int ret = tty_init_termios(tty);
1043
1044 if (ret == 0) {
1045 tty_driver_kref_get(driver);
1046 tty->count++;
1047 tty->driver_data = mp;
1048 driver->ttys[idx] = tty;
1049 } else
1050 capiminor_put(mp);
1051 return ret;
1052}
1030 1053
1031 if ((mp = capiminor_find(iminor(file->f_path.dentry->d_inode))) == NULL) 1054static void capinc_tty_cleanup(struct tty_struct *tty)
1032 return -ENXIO; 1055{
1033 if (mp->nccip == NULL) 1056 struct capiminor *mp = tty->driver_data;
1034 return -ENXIO; 1057 tty->driver_data = NULL;
1058 capiminor_put(mp);
1059}
1035 1060
1036 tty->driver_data = (void *)mp; 1061static int capinc_tty_open(struct tty_struct *tty, struct file *filp)
1062{
1063 struct capiminor *mp = tty->driver_data;
1064 int err;
1065
1066 err = tty_port_open(&mp->port, tty, filp);
1067 if (err)
1068 return err;
1037 1069
1038 spin_lock_irqsave(&workaround_lock, flags);
1039 if (atomic_read(&mp->ttyopencount) == 0)
1040 mp->tty = tty;
1041 atomic_inc(&mp->ttyopencount);
1042#ifdef _DEBUG_REFCOUNT
1043 printk(KERN_DEBUG "capinc_tty_open ocount=%d\n", atomic_read(&mp->ttyopencount));
1044#endif
1045 handle_minor_recv(mp); 1070 handle_minor_recv(mp);
1046 spin_unlock_irqrestore(&workaround_lock, flags);
1047 return 0; 1071 return 0;
1048} 1072}
1049 1073
1050static void capinc_tty_close(struct tty_struct * tty, struct file * file) 1074static void capinc_tty_close(struct tty_struct *tty, struct file *filp)
1051{ 1075{
1052 struct capiminor *mp; 1076 struct capiminor *mp = tty->driver_data;
1053
1054 mp = (struct capiminor *)tty->driver_data;
1055 if (mp) {
1056 if (atomic_dec_and_test(&mp->ttyopencount)) {
1057#ifdef _DEBUG_REFCOUNT
1058 printk(KERN_DEBUG "capinc_tty_close lastclose\n");
1059#endif
1060 tty->driver_data = NULL;
1061 mp->tty = NULL;
1062 }
1063#ifdef _DEBUG_REFCOUNT
1064 printk(KERN_DEBUG "capinc_tty_close ocount=%d\n", atomic_read(&mp->ttyopencount));
1065#endif
1066 if (mp->nccip == NULL)
1067 capiminor_free(mp);
1068 }
1069 1077
1070#ifdef _DEBUG_REFCOUNT 1078 tty_port_close(&mp->port, tty, filp);
1071 printk(KERN_DEBUG "capinc_tty_close\n");
1072#endif
1073} 1079}
1074 1080
1075static int capinc_tty_write(struct tty_struct * tty, 1081static int capinc_tty_write(struct tty_struct *tty,
1076 const unsigned char *buf, int count) 1082 const unsigned char *buf, int count)
1077{ 1083{
1078 struct capiminor *mp = (struct capiminor *)tty->driver_data; 1084 struct capiminor *mp = tty->driver_data;
1079 struct sk_buff *skb; 1085 struct sk_buff *skb;
1080 unsigned long flags;
1081 1086
1082#ifdef _DEBUG_TTYFUNCS 1087#ifdef _DEBUG_TTYFUNCS
1083 printk(KERN_DEBUG "capinc_tty_write(count=%d)\n", count); 1088 printk(KERN_DEBUG "capinc_tty_write(count=%d)\n", count);
1084#endif 1089#endif
1085 1090
1086 if (!mp || !mp->nccip) { 1091 spin_lock_bh(&mp->outlock);
1087#ifdef _DEBUG_TTYFUNCS 1092 skb = mp->outskb;
1088 printk(KERN_DEBUG "capinc_tty_write: mp or mp->ncci NULL\n");
1089#endif
1090 return 0;
1091 }
1092
1093 spin_lock_irqsave(&workaround_lock, flags);
1094 skb = mp->ttyskb;
1095 if (skb) { 1093 if (skb) {
1096 mp->ttyskb = NULL; 1094 mp->outskb = NULL;
1097 skb_queue_tail(&mp->outqueue, skb); 1095 __skb_queue_tail(&mp->outqueue, skb);
1098 mp->outbytes += skb->len; 1096 mp->outbytes += skb->len;
1099 } 1097 }
1100 1098
1101 skb = alloc_skb(CAPI_DATA_B3_REQ_LEN+count, GFP_ATOMIC); 1099 skb = alloc_skb(CAPI_DATA_B3_REQ_LEN+count, GFP_ATOMIC);
1102 if (!skb) { 1100 if (!skb) {
1103 printk(KERN_ERR "capinc_tty_write: alloc_skb failed\n"); 1101 printk(KERN_ERR "capinc_tty_write: alloc_skb failed\n");
1104 spin_unlock_irqrestore(&workaround_lock, flags); 1102 spin_unlock_bh(&mp->outlock);
1105 return -ENOMEM; 1103 return -ENOMEM;
1106 } 1104 }
1107 1105
1108 skb_reserve(skb, CAPI_DATA_B3_REQ_LEN); 1106 skb_reserve(skb, CAPI_DATA_B3_REQ_LEN);
1109 memcpy(skb_put(skb, count), buf, count); 1107 memcpy(skb_put(skb, count), buf, count);
1110 1108
1111 skb_queue_tail(&mp->outqueue, skb); 1109 __skb_queue_tail(&mp->outqueue, skb);
1112 mp->outbytes += skb->len; 1110 mp->outbytes += skb->len;
1113 (void)handle_minor_send(mp); 1111 spin_unlock_bh(&mp->outlock);
1114 (void)handle_minor_recv(mp); 1112
1115 spin_unlock_irqrestore(&workaround_lock, flags); 1113 handle_minor_send(mp);
1114
1116 return count; 1115 return count;
1117} 1116}
1118 1117
1119static int capinc_tty_put_char(struct tty_struct *tty, unsigned char ch) 1118static int capinc_tty_put_char(struct tty_struct *tty, unsigned char ch)
1120{ 1119{
1121 struct capiminor *mp = (struct capiminor *)tty->driver_data; 1120 struct capiminor *mp = tty->driver_data;
1121 bool invoke_send = false;
1122 struct sk_buff *skb; 1122 struct sk_buff *skb;
1123 unsigned long flags;
1124 int ret = 1; 1123 int ret = 1;
1125 1124
1126#ifdef _DEBUG_TTYFUNCS 1125#ifdef _DEBUG_TTYFUNCS
1127 printk(KERN_DEBUG "capinc_put_char(%u)\n", ch); 1126 printk(KERN_DEBUG "capinc_put_char(%u)\n", ch);
1128#endif 1127#endif
1129 1128
1130 if (!mp || !mp->nccip) { 1129 spin_lock_bh(&mp->outlock);
1131#ifdef _DEBUG_TTYFUNCS 1130 skb = mp->outskb;
1132 printk(KERN_DEBUG "capinc_tty_put_char: mp or mp->ncci NULL\n");
1133#endif
1134 return 0;
1135 }
1136
1137 spin_lock_irqsave(&workaround_lock, flags);
1138 skb = mp->ttyskb;
1139 if (skb) { 1131 if (skb) {
1140 if (skb_tailroom(skb) > 0) { 1132 if (skb_tailroom(skb) > 0) {
1141 *(skb_put(skb, 1)) = ch; 1133 *(skb_put(skb, 1)) = ch;
1142 spin_unlock_irqrestore(&workaround_lock, flags); 1134 goto unlock_out;
1143 return 1;
1144 } 1135 }
1145 mp->ttyskb = NULL; 1136 mp->outskb = NULL;
1146 skb_queue_tail(&mp->outqueue, skb); 1137 __skb_queue_tail(&mp->outqueue, skb);
1147 mp->outbytes += skb->len; 1138 mp->outbytes += skb->len;
1148 (void)handle_minor_send(mp); 1139 invoke_send = true;
1149 } 1140 }
1141
1150 skb = alloc_skb(CAPI_DATA_B3_REQ_LEN+CAPI_MAX_BLKSIZE, GFP_ATOMIC); 1142 skb = alloc_skb(CAPI_DATA_B3_REQ_LEN+CAPI_MAX_BLKSIZE, GFP_ATOMIC);
1151 if (skb) { 1143 if (skb) {
1152 skb_reserve(skb, CAPI_DATA_B3_REQ_LEN); 1144 skb_reserve(skb, CAPI_DATA_B3_REQ_LEN);
1153 *(skb_put(skb, 1)) = ch; 1145 *(skb_put(skb, 1)) = ch;
1154 mp->ttyskb = skb; 1146 mp->outskb = skb;
1155 } else { 1147 } else {
1156 printk(KERN_ERR "capinc_put_char: char %u lost\n", ch); 1148 printk(KERN_ERR "capinc_put_char: char %u lost\n", ch);
1157 ret = 0; 1149 ret = 0;
1158 } 1150 }
1159 spin_unlock_irqrestore(&workaround_lock, flags); 1151
1152unlock_out:
1153 spin_unlock_bh(&mp->outlock);
1154
1155 if (invoke_send)
1156 handle_minor_send(mp);
1157
1160 return ret; 1158 return ret;
1161} 1159}
1162 1160
1163static void capinc_tty_flush_chars(struct tty_struct *tty) 1161static void capinc_tty_flush_chars(struct tty_struct *tty)
1164{ 1162{
1165 struct capiminor *mp = (struct capiminor *)tty->driver_data; 1163 struct capiminor *mp = tty->driver_data;
1166 struct sk_buff *skb; 1164 struct sk_buff *skb;
1167 unsigned long flags;
1168 1165
1169#ifdef _DEBUG_TTYFUNCS 1166#ifdef _DEBUG_TTYFUNCS
1170 printk(KERN_DEBUG "capinc_tty_flush_chars\n"); 1167 printk(KERN_DEBUG "capinc_tty_flush_chars\n");
1171#endif 1168#endif
1172 1169
1173 if (!mp || !mp->nccip) { 1170 spin_lock_bh(&mp->outlock);
1174#ifdef _DEBUG_TTYFUNCS 1171 skb = mp->outskb;
1175 printk(KERN_DEBUG "capinc_tty_flush_chars: mp or mp->ncci NULL\n");
1176#endif
1177 return;
1178 }
1179
1180 spin_lock_irqsave(&workaround_lock, flags);
1181 skb = mp->ttyskb;
1182 if (skb) { 1172 if (skb) {
1183 mp->ttyskb = NULL; 1173 mp->outskb = NULL;
1184 skb_queue_tail(&mp->outqueue, skb); 1174 __skb_queue_tail(&mp->outqueue, skb);
1185 mp->outbytes += skb->len; 1175 mp->outbytes += skb->len;
1186 (void)handle_minor_send(mp); 1176 spin_unlock_bh(&mp->outlock);
1187 } 1177
1188 (void)handle_minor_recv(mp); 1178 handle_minor_send(mp);
1189 spin_unlock_irqrestore(&workaround_lock, flags); 1179 } else
1180 spin_unlock_bh(&mp->outlock);
1181
1182 handle_minor_recv(mp);
1190} 1183}
1191 1184
1192static int capinc_tty_write_room(struct tty_struct *tty) 1185static int capinc_tty_write_room(struct tty_struct *tty)
1193{ 1186{
1194 struct capiminor *mp = (struct capiminor *)tty->driver_data; 1187 struct capiminor *mp = tty->driver_data;
1195 int room; 1188 int room;
1196 if (!mp || !mp->nccip) { 1189
1197#ifdef _DEBUG_TTYFUNCS
1198 printk(KERN_DEBUG "capinc_tty_write_room: mp or mp->ncci NULL\n");
1199#endif
1200 return 0;
1201 }
1202 room = CAPINC_MAX_SENDQUEUE-skb_queue_len(&mp->outqueue); 1190 room = CAPINC_MAX_SENDQUEUE-skb_queue_len(&mp->outqueue);
1203 room *= CAPI_MAX_BLKSIZE; 1191 room *= CAPI_MAX_BLKSIZE;
1204#ifdef _DEBUG_TTYFUNCS 1192#ifdef _DEBUG_TTYFUNCS
@@ -1209,13 +1197,8 @@ static int capinc_tty_write_room(struct tty_struct *tty)
1209 1197
1210static int capinc_tty_chars_in_buffer(struct tty_struct *tty) 1198static int capinc_tty_chars_in_buffer(struct tty_struct *tty)
1211{ 1199{
1212 struct capiminor *mp = (struct capiminor *)tty->driver_data; 1200 struct capiminor *mp = tty->driver_data;
1213 if (!mp || !mp->nccip) { 1201
1214#ifdef _DEBUG_TTYFUNCS
1215 printk(KERN_DEBUG "capinc_tty_chars_in_buffer: mp or mp->ncci NULL\n");
1216#endif
1217 return 0;
1218 }
1219#ifdef _DEBUG_TTYFUNCS 1202#ifdef _DEBUG_TTYFUNCS
1220 printk(KERN_DEBUG "capinc_tty_chars_in_buffer = %d nack=%d sq=%d rq=%d\n", 1203 printk(KERN_DEBUG "capinc_tty_chars_in_buffer = %d nack=%d sq=%d rq=%d\n",
1221 mp->outbytes, mp->nack, 1204 mp->outbytes, mp->nack,
@@ -1244,62 +1227,55 @@ static void capinc_tty_set_termios(struct tty_struct *tty, struct ktermios * old
1244#endif 1227#endif
1245} 1228}
1246 1229
1247static void capinc_tty_throttle(struct tty_struct * tty) 1230static void capinc_tty_throttle(struct tty_struct *tty)
1248{ 1231{
1249 struct capiminor *mp = (struct capiminor *)tty->driver_data; 1232 struct capiminor *mp = tty->driver_data;
1250#ifdef _DEBUG_TTYFUNCS 1233#ifdef _DEBUG_TTYFUNCS
1251 printk(KERN_DEBUG "capinc_tty_throttle\n"); 1234 printk(KERN_DEBUG "capinc_tty_throttle\n");
1252#endif 1235#endif
1253 if (mp) 1236 mp->ttyinstop = 1;
1254 mp->ttyinstop = 1;
1255} 1237}
1256 1238
1257static void capinc_tty_unthrottle(struct tty_struct * tty) 1239static void capinc_tty_unthrottle(struct tty_struct *tty)
1258{ 1240{
1259 struct capiminor *mp = (struct capiminor *)tty->driver_data; 1241 struct capiminor *mp = tty->driver_data;
1260 unsigned long flags; 1242
1261#ifdef _DEBUG_TTYFUNCS 1243#ifdef _DEBUG_TTYFUNCS
1262 printk(KERN_DEBUG "capinc_tty_unthrottle\n"); 1244 printk(KERN_DEBUG "capinc_tty_unthrottle\n");
1263#endif 1245#endif
1264 if (mp) { 1246 mp->ttyinstop = 0;
1265 spin_lock_irqsave(&workaround_lock, flags); 1247 handle_minor_recv(mp);
1266 mp->ttyinstop = 0;
1267 handle_minor_recv(mp);
1268 spin_unlock_irqrestore(&workaround_lock, flags);
1269 }
1270} 1248}
1271 1249
1272static void capinc_tty_stop(struct tty_struct *tty) 1250static void capinc_tty_stop(struct tty_struct *tty)
1273{ 1251{
1274 struct capiminor *mp = (struct capiminor *)tty->driver_data; 1252 struct capiminor *mp = tty->driver_data;
1253
1275#ifdef _DEBUG_TTYFUNCS 1254#ifdef _DEBUG_TTYFUNCS
1276 printk(KERN_DEBUG "capinc_tty_stop\n"); 1255 printk(KERN_DEBUG "capinc_tty_stop\n");
1277#endif 1256#endif
1278 if (mp) { 1257 mp->ttyoutstop = 1;
1279 mp->ttyoutstop = 1;
1280 }
1281} 1258}
1282 1259
1283static void capinc_tty_start(struct tty_struct *tty) 1260static void capinc_tty_start(struct tty_struct *tty)
1284{ 1261{
1285 struct capiminor *mp = (struct capiminor *)tty->driver_data; 1262 struct capiminor *mp = tty->driver_data;
1286 unsigned long flags; 1263
1287#ifdef _DEBUG_TTYFUNCS 1264#ifdef _DEBUG_TTYFUNCS
1288 printk(KERN_DEBUG "capinc_tty_start\n"); 1265 printk(KERN_DEBUG "capinc_tty_start\n");
1289#endif 1266#endif
1290 if (mp) { 1267 mp->ttyoutstop = 0;
1291 spin_lock_irqsave(&workaround_lock, flags); 1268 handle_minor_send(mp);
1292 mp->ttyoutstop = 0;
1293 (void)handle_minor_send(mp);
1294 spin_unlock_irqrestore(&workaround_lock, flags);
1295 }
1296} 1269}
1297 1270
1298static void capinc_tty_hangup(struct tty_struct *tty) 1271static void capinc_tty_hangup(struct tty_struct *tty)
1299{ 1272{
1273 struct capiminor *mp = tty->driver_data;
1274
1300#ifdef _DEBUG_TTYFUNCS 1275#ifdef _DEBUG_TTYFUNCS
1301 printk(KERN_DEBUG "capinc_tty_hangup\n"); 1276 printk(KERN_DEBUG "capinc_tty_hangup\n");
1302#endif 1277#endif
1278 tty_port_hangup(&mp->port);
1303} 1279}
1304 1280
1305static int capinc_tty_break_ctl(struct tty_struct *tty, int state) 1281static int capinc_tty_break_ctl(struct tty_struct *tty, int state)
@@ -1331,8 +1307,6 @@ static void capinc_tty_send_xchar(struct tty_struct *tty, char ch)
1331#endif 1307#endif
1332} 1308}
1333 1309
1334static struct tty_driver *capinc_tty_driver;
1335
1336static const struct tty_operations capinc_ops = { 1310static const struct tty_operations capinc_ops = {
1337 .open = capinc_tty_open, 1311 .open = capinc_tty_open,
1338 .close = capinc_tty_close, 1312 .close = capinc_tty_close,
@@ -1352,25 +1326,34 @@ static const struct tty_operations capinc_ops = {
1352 .flush_buffer = capinc_tty_flush_buffer, 1326 .flush_buffer = capinc_tty_flush_buffer,
1353 .set_ldisc = capinc_tty_set_ldisc, 1327 .set_ldisc = capinc_tty_set_ldisc,
1354 .send_xchar = capinc_tty_send_xchar, 1328 .send_xchar = capinc_tty_send_xchar,
1329 .install = capinc_tty_install,
1330 .cleanup = capinc_tty_cleanup,
1355}; 1331};
1356 1332
1357static int capinc_tty_init(void) 1333static int __init capinc_tty_init(void)
1358{ 1334{
1359 struct tty_driver *drv; 1335 struct tty_driver *drv;
1360 1336 int err;
1337
1361 if (capi_ttyminors > CAPINC_MAX_PORTS) 1338 if (capi_ttyminors > CAPINC_MAX_PORTS)
1362 capi_ttyminors = CAPINC_MAX_PORTS; 1339 capi_ttyminors = CAPINC_MAX_PORTS;
1363 if (capi_ttyminors <= 0) 1340 if (capi_ttyminors <= 0)
1364 capi_ttyminors = CAPINC_NR_PORTS; 1341 capi_ttyminors = CAPINC_NR_PORTS;
1365 1342
1366 drv = alloc_tty_driver(capi_ttyminors); 1343 capiminors = kzalloc(sizeof(struct capi_minor *) * capi_ttyminors,
1367 if (!drv) 1344 GFP_KERNEL);
1345 if (!capiminors)
1368 return -ENOMEM; 1346 return -ENOMEM;
1369 1347
1348 drv = alloc_tty_driver(capi_ttyminors);
1349 if (!drv) {
1350 kfree(capiminors);
1351 return -ENOMEM;
1352 }
1370 drv->owner = THIS_MODULE; 1353 drv->owner = THIS_MODULE;
1371 drv->driver_name = "capi_nc"; 1354 drv->driver_name = "capi_nc";
1372 drv->name = "capi"; 1355 drv->name = "capi";
1373 drv->major = capi_ttymajor; 1356 drv->major = 0;
1374 drv->minor_start = 0; 1357 drv->minor_start = 0;
1375 drv->type = TTY_DRIVER_TYPE_SERIAL; 1358 drv->type = TTY_DRIVER_TYPE_SERIAL;
1376 drv->subtype = SERIAL_TYPE_NORMAL; 1359 drv->subtype = SERIAL_TYPE_NORMAL;
@@ -1379,27 +1362,39 @@ static int capinc_tty_init(void)
1379 drv->init_termios.c_oflag = OPOST | ONLCR; 1362 drv->init_termios.c_oflag = OPOST | ONLCR;
1380 drv->init_termios.c_cflag = B9600 | CS8 | CREAD | HUPCL | CLOCAL; 1363 drv->init_termios.c_cflag = B9600 | CS8 | CREAD | HUPCL | CLOCAL;
1381 drv->init_termios.c_lflag = 0; 1364 drv->init_termios.c_lflag = 0;
1382 drv->flags = TTY_DRIVER_REAL_RAW|TTY_DRIVER_RESET_TERMIOS; 1365 drv->flags =
1366 TTY_DRIVER_REAL_RAW | TTY_DRIVER_RESET_TERMIOS |
1367 TTY_DRIVER_DYNAMIC_DEV;
1383 tty_set_operations(drv, &capinc_ops); 1368 tty_set_operations(drv, &capinc_ops);
1384 if (tty_register_driver(drv)) { 1369
1370 err = tty_register_driver(drv);
1371 if (err) {
1385 put_tty_driver(drv); 1372 put_tty_driver(drv);
1373 kfree(capiminors);
1386 printk(KERN_ERR "Couldn't register capi_nc driver\n"); 1374 printk(KERN_ERR "Couldn't register capi_nc driver\n");
1387 return -1; 1375 return err;
1388 } 1376 }
1389 capinc_tty_driver = drv; 1377 capinc_tty_driver = drv;
1390 return 0; 1378 return 0;
1391} 1379}
1392 1380
1393static void capinc_tty_exit(void) 1381static void __exit capinc_tty_exit(void)
1394{ 1382{
1395 struct tty_driver *drv = capinc_tty_driver; 1383 tty_unregister_driver(capinc_tty_driver);
1396 int retval; 1384 put_tty_driver(capinc_tty_driver);
1397 if ((retval = tty_unregister_driver(drv))) 1385 kfree(capiminors);
1398 printk(KERN_ERR "capi: failed to unregister capi_nc driver (%d)\n", retval);
1399 put_tty_driver(drv);
1400} 1386}
1401 1387
1402#endif /* CONFIG_ISDN_CAPI_MIDDLEWARE */ 1388#else /* !CONFIG_ISDN_CAPI_MIDDLEWARE */
1389
1390static inline int capinc_tty_init(void)
1391{
1392 return 0;
1393}
1394
1395static inline void capinc_tty_exit(void) { }
1396
1397#endif /* !CONFIG_ISDN_CAPI_MIDDLEWARE */
1403 1398
1404/* -------- /proc functions ----------------------------------------- */ 1399/* -------- /proc functions ----------------------------------------- */
1405 1400
@@ -1407,134 +1402,91 @@ static void capinc_tty_exit(void)
1407 * /proc/capi/capi20: 1402 * /proc/capi/capi20:
1408 * minor applid nrecvctlpkt nrecvdatapkt nsendctlpkt nsenddatapkt 1403 * minor applid nrecvctlpkt nrecvdatapkt nsendctlpkt nsenddatapkt
1409 */ 1404 */
1410static int proc_capidev_read_proc(char *page, char **start, off_t off, 1405static int capi20_proc_show(struct seq_file *m, void *v)
1411 int count, int *eof, void *data)
1412{ 1406{
1413 struct capidev *cdev; 1407 struct capidev *cdev;
1414 struct list_head *l; 1408 struct list_head *l;
1415 int len = 0;
1416 1409
1417 read_lock(&capidev_list_lock); 1410 mutex_lock(&capidev_list_lock);
1418 list_for_each(l, &capidev_list) { 1411 list_for_each(l, &capidev_list) {
1419 cdev = list_entry(l, struct capidev, list); 1412 cdev = list_entry(l, struct capidev, list);
1420 len += sprintf(page+len, "0 %d %lu %lu %lu %lu\n", 1413 seq_printf(m, "0 %d %lu %lu %lu %lu\n",
1421 cdev->ap.applid, 1414 cdev->ap.applid,
1422 cdev->ap.nrecvctlpkt, 1415 cdev->ap.nrecvctlpkt,
1423 cdev->ap.nrecvdatapkt, 1416 cdev->ap.nrecvdatapkt,
1424 cdev->ap.nsentctlpkt, 1417 cdev->ap.nsentctlpkt,
1425 cdev->ap.nsentdatapkt); 1418 cdev->ap.nsentdatapkt);
1426 if (len <= off) {
1427 off -= len;
1428 len = 0;
1429 } else {
1430 if (len-off > count)
1431 goto endloop;
1432 }
1433 } 1419 }
1420 mutex_unlock(&capidev_list_lock);
1421 return 0;
1422}
1434 1423
1435endloop: 1424static int capi20_proc_open(struct inode *inode, struct file *file)
1436 read_unlock(&capidev_list_lock); 1425{
1437 if (len < count) 1426 return single_open(file, capi20_proc_show, NULL);
1438 *eof = 1;
1439 if (len > count) len = count;
1440 if (len < 0) len = 0;
1441 return len;
1442} 1427}
1443 1428
1429static const struct file_operations capi20_proc_fops = {
1430 .owner = THIS_MODULE,
1431 .open = capi20_proc_open,
1432 .read = seq_read,
1433 .llseek = seq_lseek,
1434 .release = single_release,
1435};
1436
1444/* 1437/*
1445 * /proc/capi/capi20ncci: 1438 * /proc/capi/capi20ncci:
1446 * applid ncci 1439 * applid ncci
1447 */ 1440 */
1448static int proc_capincci_read_proc(char *page, char **start, off_t off, 1441static int capi20ncci_proc_show(struct seq_file *m, void *v)
1449 int count, int *eof, void *data)
1450{ 1442{
1451 struct capidev *cdev; 1443 struct capidev *cdev;
1452 struct capincci *np; 1444 struct capincci *np;
1453 struct list_head *l;
1454 int len = 0;
1455 1445
1456 read_lock(&capidev_list_lock); 1446 mutex_lock(&capidev_list_lock);
1457 list_for_each(l, &capidev_list) { 1447 list_for_each_entry(cdev, &capidev_list, list) {
1458 cdev = list_entry(l, struct capidev, list); 1448 mutex_lock(&cdev->lock);
1459 for (np=cdev->nccis; np; np = np->next) { 1449 list_for_each_entry(np, &cdev->nccis, list)
1460 len += sprintf(page+len, "%d 0x%x\n", 1450 seq_printf(m, "%d 0x%x\n", cdev->ap.applid, np->ncci);
1461 cdev->ap.applid, 1451 mutex_unlock(&cdev->lock);
1462 np->ncci);
1463 if (len <= off) {
1464 off -= len;
1465 len = 0;
1466 } else {
1467 if (len-off > count)
1468 goto endloop;
1469 }
1470 }
1471 } 1452 }
1472endloop: 1453 mutex_unlock(&capidev_list_lock);
1473 read_unlock(&capidev_list_lock); 1454 return 0;
1474 *start = page+off; 1455}
1475 if (len < count) 1456
1476 *eof = 1; 1457static int capi20ncci_proc_open(struct inode *inode, struct file *file)
1477 if (len>count) len = count; 1458{
1478 if (len<0) len = 0; 1459 return single_open(file, capi20ncci_proc_show, NULL);
1479 return len;
1480} 1460}
1481 1461
1482static struct procfsentries { 1462static const struct file_operations capi20ncci_proc_fops = {
1483 char *name; 1463 .owner = THIS_MODULE,
1484 mode_t mode; 1464 .open = capi20ncci_proc_open,
1485 int (*read_proc)(char *page, char **start, off_t off, 1465 .read = seq_read,
1486 int count, int *eof, void *data); 1466 .llseek = seq_lseek,
1487 struct proc_dir_entry *procent; 1467 .release = single_release,
1488} procfsentries[] = {
1489 /* { "capi", S_IFDIR, 0 }, */
1490 { "capi/capi20", 0 , proc_capidev_read_proc },
1491 { "capi/capi20ncci", 0 , proc_capincci_read_proc },
1492}; 1468};
1493 1469
1494static void __init proc_init(void) 1470static void __init proc_init(void)
1495{ 1471{
1496 int nelem = ARRAY_SIZE(procfsentries); 1472 proc_create("capi/capi20", 0, NULL, &capi20_proc_fops);
1497 int i; 1473 proc_create("capi/capi20ncci", 0, NULL, &capi20ncci_proc_fops);
1498
1499 for (i=0; i < nelem; i++) {
1500 struct procfsentries *p = procfsentries + i;
1501 p->procent = create_proc_entry(p->name, p->mode, NULL);
1502 if (p->procent) p->procent->read_proc = p->read_proc;
1503 }
1504} 1474}
1505 1475
1506static void __exit proc_exit(void) 1476static void __exit proc_exit(void)
1507{ 1477{
1508 int nelem = ARRAY_SIZE(procfsentries); 1478 remove_proc_entry("capi/capi20", NULL);
1509 int i; 1479 remove_proc_entry("capi/capi20ncci", NULL);
1510
1511 for (i=nelem-1; i >= 0; i--) {
1512 struct procfsentries *p = procfsentries + i;
1513 if (p->procent) {
1514 remove_proc_entry(p->name, NULL);
1515 p->procent = NULL;
1516 }
1517 }
1518} 1480}
1519 1481
1520/* -------- init function and module interface ---------------------- */ 1482/* -------- init function and module interface ---------------------- */
1521 1483
1522 1484
1523static char rev[32];
1524
1525static int __init capi_init(void) 1485static int __init capi_init(void)
1526{ 1486{
1527 char *p; 1487 const char *compileinfo;
1528 char *compileinfo;
1529 int major_ret; 1488 int major_ret;
1530 1489
1531 if ((p = strchr(revision, ':')) != NULL && p[1]) {
1532 strlcpy(rev, p + 2, sizeof(rev));
1533 if ((p = strchr(rev, '$')) != NULL && p > rev)
1534 *(p-1) = 0;
1535 } else
1536 strcpy(rev, "1.0");
1537
1538 major_ret = register_chrdev(capi_major, "capi20", &capi_fops); 1490 major_ret = register_chrdev(capi_major, "capi20", &capi_fops);
1539 if (major_ret < 0) { 1491 if (major_ret < 0) {
1540 printk(KERN_ERR "capi20: unable to get major %d\n", capi_major); 1492 printk(KERN_ERR "capi20: unable to get major %d\n", capi_major);
@@ -1548,28 +1500,24 @@ static int __init capi_init(void)
1548 1500
1549 device_create(capi_class, NULL, MKDEV(capi_major, 0), NULL, "capi"); 1501 device_create(capi_class, NULL, MKDEV(capi_major, 0), NULL, "capi");
1550 1502
1551#ifdef CONFIG_ISDN_CAPI_MIDDLEWARE
1552 if (capinc_tty_init() < 0) { 1503 if (capinc_tty_init() < 0) {
1553 device_destroy(capi_class, MKDEV(capi_major, 0)); 1504 device_destroy(capi_class, MKDEV(capi_major, 0));
1554 class_destroy(capi_class); 1505 class_destroy(capi_class);
1555 unregister_chrdev(capi_major, "capi20"); 1506 unregister_chrdev(capi_major, "capi20");
1556 return -ENOMEM; 1507 return -ENOMEM;
1557 } 1508 }
1558#endif /* CONFIG_ISDN_CAPI_MIDDLEWARE */
1559 1509
1560 proc_init(); 1510 proc_init();
1561 1511
1562#ifdef CONFIG_ISDN_CAPI_MIDDLEWARE
1563#if defined(CONFIG_ISDN_CAPI_CAPIFS) || defined(CONFIG_ISDN_CAPI_CAPIFS_MODULE) 1512#if defined(CONFIG_ISDN_CAPI_CAPIFS) || defined(CONFIG_ISDN_CAPI_CAPIFS_MODULE)
1564 compileinfo = " (middleware+capifs)"; 1513 compileinfo = " (middleware+capifs)";
1565#else 1514#elif defined(CONFIG_ISDN_CAPI_MIDDLEWARE)
1566 compileinfo = " (no capifs)"; 1515 compileinfo = " (no capifs)";
1567#endif
1568#else 1516#else
1569 compileinfo = " (no middleware)"; 1517 compileinfo = " (no middleware)";
1570#endif 1518#endif
1571 printk(KERN_NOTICE "capi20: Rev %s: started up with major %d%s\n", 1519 printk(KERN_NOTICE "CAPI 2.0 started up with major %d%s\n",
1572 rev, capi_major, compileinfo); 1520 capi_major, compileinfo);
1573 1521
1574 return 0; 1522 return 0;
1575} 1523}
@@ -1582,10 +1530,7 @@ static void __exit capi_exit(void)
1582 class_destroy(capi_class); 1530 class_destroy(capi_class);
1583 unregister_chrdev(capi_major, "capi20"); 1531 unregister_chrdev(capi_major, "capi20");
1584 1532
1585#ifdef CONFIG_ISDN_CAPI_MIDDLEWARE
1586 capinc_tty_exit(); 1533 capinc_tty_exit();
1587#endif
1588 printk(KERN_NOTICE "capi: Rev %s: unloaded\n", rev);
1589} 1534}
1590 1535
1591module_init(capi_init); 1536module_init(capi_init);
diff --git a/drivers/isdn/capi/capidrv.c b/drivers/isdn/capi/capidrv.c
index 3e6d17f42a98..bf55ed5f38e3 100644
--- a/drivers/isdn/capi/capidrv.c
+++ b/drivers/isdn/capi/capidrv.c
@@ -24,6 +24,7 @@
24#include <linux/isdn.h> 24#include <linux/isdn.h>
25#include <linux/isdnif.h> 25#include <linux/isdnif.h>
26#include <linux/proc_fs.h> 26#include <linux/proc_fs.h>
27#include <linux/seq_file.h>
27#include <linux/capi.h> 28#include <linux/capi.h>
28#include <linux/kernelcapi.h> 29#include <linux/kernelcapi.h>
29#include <linux/ctype.h> 30#include <linux/ctype.h>
@@ -34,7 +35,6 @@
34#include <linux/isdn/capicmd.h> 35#include <linux/isdn/capicmd.h>
35#include "capidrv.h" 36#include "capidrv.h"
36 37
37static char *revision = "$Revision: 1.1.2.2 $";
38static int debugmode = 0; 38static int debugmode = 0;
39 39
40MODULE_DESCRIPTION("CAPI4Linux: Interface to ISDN4Linux"); 40MODULE_DESCRIPTION("CAPI4Linux: Interface to ISDN4Linux");
@@ -830,7 +830,7 @@ static void handle_controller(_cmsg * cmsg)
830 case 0: break; 830 case 0: break;
831 case 1: s = "unknown class"; break; 831 case 1: s = "unknown class"; break;
832 case 2: s = "unknown function"; break; 832 case 2: s = "unknown function"; break;
833 default: s = "unkown error"; break; 833 default: s = "unknown error"; break;
834 } 834 }
835 if (s) 835 if (s)
836 printk(KERN_INFO "capidrv-%d: %s from controller 0x%x function %d: %s\n", 836 printk(KERN_INFO "capidrv-%d: %s from controller 0x%x function %d: %s\n",
@@ -2210,96 +2210,73 @@ static int capidrv_delcontr(u16 contr)
2210} 2210}
2211 2211
2212 2212
2213static void lower_callback(unsigned int cmd, u32 contr, void *data) 2213static int
2214lower_callback(struct notifier_block *nb, unsigned long val, void *v)
2214{ 2215{
2216 capi_profile profile;
2217 u32 contr = (long)v;
2215 2218
2216 switch (cmd) { 2219 switch (val) {
2217 case KCI_CONTRUP: 2220 case CAPICTR_UP:
2218 printk(KERN_INFO "capidrv: controller %hu up\n", contr); 2221 printk(KERN_INFO "capidrv: controller %hu up\n", contr);
2219 (void) capidrv_addcontr(contr, (capi_profile *) data); 2222 if (capi20_get_profile(contr, &profile) == CAPI_NOERROR)
2223 (void) capidrv_addcontr(contr, &profile);
2220 break; 2224 break;
2221 case KCI_CONTRDOWN: 2225 case CAPICTR_DOWN:
2222 printk(KERN_INFO "capidrv: controller %hu down\n", contr); 2226 printk(KERN_INFO "capidrv: controller %hu down\n", contr);
2223 (void) capidrv_delcontr(contr); 2227 (void) capidrv_delcontr(contr);
2224 break; 2228 break;
2225 } 2229 }
2230 return NOTIFY_OK;
2226} 2231}
2227 2232
2228/* 2233/*
2229 * /proc/capi/capidrv: 2234 * /proc/capi/capidrv:
2230 * nrecvctlpkt nrecvdatapkt nsendctlpkt nsenddatapkt 2235 * nrecvctlpkt nrecvdatapkt nsendctlpkt nsenddatapkt
2231 */ 2236 */
2232static int proc_capidrv_read_proc(char *page, char **start, off_t off, 2237static int capidrv_proc_show(struct seq_file *m, void *v)
2233 int count, int *eof, void *data)
2234{ 2238{
2235 int len = 0; 2239 seq_printf(m, "%lu %lu %lu %lu\n",
2236
2237 len += sprintf(page+len, "%lu %lu %lu %lu\n",
2238 global.ap.nrecvctlpkt, 2240 global.ap.nrecvctlpkt,
2239 global.ap.nrecvdatapkt, 2241 global.ap.nrecvdatapkt,
2240 global.ap.nsentctlpkt, 2242 global.ap.nsentctlpkt,
2241 global.ap.nsentdatapkt); 2243 global.ap.nsentdatapkt);
2242 if (off+count >= len) 2244 return 0;
2243 *eof = 1;
2244 if (len < off)
2245 return 0;
2246 *start = page + off;
2247 return ((count < len-off) ? count : len-off);
2248} 2245}
2249 2246
2250static struct procfsentries { 2247static int capidrv_proc_open(struct inode *inode, struct file *file)
2251 char *name; 2248{
2252 mode_t mode; 2249 return single_open(file, capidrv_proc_show, NULL);
2253 int (*read_proc)(char *page, char **start, off_t off, 2250}
2254 int count, int *eof, void *data); 2251
2255 struct proc_dir_entry *procent; 2252static const struct file_operations capidrv_proc_fops = {
2256} procfsentries[] = { 2253 .owner = THIS_MODULE,
2257 /* { "capi", S_IFDIR, 0 }, */ 2254 .open = capidrv_proc_open,
2258 { "capi/capidrv", 0 , proc_capidrv_read_proc }, 2255 .read = seq_read,
2256 .llseek = seq_lseek,
2257 .release = single_release,
2259}; 2258};
2260 2259
2261static void __init proc_init(void) 2260static void __init proc_init(void)
2262{ 2261{
2263 int nelem = ARRAY_SIZE(procfsentries); 2262 proc_create("capi/capidrv", 0, NULL, &capidrv_proc_fops);
2264 int i;
2265
2266 for (i=0; i < nelem; i++) {
2267 struct procfsentries *p = procfsentries + i;
2268 p->procent = create_proc_entry(p->name, p->mode, NULL);
2269 if (p->procent) p->procent->read_proc = p->read_proc;
2270 }
2271} 2263}
2272 2264
2273static void __exit proc_exit(void) 2265static void __exit proc_exit(void)
2274{ 2266{
2275 int nelem = ARRAY_SIZE(procfsentries); 2267 remove_proc_entry("capi/capidrv", NULL);
2276 int i;
2277
2278 for (i=nelem-1; i >= 0; i--) {
2279 struct procfsentries *p = procfsentries + i;
2280 if (p->procent) {
2281 remove_proc_entry(p->name, NULL);
2282 p->procent = NULL;
2283 }
2284 }
2285} 2268}
2286 2269
2270static struct notifier_block capictr_nb = {
2271 .notifier_call = lower_callback,
2272};
2273
2287static int __init capidrv_init(void) 2274static int __init capidrv_init(void)
2288{ 2275{
2289 capi_profile profile; 2276 capi_profile profile;
2290 char rev[32];
2291 char *p;
2292 u32 ncontr, contr; 2277 u32 ncontr, contr;
2293 u16 errcode; 2278 u16 errcode;
2294 2279
2295 if ((p = strchr(revision, ':')) != NULL && p[1]) {
2296 strncpy(rev, p + 2, sizeof(rev));
2297 rev[sizeof(rev)-1] = 0;
2298 if ((p = strchr(rev, '$')) != NULL && p > rev)
2299 *(p-1) = 0;
2300 } else
2301 strcpy(rev, "1.0");
2302
2303 global.ap.rparam.level3cnt = -2; /* number of bchannels twice */ 2280 global.ap.rparam.level3cnt = -2; /* number of bchannels twice */
2304 global.ap.rparam.datablkcnt = 16; 2281 global.ap.rparam.datablkcnt = 16;
2305 global.ap.rparam.datablklen = 2048; 2282 global.ap.rparam.datablklen = 2048;
@@ -2310,7 +2287,7 @@ static int __init capidrv_init(void)
2310 return -EIO; 2287 return -EIO;
2311 } 2288 }
2312 2289
2313 capi20_set_callback(&global.ap, lower_callback); 2290 register_capictr_notifier(&capictr_nb);
2314 2291
2315 errcode = capi20_get_profile(0, &profile); 2292 errcode = capi20_get_profile(0, &profile);
2316 if (errcode != CAPI_NOERROR) { 2293 if (errcode != CAPI_NOERROR) {
@@ -2327,29 +2304,15 @@ static int __init capidrv_init(void)
2327 } 2304 }
2328 proc_init(); 2305 proc_init();
2329 2306
2330 printk(KERN_NOTICE "capidrv: Rev %s: loaded\n", rev);
2331 return 0; 2307 return 0;
2332} 2308}
2333 2309
2334static void __exit capidrv_exit(void) 2310static void __exit capidrv_exit(void)
2335{ 2311{
2336 char rev[32]; 2312 unregister_capictr_notifier(&capictr_nb);
2337 char *p;
2338
2339 if ((p = strchr(revision, ':')) != NULL) {
2340 strncpy(rev, p + 1, sizeof(rev));
2341 rev[sizeof(rev)-1] = 0;
2342 if ((p = strchr(rev, '$')) != NULL)
2343 *p = 0;
2344 } else {
2345 strcpy(rev, " ??? ");
2346 }
2347
2348 capi20_release(&global.ap); 2313 capi20_release(&global.ap);
2349 2314
2350 proc_exit(); 2315 proc_exit();
2351
2352 printk(KERN_NOTICE "capidrv: Rev%s: unloaded\n", rev);
2353} 2316}
2354 2317
2355module_init(capidrv_init); 2318module_init(capidrv_init);
diff --git a/drivers/isdn/capi/capifs.c b/drivers/isdn/capi/capifs.c
index 9f8f67b6c07f..2b83850997c3 100644
--- a/drivers/isdn/capi/capifs.c
+++ b/drivers/isdn/capi/capifs.c
@@ -11,6 +11,7 @@
11 11
12#include <linux/fs.h> 12#include <linux/fs.h>
13#include <linux/mount.h> 13#include <linux/mount.h>
14#include <linux/slab.h>
14#include <linux/namei.h> 15#include <linux/namei.h>
15#include <linux/module.h> 16#include <linux/module.h>
16#include <linux/init.h> 17#include <linux/init.h>
@@ -25,14 +26,10 @@ MODULE_LICENSE("GPL");
25 26
26/* ------------------------------------------------------------------ */ 27/* ------------------------------------------------------------------ */
27 28
28static char *revision = "$Revision: 1.1.2.3 $";
29
30/* ------------------------------------------------------------------ */
31
32#define CAPIFS_SUPER_MAGIC (('C'<<8)|'N') 29#define CAPIFS_SUPER_MAGIC (('C'<<8)|'N')
33 30
34static struct vfsmount *capifs_mnt; 31static struct vfsmount *capifs_mnt;
35static struct dentry *capifs_root; 32static int capifs_mnt_count;
36 33
37static struct { 34static struct {
38 int setuid; 35 int setuid;
@@ -118,7 +115,7 @@ capifs_fill_super(struct super_block *s, void *data, int silent)
118 inode->i_fop = &simple_dir_operations; 115 inode->i_fop = &simple_dir_operations;
119 inode->i_nlink = 2; 116 inode->i_nlink = 2;
120 117
121 capifs_root = s->s_root = d_alloc_root(inode); 118 s->s_root = d_alloc_root(inode);
122 if (s->s_root) 119 if (s->s_root)
123 return 0; 120 return 0;
124 121
@@ -141,82 +138,98 @@ static struct file_system_type capifs_fs_type = {
141 .kill_sb = kill_anon_super, 138 .kill_sb = kill_anon_super,
142}; 139};
143 140
144static struct dentry *get_node(int num) 141static struct dentry *new_ncci(unsigned int number, dev_t device)
145{ 142{
146 char s[10]; 143 struct super_block *s = capifs_mnt->mnt_sb;
147 struct dentry *root = capifs_root; 144 struct dentry *root = s->s_root;
145 struct dentry *dentry;
146 struct inode *inode;
147 char name[10];
148 int namelen;
149
148 mutex_lock(&root->d_inode->i_mutex); 150 mutex_lock(&root->d_inode->i_mutex);
149 return lookup_one_len(s, root, sprintf(s, "%d", num));
150}
151 151
152void capifs_new_ncci(unsigned int number, dev_t device) 152 namelen = sprintf(name, "%d", number);
153{ 153 dentry = lookup_one_len(name, root, namelen);
154 struct dentry *dentry; 154 if (IS_ERR(dentry)) {
155 struct inode *inode = new_inode(capifs_mnt->mnt_sb); 155 dentry = NULL;
156 if (!inode) 156 goto unlock_out;
157 return; 157 }
158 inode->i_ino = number+2;
159 158
160 dentry = get_node(number); 159 if (dentry->d_inode) {
160 dput(dentry);
161 dentry = NULL;
162 goto unlock_out;
163 }
164
165 inode = new_inode(s);
166 if (!inode) {
167 dput(dentry);
168 dentry = NULL;
169 goto unlock_out;
170 }
161 171
162 /* config contents is protected by root's i_mutex */ 172 /* config contents is protected by root's i_mutex */
163 inode->i_uid = config.setuid ? config.uid : current_fsuid(); 173 inode->i_uid = config.setuid ? config.uid : current_fsuid();
164 inode->i_gid = config.setgid ? config.gid : current_fsgid(); 174 inode->i_gid = config.setgid ? config.gid : current_fsgid();
165 inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME; 175 inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME;
176 inode->i_ino = number + 2;
166 init_special_inode(inode, S_IFCHR|config.mode, device); 177 init_special_inode(inode, S_IFCHR|config.mode, device);
167 //inode->i_op = &capifs_file_inode_operations;
168 178
169 if (!IS_ERR(dentry) && !dentry->d_inode) 179 d_instantiate(dentry, inode);
170 d_instantiate(dentry, inode); 180 dget(dentry);
171 mutex_unlock(&capifs_root->d_inode->i_mutex); 181
182unlock_out:
183 mutex_unlock(&root->d_inode->i_mutex);
184
185 return dentry;
172} 186}
173 187
174void capifs_free_ncci(unsigned int number) 188struct dentry *capifs_new_ncci(unsigned int number, dev_t device)
175{ 189{
176 struct dentry *dentry = get_node(number); 190 struct dentry *dentry;
177 191
178 if (!IS_ERR(dentry)) { 192 if (simple_pin_fs(&capifs_fs_type, &capifs_mnt, &capifs_mnt_count) < 0)
179 struct inode *inode = dentry->d_inode; 193 return NULL;
180 if (inode) { 194
181 inode->i_nlink--; 195 dentry = new_ncci(number, device);
182 d_delete(dentry); 196 if (!dentry)
183 dput(dentry); 197 simple_release_fs(&capifs_mnt, &capifs_mnt_count);
184 } 198
199 return dentry;
200}
201
202void capifs_free_ncci(struct dentry *dentry)
203{
204 struct dentry *root = capifs_mnt->mnt_sb->s_root;
205 struct inode *inode;
206
207 if (!dentry)
208 return;
209
210 mutex_lock(&root->d_inode->i_mutex);
211
212 inode = dentry->d_inode;
213 if (inode) {
214 drop_nlink(inode);
215 d_delete(dentry);
185 dput(dentry); 216 dput(dentry);
186 } 217 }
187 mutex_unlock(&capifs_root->d_inode->i_mutex); 218 dput(dentry);
219
220 mutex_unlock(&root->d_inode->i_mutex);
221
222 simple_release_fs(&capifs_mnt, &capifs_mnt_count);
188} 223}
189 224
190static int __init capifs_init(void) 225static int __init capifs_init(void)
191{ 226{
192 char rev[32]; 227 return register_filesystem(&capifs_fs_type);
193 char *p;
194 int err;
195
196 if ((p = strchr(revision, ':')) != NULL && p[1]) {
197 strlcpy(rev, p + 2, sizeof(rev));
198 if ((p = strchr(rev, '$')) != NULL && p > rev)
199 *(p-1) = 0;
200 } else
201 strcpy(rev, "1.0");
202
203 err = register_filesystem(&capifs_fs_type);
204 if (!err) {
205 capifs_mnt = kern_mount(&capifs_fs_type);
206 if (IS_ERR(capifs_mnt)) {
207 err = PTR_ERR(capifs_mnt);
208 unregister_filesystem(&capifs_fs_type);
209 }
210 }
211 if (!err)
212 printk(KERN_NOTICE "capifs: Rev %s\n", rev);
213 return err;
214} 228}
215 229
216static void __exit capifs_exit(void) 230static void __exit capifs_exit(void)
217{ 231{
218 unregister_filesystem(&capifs_fs_type); 232 unregister_filesystem(&capifs_fs_type);
219 mntput(capifs_mnt);
220} 233}
221 234
222EXPORT_SYMBOL(capifs_new_ncci); 235EXPORT_SYMBOL(capifs_new_ncci);
diff --git a/drivers/isdn/capi/capifs.h b/drivers/isdn/capi/capifs.h
index d0bd4c3c430a..e193d1189531 100644
--- a/drivers/isdn/capi/capifs.h
+++ b/drivers/isdn/capi/capifs.h
@@ -7,5 +7,22 @@
7 * 7 *
8 */ 8 */
9 9
10void capifs_new_ncci(unsigned int num, dev_t device); 10#include <linux/dcache.h>
11void capifs_free_ncci(unsigned int num); 11
12#if defined(CONFIG_ISDN_CAPI_CAPIFS) || defined(CONFIG_ISDN_CAPI_CAPIFS_MODULE)
13
14struct dentry *capifs_new_ncci(unsigned int num, dev_t device);
15void capifs_free_ncci(struct dentry *dentry);
16
17#else
18
19static inline struct dentry *capifs_new_ncci(unsigned int num, dev_t device)
20{
21 return NULL;
22}
23
24static inline void capifs_free_ncci(struct dentry *dentry)
25{
26}
27
28#endif
diff --git a/drivers/isdn/capi/capilib.c b/drivers/isdn/capi/capilib.c
index fcaa1241ee77..0b041df2108c 100644
--- a/drivers/isdn/capi/capilib.c
+++ b/drivers/isdn/capi/capilib.c
@@ -1,4 +1,5 @@
1 1
2#include <linux/slab.h>
2#include <linux/kernel.h> 3#include <linux/kernel.h>
3#include <linux/module.h> 4#include <linux/module.h>
4#include <linux/isdn/capilli.h> 5#include <linux/isdn/capilli.h>
diff --git a/drivers/isdn/capi/capiutil.c b/drivers/isdn/capi/capiutil.c
index 26626eead828..03c469e4451f 100644
--- a/drivers/isdn/capi/capiutil.c
+++ b/drivers/isdn/capi/capiutil.c
@@ -18,6 +18,7 @@
18#include <linux/mm.h> 18#include <linux/mm.h>
19#include <linux/init.h> 19#include <linux/init.h>
20#include <linux/isdn/capiutil.h> 20#include <linux/isdn/capiutil.h>
21#include <linux/slab.h>
21 22
22/* from CAPI2.0 DDK AVM Berlin GmbH */ 23/* from CAPI2.0 DDK AVM Berlin GmbH */
23 24
diff --git a/drivers/isdn/capi/kcapi.c b/drivers/isdn/capi/kcapi.c
index dc506ab99cac..bd00dceacaf0 100644
--- a/drivers/isdn/capi/kcapi.c
+++ b/drivers/isdn/capi/kcapi.c
@@ -27,6 +27,7 @@
27#include <linux/init.h> 27#include <linux/init.h>
28#include <linux/moduleparam.h> 28#include <linux/moduleparam.h>
29#include <linux/delay.h> 29#include <linux/delay.h>
30#include <linux/slab.h>
30#include <asm/uaccess.h> 31#include <asm/uaccess.h>
31#include <linux/isdn/capicmd.h> 32#include <linux/isdn/capicmd.h>
32#include <linux/isdn/capiutil.h> 33#include <linux/isdn/capiutil.h>
@@ -34,10 +35,7 @@
34#include <linux/b1lli.h> 35#include <linux/b1lli.h>
35#endif 36#endif
36#include <linux/mutex.h> 37#include <linux/mutex.h>
37 38#include <linux/rcupdate.h>
38static char *revision = "$Revision: 1.1.2.8 $";
39
40/* ------------------------------------------------------------- */
41 39
42static int showcapimsgs = 0; 40static int showcapimsgs = 0;
43 41
@@ -48,12 +46,10 @@ module_param(showcapimsgs, uint, 0);
48 46
49/* ------------------------------------------------------------- */ 47/* ------------------------------------------------------------- */
50 48
51struct capi_notifier { 49struct capictr_event {
52 struct work_struct work; 50 struct work_struct work;
53 unsigned int cmd; 51 unsigned int type;
54 u32 controller; 52 u32 controller;
55 u16 applid;
56 u32 ncci;
57}; 53};
58 54
59/* ------------------------------------------------------------- */ 55/* ------------------------------------------------------------- */
@@ -65,30 +61,31 @@ static char capi_manufakturer[64] = "AVM Berlin";
65#define NCCI2CTRL(ncci) (((ncci) >> 24) & 0x7f) 61#define NCCI2CTRL(ncci) (((ncci) >> 24) & 0x7f)
66 62
67LIST_HEAD(capi_drivers); 63LIST_HEAD(capi_drivers);
68DEFINE_RWLOCK(capi_drivers_list_lock); 64DEFINE_MUTEX(capi_drivers_lock);
69 65
70static DEFINE_RWLOCK(application_lock); 66struct capi_ctr *capi_controller[CAPI_MAXCONTR];
71static DEFINE_MUTEX(controller_mutex); 67DEFINE_MUTEX(capi_controller_lock);
72 68
73struct capi20_appl *capi_applications[CAPI_MAXAPPL]; 69struct capi20_appl *capi_applications[CAPI_MAXAPPL];
74struct capi_ctr *capi_cards[CAPI_MAXCONTR];
75 70
76static int ncards; 71static int ncontrollers;
72
73static BLOCKING_NOTIFIER_HEAD(ctr_notifier_list);
77 74
78/* -------- controller ref counting -------------------------------------- */ 75/* -------- controller ref counting -------------------------------------- */
79 76
80static inline struct capi_ctr * 77static inline struct capi_ctr *
81capi_ctr_get(struct capi_ctr *card) 78capi_ctr_get(struct capi_ctr *ctr)
82{ 79{
83 if (!try_module_get(card->owner)) 80 if (!try_module_get(ctr->owner))
84 return NULL; 81 return NULL;
85 return card; 82 return ctr;
86} 83}
87 84
88static inline void 85static inline void
89capi_ctr_put(struct capi_ctr *card) 86capi_ctr_put(struct capi_ctr *ctr)
90{ 87{
91 module_put(card->owner); 88 module_put(ctr->owner);
92} 89}
93 90
94/* ------------------------------------------------------------- */ 91/* ------------------------------------------------------------- */
@@ -98,7 +95,7 @@ static inline struct capi_ctr *get_capi_ctr_by_nr(u16 contr)
98 if (contr - 1 >= CAPI_MAXCONTR) 95 if (contr - 1 >= CAPI_MAXCONTR)
99 return NULL; 96 return NULL;
100 97
101 return capi_cards[contr - 1]; 98 return capi_controller[contr - 1];
102} 99}
103 100
104static inline struct capi20_appl *get_capi_appl_by_nr(u16 applid) 101static inline struct capi20_appl *get_capi_appl_by_nr(u16 applid)
@@ -106,7 +103,7 @@ static inline struct capi20_appl *get_capi_appl_by_nr(u16 applid)
106 if (applid - 1 >= CAPI_MAXAPPL) 103 if (applid - 1 >= CAPI_MAXAPPL)
107 return NULL; 104 return NULL;
108 105
109 return capi_applications[applid - 1]; 106 return rcu_dereference(capi_applications[applid - 1]);
110} 107}
111 108
112/* -------- util functions ------------------------------------ */ 109/* -------- util functions ------------------------------------ */
@@ -148,106 +145,159 @@ static inline int capi_subcmd_valid(u8 subcmd)
148 145
149/* ------------------------------------------------------------ */ 146/* ------------------------------------------------------------ */
150 147
151static void register_appl(struct capi_ctr *card, u16 applid, capi_register_params *rparam) 148static void
149register_appl(struct capi_ctr *ctr, u16 applid, capi_register_params *rparam)
152{ 150{
153 card = capi_ctr_get(card); 151 ctr = capi_ctr_get(ctr);
154 152
155 if (card) 153 if (ctr)
156 card->register_appl(card, applid, rparam); 154 ctr->register_appl(ctr, applid, rparam);
157 else 155 else
158 printk(KERN_WARNING "%s: cannot get card resources\n", __func__); 156 printk(KERN_WARNING "%s: cannot get controller resources\n",
157 __func__);
159} 158}
160 159
161 160
162static void release_appl(struct capi_ctr *card, u16 applid) 161static void release_appl(struct capi_ctr *ctr, u16 applid)
163{ 162{
164 DBG("applid %#x", applid); 163 DBG("applid %#x", applid);
165 164
166 card->release_appl(card, applid); 165 ctr->release_appl(ctr, applid);
167 capi_ctr_put(card); 166 capi_ctr_put(ctr);
168} 167}
169 168
170/* -------- KCI_CONTRUP --------------------------------------- */
171
172static void notify_up(u32 contr) 169static void notify_up(u32 contr)
173{ 170{
174 struct capi_ctr *card = get_capi_ctr_by_nr(contr);
175 struct capi20_appl *ap; 171 struct capi20_appl *ap;
172 struct capi_ctr *ctr;
176 u16 applid; 173 u16 applid;
177 174
178 if (showcapimsgs & 1) { 175 mutex_lock(&capi_controller_lock);
176
177 if (showcapimsgs & 1)
179 printk(KERN_DEBUG "kcapi: notify up contr %d\n", contr); 178 printk(KERN_DEBUG "kcapi: notify up contr %d\n", contr);
180 } 179
181 if (!card) { 180 ctr = get_capi_ctr_by_nr(contr);
181 if (ctr) {
182 if (ctr->state == CAPI_CTR_RUNNING)
183 goto unlock_out;
184
185 ctr->state = CAPI_CTR_RUNNING;
186
187 for (applid = 1; applid <= CAPI_MAXAPPL; applid++) {
188 ap = get_capi_appl_by_nr(applid);
189 if (!ap)
190 continue;
191 register_appl(ctr, applid, &ap->rparam);
192 }
193
194 wake_up_interruptible_all(&ctr->state_wait_queue);
195 } else
182 printk(KERN_WARNING "%s: invalid contr %d\n", __func__, contr); 196 printk(KERN_WARNING "%s: invalid contr %d\n", __func__, contr);
183 return;
184 }
185 for (applid = 1; applid <= CAPI_MAXAPPL; applid++) {
186 ap = get_capi_appl_by_nr(applid);
187 if (!ap || ap->release_in_progress) continue;
188 register_appl(card, applid, &ap->rparam);
189 if (ap->callback && !ap->release_in_progress)
190 ap->callback(KCI_CONTRUP, contr, &card->profile);
191 }
192}
193 197
194/* -------- KCI_CONTRDOWN ------------------------------------- */ 198unlock_out:
199 mutex_unlock(&capi_controller_lock);
200}
195 201
196static void notify_down(u32 contr) 202static void ctr_down(struct capi_ctr *ctr, int new_state)
197{ 203{
198 struct capi20_appl *ap; 204 struct capi20_appl *ap;
199 u16 applid; 205 u16 applid;
200 206
201 if (showcapimsgs & 1) { 207 if (ctr->state == CAPI_CTR_DETECTED || ctr->state == CAPI_CTR_DETACHED)
202 printk(KERN_DEBUG "kcapi: notify down contr %d\n", contr); 208 return;
203 } 209
210 ctr->state = new_state;
211
212 memset(ctr->manu, 0, sizeof(ctr->manu));
213 memset(&ctr->version, 0, sizeof(ctr->version));
214 memset(&ctr->profile, 0, sizeof(ctr->profile));
215 memset(ctr->serial, 0, sizeof(ctr->serial));
204 216
205 for (applid = 1; applid <= CAPI_MAXAPPL; applid++) { 217 for (applid = 1; applid <= CAPI_MAXAPPL; applid++) {
206 ap = get_capi_appl_by_nr(applid); 218 ap = get_capi_appl_by_nr(applid);
207 if (ap && ap->callback && !ap->release_in_progress) 219 if (ap)
208 ap->callback(KCI_CONTRDOWN, contr, NULL); 220 capi_ctr_put(ctr);
209 } 221 }
222
223 wake_up_interruptible_all(&ctr->state_wait_queue);
210} 224}
211 225
212static void notify_handler(struct work_struct *work) 226static void notify_down(u32 contr)
213{ 227{
214 struct capi_notifier *np = 228 struct capi_ctr *ctr;
215 container_of(work, struct capi_notifier, work);
216 229
217 switch (np->cmd) { 230 mutex_lock(&capi_controller_lock);
218 case KCI_CONTRUP: 231
219 notify_up(np->controller); 232 if (showcapimsgs & 1)
233 printk(KERN_DEBUG "kcapi: notify down contr %d\n", contr);
234
235 ctr = get_capi_ctr_by_nr(contr);
236 if (ctr)
237 ctr_down(ctr, CAPI_CTR_DETECTED);
238 else
239 printk(KERN_WARNING "%s: invalid contr %d\n", __func__, contr);
240
241 mutex_unlock(&capi_controller_lock);
242}
243
244static int
245notify_handler(struct notifier_block *nb, unsigned long val, void *v)
246{
247 u32 contr = (long)v;
248
249 switch (val) {
250 case CAPICTR_UP:
251 notify_up(contr);
220 break; 252 break;
221 case KCI_CONTRDOWN: 253 case CAPICTR_DOWN:
222 notify_down(np->controller); 254 notify_down(contr);
223 break; 255 break;
224 } 256 }
257 return NOTIFY_OK;
258}
259
260static void do_notify_work(struct work_struct *work)
261{
262 struct capictr_event *event =
263 container_of(work, struct capictr_event, work);
225 264
226 kfree(np); 265 blocking_notifier_call_chain(&ctr_notifier_list, event->type,
266 (void *)(long)event->controller);
267 kfree(event);
227} 268}
228 269
229/* 270/*
230 * The notifier will result in adding/deleteing of devices. Devices can 271 * The notifier will result in adding/deleteing of devices. Devices can
231 * only removed in user process, not in bh. 272 * only removed in user process, not in bh.
232 */ 273 */
233static int notify_push(unsigned int cmd, u32 controller, u16 applid, u32 ncci) 274static int notify_push(unsigned int event_type, u32 controller)
234{ 275{
235 struct capi_notifier *np = kmalloc(sizeof(*np), GFP_ATOMIC); 276 struct capictr_event *event = kmalloc(sizeof(*event), GFP_ATOMIC);
236 277
237 if (!np) 278 if (!event)
238 return -ENOMEM; 279 return -ENOMEM;
239 280
240 INIT_WORK(&np->work, notify_handler); 281 INIT_WORK(&event->work, do_notify_work);
241 np->cmd = cmd; 282 event->type = event_type;
242 np->controller = controller; 283 event->controller = controller;
243 np->applid = applid;
244 np->ncci = ncci;
245 284
246 schedule_work(&np->work); 285 schedule_work(&event->work);
247 return 0; 286 return 0;
248} 287}
249 288
250 289int register_capictr_notifier(struct notifier_block *nb)
290{
291 return blocking_notifier_chain_register(&ctr_notifier_list, nb);
292}
293EXPORT_SYMBOL_GPL(register_capictr_notifier);
294
295int unregister_capictr_notifier(struct notifier_block *nb)
296{
297 return blocking_notifier_chain_unregister(&ctr_notifier_list, nb);
298}
299EXPORT_SYMBOL_GPL(unregister_capictr_notifier);
300
251/* -------- Receiver ------------------------------------------ */ 301/* -------- Receiver ------------------------------------------ */
252 302
253static void recv_handler(struct work_struct *work) 303static void recv_handler(struct work_struct *work)
@@ -273,68 +323,70 @@ static void recv_handler(struct work_struct *work)
273 323
274/** 324/**
275 * capi_ctr_handle_message() - handle incoming CAPI message 325 * capi_ctr_handle_message() - handle incoming CAPI message
276 * @card: controller descriptor structure. 326 * @ctr: controller descriptor structure.
277 * @appl: application ID. 327 * @appl: application ID.
278 * @skb: message. 328 * @skb: message.
279 * 329 *
280 * Called by hardware driver to pass a CAPI message to the application. 330 * Called by hardware driver to pass a CAPI message to the application.
281 */ 331 */
282 332
283void capi_ctr_handle_message(struct capi_ctr * card, u16 appl, struct sk_buff *skb) 333void capi_ctr_handle_message(struct capi_ctr *ctr, u16 appl,
334 struct sk_buff *skb)
284{ 335{
285 struct capi20_appl *ap; 336 struct capi20_appl *ap;
286 int showctl = 0; 337 int showctl = 0;
287 u8 cmd, subcmd; 338 u8 cmd, subcmd;
288 unsigned long flags;
289 _cdebbuf *cdb; 339 _cdebbuf *cdb;
290 340
291 if (card->cardstate != CARD_RUNNING) { 341 if (ctr->state != CAPI_CTR_RUNNING) {
292 cdb = capi_message2str(skb->data); 342 cdb = capi_message2str(skb->data);
293 if (cdb) { 343 if (cdb) {
294 printk(KERN_INFO "kcapi: controller [%03d] not active, got: %s", 344 printk(KERN_INFO "kcapi: controller [%03d] not active, got: %s",
295 card->cnr, cdb->buf); 345 ctr->cnr, cdb->buf);
296 cdebbuf_free(cdb); 346 cdebbuf_free(cdb);
297 } else 347 } else
298 printk(KERN_INFO "kcapi: controller [%03d] not active, cannot trace\n", 348 printk(KERN_INFO "kcapi: controller [%03d] not active, cannot trace\n",
299 card->cnr); 349 ctr->cnr);
300 goto error; 350 goto error;
301 } 351 }
302 352
303 cmd = CAPIMSG_COMMAND(skb->data); 353 cmd = CAPIMSG_COMMAND(skb->data);
304 subcmd = CAPIMSG_SUBCOMMAND(skb->data); 354 subcmd = CAPIMSG_SUBCOMMAND(skb->data);
305 if (cmd == CAPI_DATA_B3 && subcmd == CAPI_IND) { 355 if (cmd == CAPI_DATA_B3 && subcmd == CAPI_IND) {
306 card->nrecvdatapkt++; 356 ctr->nrecvdatapkt++;
307 if (card->traceflag > 2) showctl |= 2; 357 if (ctr->traceflag > 2)
358 showctl |= 2;
308 } else { 359 } else {
309 card->nrecvctlpkt++; 360 ctr->nrecvctlpkt++;
310 if (card->traceflag) showctl |= 2; 361 if (ctr->traceflag)
362 showctl |= 2;
311 } 363 }
312 showctl |= (card->traceflag & 1); 364 showctl |= (ctr->traceflag & 1);
313 if (showctl & 2) { 365 if (showctl & 2) {
314 if (showctl & 1) { 366 if (showctl & 1) {
315 printk(KERN_DEBUG "kcapi: got [%03d] id#%d %s len=%u\n", 367 printk(KERN_DEBUG "kcapi: got [%03d] id#%d %s len=%u\n",
316 card->cnr, CAPIMSG_APPID(skb->data), 368 ctr->cnr, CAPIMSG_APPID(skb->data),
317 capi_cmd2str(cmd, subcmd), 369 capi_cmd2str(cmd, subcmd),
318 CAPIMSG_LEN(skb->data)); 370 CAPIMSG_LEN(skb->data));
319 } else { 371 } else {
320 cdb = capi_message2str(skb->data); 372 cdb = capi_message2str(skb->data);
321 if (cdb) { 373 if (cdb) {
322 printk(KERN_DEBUG "kcapi: got [%03d] %s\n", 374 printk(KERN_DEBUG "kcapi: got [%03d] %s\n",
323 card->cnr, cdb->buf); 375 ctr->cnr, cdb->buf);
324 cdebbuf_free(cdb); 376 cdebbuf_free(cdb);
325 } else 377 } else
326 printk(KERN_DEBUG "kcapi: got [%03d] id#%d %s len=%u, cannot trace\n", 378 printk(KERN_DEBUG "kcapi: got [%03d] id#%d %s len=%u, cannot trace\n",
327 card->cnr, CAPIMSG_APPID(skb->data), 379 ctr->cnr, CAPIMSG_APPID(skb->data),
328 capi_cmd2str(cmd, subcmd), 380 capi_cmd2str(cmd, subcmd),
329 CAPIMSG_LEN(skb->data)); 381 CAPIMSG_LEN(skb->data));
330 } 382 }
331 383
332 } 384 }
333 385
334 read_lock_irqsave(&application_lock, flags); 386 rcu_read_lock();
335 ap = get_capi_appl_by_nr(CAPIMSG_APPID(skb->data)); 387 ap = get_capi_appl_by_nr(CAPIMSG_APPID(skb->data));
336 if ((!ap) || (ap->release_in_progress)) { 388 if (!ap) {
337 read_unlock_irqrestore(&application_lock, flags); 389 rcu_read_unlock();
338 cdb = capi_message2str(skb->data); 390 cdb = capi_message2str(skb->data);
339 if (cdb) { 391 if (cdb) {
340 printk(KERN_ERR "kcapi: handle_message: applid %d state released (%s)\n", 392 printk(KERN_ERR "kcapi: handle_message: applid %d state released (%s)\n",
@@ -348,7 +400,7 @@ void capi_ctr_handle_message(struct capi_ctr * card, u16 appl, struct sk_buff *s
348 } 400 }
349 skb_queue_tail(&ap->recv_queue, skb); 401 skb_queue_tail(&ap->recv_queue, skb);
350 schedule_work(&ap->recv_work); 402 schedule_work(&ap->recv_work);
351 read_unlock_irqrestore(&application_lock, flags); 403 rcu_read_unlock();
352 404
353 return; 405 return;
354 406
@@ -360,74 +412,54 @@ EXPORT_SYMBOL(capi_ctr_handle_message);
360 412
361/** 413/**
362 * capi_ctr_ready() - signal CAPI controller ready 414 * capi_ctr_ready() - signal CAPI controller ready
363 * @card: controller descriptor structure. 415 * @ctr: controller descriptor structure.
364 * 416 *
365 * Called by hardware driver to signal that the controller is up and running. 417 * Called by hardware driver to signal that the controller is up and running.
366 */ 418 */
367 419
368void capi_ctr_ready(struct capi_ctr * card) 420void capi_ctr_ready(struct capi_ctr *ctr)
369{ 421{
370 card->cardstate = CARD_RUNNING; 422 printk(KERN_NOTICE "kcapi: controller [%03d] \"%s\" ready.\n",
371 423 ctr->cnr, ctr->name);
372 printk(KERN_NOTICE "kcapi: card [%03d] \"%s\" ready.\n",
373 card->cnr, card->name);
374 424
375 notify_push(KCI_CONTRUP, card->cnr, 0, 0); 425 notify_push(CAPICTR_UP, ctr->cnr);
376} 426}
377 427
378EXPORT_SYMBOL(capi_ctr_ready); 428EXPORT_SYMBOL(capi_ctr_ready);
379 429
380/** 430/**
381 * capi_ctr_down() - signal CAPI controller not ready 431 * capi_ctr_down() - signal CAPI controller not ready
382 * @card: controller descriptor structure. 432 * @ctr: controller descriptor structure.
383 * 433 *
384 * Called by hardware driver to signal that the controller is down and 434 * Called by hardware driver to signal that the controller is down and
385 * unavailable for use. 435 * unavailable for use.
386 */ 436 */
387 437
388void capi_ctr_down(struct capi_ctr * card) 438void capi_ctr_down(struct capi_ctr *ctr)
389{ 439{
390 u16 appl; 440 printk(KERN_NOTICE "kcapi: controller [%03d] down.\n", ctr->cnr);
391
392 DBG("");
393
394 if (card->cardstate == CARD_DETECTED)
395 return;
396
397 card->cardstate = CARD_DETECTED;
398
399 memset(card->manu, 0, sizeof(card->manu));
400 memset(&card->version, 0, sizeof(card->version));
401 memset(&card->profile, 0, sizeof(card->profile));
402 memset(card->serial, 0, sizeof(card->serial));
403
404 for (appl = 1; appl <= CAPI_MAXAPPL; appl++) {
405 struct capi20_appl *ap = get_capi_appl_by_nr(appl);
406 if (!ap || ap->release_in_progress)
407 continue;
408
409 capi_ctr_put(card);
410 }
411
412 printk(KERN_NOTICE "kcapi: card [%03d] down.\n", card->cnr);
413 441
414 notify_push(KCI_CONTRDOWN, card->cnr, 0, 0); 442 notify_push(CAPICTR_DOWN, ctr->cnr);
415} 443}
416 444
417EXPORT_SYMBOL(capi_ctr_down); 445EXPORT_SYMBOL(capi_ctr_down);
418 446
419/** 447/**
420 * capi_ctr_suspend_output() - suspend controller 448 * capi_ctr_suspend_output() - suspend controller
421 * @card: controller descriptor structure. 449 * @ctr: controller descriptor structure.
422 * 450 *
423 * Called by hardware driver to stop data flow. 451 * Called by hardware driver to stop data flow.
452 *
453 * Note: The caller is responsible for synchronizing concurrent state changes
454 * as well as invocations of capi_ctr_handle_message.
424 */ 455 */
425 456
426void capi_ctr_suspend_output(struct capi_ctr *card) 457void capi_ctr_suspend_output(struct capi_ctr *ctr)
427{ 458{
428 if (!card->blocked) { 459 if (!ctr->blocked) {
429 printk(KERN_DEBUG "kcapi: card [%03d] suspend\n", card->cnr); 460 printk(KERN_DEBUG "kcapi: controller [%03d] suspend\n",
430 card->blocked = 1; 461 ctr->cnr);
462 ctr->blocked = 1;
431 } 463 }
432} 464}
433 465
@@ -435,16 +467,20 @@ EXPORT_SYMBOL(capi_ctr_suspend_output);
435 467
436/** 468/**
437 * capi_ctr_resume_output() - resume controller 469 * capi_ctr_resume_output() - resume controller
438 * @card: controller descriptor structure. 470 * @ctr: controller descriptor structure.
439 * 471 *
440 * Called by hardware driver to resume data flow. 472 * Called by hardware driver to resume data flow.
473 *
474 * Note: The caller is responsible for synchronizing concurrent state changes
475 * as well as invocations of capi_ctr_handle_message.
441 */ 476 */
442 477
443void capi_ctr_resume_output(struct capi_ctr *card) 478void capi_ctr_resume_output(struct capi_ctr *ctr)
444{ 479{
445 if (card->blocked) { 480 if (ctr->blocked) {
446 printk(KERN_DEBUG "kcapi: card [%03d] resume\n", card->cnr); 481 printk(KERN_DEBUG "kcapi: controller [%03d] resumed\n",
447 card->blocked = 0; 482 ctr->cnr);
483 ctr->blocked = 0;
448 } 484 }
449} 485}
450 486
@@ -454,53 +490,48 @@ EXPORT_SYMBOL(capi_ctr_resume_output);
454 490
455/** 491/**
456 * attach_capi_ctr() - register CAPI controller 492 * attach_capi_ctr() - register CAPI controller
457 * @card: controller descriptor structure. 493 * @ctr: controller descriptor structure.
458 * 494 *
459 * Called by hardware driver to register a controller with the CAPI subsystem. 495 * Called by hardware driver to register a controller with the CAPI subsystem.
460 * Return value: 0 on success, error code < 0 on error 496 * Return value: 0 on success, error code < 0 on error
461 */ 497 */
462 498
463int 499int attach_capi_ctr(struct capi_ctr *ctr)
464attach_capi_ctr(struct capi_ctr *card)
465{ 500{
466 int i; 501 int i;
467 502
468 mutex_lock(&controller_mutex); 503 mutex_lock(&capi_controller_lock);
469 504
470 for (i = 0; i < CAPI_MAXCONTR; i++) { 505 for (i = 0; i < CAPI_MAXCONTR; i++) {
471 if (capi_cards[i] == NULL) 506 if (!capi_controller[i])
472 break; 507 break;
473 } 508 }
474 if (i == CAPI_MAXCONTR) { 509 if (i == CAPI_MAXCONTR) {
475 mutex_unlock(&controller_mutex); 510 mutex_unlock(&capi_controller_lock);
476 printk(KERN_ERR "kcapi: out of controller slots\n"); 511 printk(KERN_ERR "kcapi: out of controller slots\n");
477 return -EBUSY; 512 return -EBUSY;
478 } 513 }
479 capi_cards[i] = card; 514 capi_controller[i] = ctr;
480 515
481 mutex_unlock(&controller_mutex); 516 ctr->nrecvctlpkt = 0;
482 517 ctr->nrecvdatapkt = 0;
483 card->nrecvctlpkt = 0; 518 ctr->nsentctlpkt = 0;
484 card->nrecvdatapkt = 0; 519 ctr->nsentdatapkt = 0;
485 card->nsentctlpkt = 0; 520 ctr->cnr = i + 1;
486 card->nsentdatapkt = 0; 521 ctr->state = CAPI_CTR_DETECTED;
487 card->cnr = i + 1; 522 ctr->blocked = 0;
488 card->cardstate = CARD_DETECTED; 523 ctr->traceflag = showcapimsgs;
489 card->blocked = 0; 524 init_waitqueue_head(&ctr->state_wait_queue);
490 card->traceflag = showcapimsgs;
491
492 sprintf(card->procfn, "capi/controllers/%d", card->cnr);
493 card->procent = create_proc_entry(card->procfn, 0, NULL);
494 if (card->procent) {
495 card->procent->read_proc =
496 (int (*)(char *,char **,off_t,int,int *,void *))
497 card->ctr_read_proc;
498 card->procent->data = card;
499 }
500 525
501 ncards++; 526 sprintf(ctr->procfn, "capi/controllers/%d", ctr->cnr);
502 printk(KERN_NOTICE "kcapi: Controller [%03d]: %s attached\n", 527 ctr->procent = proc_create_data(ctr->procfn, 0, NULL, ctr->proc_fops, ctr);
503 card->cnr, card->name); 528
529 ncontrollers++;
530
531 mutex_unlock(&capi_controller_lock);
532
533 printk(KERN_NOTICE "kcapi: controller [%03d]: %s attached\n",
534 ctr->cnr, ctr->name);
504 return 0; 535 return 0;
505} 536}
506 537
@@ -508,29 +539,38 @@ EXPORT_SYMBOL(attach_capi_ctr);
508 539
509/** 540/**
510 * detach_capi_ctr() - unregister CAPI controller 541 * detach_capi_ctr() - unregister CAPI controller
511 * @card: controller descriptor structure. 542 * @ctr: controller descriptor structure.
512 * 543 *
513 * Called by hardware driver to remove the registration of a controller 544 * Called by hardware driver to remove the registration of a controller
514 * with the CAPI subsystem. 545 * with the CAPI subsystem.
515 * Return value: 0 on success, error code < 0 on error 546 * Return value: 0 on success, error code < 0 on error
516 */ 547 */
517 548
518int detach_capi_ctr(struct capi_ctr *card) 549int detach_capi_ctr(struct capi_ctr *ctr)
519{ 550{
520 if (card->cardstate != CARD_DETECTED) 551 int err = 0;
521 capi_ctr_down(card);
522 552
523 ncards--; 553 mutex_lock(&capi_controller_lock);
524 554
525 if (card->procent) { 555 ctr_down(ctr, CAPI_CTR_DETACHED);
526 remove_proc_entry(card->procfn, NULL); 556
527 card->procent = NULL; 557 if (capi_controller[ctr->cnr - 1] != ctr) {
558 err = -EINVAL;
559 goto unlock_out;
528 } 560 }
529 capi_cards[card->cnr - 1] = NULL; 561 capi_controller[ctr->cnr - 1] = NULL;
530 printk(KERN_NOTICE "kcapi: Controller [%03d]: %s unregistered\n", 562 ncontrollers--;
531 card->cnr, card->name);
532 563
533 return 0; 564 if (ctr->procent)
565 remove_proc_entry(ctr->procfn, NULL);
566
567 printk(KERN_NOTICE "kcapi: controller [%03d]: %s unregistered\n",
568 ctr->cnr, ctr->name);
569
570unlock_out:
571 mutex_unlock(&capi_controller_lock);
572
573 return err;
534} 574}
535 575
536EXPORT_SYMBOL(detach_capi_ctr); 576EXPORT_SYMBOL(detach_capi_ctr);
@@ -544,11 +584,9 @@ EXPORT_SYMBOL(detach_capi_ctr);
544 584
545void register_capi_driver(struct capi_driver *driver) 585void register_capi_driver(struct capi_driver *driver)
546{ 586{
547 unsigned long flags; 587 mutex_lock(&capi_drivers_lock);
548
549 write_lock_irqsave(&capi_drivers_list_lock, flags);
550 list_add_tail(&driver->list, &capi_drivers); 588 list_add_tail(&driver->list, &capi_drivers);
551 write_unlock_irqrestore(&capi_drivers_list_lock, flags); 589 mutex_unlock(&capi_drivers_lock);
552} 590}
553 591
554EXPORT_SYMBOL(register_capi_driver); 592EXPORT_SYMBOL(register_capi_driver);
@@ -562,11 +600,9 @@ EXPORT_SYMBOL(register_capi_driver);
562 600
563void unregister_capi_driver(struct capi_driver *driver) 601void unregister_capi_driver(struct capi_driver *driver)
564{ 602{
565 unsigned long flags; 603 mutex_lock(&capi_drivers_lock);
566
567 write_lock_irqsave(&capi_drivers_list_lock, flags);
568 list_del(&driver->list); 604 list_del(&driver->list);
569 write_unlock_irqrestore(&capi_drivers_list_lock, flags); 605 mutex_unlock(&capi_drivers_lock);
570} 606}
571 607
572EXPORT_SYMBOL(unregister_capi_driver); 608EXPORT_SYMBOL(unregister_capi_driver);
@@ -584,12 +620,21 @@ EXPORT_SYMBOL(unregister_capi_driver);
584 620
585u16 capi20_isinstalled(void) 621u16 capi20_isinstalled(void)
586{ 622{
623 u16 ret = CAPI_REGNOTINSTALLED;
587 int i; 624 int i;
588 for (i = 0; i < CAPI_MAXCONTR; i++) { 625
589 if (capi_cards[i] && capi_cards[i]->cardstate == CARD_RUNNING) 626 mutex_lock(&capi_controller_lock);
590 return CAPI_NOERROR; 627
591 } 628 for (i = 0; i < CAPI_MAXCONTR; i++)
592 return CAPI_REGNOTINSTALLED; 629 if (capi_controller[i] &&
630 capi_controller[i]->state == CAPI_CTR_RUNNING) {
631 ret = CAPI_NOERROR;
632 break;
633 }
634
635 mutex_unlock(&capi_controller_lock);
636
637 return ret;
593} 638}
594 639
595EXPORT_SYMBOL(capi20_isinstalled); 640EXPORT_SYMBOL(capi20_isinstalled);
@@ -610,46 +655,43 @@ u16 capi20_register(struct capi20_appl *ap)
610{ 655{
611 int i; 656 int i;
612 u16 applid; 657 u16 applid;
613 unsigned long flags;
614 658
615 DBG(""); 659 DBG("");
616 660
617 if (ap->rparam.datablklen < 128) 661 if (ap->rparam.datablklen < 128)
618 return CAPI_LOGBLKSIZETOSMALL; 662 return CAPI_LOGBLKSIZETOSMALL;
619 663
620 write_lock_irqsave(&application_lock, flags); 664 ap->nrecvctlpkt = 0;
665 ap->nrecvdatapkt = 0;
666 ap->nsentctlpkt = 0;
667 ap->nsentdatapkt = 0;
668 mutex_init(&ap->recv_mtx);
669 skb_queue_head_init(&ap->recv_queue);
670 INIT_WORK(&ap->recv_work, recv_handler);
671 ap->release_in_progress = 0;
672
673 mutex_lock(&capi_controller_lock);
621 674
622 for (applid = 1; applid <= CAPI_MAXAPPL; applid++) { 675 for (applid = 1; applid <= CAPI_MAXAPPL; applid++) {
623 if (capi_applications[applid - 1] == NULL) 676 if (capi_applications[applid - 1] == NULL)
624 break; 677 break;
625 } 678 }
626 if (applid > CAPI_MAXAPPL) { 679 if (applid > CAPI_MAXAPPL) {
627 write_unlock_irqrestore(&application_lock, flags); 680 mutex_unlock(&capi_controller_lock);
628 return CAPI_TOOMANYAPPLS; 681 return CAPI_TOOMANYAPPLS;
629 } 682 }
630 683
631 ap->applid = applid; 684 ap->applid = applid;
632 capi_applications[applid - 1] = ap; 685 capi_applications[applid - 1] = ap;
633 686
634 ap->nrecvctlpkt = 0;
635 ap->nrecvdatapkt = 0;
636 ap->nsentctlpkt = 0;
637 ap->nsentdatapkt = 0;
638 ap->callback = NULL;
639 mutex_init(&ap->recv_mtx);
640 skb_queue_head_init(&ap->recv_queue);
641 INIT_WORK(&ap->recv_work, recv_handler);
642 ap->release_in_progress = 0;
643
644 write_unlock_irqrestore(&application_lock, flags);
645
646 mutex_lock(&controller_mutex);
647 for (i = 0; i < CAPI_MAXCONTR; i++) { 687 for (i = 0; i < CAPI_MAXCONTR; i++) {
648 if (!capi_cards[i] || capi_cards[i]->cardstate != CARD_RUNNING) 688 if (!capi_controller[i] ||
689 capi_controller[i]->state != CAPI_CTR_RUNNING)
649 continue; 690 continue;
650 register_appl(capi_cards[i], applid, &ap->rparam); 691 register_appl(capi_controller[i], applid, &ap->rparam);
651 } 692 }
652 mutex_unlock(&controller_mutex); 693
694 mutex_unlock(&capi_controller_lock);
653 695
654 if (showcapimsgs & 1) { 696 if (showcapimsgs & 1) {
655 printk(KERN_DEBUG "kcapi: appl %d up\n", applid); 697 printk(KERN_DEBUG "kcapi: appl %d up\n", applid);
@@ -673,22 +715,24 @@ EXPORT_SYMBOL(capi20_register);
673u16 capi20_release(struct capi20_appl *ap) 715u16 capi20_release(struct capi20_appl *ap)
674{ 716{
675 int i; 717 int i;
676 unsigned long flags;
677 718
678 DBG("applid %#x", ap->applid); 719 DBG("applid %#x", ap->applid);
679 720
680 write_lock_irqsave(&application_lock, flags); 721 mutex_lock(&capi_controller_lock);
722
681 ap->release_in_progress = 1; 723 ap->release_in_progress = 1;
682 capi_applications[ap->applid - 1] = NULL; 724 capi_applications[ap->applid - 1] = NULL;
683 write_unlock_irqrestore(&application_lock, flags);
684 725
685 mutex_lock(&controller_mutex); 726 synchronize_rcu();
727
686 for (i = 0; i < CAPI_MAXCONTR; i++) { 728 for (i = 0; i < CAPI_MAXCONTR; i++) {
687 if (!capi_cards[i] || capi_cards[i]->cardstate != CARD_RUNNING) 729 if (!capi_controller[i] ||
730 capi_controller[i]->state != CAPI_CTR_RUNNING)
688 continue; 731 continue;
689 release_appl(capi_cards[i], ap->applid); 732 release_appl(capi_controller[i], ap->applid);
690 } 733 }
691 mutex_unlock(&controller_mutex); 734
735 mutex_unlock(&capi_controller_lock);
692 736
693 flush_scheduled_work(); 737 flush_scheduled_work();
694 skb_queue_purge(&ap->recv_queue); 738 skb_queue_purge(&ap->recv_queue);
@@ -713,13 +757,13 @@ EXPORT_SYMBOL(capi20_release);
713 757
714u16 capi20_put_message(struct capi20_appl *ap, struct sk_buff *skb) 758u16 capi20_put_message(struct capi20_appl *ap, struct sk_buff *skb)
715{ 759{
716 struct capi_ctr *card; 760 struct capi_ctr *ctr;
717 int showctl = 0; 761 int showctl = 0;
718 u8 cmd, subcmd; 762 u8 cmd, subcmd;
719 763
720 DBG("applid %#x", ap->applid); 764 DBG("applid %#x", ap->applid);
721 765
722 if (ncards == 0) 766 if (ncontrollers == 0)
723 return CAPI_REGNOTINSTALLED; 767 return CAPI_REGNOTINSTALLED;
724 if ((ap->applid == 0) || ap->release_in_progress) 768 if ((ap->applid == 0) || ap->release_in_progress)
725 return CAPI_ILLAPPNR; 769 return CAPI_ILLAPPNR;
@@ -727,28 +771,33 @@ u16 capi20_put_message(struct capi20_appl *ap, struct sk_buff *skb)
727 || !capi_cmd_valid(CAPIMSG_COMMAND(skb->data)) 771 || !capi_cmd_valid(CAPIMSG_COMMAND(skb->data))
728 || !capi_subcmd_valid(CAPIMSG_SUBCOMMAND(skb->data))) 772 || !capi_subcmd_valid(CAPIMSG_SUBCOMMAND(skb->data)))
729 return CAPI_ILLCMDORSUBCMDORMSGTOSMALL; 773 return CAPI_ILLCMDORSUBCMDORMSGTOSMALL;
730 card = get_capi_ctr_by_nr(CAPIMSG_CONTROLLER(skb->data)); 774
731 if (!card || card->cardstate != CARD_RUNNING) { 775 /*
732 card = get_capi_ctr_by_nr(1); // XXX why? 776 * The controller reference is protected by the existence of the
733 if (!card || card->cardstate != CARD_RUNNING) 777 * application passed to us. We assume that the caller properly
734 return CAPI_REGNOTINSTALLED; 778 * synchronizes this service with capi20_release.
735 } 779 */
736 if (card->blocked) 780 ctr = get_capi_ctr_by_nr(CAPIMSG_CONTROLLER(skb->data));
781 if (!ctr || ctr->state != CAPI_CTR_RUNNING)
782 return CAPI_REGNOTINSTALLED;
783 if (ctr->blocked)
737 return CAPI_SENDQUEUEFULL; 784 return CAPI_SENDQUEUEFULL;
738 785
739 cmd = CAPIMSG_COMMAND(skb->data); 786 cmd = CAPIMSG_COMMAND(skb->data);
740 subcmd = CAPIMSG_SUBCOMMAND(skb->data); 787 subcmd = CAPIMSG_SUBCOMMAND(skb->data);
741 788
742 if (cmd == CAPI_DATA_B3 && subcmd== CAPI_REQ) { 789 if (cmd == CAPI_DATA_B3 && subcmd== CAPI_REQ) {
743 card->nsentdatapkt++; 790 ctr->nsentdatapkt++;
744 ap->nsentdatapkt++; 791 ap->nsentdatapkt++;
745 if (card->traceflag > 2) showctl |= 2; 792 if (ctr->traceflag > 2)
793 showctl |= 2;
746 } else { 794 } else {
747 card->nsentctlpkt++; 795 ctr->nsentctlpkt++;
748 ap->nsentctlpkt++; 796 ap->nsentctlpkt++;
749 if (card->traceflag) showctl |= 2; 797 if (ctr->traceflag)
798 showctl |= 2;
750 } 799 }
751 showctl |= (card->traceflag & 1); 800 showctl |= (ctr->traceflag & 1);
752 if (showctl & 2) { 801 if (showctl & 2) {
753 if (showctl & 1) { 802 if (showctl & 1) {
754 printk(KERN_DEBUG "kcapi: put [%03d] id#%d %s len=%u\n", 803 printk(KERN_DEBUG "kcapi: put [%03d] id#%d %s len=%u\n",
@@ -771,7 +820,7 @@ u16 capi20_put_message(struct capi20_appl *ap, struct sk_buff *skb)
771 CAPIMSG_LEN(skb->data)); 820 CAPIMSG_LEN(skb->data));
772 } 821 }
773 } 822 }
774 return card->send_message(card, skb); 823 return ctr->send_message(ctr, skb);
775} 824}
776 825
777EXPORT_SYMBOL(capi20_put_message); 826EXPORT_SYMBOL(capi20_put_message);
@@ -788,17 +837,25 @@ EXPORT_SYMBOL(capi20_put_message);
788 837
789u16 capi20_get_manufacturer(u32 contr, u8 *buf) 838u16 capi20_get_manufacturer(u32 contr, u8 *buf)
790{ 839{
791 struct capi_ctr *card; 840 struct capi_ctr *ctr;
841 u16 ret;
792 842
793 if (contr == 0) { 843 if (contr == 0) {
794 strlcpy(buf, capi_manufakturer, CAPI_MANUFACTURER_LEN); 844 strlcpy(buf, capi_manufakturer, CAPI_MANUFACTURER_LEN);
795 return CAPI_NOERROR; 845 return CAPI_NOERROR;
796 } 846 }
797 card = get_capi_ctr_by_nr(contr); 847
798 if (!card || card->cardstate != CARD_RUNNING) 848 mutex_lock(&capi_controller_lock);
799 return CAPI_REGNOTINSTALLED; 849
800 strlcpy(buf, card->manu, CAPI_MANUFACTURER_LEN); 850 ctr = get_capi_ctr_by_nr(contr);
801 return CAPI_NOERROR; 851 if (ctr && ctr->state == CAPI_CTR_RUNNING) {
852 strlcpy(buf, ctr->manu, CAPI_MANUFACTURER_LEN);
853 ret = CAPI_NOERROR;
854 } else
855 ret = CAPI_REGNOTINSTALLED;
856
857 mutex_unlock(&capi_controller_lock);
858 return ret;
802} 859}
803 860
804EXPORT_SYMBOL(capi20_get_manufacturer); 861EXPORT_SYMBOL(capi20_get_manufacturer);
@@ -815,18 +872,25 @@ EXPORT_SYMBOL(capi20_get_manufacturer);
815 872
816u16 capi20_get_version(u32 contr, struct capi_version *verp) 873u16 capi20_get_version(u32 contr, struct capi_version *verp)
817{ 874{
818 struct capi_ctr *card; 875 struct capi_ctr *ctr;
876 u16 ret;
819 877
820 if (contr == 0) { 878 if (contr == 0) {
821 *verp = driver_version; 879 *verp = driver_version;
822 return CAPI_NOERROR; 880 return CAPI_NOERROR;
823 } 881 }
824 card = get_capi_ctr_by_nr(contr);
825 if (!card || card->cardstate != CARD_RUNNING)
826 return CAPI_REGNOTINSTALLED;
827 882
828 memcpy((void *) verp, &card->version, sizeof(capi_version)); 883 mutex_lock(&capi_controller_lock);
829 return CAPI_NOERROR; 884
885 ctr = get_capi_ctr_by_nr(contr);
886 if (ctr && ctr->state == CAPI_CTR_RUNNING) {
887 memcpy(verp, &ctr->version, sizeof(capi_version));
888 ret = CAPI_NOERROR;
889 } else
890 ret = CAPI_REGNOTINSTALLED;
891
892 mutex_unlock(&capi_controller_lock);
893 return ret;
830} 894}
831 895
832EXPORT_SYMBOL(capi20_get_version); 896EXPORT_SYMBOL(capi20_get_version);
@@ -843,18 +907,25 @@ EXPORT_SYMBOL(capi20_get_version);
843 907
844u16 capi20_get_serial(u32 contr, u8 *serial) 908u16 capi20_get_serial(u32 contr, u8 *serial)
845{ 909{
846 struct capi_ctr *card; 910 struct capi_ctr *ctr;
911 u16 ret;
847 912
848 if (contr == 0) { 913 if (contr == 0) {
849 strlcpy(serial, driver_serial, CAPI_SERIAL_LEN); 914 strlcpy(serial, driver_serial, CAPI_SERIAL_LEN);
850 return CAPI_NOERROR; 915 return CAPI_NOERROR;
851 } 916 }
852 card = get_capi_ctr_by_nr(contr);
853 if (!card || card->cardstate != CARD_RUNNING)
854 return CAPI_REGNOTINSTALLED;
855 917
856 strlcpy((void *) serial, card->serial, CAPI_SERIAL_LEN); 918 mutex_lock(&capi_controller_lock);
857 return CAPI_NOERROR; 919
920 ctr = get_capi_ctr_by_nr(contr);
921 if (ctr && ctr->state == CAPI_CTR_RUNNING) {
922 strlcpy(serial, ctr->serial, CAPI_SERIAL_LEN);
923 ret = CAPI_NOERROR;
924 } else
925 ret = CAPI_REGNOTINSTALLED;
926
927 mutex_unlock(&capi_controller_lock);
928 return ret;
858} 929}
859 930
860EXPORT_SYMBOL(capi20_get_serial); 931EXPORT_SYMBOL(capi20_get_serial);
@@ -871,23 +942,65 @@ EXPORT_SYMBOL(capi20_get_serial);
871 942
872u16 capi20_get_profile(u32 contr, struct capi_profile *profp) 943u16 capi20_get_profile(u32 contr, struct capi_profile *profp)
873{ 944{
874 struct capi_ctr *card; 945 struct capi_ctr *ctr;
946 u16 ret;
875 947
876 if (contr == 0) { 948 if (contr == 0) {
877 profp->ncontroller = ncards; 949 profp->ncontroller = ncontrollers;
878 return CAPI_NOERROR; 950 return CAPI_NOERROR;
879 } 951 }
880 card = get_capi_ctr_by_nr(contr);
881 if (!card || card->cardstate != CARD_RUNNING)
882 return CAPI_REGNOTINSTALLED;
883 952
884 memcpy((void *) profp, &card->profile, 953 mutex_lock(&capi_controller_lock);
885 sizeof(struct capi_profile)); 954
886 return CAPI_NOERROR; 955 ctr = get_capi_ctr_by_nr(contr);
956 if (ctr && ctr->state == CAPI_CTR_RUNNING) {
957 memcpy(profp, &ctr->profile, sizeof(struct capi_profile));
958 ret = CAPI_NOERROR;
959 } else
960 ret = CAPI_REGNOTINSTALLED;
961
962 mutex_unlock(&capi_controller_lock);
963 return ret;
887} 964}
888 965
889EXPORT_SYMBOL(capi20_get_profile); 966EXPORT_SYMBOL(capi20_get_profile);
890 967
968/* Must be called with capi_controller_lock held. */
969static int wait_on_ctr_state(struct capi_ctr *ctr, unsigned int state)
970{
971 DEFINE_WAIT(wait);
972 int retval = 0;
973
974 ctr = capi_ctr_get(ctr);
975 if (!ctr)
976 return -ESRCH;
977
978 for (;;) {
979 prepare_to_wait(&ctr->state_wait_queue, &wait,
980 TASK_INTERRUPTIBLE);
981
982 if (ctr->state == state)
983 break;
984 if (ctr->state == CAPI_CTR_DETACHED) {
985 retval = -ESRCH;
986 break;
987 }
988 if (signal_pending(current)) {
989 retval = -EINTR;
990 break;
991 }
992
993 mutex_unlock(&capi_controller_lock);
994 schedule();
995 mutex_lock(&capi_controller_lock);
996 }
997 finish_wait(&ctr->state_wait_queue, &wait);
998
999 capi_ctr_put(ctr);
1000
1001 return retval;
1002}
1003
891#ifdef AVMB1_COMPAT 1004#ifdef AVMB1_COMPAT
892static int old_capi_manufacturer(unsigned int cmd, void __user *data) 1005static int old_capi_manufacturer(unsigned int cmd, void __user *data)
893{ 1006{
@@ -895,11 +1008,10 @@ static int old_capi_manufacturer(unsigned int cmd, void __user *data)
895 avmb1_extcarddef cdef; 1008 avmb1_extcarddef cdef;
896 avmb1_resetdef rdef; 1009 avmb1_resetdef rdef;
897 capicardparams cparams; 1010 capicardparams cparams;
898 struct capi_ctr *card; 1011 struct capi_ctr *ctr;
899 struct capi_driver *driver = NULL; 1012 struct capi_driver *driver = NULL;
900 capiloaddata ldata; 1013 capiloaddata ldata;
901 struct list_head *l; 1014 struct list_head *l;
902 unsigned long flags;
903 int retval; 1015 int retval;
904 1016
905 switch (cmd) { 1017 switch (cmd) {
@@ -919,7 +1031,8 @@ static int old_capi_manufacturer(unsigned int cmd, void __user *data)
919 cparams.irq = cdef.irq; 1031 cparams.irq = cdef.irq;
920 cparams.cardnr = cdef.cardnr; 1032 cparams.cardnr = cdef.cardnr;
921 1033
922 read_lock_irqsave(&capi_drivers_list_lock, flags); 1034 mutex_lock(&capi_drivers_lock);
1035
923 switch (cdef.cardtype) { 1036 switch (cdef.cardtype) {
924 case AVM_CARDTYPE_B1: 1037 case AVM_CARDTYPE_B1:
925 list_for_each(l, &capi_drivers) { 1038 list_for_each(l, &capi_drivers) {
@@ -940,18 +1053,15 @@ static int old_capi_manufacturer(unsigned int cmd, void __user *data)
940 break; 1053 break;
941 } 1054 }
942 if (!driver) { 1055 if (!driver) {
943 read_unlock_irqrestore(&capi_drivers_list_lock, flags);
944 printk(KERN_ERR "kcapi: driver not loaded.\n"); 1056 printk(KERN_ERR "kcapi: driver not loaded.\n");
945 return -EIO; 1057 retval = -EIO;
946 } 1058 } else if (!driver->add_card) {
947 if (!driver->add_card) {
948 read_unlock_irqrestore(&capi_drivers_list_lock, flags);
949 printk(KERN_ERR "kcapi: driver has no add card function.\n"); 1059 printk(KERN_ERR "kcapi: driver has no add card function.\n");
950 return -EIO; 1060 retval = -EIO;
951 } 1061 } else
1062 retval = driver->add_card(driver, &cparams);
952 1063
953 retval = driver->add_card(driver, &cparams); 1064 mutex_unlock(&capi_drivers_lock);
954 read_unlock_irqrestore(&capi_drivers_list_lock, flags);
955 return retval; 1065 return retval;
956 1066
957 case AVMB1_LOAD: 1067 case AVMB1_LOAD:
@@ -968,27 +1078,30 @@ static int old_capi_manufacturer(unsigned int cmd, void __user *data)
968 sizeof(avmb1_loadandconfigdef))) 1078 sizeof(avmb1_loadandconfigdef)))
969 return -EFAULT; 1079 return -EFAULT;
970 } 1080 }
971 card = get_capi_ctr_by_nr(ldef.contr); 1081
972 if (!card) 1082 mutex_lock(&capi_controller_lock);
973 return -EINVAL; 1083
974 card = capi_ctr_get(card); 1084 ctr = get_capi_ctr_by_nr(ldef.contr);
975 if (!card) 1085 if (!ctr) {
976 return -ESRCH; 1086 retval = -EINVAL;
977 if (card->load_firmware == NULL) { 1087 goto load_unlock_out;
1088 }
1089
1090 if (ctr->load_firmware == NULL) {
978 printk(KERN_DEBUG "kcapi: load: no load function\n"); 1091 printk(KERN_DEBUG "kcapi: load: no load function\n");
979 capi_ctr_put(card); 1092 retval = -ESRCH;
980 return -ESRCH; 1093 goto load_unlock_out;
981 } 1094 }
982 1095
983 if (ldef.t4file.len <= 0) { 1096 if (ldef.t4file.len <= 0) {
984 printk(KERN_DEBUG "kcapi: load: invalid parameter: length of t4file is %d ?\n", ldef.t4file.len); 1097 printk(KERN_DEBUG "kcapi: load: invalid parameter: length of t4file is %d ?\n", ldef.t4file.len);
985 capi_ctr_put(card); 1098 retval = -EINVAL;
986 return -EINVAL; 1099 goto load_unlock_out;
987 } 1100 }
988 if (ldef.t4file.data == NULL) { 1101 if (ldef.t4file.data == NULL) {
989 printk(KERN_DEBUG "kcapi: load: invalid parameter: dataptr is 0\n"); 1102 printk(KERN_DEBUG "kcapi: load: invalid parameter: dataptr is 0\n");
990 capi_ctr_put(card); 1103 retval = -EINVAL;
991 return -EINVAL; 1104 goto load_unlock_out;
992 } 1105 }
993 1106
994 ldata.firmware.user = 1; 1107 ldata.firmware.user = 1;
@@ -998,54 +1111,49 @@ static int old_capi_manufacturer(unsigned int cmd, void __user *data)
998 ldata.configuration.data = ldef.t4config.data; 1111 ldata.configuration.data = ldef.t4config.data;
999 ldata.configuration.len = ldef.t4config.len; 1112 ldata.configuration.len = ldef.t4config.len;
1000 1113
1001 if (card->cardstate != CARD_DETECTED) { 1114 if (ctr->state != CAPI_CTR_DETECTED) {
1002 printk(KERN_INFO "kcapi: load: contr=%d not in detect state\n", ldef.contr); 1115 printk(KERN_INFO "kcapi: load: contr=%d not in detect state\n", ldef.contr);
1003 capi_ctr_put(card); 1116 retval = -EBUSY;
1004 return -EBUSY; 1117 goto load_unlock_out;
1005 } 1118 }
1006 card->cardstate = CARD_LOADING; 1119 ctr->state = CAPI_CTR_LOADING;
1007
1008 retval = card->load_firmware(card, &ldata);
1009 1120
1121 retval = ctr->load_firmware(ctr, &ldata);
1010 if (retval) { 1122 if (retval) {
1011 card->cardstate = CARD_DETECTED; 1123 ctr->state = CAPI_CTR_DETECTED;
1012 capi_ctr_put(card); 1124 goto load_unlock_out;
1013 return retval;
1014 } 1125 }
1015 1126
1016 while (card->cardstate != CARD_RUNNING) { 1127 retval = wait_on_ctr_state(ctr, CAPI_CTR_RUNNING);
1017
1018 msleep_interruptible(100); /* 0.1 sec */
1019 1128
1020 if (signal_pending(current)) { 1129load_unlock_out:
1021 capi_ctr_put(card); 1130 mutex_unlock(&capi_controller_lock);
1022 return -EINTR; 1131 return retval;
1023 }
1024 }
1025 capi_ctr_put(card);
1026 return 0;
1027 1132
1028 case AVMB1_RESETCARD: 1133 case AVMB1_RESETCARD:
1029 if (copy_from_user(&rdef, data, sizeof(avmb1_resetdef))) 1134 if (copy_from_user(&rdef, data, sizeof(avmb1_resetdef)))
1030 return -EFAULT; 1135 return -EFAULT;
1031 card = get_capi_ctr_by_nr(rdef.contr);
1032 if (!card)
1033 return -ESRCH;
1034 1136
1035 if (card->cardstate == CARD_DETECTED) 1137 retval = 0;
1036 return 0;
1037 1138
1038 card->reset_ctr(card); 1139 mutex_lock(&capi_controller_lock);
1039 1140
1040 while (card->cardstate > CARD_DETECTED) { 1141 ctr = get_capi_ctr_by_nr(rdef.contr);
1142 if (!ctr) {
1143 retval = -ESRCH;
1144 goto reset_unlock_out;
1145 }
1041 1146
1042 msleep_interruptible(100); /* 0.1 sec */ 1147 if (ctr->state == CAPI_CTR_DETECTED)
1148 goto reset_unlock_out;
1043 1149
1044 if (signal_pending(current)) 1150 ctr->reset_ctr(ctr);
1045 return -EINTR; 1151
1046 } 1152 retval = wait_on_ctr_state(ctr, CAPI_CTR_DETECTED);
1047 return 0;
1048 1153
1154reset_unlock_out:
1155 mutex_unlock(&capi_controller_lock);
1156 return retval;
1049 } 1157 }
1050 return -EINVAL; 1158 return -EINVAL;
1051} 1159}
@@ -1062,7 +1170,8 @@ static int old_capi_manufacturer(unsigned int cmd, void __user *data)
1062 1170
1063int capi20_manufacturer(unsigned int cmd, void __user *data) 1171int capi20_manufacturer(unsigned int cmd, void __user *data)
1064{ 1172{
1065 struct capi_ctr *card; 1173 struct capi_ctr *ctr;
1174 int retval;
1066 1175
1067 switch (cmd) { 1176 switch (cmd) {
1068#ifdef AVMB1_COMPAT 1177#ifdef AVMB1_COMPAT
@@ -1080,14 +1189,20 @@ int capi20_manufacturer(unsigned int cmd, void __user *data)
1080 if (copy_from_user(&fdef, data, sizeof(kcapi_flagdef))) 1189 if (copy_from_user(&fdef, data, sizeof(kcapi_flagdef)))
1081 return -EFAULT; 1190 return -EFAULT;
1082 1191
1083 card = get_capi_ctr_by_nr(fdef.contr); 1192 mutex_lock(&capi_controller_lock);
1084 if (!card) 1193
1085 return -ESRCH; 1194 ctr = get_capi_ctr_by_nr(fdef.contr);
1195 if (ctr) {
1196 ctr->traceflag = fdef.flag;
1197 printk(KERN_INFO "kcapi: contr [%03d] set trace=%d\n",
1198 ctr->cnr, ctr->traceflag);
1199 retval = 0;
1200 } else
1201 retval = -ESRCH;
1202
1203 mutex_unlock(&capi_controller_lock);
1086 1204
1087 card->traceflag = fdef.flag; 1205 return retval;
1088 printk(KERN_INFO "kcapi: contr [%03d] set trace=%d\n",
1089 card->cnr, card->traceflag);
1090 return 0;
1091 } 1206 }
1092 case KCAPI_CMD_ADDCARD: 1207 case KCAPI_CMD_ADDCARD:
1093 { 1208 {
@@ -1095,7 +1210,6 @@ int capi20_manufacturer(unsigned int cmd, void __user *data)
1095 struct capi_driver *driver = NULL; 1210 struct capi_driver *driver = NULL;
1096 capicardparams cparams; 1211 capicardparams cparams;
1097 kcapi_carddef cdef; 1212 kcapi_carddef cdef;
1098 int retval;
1099 1213
1100 if ((retval = copy_from_user(&cdef, data, sizeof(cdef)))) 1214 if ((retval = copy_from_user(&cdef, data, sizeof(cdef))))
1101 return retval; 1215 return retval;
@@ -1107,6 +1221,8 @@ int capi20_manufacturer(unsigned int cmd, void __user *data)
1107 cparams.cardtype = 0; 1221 cparams.cardtype = 0;
1108 cdef.driver[sizeof(cdef.driver)-1] = 0; 1222 cdef.driver[sizeof(cdef.driver)-1] = 0;
1109 1223
1224 mutex_lock(&capi_drivers_lock);
1225
1110 list_for_each(l, &capi_drivers) { 1226 list_for_each(l, &capi_drivers) {
1111 driver = list_entry(l, struct capi_driver, list); 1227 driver = list_entry(l, struct capi_driver, list);
1112 if (strcmp(driver->name, cdef.driver) == 0) 1228 if (strcmp(driver->name, cdef.driver) == 0)
@@ -1115,15 +1231,15 @@ int capi20_manufacturer(unsigned int cmd, void __user *data)
1115 if (driver == NULL) { 1231 if (driver == NULL) {
1116 printk(KERN_ERR "kcapi: driver \"%s\" not loaded.\n", 1232 printk(KERN_ERR "kcapi: driver \"%s\" not loaded.\n",
1117 cdef.driver); 1233 cdef.driver);
1118 return -ESRCH; 1234 retval = -ESRCH;
1119 } 1235 } else if (!driver->add_card) {
1120
1121 if (!driver->add_card) {
1122 printk(KERN_ERR "kcapi: driver \"%s\" has no add card function.\n", cdef.driver); 1236 printk(KERN_ERR "kcapi: driver \"%s\" has no add card function.\n", cdef.driver);
1123 return -EIO; 1237 retval = -EIO;
1124 } 1238 } else
1239 retval = driver->add_card(driver, &cparams);
1125 1240
1126 return driver->add_card(driver, &cparams); 1241 mutex_unlock(&capi_drivers_lock);
1242 return retval;
1127 } 1243 }
1128 1244
1129 default: 1245 default:
@@ -1137,30 +1253,6 @@ int capi20_manufacturer(unsigned int cmd, void __user *data)
1137 1253
1138EXPORT_SYMBOL(capi20_manufacturer); 1254EXPORT_SYMBOL(capi20_manufacturer);
1139 1255
1140/* temporary hack */
1141
1142/**
1143 * capi20_set_callback() - set CAPI application notification callback function
1144 * @ap: CAPI application descriptor structure.
1145 * @callback: callback function (NULL to remove).
1146 *
1147 * If not NULL, the callback function will be called to notify the
1148 * application of the addition or removal of a controller.
1149 * The first argument (cmd) will tell whether the controller was added
1150 * (KCI_CONTRUP) or removed (KCI_CONTRDOWN).
1151 * The second argument (contr) will be the controller number.
1152 * For cmd==KCI_CONTRUP the third argument (data) will be a pointer to the
1153 * new controller's capability profile structure.
1154 */
1155
1156void capi20_set_callback(struct capi20_appl *ap,
1157 void (*callback) (unsigned int cmd, __u32 contr, void *data))
1158{
1159 ap->callback = callback;
1160}
1161
1162EXPORT_SYMBOL(capi20_set_callback);
1163
1164/* ------------------------------------------------------------- */ 1256/* ------------------------------------------------------------- */
1165/* -------- Init & Cleanup ------------------------------------- */ 1257/* -------- Init & Cleanup ------------------------------------- */
1166/* ------------------------------------------------------------- */ 1258/* ------------------------------------------------------------- */
@@ -1169,27 +1261,21 @@ EXPORT_SYMBOL(capi20_set_callback);
1169 * init / exit functions 1261 * init / exit functions
1170 */ 1262 */
1171 1263
1264static struct notifier_block capictr_nb = {
1265 .notifier_call = notify_handler,
1266 .priority = INT_MAX,
1267};
1268
1172static int __init kcapi_init(void) 1269static int __init kcapi_init(void)
1173{ 1270{
1174 char *p; 1271 int err;
1175 char rev[32];
1176 int ret;
1177
1178 ret = cdebug_init();
1179 if (ret)
1180 return ret;
1181 kcapi_proc_init();
1182
1183 if ((p = strchr(revision, ':')) != NULL && p[1]) {
1184 strlcpy(rev, p + 2, sizeof(rev));
1185 if ((p = strchr(rev, '$')) != NULL && p > rev)
1186 *(p-1) = 0;
1187 } else
1188 strcpy(rev, "1.0");
1189 1272
1190 printk(KERN_NOTICE "CAPI Subsystem Rev %s\n", rev); 1273 register_capictr_notifier(&capictr_nb);
1191 1274
1192 return 0; 1275 err = cdebug_init();
1276 if (!err)
1277 kcapi_proc_init();
1278 return err;
1193} 1279}
1194 1280
1195static void __exit kcapi_exit(void) 1281static void __exit kcapi_exit(void)
diff --git a/drivers/isdn/capi/kcapi.h b/drivers/isdn/capi/kcapi.h
index 244711f7f838..f4620b38ec51 100644
--- a/drivers/isdn/capi/kcapi.h
+++ b/drivers/isdn/capi/kcapi.h
@@ -24,16 +24,19 @@ printk(KERN_DEBUG "%s: " format "\n" , __func__ , ## arg); \
24#endif 24#endif
25 25
26enum { 26enum {
27 CARD_DETECTED = 1, 27 CAPI_CTR_DETACHED = 0,
28 CARD_LOADING = 2, 28 CAPI_CTR_DETECTED = 1,
29 CARD_RUNNING = 3, 29 CAPI_CTR_LOADING = 2,
30 CAPI_CTR_RUNNING = 3,
30}; 31};
31 32
32extern struct list_head capi_drivers; 33extern struct list_head capi_drivers;
33extern rwlock_t capi_drivers_list_lock; 34extern struct mutex capi_drivers_lock;
35
36extern struct capi_ctr *capi_controller[CAPI_MAXCONTR];
37extern struct mutex capi_controller_lock;
34 38
35extern struct capi20_appl *capi_applications[CAPI_MAXAPPL]; 39extern struct capi20_appl *capi_applications[CAPI_MAXAPPL];
36extern struct capi_ctr *capi_cards[CAPI_MAXCONTR];
37 40
38#ifdef CONFIG_PROC_FS 41#ifdef CONFIG_PROC_FS
39 42
diff --git a/drivers/isdn/capi/kcapi_proc.c b/drivers/isdn/capi/kcapi_proc.c
index 09d4db764d22..ea2dff602e49 100644
--- a/drivers/isdn/capi/kcapi_proc.c
+++ b/drivers/isdn/capi/kcapi_proc.c
@@ -15,13 +15,12 @@
15#include <linux/seq_file.h> 15#include <linux/seq_file.h>
16#include <linux/init.h> 16#include <linux/init.h>
17 17
18static char * 18static char *state2str(unsigned short state)
19cardstate2str(unsigned short cardstate)
20{ 19{
21 switch (cardstate) { 20 switch (state) {
22 case CARD_DETECTED: return "detected"; 21 case CAPI_CTR_DETECTED: return "detected";
23 case CARD_LOADING: return "loading"; 22 case CAPI_CTR_LOADING: return "loading";
24 case CARD_RUNNING: return "running"; 23 case CAPI_CTR_RUNNING: return "running";
25 default: return "???"; 24 default: return "???";
26 } 25 }
27} 26}
@@ -36,9 +35,12 @@ cardstate2str(unsigned short cardstate)
36// --------------------------------------------------------------------------- 35// ---------------------------------------------------------------------------
37 36
38static void *controller_start(struct seq_file *seq, loff_t *pos) 37static void *controller_start(struct seq_file *seq, loff_t *pos)
38 __acquires(capi_controller_lock)
39{ 39{
40 mutex_lock(&capi_controller_lock);
41
40 if (*pos < CAPI_MAXCONTR) 42 if (*pos < CAPI_MAXCONTR)
41 return &capi_cards[*pos]; 43 return &capi_controller[*pos];
42 44
43 return NULL; 45 return NULL;
44} 46}
@@ -47,13 +49,15 @@ static void *controller_next(struct seq_file *seq, void *v, loff_t *pos)
47{ 49{
48 ++*pos; 50 ++*pos;
49 if (*pos < CAPI_MAXCONTR) 51 if (*pos < CAPI_MAXCONTR)
50 return &capi_cards[*pos]; 52 return &capi_controller[*pos];
51 53
52 return NULL; 54 return NULL;
53} 55}
54 56
55static void controller_stop(struct seq_file *seq, void *v) 57static void controller_stop(struct seq_file *seq, void *v)
58 __releases(capi_controller_lock)
56{ 59{
60 mutex_unlock(&capi_controller_lock);
57} 61}
58 62
59static int controller_show(struct seq_file *seq, void *v) 63static int controller_show(struct seq_file *seq, void *v)
@@ -65,7 +69,7 @@ static int controller_show(struct seq_file *seq, void *v)
65 69
66 seq_printf(seq, "%d %-10s %-8s %-16s %s\n", 70 seq_printf(seq, "%d %-10s %-8s %-16s %s\n",
67 ctr->cnr, ctr->driver_name, 71 ctr->cnr, ctr->driver_name,
68 cardstate2str(ctr->cardstate), 72 state2str(ctr->state),
69 ctr->name, 73 ctr->name,
70 ctr->procinfo ? ctr->procinfo(ctr) : ""); 74 ctr->procinfo ? ctr->procinfo(ctr) : "");
71 75
@@ -135,9 +139,11 @@ static const struct file_operations proc_contrstats_ops = {
135// applid nrecvctlpkt nrecvdatapkt nsentctlpkt nsentdatapkt 139// applid nrecvctlpkt nrecvdatapkt nsentctlpkt nsentdatapkt
136// --------------------------------------------------------------------------- 140// ---------------------------------------------------------------------------
137 141
138static void * 142static void *applications_start(struct seq_file *seq, loff_t *pos)
139applications_start(struct seq_file *seq, loff_t *pos) 143 __acquires(capi_controller_lock)
140{ 144{
145 mutex_lock(&capi_controller_lock);
146
141 if (*pos < CAPI_MAXAPPL) 147 if (*pos < CAPI_MAXAPPL)
142 return &capi_applications[*pos]; 148 return &capi_applications[*pos];
143 149
@@ -154,9 +160,10 @@ applications_next(struct seq_file *seq, void *v, loff_t *pos)
154 return NULL; 160 return NULL;
155} 161}
156 162
157static void 163static void applications_stop(struct seq_file *seq, void *v)
158applications_stop(struct seq_file *seq, void *v) 164 __releases(capi_controller_lock)
159{ 165{
166 mutex_unlock(&capi_controller_lock);
160} 167}
161 168
162static int 169static int
@@ -239,9 +246,9 @@ static const struct file_operations proc_applstats_ops = {
239// --------------------------------------------------------------------------- 246// ---------------------------------------------------------------------------
240 247
241static void *capi_driver_start(struct seq_file *seq, loff_t *pos) 248static void *capi_driver_start(struct seq_file *seq, loff_t *pos)
242 __acquires(&capi_drivers_list_lock) 249 __acquires(&capi_drivers_lock)
243{ 250{
244 read_lock(&capi_drivers_list_lock); 251 mutex_lock(&capi_drivers_lock);
245 return seq_list_start(&capi_drivers, *pos); 252 return seq_list_start(&capi_drivers, *pos);
246} 253}
247 254
@@ -251,9 +258,9 @@ static void *capi_driver_next(struct seq_file *seq, void *v, loff_t *pos)
251} 258}
252 259
253static void capi_driver_stop(struct seq_file *seq, void *v) 260static void capi_driver_stop(struct seq_file *seq, void *v)
254 __releases(&capi_drivers_list_lock) 261 __releases(&capi_drivers_lock)
255{ 262{
256 read_unlock(&capi_drivers_list_lock); 263 mutex_unlock(&capi_drivers_lock);
257} 264}
258 265
259static int capi_driver_show(struct seq_file *seq, void *v) 266static int capi_driver_show(struct seq_file *seq, void *v)
diff --git a/drivers/isdn/divert/divert_procfs.c b/drivers/isdn/divert/divert_procfs.c
index 3697c409bec6..9f49d9065791 100644
--- a/drivers/isdn/divert/divert_procfs.c
+++ b/drivers/isdn/divert/divert_procfs.c
@@ -11,6 +11,7 @@
11 11
12#include <linux/module.h> 12#include <linux/module.h>
13#include <linux/poll.h> 13#include <linux/poll.h>
14#include <linux/slab.h>
14#ifdef CONFIG_PROC_FS 15#ifdef CONFIG_PROC_FS
15#include <linux/proc_fs.h> 16#include <linux/proc_fs.h>
16#else 17#else
diff --git a/drivers/isdn/divert/isdn_divert.c b/drivers/isdn/divert/isdn_divert.c
index 77e9fdda0597..70cf6bac7a5a 100644
--- a/drivers/isdn/divert/isdn_divert.c
+++ b/drivers/isdn/divert/isdn_divert.c
@@ -10,6 +10,7 @@
10 */ 10 */
11 11
12#include <linux/proc_fs.h> 12#include <linux/proc_fs.h>
13#include <linux/slab.h>
13#include <linux/timer.h> 14#include <linux/timer.h>
14#include <linux/jiffies.h> 15#include <linux/jiffies.h>
15 16
diff --git a/drivers/isdn/gigaset/Kconfig b/drivers/isdn/gigaset/Kconfig
index 18ab8652aa57..dcefedc7044a 100644
--- a/drivers/isdn/gigaset/Kconfig
+++ b/drivers/isdn/gigaset/Kconfig
@@ -1,6 +1,5 @@
1menuconfig ISDN_DRV_GIGASET 1menuconfig ISDN_DRV_GIGASET
2 tristate "Siemens Gigaset support" 2 tristate "Siemens Gigaset support"
3 depends on ISDN_I4L
4 select CRC_CCITT 3 select CRC_CCITT
5 select BITREVERSE 4 select BITREVERSE
6 help 5 help
@@ -11,9 +10,33 @@ menuconfig ISDN_DRV_GIGASET
11 If you have one of these devices, say M here and for at least 10 If you have one of these devices, say M here and for at least
12 one of the connection specific parts that follow. 11 one of the connection specific parts that follow.
13 This will build a module called "gigaset". 12 This will build a module called "gigaset".
13 Note: If you build your ISDN subsystem (ISDN_CAPI or ISDN_I4L)
14 as a module, you have to build this driver as a module too,
15 otherwise the Gigaset device won't show up as an ISDN device.
14 16
15if ISDN_DRV_GIGASET 17if ISDN_DRV_GIGASET
16 18
19config GIGASET_CAPI
20 bool "Gigaset CAPI support (EXPERIMENTAL)"
21 depends on EXPERIMENTAL
22 depends on ISDN_CAPI='y'||(ISDN_CAPI='m'&&ISDN_DRV_GIGASET='m')
23 default ISDN_I4L='n'
24 help
25 Build the Gigaset driver as a CAPI 2.0 driver interfacing with
26 the Kernel CAPI subsystem. To use it with the old ISDN4Linux
27 subsystem you'll have to enable the capidrv glue driver.
28 (select ISDN_CAPI_CAPIDRV.)
29 Say N to build the old native ISDN4Linux variant.
30
31config GIGASET_I4L
32 bool
33 depends on ISDN_I4L='y'||(ISDN_I4L='m'&&ISDN_DRV_GIGASET='m')
34 default !GIGASET_CAPI
35
36config GIGASET_DUMMYLL
37 bool
38 default !GIGASET_CAPI&&!GIGASET_I4L
39
17config GIGASET_BASE 40config GIGASET_BASE
18 tristate "Gigaset base station support" 41 tristate "Gigaset base station support"
19 depends on USB 42 depends on USB
diff --git a/drivers/isdn/gigaset/Makefile b/drivers/isdn/gigaset/Makefile
index e9d3189f56b7..c453b72272a0 100644
--- a/drivers/isdn/gigaset/Makefile
+++ b/drivers/isdn/gigaset/Makefile
@@ -1,4 +1,7 @@
1gigaset-y := common.o interface.o proc.o ev-layer.o i4l.o asyncdata.o 1gigaset-y := common.o interface.o proc.o ev-layer.o asyncdata.o
2gigaset-$(CONFIG_GIGASET_CAPI) += capi.o
3gigaset-$(CONFIG_GIGASET_I4L) += i4l.o
4gigaset-$(CONFIG_GIGASET_DUMMYLL) += dummyll.o
2usb_gigaset-y := usb-gigaset.o 5usb_gigaset-y := usb-gigaset.o
3ser_gigaset-y := ser-gigaset.o 6ser_gigaset-y := ser-gigaset.o
4bas_gigaset-y := bas-gigaset.o isocdata.o 7bas_gigaset-y := bas-gigaset.o isocdata.o
diff --git a/drivers/isdn/gigaset/asyncdata.c b/drivers/isdn/gigaset/asyncdata.c
index 44a58e6f8f65..c5016bd2d94f 100644
--- a/drivers/isdn/gigaset/asyncdata.c
+++ b/drivers/isdn/gigaset/asyncdata.c
@@ -19,7 +19,7 @@
19 19
20/* check if byte must be stuffed/escaped 20/* check if byte must be stuffed/escaped
21 * I'm not sure which data should be encoded. 21 * I'm not sure which data should be encoded.
22 * Therefore I will go the hard way and decode every value 22 * Therefore I will go the hard way and encode every value
23 * less than 0x20, the flag sequence and the control escape char. 23 * less than 0x20, the flag sequence and the control escape char.
24 */ 24 */
25static inline int muststuff(unsigned char c) 25static inline int muststuff(unsigned char c)
@@ -35,303 +35,385 @@ static inline int muststuff(unsigned char c)
35 35
36/* == data input =========================================================== */ 36/* == data input =========================================================== */
37 37
38/* process a block of received bytes in command mode (modem response) 38/* process a block of received bytes in command mode
39 * (mstate != MS_LOCKED && (inputstate & INS_command))
40 * Append received bytes to the command response buffer and forward them
41 * line by line to the response handler. Exit whenever a mode/state change
42 * might have occurred.
43 * Note: Received lines may be terminated by CR, LF, or CR LF, which will be
44 * removed before passing the line to the response handler.
39 * Return value: 45 * Return value:
40 * number of processed bytes 46 * number of processed bytes
41 */ 47 */
42static inline int cmd_loop(unsigned char c, unsigned char *src, int numbytes, 48static unsigned cmd_loop(unsigned numbytes, struct inbuf_t *inbuf)
43 struct inbuf_t *inbuf)
44{ 49{
50 unsigned char *src = inbuf->data + inbuf->head;
45 struct cardstate *cs = inbuf->cs; 51 struct cardstate *cs = inbuf->cs;
46 unsigned cbytes = cs->cbytes; 52 unsigned cbytes = cs->cbytes;
47 int inputstate = inbuf->inputstate; 53 unsigned procbytes = 0;
48 int startbytes = numbytes; 54 unsigned char c;
49
50 for (;;) {
51 cs->respdata[cbytes] = c;
52 if (c == 10 || c == 13) {
53 gig_dbg(DEBUG_TRANSCMD, "%s: End of Command (%d Bytes)",
54 __func__, cbytes);
55 cs->cbytes = cbytes;
56 gigaset_handle_modem_response(cs); /* can change
57 cs->dle */
58 cbytes = 0;
59 55
60 if (cs->dle && 56 while (procbytes < numbytes) {
61 !(inputstate & INS_DLE_command)) { 57 c = *src++;
62 inputstate &= ~INS_command; 58 procbytes++;
59
60 switch (c) {
61 case '\n':
62 if (cbytes == 0 && cs->respdata[0] == '\r') {
63 /* collapse LF with preceding CR */
64 cs->respdata[0] = 0;
63 break; 65 break;
64 } 66 }
65 } else { 67 /* --v-- fall through --v-- */
66 /* advance in line buffer, checking for overflow */ 68 case '\r':
67 if (cbytes < MAX_RESP_SIZE - 1) 69 /* end of message line, pass to response handler */
68 cbytes++; 70 if (cbytes >= MAX_RESP_SIZE) {
69 else 71 dev_warn(cs->dev, "response too large (%d)\n",
70 dev_warn(cs->dev, "response too large\n"); 72 cbytes);
71 } 73 cbytes = MAX_RESP_SIZE;
74 }
75 cs->cbytes = cbytes;
76 gigaset_dbg_buffer(DEBUG_TRANSCMD, "received response",
77 cbytes, cs->respdata);
78 gigaset_handle_modem_response(cs);
79 cbytes = 0;
72 80
73 if (!numbytes) 81 /* store EOL byte for CRLF collapsing */
74 break; 82 cs->respdata[0] = c;
75 c = *src++; 83
76 --numbytes; 84 /* cs->dle may have changed */
77 if (c == DLE_FLAG && 85 if (cs->dle && !(inbuf->inputstate & INS_DLE_command))
78 (cs->dle || inputstate & INS_DLE_command)) { 86 inbuf->inputstate &= ~INS_command;
79 inputstate |= INS_DLE_char; 87
80 break; 88 /* return for reevaluating state */
89 goto exit;
90
91 case DLE_FLAG:
92 if (inbuf->inputstate & INS_DLE_char) {
93 /* quoted DLE: clear quote flag */
94 inbuf->inputstate &= ~INS_DLE_char;
95 } else if (cs->dle ||
96 (inbuf->inputstate & INS_DLE_command)) {
97 /* DLE escape, pass up for handling */
98 inbuf->inputstate |= INS_DLE_char;
99 goto exit;
100 }
101 /* quoted or not in DLE mode: treat as regular data */
102 /* --v-- fall through --v-- */
103 default:
104 /* append to line buffer if possible */
105 if (cbytes < MAX_RESP_SIZE)
106 cs->respdata[cbytes] = c;
107 cbytes++;
81 } 108 }
82 } 109 }
83 110exit:
84 cs->cbytes = cbytes; 111 cs->cbytes = cbytes;
85 inbuf->inputstate = inputstate; 112 return procbytes;
86
87 return startbytes - numbytes;
88} 113}
89 114
90/* process a block of received bytes in lock mode (tty i/f) 115/* process a block of received bytes in lock mode
116 * All received bytes are passed unmodified to the tty i/f.
91 * Return value: 117 * Return value:
92 * number of processed bytes 118 * number of processed bytes
93 */ 119 */
94static inline int lock_loop(unsigned char *src, int numbytes, 120static unsigned lock_loop(unsigned numbytes, struct inbuf_t *inbuf)
95 struct inbuf_t *inbuf)
96{ 121{
97 struct cardstate *cs = inbuf->cs; 122 unsigned char *src = inbuf->data + inbuf->head;
98
99 gigaset_dbg_buffer(DEBUG_LOCKCMD, "received response",
100 numbytes, src);
101 gigaset_if_receive(cs, src, numbytes);
102 123
124 gigaset_dbg_buffer(DEBUG_LOCKCMD, "received response", numbytes, src);
125 gigaset_if_receive(inbuf->cs, src, numbytes);
103 return numbytes; 126 return numbytes;
104} 127}
105 128
129/* set up next receive skb for data mode
130 */
131static void new_rcv_skb(struct bc_state *bcs)
132{
133 struct cardstate *cs = bcs->cs;
134 unsigned short hw_hdr_len = cs->hw_hdr_len;
135
136 if (bcs->ignore) {
137 bcs->skb = NULL;
138 return;
139 }
140
141 bcs->skb = dev_alloc_skb(SBUFSIZE + hw_hdr_len);
142 if (bcs->skb == NULL) {
143 dev_warn(cs->dev, "could not allocate new skb\n");
144 return;
145 }
146 skb_reserve(bcs->skb, hw_hdr_len);
147}
148
106/* process a block of received bytes in HDLC data mode 149/* process a block of received bytes in HDLC data mode
150 * (mstate != MS_LOCKED && !(inputstate & INS_command) && proto2 == L2_HDLC)
107 * Collect HDLC frames, undoing byte stuffing and watching for DLE escapes. 151 * Collect HDLC frames, undoing byte stuffing and watching for DLE escapes.
108 * When a frame is complete, check the FCS and pass valid frames to the LL. 152 * When a frame is complete, check the FCS and pass valid frames to the LL.
109 * If DLE is encountered, return immediately to let the caller handle it. 153 * If DLE is encountered, return immediately to let the caller handle it.
110 * Return value: 154 * Return value:
111 * number of processed bytes 155 * number of processed bytes
112 * numbytes (all bytes processed) on error --FIXME
113 */ 156 */
114static inline int hdlc_loop(unsigned char c, unsigned char *src, int numbytes, 157static unsigned hdlc_loop(unsigned numbytes, struct inbuf_t *inbuf)
115 struct inbuf_t *inbuf)
116{ 158{
117 struct cardstate *cs = inbuf->cs; 159 struct cardstate *cs = inbuf->cs;
118 struct bc_state *bcs = inbuf->bcs; 160 struct bc_state *bcs = cs->bcs;
119 int inputstate = bcs->inputstate; 161 int inputstate = bcs->inputstate;
120 __u16 fcs = bcs->fcs; 162 __u16 fcs = bcs->fcs;
121 struct sk_buff *skb = bcs->skb; 163 struct sk_buff *skb = bcs->skb;
122 unsigned char error; 164 unsigned char *src = inbuf->data + inbuf->head;
123 struct sk_buff *compskb; 165 unsigned procbytes = 0;
124 int startbytes = numbytes; 166 unsigned char c;
125 int l;
126 167
127 if (unlikely(inputstate & INS_byte_stuff)) { 168 if (inputstate & INS_byte_stuff) {
169 if (!numbytes)
170 return 0;
128 inputstate &= ~INS_byte_stuff; 171 inputstate &= ~INS_byte_stuff;
129 goto byte_stuff; 172 goto byte_stuff;
130 } 173 }
131 for (;;) { 174
132 if (unlikely(c == PPP_ESCAPE)) { 175 while (procbytes < numbytes) {
133 if (unlikely(!numbytes)) { 176 c = *src++;
134 inputstate |= INS_byte_stuff; 177 procbytes++;
178 if (c == DLE_FLAG) {
179 if (inputstate & INS_DLE_char) {
180 /* quoted DLE: clear quote flag */
181 inputstate &= ~INS_DLE_char;
182 } else if (cs->dle || (inputstate & INS_DLE_command)) {
183 /* DLE escape, pass up for handling */
184 inputstate |= INS_DLE_char;
135 break; 185 break;
136 } 186 }
137 c = *src++; 187 }
138 --numbytes; 188
139 if (unlikely(c == DLE_FLAG && 189 if (c == PPP_ESCAPE) {
140 (cs->dle || 190 /* byte stuffing indicator: pull in next byte */
141 inbuf->inputstate & INS_DLE_command))) { 191 if (procbytes >= numbytes) {
142 inbuf->inputstate |= INS_DLE_char; 192 /* end of buffer, save for later processing */
143 inputstate |= INS_byte_stuff; 193 inputstate |= INS_byte_stuff;
144 break; 194 break;
145 } 195 }
146byte_stuff: 196byte_stuff:
197 c = *src++;
198 procbytes++;
199 if (c == DLE_FLAG) {
200 if (inputstate & INS_DLE_char) {
201 /* quoted DLE: clear quote flag */
202 inputstate &= ~INS_DLE_char;
203 } else if (cs->dle ||
204 (inputstate & INS_DLE_command)) {
205 /* DLE escape, pass up for handling */
206 inputstate |=
207 INS_DLE_char | INS_byte_stuff;
208 break;
209 }
210 }
147 c ^= PPP_TRANS; 211 c ^= PPP_TRANS;
148 if (unlikely(!muststuff(c)))
149 gig_dbg(DEBUG_HDLC, "byte stuffed: 0x%02x", c);
150 } else if (unlikely(c == PPP_FLAG)) {
151 if (unlikely(inputstate & INS_skip_frame)) {
152#ifdef CONFIG_GIGASET_DEBUG
153 if (!(inputstate & INS_have_data)) { /* 7E 7E */
154 ++bcs->emptycount;
155 } else
156 gig_dbg(DEBUG_HDLC,
157 "7e----------------------------");
158#endif
159
160 /* end of frame */
161 error = 1;
162 gigaset_rcv_error(NULL, cs, bcs);
163 } else if (!(inputstate & INS_have_data)) { /* 7E 7E */
164#ifdef CONFIG_GIGASET_DEBUG 212#ifdef CONFIG_GIGASET_DEBUG
165 ++bcs->emptycount; 213 if (!muststuff(c))
214 gig_dbg(DEBUG_HDLC, "byte stuffed: 0x%02x", c);
166#endif 215#endif
167 break; 216 } else if (c == PPP_FLAG) {
168 } else { 217 /* end of frame: process content if any */
218 if (inputstate & INS_have_data) {
169 gig_dbg(DEBUG_HDLC, 219 gig_dbg(DEBUG_HDLC,
170 "7e----------------------------"); 220 "7e----------------------------");
171 221
172 /* end of frame */ 222 /* check and pass received frame */
173 error = 0; 223 if (!skb) {
174 224 /* skipped frame */
175 if (unlikely(fcs != PPP_GOODFCS)) { 225 gigaset_isdn_rcv_err(bcs);
226 } else if (skb->len < 2) {
227 /* frame too short for FCS */
228 dev_warn(cs->dev,
229 "short frame (%d)\n",
230 skb->len);
231 gigaset_isdn_rcv_err(bcs);
232 dev_kfree_skb_any(skb);
233 } else if (fcs != PPP_GOODFCS) {
234 /* frame check error */
176 dev_err(cs->dev, 235 dev_err(cs->dev,
177 "Checksum failed, %u bytes corrupted!\n", 236 "Checksum failed, %u bytes corrupted!\n",
178 skb->len); 237 skb->len);
179 compskb = NULL; 238 gigaset_isdn_rcv_err(bcs);
180 gigaset_rcv_error(compskb, cs, bcs); 239 dev_kfree_skb_any(skb);
181 error = 1;
182 } else { 240 } else {
183 if (likely((l = skb->len) > 2)) { 241 /* good frame */
184 skb->tail -= 2; 242 __skb_trim(skb, skb->len - 2);
185 skb->len -= 2; 243 gigaset_skb_rcvd(bcs, skb);
186 } else {
187 dev_kfree_skb(skb);
188 skb = NULL;
189 inputstate |= INS_skip_frame;
190 if (l == 1) {
191 dev_err(cs->dev,
192 "invalid packet size (1)!\n");
193 error = 1;
194 gigaset_rcv_error(NULL,
195 cs, bcs);
196 }
197 }
198 if (likely(!(error ||
199 (inputstate &
200 INS_skip_frame)))) {
201 gigaset_rcv_skb(skb, cs, bcs);
202 }
203 } 244 }
204 }
205 245
206 if (unlikely(error)) 246 /* prepare reception of next frame */
207 if (skb) 247 inputstate &= ~INS_have_data;
208 dev_kfree_skb(skb); 248 new_rcv_skb(bcs);
209 249 skb = bcs->skb;
210 fcs = PPP_INITFCS;
211 inputstate &= ~(INS_have_data | INS_skip_frame);
212 if (unlikely(bcs->ignore)) {
213 inputstate |= INS_skip_frame;
214 skb = NULL;
215 } else if (likely((skb = dev_alloc_skb(SBUFSIZE + HW_HDR_LEN)) != NULL)) {
216 skb_reserve(skb, HW_HDR_LEN);
217 } else { 250 } else {
218 dev_warn(cs->dev, 251 /* empty frame (7E 7E) */
219 "could not allocate new skb\n"); 252#ifdef CONFIG_GIGASET_DEBUG
220 inputstate |= INS_skip_frame; 253 ++bcs->emptycount;
254#endif
255 if (!skb) {
256 /* skipped (?) */
257 gigaset_isdn_rcv_err(bcs);
258 new_rcv_skb(bcs);
259 skb = bcs->skb;
260 }
221 } 261 }
222 262
223 break; 263 fcs = PPP_INITFCS;
224 } else if (unlikely(muststuff(c))) { 264 continue;
265#ifdef CONFIG_GIGASET_DEBUG
266 } else if (muststuff(c)) {
225 /* Should not happen. Possible after ZDLE=1<CR><LF>. */ 267 /* Should not happen. Possible after ZDLE=1<CR><LF>. */
226 gig_dbg(DEBUG_HDLC, "not byte stuffed: 0x%02x", c); 268 gig_dbg(DEBUG_HDLC, "not byte stuffed: 0x%02x", c);
269#endif
227 } 270 }
228 271
229 /* add character */ 272 /* regular data byte, append to skb */
230
231#ifdef CONFIG_GIGASET_DEBUG 273#ifdef CONFIG_GIGASET_DEBUG
232 if (unlikely(!(inputstate & INS_have_data))) { 274 if (!(inputstate & INS_have_data)) {
233 gig_dbg(DEBUG_HDLC, "7e (%d x) ================", 275 gig_dbg(DEBUG_HDLC, "7e (%d x) ================",
234 bcs->emptycount); 276 bcs->emptycount);
235 bcs->emptycount = 0; 277 bcs->emptycount = 0;
236 } 278 }
237#endif 279#endif
238
239 inputstate |= INS_have_data; 280 inputstate |= INS_have_data;
240 281 if (skb) {
241 if (likely(!(inputstate & INS_skip_frame))) { 282 if (skb->len == SBUFSIZE) {
242 if (unlikely(skb->len == SBUFSIZE)) {
243 dev_warn(cs->dev, "received packet too long\n"); 283 dev_warn(cs->dev, "received packet too long\n");
244 dev_kfree_skb_any(skb); 284 dev_kfree_skb_any(skb);
245 skb = NULL; 285 /* skip remainder of packet */
246 inputstate |= INS_skip_frame; 286 bcs->skb = skb = NULL;
247 break; 287 } else {
288 *__skb_put(skb, 1) = c;
289 fcs = crc_ccitt_byte(fcs, c);
248 } 290 }
249 *__skb_put(skb, 1) = c;
250 fcs = crc_ccitt_byte(fcs, c);
251 }
252
253 if (unlikely(!numbytes))
254 break;
255 c = *src++;
256 --numbytes;
257 if (unlikely(c == DLE_FLAG &&
258 (cs->dle ||
259 inbuf->inputstate & INS_DLE_command))) {
260 inbuf->inputstate |= INS_DLE_char;
261 break;
262 } 291 }
263 } 292 }
293
264 bcs->inputstate = inputstate; 294 bcs->inputstate = inputstate;
265 bcs->fcs = fcs; 295 bcs->fcs = fcs;
266 bcs->skb = skb; 296 return procbytes;
267 return startbytes - numbytes;
268} 297}
269 298
270/* process a block of received bytes in transparent data mode 299/* process a block of received bytes in transparent data mode
300 * (mstate != MS_LOCKED && !(inputstate & INS_command) && proto2 != L2_HDLC)
271 * Invert bytes, undoing byte stuffing and watching for DLE escapes. 301 * Invert bytes, undoing byte stuffing and watching for DLE escapes.
272 * If DLE is encountered, return immediately to let the caller handle it. 302 * If DLE is encountered, return immediately to let the caller handle it.
273 * Return value: 303 * Return value:
274 * number of processed bytes 304 * number of processed bytes
275 * numbytes (all bytes processed) on error --FIXME
276 */ 305 */
277static inline int iraw_loop(unsigned char c, unsigned char *src, int numbytes, 306static unsigned iraw_loop(unsigned numbytes, struct inbuf_t *inbuf)
278 struct inbuf_t *inbuf)
279{ 307{
280 struct cardstate *cs = inbuf->cs; 308 struct cardstate *cs = inbuf->cs;
281 struct bc_state *bcs = inbuf->bcs; 309 struct bc_state *bcs = cs->bcs;
282 int inputstate = bcs->inputstate; 310 int inputstate = bcs->inputstate;
283 struct sk_buff *skb = bcs->skb; 311 struct sk_buff *skb = bcs->skb;
284 int startbytes = numbytes; 312 unsigned char *src = inbuf->data + inbuf->head;
313 unsigned procbytes = 0;
314 unsigned char c;
285 315
286 for (;;) { 316 if (!skb) {
287 /* add character */ 317 /* skip this block */
288 inputstate |= INS_have_data; 318 new_rcv_skb(bcs);
319 return numbytes;
320 }
289 321
290 if (likely(!(inputstate & INS_skip_frame))) { 322 while (procbytes < numbytes && skb->len < SBUFSIZE) {
291 if (unlikely(skb->len == SBUFSIZE)) { 323 c = *src++;
292 //FIXME just pass skb up and allocate a new one 324 procbytes++;
293 dev_warn(cs->dev, "received packet too long\n"); 325
294 dev_kfree_skb_any(skb); 326 if (c == DLE_FLAG) {
295 skb = NULL; 327 if (inputstate & INS_DLE_char) {
296 inputstate |= INS_skip_frame; 328 /* quoted DLE: clear quote flag */
329 inputstate &= ~INS_DLE_char;
330 } else if (cs->dle || (inputstate & INS_DLE_command)) {
331 /* DLE escape, pass up for handling */
332 inputstate |= INS_DLE_char;
297 break; 333 break;
298 } 334 }
299 *__skb_put(skb, 1) = bitrev8(c);
300 } 335 }
301 336
302 if (unlikely(!numbytes)) 337 /* regular data byte: append to current skb */
303 break; 338 inputstate |= INS_have_data;
304 c = *src++; 339 *__skb_put(skb, 1) = bitrev8(c);
305 --numbytes;
306 if (unlikely(c == DLE_FLAG &&
307 (cs->dle ||
308 inbuf->inputstate & INS_DLE_command))) {
309 inbuf->inputstate |= INS_DLE_char;
310 break;
311 }
312 } 340 }
313 341
314 /* pass data up */ 342 /* pass data up */
315 if (likely(inputstate & INS_have_data)) { 343 if (inputstate & INS_have_data) {
316 if (likely(!(inputstate & INS_skip_frame))) { 344 gigaset_skb_rcvd(bcs, skb);
317 gigaset_rcv_skb(skb, cs, bcs); 345 inputstate &= ~INS_have_data;
318 } 346 new_rcv_skb(bcs);
319 inputstate &= ~(INS_have_data | INS_skip_frame); 347 }
320 if (unlikely(bcs->ignore)) { 348
321 inputstate |= INS_skip_frame; 349 bcs->inputstate = inputstate;
322 skb = NULL; 350 return procbytes;
323 } else if (likely((skb = dev_alloc_skb(SBUFSIZE + HW_HDR_LEN)) 351}
324 != NULL)) { 352
325 skb_reserve(skb, HW_HDR_LEN); 353/* process DLE escapes
354 * Called whenever a DLE sequence might be encountered in the input stream.
355 * Either processes the entire DLE sequence or, if that isn't possible,
356 * notes the fact that an initial DLE has been received in the INS_DLE_char
357 * inputstate flag and resumes processing of the sequence on the next call.
358 */
359static void handle_dle(struct inbuf_t *inbuf)
360{
361 struct cardstate *cs = inbuf->cs;
362
363 if (cs->mstate == MS_LOCKED)
364 return; /* no DLE processing in lock mode */
365
366 if (!(inbuf->inputstate & INS_DLE_char)) {
367 /* no DLE pending */
368 if (inbuf->data[inbuf->head] == DLE_FLAG &&
369 (cs->dle || inbuf->inputstate & INS_DLE_command)) {
370 /* start of DLE sequence */
371 inbuf->head++;
372 if (inbuf->head == inbuf->tail ||
373 inbuf->head == RBUFSIZE) {
374 /* end of buffer, save for later processing */
375 inbuf->inputstate |= INS_DLE_char;
376 return;
377 }
326 } else { 378 } else {
327 dev_warn(cs->dev, "could not allocate new skb\n"); 379 /* regular data byte */
328 inputstate |= INS_skip_frame; 380 return;
329 } 381 }
330 } 382 }
331 383
332 bcs->inputstate = inputstate; 384 /* consume pending DLE */
333 bcs->skb = skb; 385 inbuf->inputstate &= ~INS_DLE_char;
334 return startbytes - numbytes; 386
387 switch (inbuf->data[inbuf->head]) {
388 case 'X': /* begin of event message */
389 if (inbuf->inputstate & INS_command)
390 dev_notice(cs->dev,
391 "received <DLE>X in command mode\n");
392 inbuf->inputstate |= INS_command | INS_DLE_command;
393 inbuf->head++; /* byte consumed */
394 break;
395 case '.': /* end of event message */
396 if (!(inbuf->inputstate & INS_DLE_command))
397 dev_notice(cs->dev,
398 "received <DLE>. without <DLE>X\n");
399 inbuf->inputstate &= ~INS_DLE_command;
400 /* return to data mode if in DLE mode */
401 if (cs->dle)
402 inbuf->inputstate &= ~INS_command;
403 inbuf->head++; /* byte consumed */
404 break;
405 case DLE_FLAG: /* DLE in data stream */
406 /* mark as quoted */
407 inbuf->inputstate |= INS_DLE_char;
408 if (!(cs->dle || inbuf->inputstate & INS_DLE_command))
409 dev_notice(cs->dev,
410 "received <DLE><DLE> not in DLE mode\n");
411 break; /* quoted byte left in buffer */
412 default:
413 dev_notice(cs->dev, "received <DLE><%02x>\n",
414 inbuf->data[inbuf->head]);
415 /* quoted byte left in buffer */
416 }
335} 417}
336 418
337/** 419/**
@@ -345,94 +427,39 @@ static inline int iraw_loop(unsigned char c, unsigned char *src, int numbytes,
345 */ 427 */
346void gigaset_m10x_input(struct inbuf_t *inbuf) 428void gigaset_m10x_input(struct inbuf_t *inbuf)
347{ 429{
348 struct cardstate *cs; 430 struct cardstate *cs = inbuf->cs;
349 unsigned tail, head, numbytes; 431 unsigned numbytes, procbytes;
350 unsigned char *src, c;
351 int procbytes;
352
353 head = inbuf->head;
354 tail = inbuf->tail;
355 gig_dbg(DEBUG_INTR, "buffer state: %u -> %u", head, tail);
356
357 if (head != tail) {
358 cs = inbuf->cs;
359 src = inbuf->data + head;
360 numbytes = (head > tail ? RBUFSIZE : tail) - head;
361 gig_dbg(DEBUG_INTR, "processing %u bytes", numbytes);
362 432
363 while (numbytes) { 433 gig_dbg(DEBUG_INTR, "buffer state: %u -> %u", inbuf->head, inbuf->tail);
364 if (cs->mstate == MS_LOCKED) {
365 procbytes = lock_loop(src, numbytes, inbuf);
366 src += procbytes;
367 numbytes -= procbytes;
368 } else {
369 c = *src++;
370 --numbytes;
371 if (c == DLE_FLAG && (cs->dle ||
372 inbuf->inputstate & INS_DLE_command)) {
373 if (!(inbuf->inputstate & INS_DLE_char)) {
374 inbuf->inputstate |= INS_DLE_char;
375 goto nextbyte;
376 }
377 /* <DLE> <DLE> => <DLE> in data stream */
378 inbuf->inputstate &= ~INS_DLE_char;
379 }
380 434
381 if (!(inbuf->inputstate & INS_DLE_char)) { 435 while (inbuf->head != inbuf->tail) {
382 436 /* check for DLE escape */
383 /* FIXME use function pointers? */ 437 handle_dle(inbuf);
384 if (inbuf->inputstate & INS_command)
385 procbytes = cmd_loop(c, src, numbytes, inbuf);
386 else if (inbuf->bcs->proto2 == ISDN_PROTO_L2_HDLC)
387 procbytes = hdlc_loop(c, src, numbytes, inbuf);
388 else
389 procbytes = iraw_loop(c, src, numbytes, inbuf);
390
391 src += procbytes;
392 numbytes -= procbytes;
393 } else { /* DLE char */
394 inbuf->inputstate &= ~INS_DLE_char;
395 switch (c) {
396 case 'X': /*begin of command*/
397 if (inbuf->inputstate & INS_command)
398 dev_warn(cs->dev,
399 "received <DLE> 'X' in command mode\n");
400 inbuf->inputstate |=
401 INS_command | INS_DLE_command;
402 break;
403 case '.': /*end of command*/
404 if (!(inbuf->inputstate & INS_command))
405 dev_warn(cs->dev,
406 "received <DLE> '.' in hdlc mode\n");
407 inbuf->inputstate &= cs->dle ?
408 ~(INS_DLE_command|INS_command)
409 : ~INS_DLE_command;
410 break;
411 //case DLE_FLAG: /*DLE_FLAG in data stream*/ /* schon oben behandelt! */
412 default:
413 dev_err(cs->dev,
414 "received 0x10 0x%02x!\n",
415 (int) c);
416 /* FIXME: reset driver?? */
417 }
418 }
419 }
420nextbyte:
421 if (!numbytes) {
422 /* end of buffer, check for wrap */
423 if (head > tail) {
424 head = 0;
425 src = inbuf->data;
426 numbytes = tail;
427 } else {
428 head = tail;
429 break;
430 }
431 }
432 }
433 438
434 gig_dbg(DEBUG_INTR, "setting head to %u", head); 439 /* process a contiguous block of bytes */
435 inbuf->head = head; 440 numbytes = (inbuf->head > inbuf->tail ?
441 RBUFSIZE : inbuf->tail) - inbuf->head;
442 gig_dbg(DEBUG_INTR, "processing %u bytes", numbytes);
443 /*
444 * numbytes may be 0 if handle_dle() ate the last byte.
445 * This does no harm, *_loop() will just return 0 immediately.
446 */
447
448 if (cs->mstate == MS_LOCKED)
449 procbytes = lock_loop(numbytes, inbuf);
450 else if (inbuf->inputstate & INS_command)
451 procbytes = cmd_loop(numbytes, inbuf);
452 else if (cs->bcs->proto2 == L2_HDLC)
453 procbytes = hdlc_loop(numbytes, inbuf);
454 else
455 procbytes = iraw_loop(numbytes, inbuf);
456 inbuf->head += procbytes;
457
458 /* check for buffer wraparound */
459 if (inbuf->head >= RBUFSIZE)
460 inbuf->head = 0;
461
462 gig_dbg(DEBUG_INTR, "head set to %u", inbuf->head);
436 } 463 }
437} 464}
438EXPORT_SYMBOL_GPL(gigaset_m10x_input); 465EXPORT_SYMBOL_GPL(gigaset_m10x_input);
@@ -440,16 +467,16 @@ EXPORT_SYMBOL_GPL(gigaset_m10x_input);
440 467
441/* == data output ========================================================== */ 468/* == data output ========================================================== */
442 469
443/* Encoding of a PPP packet into an octet stuffed HDLC frame 470/*
444 * with FCS, opening and closing flags. 471 * Encode a data packet into an octet stuffed HDLC frame with FCS,
472 * opening and closing flags, preserving headroom data.
445 * parameters: 473 * parameters:
446 * skb skb containing original packet (freed upon return) 474 * skb skb containing original packet (freed upon return)
447 * head number of headroom bytes to allocate in result skb
448 * tail number of tailroom bytes to allocate in result skb
449 * Return value: 475 * Return value:
450 * pointer to newly allocated skb containing the result frame 476 * pointer to newly allocated skb containing the result frame
477 * and the original link layer header, NULL on error
451 */ 478 */
452static struct sk_buff *HDLC_Encode(struct sk_buff *skb, int head, int tail) 479static struct sk_buff *HDLC_Encode(struct sk_buff *skb)
453{ 480{
454 struct sk_buff *hdlc_skb; 481 struct sk_buff *hdlc_skb;
455 __u16 fcs; 482 __u16 fcs;
@@ -471,16 +498,19 @@ static struct sk_buff *HDLC_Encode(struct sk_buff *skb, int head, int tail)
471 498
472 /* size of new buffer: original size + number of stuffing bytes 499 /* size of new buffer: original size + number of stuffing bytes
473 * + 2 bytes FCS + 2 stuffing bytes for FCS (if needed) + 2 flag bytes 500 * + 2 bytes FCS + 2 stuffing bytes for FCS (if needed) + 2 flag bytes
501 * + room for link layer header
474 */ 502 */
475 hdlc_skb = dev_alloc_skb(skb->len + stuf_cnt + 6 + tail + head); 503 hdlc_skb = dev_alloc_skb(skb->len + stuf_cnt + 6 + skb->mac_len);
476 if (!hdlc_skb) { 504 if (!hdlc_skb) {
477 dev_kfree_skb(skb); 505 dev_kfree_skb_any(skb);
478 return NULL; 506 return NULL;
479 } 507 }
480 skb_reserve(hdlc_skb, head);
481 508
482 /* Copy acknowledge request into new skb */ 509 /* Copy link layer header into new skb */
483 memcpy(hdlc_skb->head, skb->head, 2); 510 skb_reset_mac_header(hdlc_skb);
511 skb_reserve(hdlc_skb, skb->mac_len);
512 memcpy(skb_mac_header(hdlc_skb), skb_mac_header(skb), skb->mac_len);
513 hdlc_skb->mac_len = skb->mac_len;
484 514
485 /* Add flag sequence in front of everything.. */ 515 /* Add flag sequence in front of everything.. */
486 *(skb_put(hdlc_skb, 1)) = PPP_FLAG; 516 *(skb_put(hdlc_skb, 1)) = PPP_FLAG;
@@ -511,33 +541,42 @@ static struct sk_buff *HDLC_Encode(struct sk_buff *skb, int head, int tail)
511 541
512 *(skb_put(hdlc_skb, 1)) = PPP_FLAG; 542 *(skb_put(hdlc_skb, 1)) = PPP_FLAG;
513 543
514 dev_kfree_skb(skb); 544 dev_kfree_skb_any(skb);
515 return hdlc_skb; 545 return hdlc_skb;
516} 546}
517 547
518/* Encoding of a raw packet into an octet stuffed bit inverted frame 548/*
549 * Encode a data packet into an octet stuffed raw bit inverted frame,
550 * preserving headroom data.
519 * parameters: 551 * parameters:
520 * skb skb containing original packet (freed upon return) 552 * skb skb containing original packet (freed upon return)
521 * head number of headroom bytes to allocate in result skb
522 * tail number of tailroom bytes to allocate in result skb
523 * Return value: 553 * Return value:
524 * pointer to newly allocated skb containing the result frame 554 * pointer to newly allocated skb containing the result frame
555 * and the original link layer header, NULL on error
525 */ 556 */
526static struct sk_buff *iraw_encode(struct sk_buff *skb, int head, int tail) 557static struct sk_buff *iraw_encode(struct sk_buff *skb)
527{ 558{
528 struct sk_buff *iraw_skb; 559 struct sk_buff *iraw_skb;
529 unsigned char c; 560 unsigned char c;
530 unsigned char *cp; 561 unsigned char *cp;
531 int len; 562 int len;
532 563
533 /* worst case: every byte must be stuffed */ 564 /* size of new buffer (worst case = every byte must be stuffed):
534 iraw_skb = dev_alloc_skb(2*skb->len + tail + head); 565 * 2 * original size + room for link layer header
566 */
567 iraw_skb = dev_alloc_skb(2*skb->len + skb->mac_len);
535 if (!iraw_skb) { 568 if (!iraw_skb) {
536 dev_kfree_skb(skb); 569 dev_kfree_skb_any(skb);
537 return NULL; 570 return NULL;
538 } 571 }
539 skb_reserve(iraw_skb, head);
540 572
573 /* copy link layer header into new skb */
574 skb_reset_mac_header(iraw_skb);
575 skb_reserve(iraw_skb, skb->mac_len);
576 memcpy(skb_mac_header(iraw_skb), skb_mac_header(skb), skb->mac_len);
577 iraw_skb->mac_len = skb->mac_len;
578
579 /* copy and stuff data */
541 cp = skb->data; 580 cp = skb->data;
542 len = skb->len; 581 len = skb->len;
543 while (len--) { 582 while (len--) {
@@ -546,7 +585,7 @@ static struct sk_buff *iraw_encode(struct sk_buff *skb, int head, int tail)
546 *(skb_put(iraw_skb, 1)) = c; 585 *(skb_put(iraw_skb, 1)) = c;
547 *(skb_put(iraw_skb, 1)) = c; 586 *(skb_put(iraw_skb, 1)) = c;
548 } 587 }
549 dev_kfree_skb(skb); 588 dev_kfree_skb_any(skb);
550 return iraw_skb; 589 return iraw_skb;
551} 590}
552 591
@@ -555,8 +594,10 @@ static struct sk_buff *iraw_encode(struct sk_buff *skb, int head, int tail)
555 * @bcs: B channel descriptor structure. 594 * @bcs: B channel descriptor structure.
556 * @skb: data to send. 595 * @skb: data to send.
557 * 596 *
558 * Called by i4l.c to encode and queue an skb for sending, and start 597 * Called by LL to encode and queue an skb for sending, and start
559 * transmission if necessary. 598 * transmission if necessary.
599 * Once the payload data has been transmitted completely, gigaset_skb_sent()
600 * will be called with the skb's link layer header preserved.
560 * 601 *
561 * Return value: 602 * Return value:
562 * number of bytes accepted for sending (skb->len) if ok, 603 * number of bytes accepted for sending (skb->len) if ok,
@@ -564,24 +605,25 @@ static struct sk_buff *iraw_encode(struct sk_buff *skb, int head, int tail)
564 */ 605 */
565int gigaset_m10x_send_skb(struct bc_state *bcs, struct sk_buff *skb) 606int gigaset_m10x_send_skb(struct bc_state *bcs, struct sk_buff *skb)
566{ 607{
608 struct cardstate *cs = bcs->cs;
567 unsigned len = skb->len; 609 unsigned len = skb->len;
568 unsigned long flags; 610 unsigned long flags;
569 611
570 if (bcs->proto2 == ISDN_PROTO_L2_HDLC) 612 if (bcs->proto2 == L2_HDLC)
571 skb = HDLC_Encode(skb, HW_HDR_LEN, 0); 613 skb = HDLC_Encode(skb);
572 else 614 else
573 skb = iraw_encode(skb, HW_HDR_LEN, 0); 615 skb = iraw_encode(skb);
574 if (!skb) { 616 if (!skb) {
575 dev_err(bcs->cs->dev, 617 dev_err(cs->dev,
576 "unable to allocate memory for encoding!\n"); 618 "unable to allocate memory for encoding!\n");
577 return -ENOMEM; 619 return -ENOMEM;
578 } 620 }
579 621
580 skb_queue_tail(&bcs->squeue, skb); 622 skb_queue_tail(&bcs->squeue, skb);
581 spin_lock_irqsave(&bcs->cs->lock, flags); 623 spin_lock_irqsave(&cs->lock, flags);
582 if (bcs->cs->connected) 624 if (cs->connected)
583 tasklet_schedule(&bcs->cs->write_tasklet); 625 tasklet_schedule(&cs->write_tasklet);
584 spin_unlock_irqrestore(&bcs->cs->lock, flags); 626 spin_unlock_irqrestore(&cs->lock, flags);
585 627
586 return len; /* ok so far */ 628 return len; /* ok so far */
587} 629}
diff --git a/drivers/isdn/gigaset/bas-gigaset.c b/drivers/isdn/gigaset/bas-gigaset.c
index 5ed1d99eb9f3..47a5ffec55a3 100644
--- a/drivers/isdn/gigaset/bas-gigaset.c
+++ b/drivers/isdn/gigaset/bas-gigaset.c
@@ -14,11 +14,6 @@
14 */ 14 */
15 15
16#include "gigaset.h" 16#include "gigaset.h"
17
18#include <linux/errno.h>
19#include <linux/init.h>
20#include <linux/slab.h>
21#include <linux/timer.h>
22#include <linux/usb.h> 17#include <linux/usb.h>
23#include <linux/module.h> 18#include <linux/module.h>
24#include <linux/moduleparam.h> 19#include <linux/moduleparam.h>
@@ -57,7 +52,7 @@ MODULE_PARM_DESC(cidmode, "Call-ID mode");
57#define USB_SX353_PRODUCT_ID 0x0022 52#define USB_SX353_PRODUCT_ID 0x0022
58 53
59/* table of devices that work with this driver */ 54/* table of devices that work with this driver */
60static const struct usb_device_id gigaset_table [] = { 55static const struct usb_device_id gigaset_table[] = {
61 { USB_DEVICE(USB_GIGA_VENDOR_ID, USB_3070_PRODUCT_ID) }, 56 { USB_DEVICE(USB_GIGA_VENDOR_ID, USB_3070_PRODUCT_ID) },
62 { USB_DEVICE(USB_GIGA_VENDOR_ID, USB_3075_PRODUCT_ID) }, 57 { USB_DEVICE(USB_GIGA_VENDOR_ID, USB_3075_PRODUCT_ID) },
63 { USB_DEVICE(USB_GIGA_VENDOR_ID, USB_SX303_PRODUCT_ID) }, 58 { USB_DEVICE(USB_GIGA_VENDOR_ID, USB_SX303_PRODUCT_ID) },
@@ -137,7 +132,7 @@ struct bas_cardstate {
137#define BS_RESETTING 0x200 /* waiting for HD_RESET_INTERRUPT_PIPE_ACK */ 132#define BS_RESETTING 0x200 /* waiting for HD_RESET_INTERRUPT_PIPE_ACK */
138 133
139 134
140static struct gigaset_driver *driver = NULL; 135static struct gigaset_driver *driver;
141 136
142/* usb specific object needed to register this driver with the usb subsystem */ 137/* usb specific object needed to register this driver with the usb subsystem */
143static struct usb_driver gigaset_usb_driver = { 138static struct usb_driver gigaset_usb_driver = {
@@ -347,12 +342,7 @@ static inline void error_hangup(struct bc_state *bcs)
347{ 342{
348 struct cardstate *cs = bcs->cs; 343 struct cardstate *cs = bcs->cs;
349 344
350 gig_dbg(DEBUG_ANY, "%s: scheduling HUP for channel %d", 345 gigaset_add_event(cs, &bcs->at_state, EV_HUP, NULL, 0, NULL);
351 __func__, bcs->channel);
352
353 if (!gigaset_add_event(cs, &bcs->at_state, EV_HUP, NULL, 0, NULL))
354 dev_err(cs->dev, "event queue full\n");
355
356 gigaset_schedule_event(cs); 346 gigaset_schedule_event(cs);
357} 347}
358 348
@@ -601,11 +591,12 @@ static int atread_submit(struct cardstate *cs, int timeout)
601 ucs->dr_cmd_in.wLength = cpu_to_le16(ucs->rcvbuf_size); 591 ucs->dr_cmd_in.wLength = cpu_to_le16(ucs->rcvbuf_size);
602 usb_fill_control_urb(ucs->urb_cmd_in, ucs->udev, 592 usb_fill_control_urb(ucs->urb_cmd_in, ucs->udev,
603 usb_rcvctrlpipe(ucs->udev, 0), 593 usb_rcvctrlpipe(ucs->udev, 0),
604 (unsigned char*) & ucs->dr_cmd_in, 594 (unsigned char *) &ucs->dr_cmd_in,
605 ucs->rcvbuf, ucs->rcvbuf_size, 595 ucs->rcvbuf, ucs->rcvbuf_size,
606 read_ctrl_callback, cs->inbuf); 596 read_ctrl_callback, cs->inbuf);
607 597
608 if ((ret = usb_submit_urb(ucs->urb_cmd_in, GFP_ATOMIC)) != 0) { 598 ret = usb_submit_urb(ucs->urb_cmd_in, GFP_ATOMIC);
599 if (ret != 0) {
609 update_basstate(ucs, 0, BS_ATRDPEND); 600 update_basstate(ucs, 0, BS_ATRDPEND);
610 dev_err(cs->dev, "could not submit HD_READ_ATMESSAGE: %s\n", 601 dev_err(cs->dev, "could not submit HD_READ_ATMESSAGE: %s\n",
611 get_usb_rcmsg(ret)); 602 get_usb_rcmsg(ret));
@@ -652,13 +643,11 @@ static void read_int_callback(struct urb *urb)
652 return; 643 return;
653 case -ENODEV: /* device removed */ 644 case -ENODEV: /* device removed */
654 case -ESHUTDOWN: /* device shut down */ 645 case -ESHUTDOWN: /* device shut down */
655 //FIXME use this as disconnect indicator?
656 gig_dbg(DEBUG_USBREQ, "%s: device disconnected", __func__); 646 gig_dbg(DEBUG_USBREQ, "%s: device disconnected", __func__);
657 return; 647 return;
658 default: /* severe trouble */ 648 default: /* severe trouble */
659 dev_warn(cs->dev, "interrupt read: %s\n", 649 dev_warn(cs->dev, "interrupt read: %s\n",
660 get_usb_statmsg(status)); 650 get_usb_statmsg(status));
661 //FIXME corrective action? resubmission always ok?
662 goto resubmit; 651 goto resubmit;
663 } 652 }
664 653
@@ -742,7 +731,8 @@ static void read_int_callback(struct urb *urb)
742 kfree(ucs->rcvbuf); 731 kfree(ucs->rcvbuf);
743 ucs->rcvbuf_size = 0; 732 ucs->rcvbuf_size = 0;
744 } 733 }
745 if ((ucs->rcvbuf = kmalloc(l, GFP_ATOMIC)) == NULL) { 734 ucs->rcvbuf = kmalloc(l, GFP_ATOMIC);
735 if (ucs->rcvbuf == NULL) {
746 spin_unlock_irqrestore(&cs->lock, flags); 736 spin_unlock_irqrestore(&cs->lock, flags);
747 dev_err(cs->dev, "out of memory receiving AT data\n"); 737 dev_err(cs->dev, "out of memory receiving AT data\n");
748 error_reset(cs); 738 error_reset(cs);
@@ -750,12 +740,12 @@ static void read_int_callback(struct urb *urb)
750 } 740 }
751 ucs->rcvbuf_size = l; 741 ucs->rcvbuf_size = l;
752 ucs->retry_cmd_in = 0; 742 ucs->retry_cmd_in = 0;
753 if ((rc = atread_submit(cs, BAS_TIMEOUT)) < 0) { 743 rc = atread_submit(cs, BAS_TIMEOUT);
744 if (rc < 0) {
754 kfree(ucs->rcvbuf); 745 kfree(ucs->rcvbuf);
755 ucs->rcvbuf = NULL; 746 ucs->rcvbuf = NULL;
756 ucs->rcvbuf_size = 0; 747 ucs->rcvbuf_size = 0;
757 if (rc != -ENODEV) { 748 if (rc != -ENODEV) {
758 //FIXME corrective action?
759 spin_unlock_irqrestore(&cs->lock, flags); 749 spin_unlock_irqrestore(&cs->lock, flags);
760 error_reset(cs); 750 error_reset(cs);
761 break; 751 break;
@@ -911,7 +901,7 @@ static int starturbs(struct bc_state *bcs)
911 int rc; 901 int rc;
912 902
913 /* initialize L2 reception */ 903 /* initialize L2 reception */
914 if (bcs->proto2 == ISDN_PROTO_L2_HDLC) 904 if (bcs->proto2 == L2_HDLC)
915 bcs->inputstate |= INS_flag_hunt; 905 bcs->inputstate |= INS_flag_hunt;
916 906
917 /* submit all isochronous input URBs */ 907 /* submit all isochronous input URBs */
@@ -940,7 +930,8 @@ static int starturbs(struct bc_state *bcs)
940 } 930 }
941 931
942 dump_urb(DEBUG_ISO, "Initial isoc read", urb); 932 dump_urb(DEBUG_ISO, "Initial isoc read", urb);
943 if ((rc = usb_submit_urb(urb, GFP_ATOMIC)) != 0) 933 rc = usb_submit_urb(urb, GFP_ATOMIC);
934 if (rc != 0)
944 goto error; 935 goto error;
945 } 936 }
946 937
@@ -1045,7 +1036,8 @@ static int submit_iso_write_urb(struct isow_urbctx_t *ucx)
1045 1036
1046 /* compute frame length according to flow control */ 1037 /* compute frame length according to flow control */
1047 ifd->length = BAS_NORMFRAME; 1038 ifd->length = BAS_NORMFRAME;
1048 if ((corrbytes = atomic_read(&ubc->corrbytes)) != 0) { 1039 corrbytes = atomic_read(&ubc->corrbytes);
1040 if (corrbytes != 0) {
1049 gig_dbg(DEBUG_ISO, "%s: corrbytes=%d", 1041 gig_dbg(DEBUG_ISO, "%s: corrbytes=%d",
1050 __func__, corrbytes); 1042 __func__, corrbytes);
1051 if (corrbytes > BAS_HIGHFRAME - BAS_NORMFRAME) 1043 if (corrbytes > BAS_HIGHFRAME - BAS_NORMFRAME)
@@ -1064,7 +1056,7 @@ static int submit_iso_write_urb(struct isow_urbctx_t *ucx)
1064 "%s: buffer busy at frame %d", 1056 "%s: buffer busy at frame %d",
1065 __func__, nframe); 1057 __func__, nframe);
1066 /* tasklet will be restarted from 1058 /* tasklet will be restarted from
1067 gigaset_send_skb() */ 1059 gigaset_isoc_send_skb() */
1068 } else { 1060 } else {
1069 dev_err(ucx->bcs->cs->dev, 1061 dev_err(ucx->bcs->cs->dev,
1070 "%s: buffer error %d at frame %d\n", 1062 "%s: buffer error %d at frame %d\n",
@@ -1284,7 +1276,8 @@ static void read_iso_tasklet(unsigned long data)
1284 for (;;) { 1276 for (;;) {
1285 /* retrieve URB */ 1277 /* retrieve URB */
1286 spin_lock_irqsave(&ubc->isoinlock, flags); 1278 spin_lock_irqsave(&ubc->isoinlock, flags);
1287 if (!(urb = ubc->isoindone)) { 1279 urb = ubc->isoindone;
1280 if (!urb) {
1288 spin_unlock_irqrestore(&ubc->isoinlock, flags); 1281 spin_unlock_irqrestore(&ubc->isoinlock, flags);
1289 return; 1282 return;
1290 } 1283 }
@@ -1371,7 +1364,7 @@ static void read_iso_tasklet(unsigned long data)
1371 "isochronous read: %d data bytes missing\n", 1364 "isochronous read: %d data bytes missing\n",
1372 totleft); 1365 totleft);
1373 1366
1374 error: 1367error:
1375 /* URB processed, resubmit */ 1368 /* URB processed, resubmit */
1376 for (frame = 0; frame < BAS_NUMFRAMES; frame++) { 1369 for (frame = 0; frame < BAS_NUMFRAMES; frame++) {
1377 urb->iso_frame_desc[frame].status = 0; 1370 urb->iso_frame_desc[frame].status = 0;
@@ -1568,7 +1561,7 @@ static int req_submit(struct bc_state *bcs, int req, int val, int timeout)
1568 ucs->dr_ctrl.wLength = 0; 1561 ucs->dr_ctrl.wLength = 0;
1569 usb_fill_control_urb(ucs->urb_ctrl, ucs->udev, 1562 usb_fill_control_urb(ucs->urb_ctrl, ucs->udev,
1570 usb_sndctrlpipe(ucs->udev, 0), 1563 usb_sndctrlpipe(ucs->udev, 0),
1571 (unsigned char*) &ucs->dr_ctrl, NULL, 0, 1564 (unsigned char *) &ucs->dr_ctrl, NULL, 0,
1572 write_ctrl_callback, ucs); 1565 write_ctrl_callback, ucs);
1573 ucs->retry_ctrl = 0; 1566 ucs->retry_ctrl = 0;
1574 ret = usb_submit_urb(ucs->urb_ctrl, GFP_ATOMIC); 1567 ret = usb_submit_urb(ucs->urb_ctrl, GFP_ATOMIC);
@@ -1621,7 +1614,8 @@ static int gigaset_init_bchannel(struct bc_state *bcs)
1621 return -EHOSTUNREACH; 1614 return -EHOSTUNREACH;
1622 } 1615 }
1623 1616
1624 if ((ret = starturbs(bcs)) < 0) { 1617 ret = starturbs(bcs);
1618 if (ret < 0) {
1625 dev_err(cs->dev, 1619 dev_err(cs->dev,
1626 "could not start isochronous I/O for channel B%d: %s\n", 1620 "could not start isochronous I/O for channel B%d: %s\n",
1627 bcs->channel + 1, 1621 bcs->channel + 1,
@@ -1633,7 +1627,8 @@ static int gigaset_init_bchannel(struct bc_state *bcs)
1633 } 1627 }
1634 1628
1635 req = bcs->channel ? HD_OPEN_B2CHANNEL : HD_OPEN_B1CHANNEL; 1629 req = bcs->channel ? HD_OPEN_B2CHANNEL : HD_OPEN_B1CHANNEL;
1636 if ((ret = req_submit(bcs, req, 0, BAS_TIMEOUT)) < 0) { 1630 ret = req_submit(bcs, req, 0, BAS_TIMEOUT);
1631 if (ret < 0) {
1637 dev_err(cs->dev, "could not open channel B%d\n", 1632 dev_err(cs->dev, "could not open channel B%d\n",
1638 bcs->channel + 1); 1633 bcs->channel + 1);
1639 stopurbs(bcs->hw.bas); 1634 stopurbs(bcs->hw.bas);
@@ -1677,7 +1672,8 @@ static int gigaset_close_bchannel(struct bc_state *bcs)
1677 1672
1678 /* channel running: tell device to close it */ 1673 /* channel running: tell device to close it */
1679 req = bcs->channel ? HD_CLOSE_B2CHANNEL : HD_CLOSE_B1CHANNEL; 1674 req = bcs->channel ? HD_CLOSE_B2CHANNEL : HD_CLOSE_B1CHANNEL;
1680 if ((ret = req_submit(bcs, req, 0, BAS_TIMEOUT)) < 0) 1675 ret = req_submit(bcs, req, 0, BAS_TIMEOUT);
1676 if (ret < 0)
1681 dev_err(cs->dev, "closing channel B%d failed\n", 1677 dev_err(cs->dev, "closing channel B%d failed\n",
1682 bcs->channel + 1); 1678 bcs->channel + 1);
1683 1679
@@ -1700,13 +1696,14 @@ static void complete_cb(struct cardstate *cs)
1700 1696
1701 /* unqueue completed buffer */ 1697 /* unqueue completed buffer */
1702 cs->cmdbytes -= cs->curlen; 1698 cs->cmdbytes -= cs->curlen;
1703 gig_dbg(DEBUG_TRANSCMD|DEBUG_LOCKCMD, 1699 gig_dbg(DEBUG_OUTPUT, "write_command: sent %u bytes, %u left",
1704 "write_command: sent %u bytes, %u left",
1705 cs->curlen, cs->cmdbytes); 1700 cs->curlen, cs->cmdbytes);
1706 if ((cs->cmdbuf = cb->next) != NULL) { 1701 if (cb->next != NULL) {
1702 cs->cmdbuf = cb->next;
1707 cs->cmdbuf->prev = NULL; 1703 cs->cmdbuf->prev = NULL;
1708 cs->curlen = cs->cmdbuf->len; 1704 cs->curlen = cs->cmdbuf->len;
1709 } else { 1705 } else {
1706 cs->cmdbuf = NULL;
1710 cs->lastcmdbuf = NULL; 1707 cs->lastcmdbuf = NULL;
1711 cs->curlen = 0; 1708 cs->curlen = 0;
1712 } 1709 }
@@ -1833,7 +1830,7 @@ static int atwrite_submit(struct cardstate *cs, unsigned char *buf, int len)
1833 ucs->dr_cmd_out.wLength = cpu_to_le16(len); 1830 ucs->dr_cmd_out.wLength = cpu_to_le16(len);
1834 usb_fill_control_urb(ucs->urb_cmd_out, ucs->udev, 1831 usb_fill_control_urb(ucs->urb_cmd_out, ucs->udev,
1835 usb_sndctrlpipe(ucs->udev, 0), 1832 usb_sndctrlpipe(ucs->udev, 0),
1836 (unsigned char*) &ucs->dr_cmd_out, buf, len, 1833 (unsigned char *) &ucs->dr_cmd_out, buf, len,
1837 write_command_callback, cs); 1834 write_command_callback, cs);
1838 rc = usb_submit_urb(ucs->urb_cmd_out, GFP_ATOMIC); 1835 rc = usb_submit_urb(ucs->urb_cmd_out, GFP_ATOMIC);
1839 if (unlikely(rc)) { 1836 if (unlikely(rc)) {
@@ -1873,13 +1870,13 @@ static int start_cbsend(struct cardstate *cs)
1873 1870
1874 /* check if suspend requested */ 1871 /* check if suspend requested */
1875 if (ucs->basstate & BS_SUSPEND) { 1872 if (ucs->basstate & BS_SUSPEND) {
1876 gig_dbg(DEBUG_TRANSCMD|DEBUG_LOCKCMD, "suspending"); 1873 gig_dbg(DEBUG_OUTPUT, "suspending");
1877 return -EHOSTUNREACH; 1874 return -EHOSTUNREACH;
1878 } 1875 }
1879 1876
1880 /* check if AT channel is open */ 1877 /* check if AT channel is open */
1881 if (!(ucs->basstate & BS_ATOPEN)) { 1878 if (!(ucs->basstate & BS_ATOPEN)) {
1882 gig_dbg(DEBUG_TRANSCMD|DEBUG_LOCKCMD, "AT channel not open"); 1879 gig_dbg(DEBUG_OUTPUT, "AT channel not open");
1883 rc = req_submit(cs->bcs, HD_OPEN_ATCHANNEL, 0, BAS_TIMEOUT); 1880 rc = req_submit(cs->bcs, HD_OPEN_ATCHANNEL, 0, BAS_TIMEOUT);
1884 if (rc < 0) { 1881 if (rc < 0) {
1885 /* flush command queue */ 1882 /* flush command queue */
@@ -1953,7 +1950,8 @@ static int gigaset_write_cmd(struct cardstate *cs,
1953 1950
1954 if (len > IF_WRITEBUF) 1951 if (len > IF_WRITEBUF)
1955 len = IF_WRITEBUF; 1952 len = IF_WRITEBUF;
1956 if (!(cb = kmalloc(sizeof(struct cmdbuf_t) + len, GFP_ATOMIC))) { 1953 cb = kmalloc(sizeof(struct cmdbuf_t) + len, GFP_ATOMIC);
1954 if (!cb) {
1957 dev_err(cs->dev, "%s: out of memory\n", __func__); 1955 dev_err(cs->dev, "%s: out of memory\n", __func__);
1958 rc = -ENOMEM; 1956 rc = -ENOMEM;
1959 goto notqueued; 1957 goto notqueued;
@@ -2100,14 +2098,15 @@ static int gigaset_initbcshw(struct bc_state *bcs)
2100 } 2098 }
2101 ubc->isooutdone = ubc->isooutfree = ubc->isooutovfl = NULL; 2099 ubc->isooutdone = ubc->isooutfree = ubc->isooutovfl = NULL;
2102 ubc->numsub = 0; 2100 ubc->numsub = 0;
2103 if (!(ubc->isooutbuf = kmalloc(sizeof(struct isowbuf_t), GFP_KERNEL))) { 2101 ubc->isooutbuf = kmalloc(sizeof(struct isowbuf_t), GFP_KERNEL);
2102 if (!ubc->isooutbuf) {
2104 pr_err("out of memory\n"); 2103 pr_err("out of memory\n");
2105 kfree(ubc); 2104 kfree(ubc);
2106 bcs->hw.bas = NULL; 2105 bcs->hw.bas = NULL;
2107 return 0; 2106 return 0;
2108 } 2107 }
2109 tasklet_init(&ubc->sent_tasklet, 2108 tasklet_init(&ubc->sent_tasklet,
2110 &write_iso_tasklet, (unsigned long) bcs); 2109 write_iso_tasklet, (unsigned long) bcs);
2111 2110
2112 spin_lock_init(&ubc->isoinlock); 2111 spin_lock_init(&ubc->isoinlock);
2113 for (i = 0; i < BAS_INURBS; ++i) 2112 for (i = 0; i < BAS_INURBS; ++i)
@@ -2128,7 +2127,7 @@ static int gigaset_initbcshw(struct bc_state *bcs)
2128 ubc->shared0s = 0; 2127 ubc->shared0s = 0;
2129 ubc->stolen0s = 0; 2128 ubc->stolen0s = 0;
2130 tasklet_init(&ubc->rcvd_tasklet, 2129 tasklet_init(&ubc->rcvd_tasklet,
2131 &read_iso_tasklet, (unsigned long) bcs); 2130 read_iso_tasklet, (unsigned long) bcs);
2132 return 1; 2131 return 1;
2133} 2132}
2134 2133
@@ -2241,7 +2240,7 @@ static int gigaset_probe(struct usb_interface *interface,
2241 int i, j; 2240 int i, j;
2242 int rc; 2241 int rc;
2243 2242
2244 gig_dbg(DEBUG_ANY, 2243 gig_dbg(DEBUG_INIT,
2245 "%s: Check if device matches .. (Vendor: 0x%x, Product: 0x%x)", 2244 "%s: Check if device matches .. (Vendor: 0x%x, Product: 0x%x)",
2246 __func__, le16_to_cpu(udev->descriptor.idVendor), 2245 __func__, le16_to_cpu(udev->descriptor.idVendor),
2247 le16_to_cpu(udev->descriptor.idProduct)); 2246 le16_to_cpu(udev->descriptor.idProduct));
@@ -2249,10 +2248,11 @@ static int gigaset_probe(struct usb_interface *interface,
2249 /* set required alternate setting */ 2248 /* set required alternate setting */
2250 hostif = interface->cur_altsetting; 2249 hostif = interface->cur_altsetting;
2251 if (hostif->desc.bAlternateSetting != 3) { 2250 if (hostif->desc.bAlternateSetting != 3) {
2252 gig_dbg(DEBUG_ANY, 2251 gig_dbg(DEBUG_INIT,
2253 "%s: wrong alternate setting %d - trying to switch", 2252 "%s: wrong alternate setting %d - trying to switch",
2254 __func__, hostif->desc.bAlternateSetting); 2253 __func__, hostif->desc.bAlternateSetting);
2255 if (usb_set_interface(udev, hostif->desc.bInterfaceNumber, 3) < 0) { 2254 if (usb_set_interface(udev, hostif->desc.bInterfaceNumber, 3)
2255 < 0) {
2256 dev_warn(&udev->dev, "usb_set_interface failed, " 2256 dev_warn(&udev->dev, "usb_set_interface failed, "
2257 "device %d interface %d altsetting %d\n", 2257 "device %d interface %d altsetting %d\n",
2258 udev->devnum, hostif->desc.bInterfaceNumber, 2258 udev->devnum, hostif->desc.bInterfaceNumber,
@@ -2321,14 +2321,16 @@ static int gigaset_probe(struct usb_interface *interface,
2321 (endpoint->bEndpointAddress) & 0x0f), 2321 (endpoint->bEndpointAddress) & 0x0f),
2322 ucs->int_in_buf, IP_MSGSIZE, read_int_callback, cs, 2322 ucs->int_in_buf, IP_MSGSIZE, read_int_callback, cs,
2323 endpoint->bInterval); 2323 endpoint->bInterval);
2324 if ((rc = usb_submit_urb(ucs->urb_int_in, GFP_KERNEL)) != 0) { 2324 rc = usb_submit_urb(ucs->urb_int_in, GFP_KERNEL);
2325 if (rc != 0) {
2325 dev_err(cs->dev, "could not submit interrupt URB: %s\n", 2326 dev_err(cs->dev, "could not submit interrupt URB: %s\n",
2326 get_usb_rcmsg(rc)); 2327 get_usb_rcmsg(rc));
2327 goto error; 2328 goto error;
2328 } 2329 }
2329 2330
2330 /* tell the device that the driver is ready */ 2331 /* tell the device that the driver is ready */
2331 if ((rc = req_submit(cs->bcs, HD_DEVICE_INIT_ACK, 0, 0)) != 0) 2332 rc = req_submit(cs->bcs, HD_DEVICE_INIT_ACK, 0, 0);
2333 if (rc != 0)
2332 goto error; 2334 goto error;
2333 2335
2334 /* tell common part that the device is ready */ 2336 /* tell common part that the device is ready */
@@ -2524,9 +2526,10 @@ static int __init bas_gigaset_init(void)
2524 int result; 2526 int result;
2525 2527
2526 /* allocate memory for our driver state and intialize it */ 2528 /* allocate memory for our driver state and intialize it */
2527 if ((driver = gigaset_initdriver(GIGASET_MINOR, GIGASET_MINORS, 2529 driver = gigaset_initdriver(GIGASET_MINOR, GIGASET_MINORS,
2528 GIGASET_MODULENAME, GIGASET_DEVNAME, 2530 GIGASET_MODULENAME, GIGASET_DEVNAME,
2529 &gigops, THIS_MODULE)) == NULL) 2531 &gigops, THIS_MODULE);
2532 if (driver == NULL)
2530 goto error; 2533 goto error;
2531 2534
2532 /* register this driver with the USB subsystem */ 2535 /* register this driver with the USB subsystem */
diff --git a/drivers/isdn/gigaset/capi.c b/drivers/isdn/gigaset/capi.c
new file mode 100644
index 000000000000..964a55fb1486
--- /dev/null
+++ b/drivers/isdn/gigaset/capi.c
@@ -0,0 +1,2273 @@
1/*
2 * Kernel CAPI interface for the Gigaset driver
3 *
4 * Copyright (c) 2009 by Tilman Schmidt <tilman@imap.cc>.
5 *
6 * =====================================================================
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License as
9 * published by the Free Software Foundation; either version 2 of
10 * the License, or (at your option) any later version.
11 * =====================================================================
12 */
13
14#include "gigaset.h"
15#include <linux/proc_fs.h>
16#include <linux/seq_file.h>
17#include <linux/isdn/capilli.h>
18#include <linux/isdn/capicmd.h>
19#include <linux/isdn/capiutil.h>
20
21/* missing from kernelcapi.h */
22#define CapiNcpiNotSupportedByProtocol 0x0001
23#define CapiFlagsNotSupportedByProtocol 0x0002
24#define CapiAlertAlreadySent 0x0003
25#define CapiFacilitySpecificFunctionNotSupported 0x3011
26
27/* missing from capicmd.h */
28#define CAPI_CONNECT_IND_BASELEN (CAPI_MSG_BASELEN+4+2+8*1)
29#define CAPI_CONNECT_ACTIVE_IND_BASELEN (CAPI_MSG_BASELEN+4+3*1)
30#define CAPI_CONNECT_B3_IND_BASELEN (CAPI_MSG_BASELEN+4+1)
31#define CAPI_CONNECT_B3_ACTIVE_IND_BASELEN (CAPI_MSG_BASELEN+4+1)
32#define CAPI_DATA_B3_REQ_LEN64 (CAPI_MSG_BASELEN+4+4+2+2+2+8)
33#define CAPI_DATA_B3_CONF_LEN (CAPI_MSG_BASELEN+4+2+2)
34#define CAPI_DISCONNECT_IND_LEN (CAPI_MSG_BASELEN+4+2)
35#define CAPI_DISCONNECT_B3_IND_BASELEN (CAPI_MSG_BASELEN+4+2+1)
36#define CAPI_FACILITY_CONF_BASELEN (CAPI_MSG_BASELEN+4+2+2+1)
37/* most _CONF messages contain only Controller/PLCI/NCCI and Info parameters */
38#define CAPI_STDCONF_LEN (CAPI_MSG_BASELEN+4+2)
39
40#define CAPI_FACILITY_HANDSET 0x0000
41#define CAPI_FACILITY_DTMF 0x0001
42#define CAPI_FACILITY_V42BIS 0x0002
43#define CAPI_FACILITY_SUPPSVC 0x0003
44#define CAPI_FACILITY_WAKEUP 0x0004
45#define CAPI_FACILITY_LI 0x0005
46
47#define CAPI_SUPPSVC_GETSUPPORTED 0x0000
48
49/* missing from capiutil.h */
50#define CAPIMSG_PLCI_PART(m) CAPIMSG_U8(m, 9)
51#define CAPIMSG_NCCI_PART(m) CAPIMSG_U16(m, 10)
52#define CAPIMSG_HANDLE_REQ(m) CAPIMSG_U16(m, 18) /* DATA_B3_REQ/_IND only! */
53#define CAPIMSG_FLAGS(m) CAPIMSG_U16(m, 20)
54#define CAPIMSG_SETCONTROLLER(m, contr) capimsg_setu8(m, 8, contr)
55#define CAPIMSG_SETPLCI_PART(m, plci) capimsg_setu8(m, 9, plci)
56#define CAPIMSG_SETNCCI_PART(m, ncci) capimsg_setu16(m, 10, ncci)
57#define CAPIMSG_SETFLAGS(m, flags) capimsg_setu16(m, 20, flags)
58
59/* parameters with differing location in DATA_B3_CONF/_RESP: */
60#define CAPIMSG_SETHANDLE_CONF(m, handle) capimsg_setu16(m, 12, handle)
61#define CAPIMSG_SETINFO_CONF(m, info) capimsg_setu16(m, 14, info)
62
63/* Flags (DATA_B3_REQ/_IND) */
64#define CAPI_FLAGS_DELIVERY_CONFIRMATION 0x04
65#define CAPI_FLAGS_RESERVED (~0x1f)
66
67/* buffer sizes */
68#define MAX_BC_OCTETS 11
69#define MAX_HLC_OCTETS 3
70#define MAX_NUMBER_DIGITS 20
71#define MAX_FMT_IE_LEN 20
72
73/* values for gigaset_capi_appl.connected */
74#define APCONN_NONE 0 /* inactive/listening */
75#define APCONN_SETUP 1 /* connecting */
76#define APCONN_ACTIVE 2 /* B channel up */
77
78/* registered application data structure */
79struct gigaset_capi_appl {
80 struct list_head ctrlist;
81 struct gigaset_capi_appl *bcnext;
82 u16 id;
83 u16 nextMessageNumber;
84 u32 listenInfoMask;
85 u32 listenCIPmask;
86 int connected;
87};
88
89/* CAPI specific controller data structure */
90struct gigaset_capi_ctr {
91 struct capi_ctr ctr;
92 struct list_head appls;
93 struct sk_buff_head sendqueue;
94 atomic_t sendqlen;
95 /* two _cmsg structures possibly used concurrently: */
96 _cmsg hcmsg; /* for message composition triggered from hardware */
97 _cmsg acmsg; /* for dissection of messages sent from application */
98 u8 bc_buf[MAX_BC_OCTETS+1];
99 u8 hlc_buf[MAX_HLC_OCTETS+1];
100 u8 cgpty_buf[MAX_NUMBER_DIGITS+3];
101 u8 cdpty_buf[MAX_NUMBER_DIGITS+2];
102};
103
104/* CIP Value table (from CAPI 2.0 standard, ch. 6.1) */
105static struct {
106 u8 *bc;
107 u8 *hlc;
108} cip2bchlc[] = {
109 [1] = { "8090A3", NULL },
110 /* Speech (A-law) */
111 [2] = { "8890", NULL },
112 /* Unrestricted digital information */
113 [3] = { "8990", NULL },
114 /* Restricted digital information */
115 [4] = { "9090A3", NULL },
116 /* 3,1 kHz audio (A-law) */
117 [5] = { "9190", NULL },
118 /* 7 kHz audio */
119 [6] = { "9890", NULL },
120 /* Video */
121 [7] = { "88C0C6E6", NULL },
122 /* Packet mode */
123 [8] = { "8890218F", NULL },
124 /* 56 kbit/s rate adaptation */
125 [9] = { "9190A5", NULL },
126 /* Unrestricted digital information with tones/announcements */
127 [16] = { "8090A3", "9181" },
128 /* Telephony */
129 [17] = { "9090A3", "9184" },
130 /* Group 2/3 facsimile */
131 [18] = { "8890", "91A1" },
132 /* Group 4 facsimile Class 1 */
133 [19] = { "8890", "91A4" },
134 /* Teletex service basic and mixed mode
135 and Group 4 facsimile service Classes II and III */
136 [20] = { "8890", "91A8" },
137 /* Teletex service basic and processable mode */
138 [21] = { "8890", "91B1" },
139 /* Teletex service basic mode */
140 [22] = { "8890", "91B2" },
141 /* International interworking for Videotex */
142 [23] = { "8890", "91B5" },
143 /* Telex */
144 [24] = { "8890", "91B8" },
145 /* Message Handling Systems in accordance with X.400 */
146 [25] = { "8890", "91C1" },
147 /* OSI application in accordance with X.200 */
148 [26] = { "9190A5", "9181" },
149 /* 7 kHz telephony */
150 [27] = { "9190A5", "916001" },
151 /* Video telephony, first connection */
152 [28] = { "8890", "916002" },
153 /* Video telephony, second connection */
154};
155
156/*
157 * helper functions
158 * ================
159 */
160
161/*
162 * emit unsupported parameter warning
163 */
164static inline void ignore_cstruct_param(struct cardstate *cs, _cstruct param,
165 char *msgname, char *paramname)
166{
167 if (param && *param)
168 dev_warn(cs->dev, "%s: ignoring unsupported parameter: %s\n",
169 msgname, paramname);
170}
171
172/*
173 * convert hex to binary
174 */
175static inline u8 hex2bin(char c)
176{
177 int result = c & 0x0f;
178 if (c & 0x40)
179 result += 9;
180 return result;
181}
182
183/*
184 * convert an IE from Gigaset hex string to ETSI binary representation
185 * including length byte
186 * return value: result length, -1 on error
187 */
188static int encode_ie(char *in, u8 *out, int maxlen)
189{
190 int l = 0;
191 while (*in) {
192 if (!isxdigit(in[0]) || !isxdigit(in[1]) || l >= maxlen)
193 return -1;
194 out[++l] = (hex2bin(in[0]) << 4) + hex2bin(in[1]);
195 in += 2;
196 }
197 out[0] = l;
198 return l;
199}
200
201/*
202 * convert an IE from ETSI binary representation including length byte
203 * to Gigaset hex string
204 */
205static void decode_ie(u8 *in, char *out)
206{
207 int i = *in;
208 while (i-- > 0) {
209 /* ToDo: conversion to upper case necessary? */
210 *out++ = toupper(hex_asc_hi(*++in));
211 *out++ = toupper(hex_asc_lo(*in));
212 }
213}
214
215/*
216 * retrieve application data structure for an application ID
217 */
218static inline struct gigaset_capi_appl *
219get_appl(struct gigaset_capi_ctr *iif, u16 appl)
220{
221 struct gigaset_capi_appl *ap;
222
223 list_for_each_entry(ap, &iif->appls, ctrlist)
224 if (ap->id == appl)
225 return ap;
226 return NULL;
227}
228
229/*
230 * dump CAPI message to kernel messages for debugging
231 */
232static inline void dump_cmsg(enum debuglevel level, const char *tag, _cmsg *p)
233{
234#ifdef CONFIG_GIGASET_DEBUG
235 _cdebbuf *cdb;
236
237 if (!(gigaset_debuglevel & level))
238 return;
239
240 cdb = capi_cmsg2str(p);
241 if (cdb) {
242 gig_dbg(level, "%s: [%d] %s", tag, p->ApplId, cdb->buf);
243 cdebbuf_free(cdb);
244 } else {
245 gig_dbg(level, "%s: [%d] %s", tag, p->ApplId,
246 capi_cmd2str(p->Command, p->Subcommand));
247 }
248#endif
249}
250
251static inline void dump_rawmsg(enum debuglevel level, const char *tag,
252 unsigned char *data)
253{
254#ifdef CONFIG_GIGASET_DEBUG
255 char *dbgline;
256 int i, l;
257
258 if (!(gigaset_debuglevel & level))
259 return;
260
261 l = CAPIMSG_LEN(data);
262 if (l < 12) {
263 gig_dbg(level, "%s: ??? LEN=%04d", tag, l);
264 return;
265 }
266 gig_dbg(level, "%s: 0x%02x:0x%02x: ID=%03d #0x%04x LEN=%04d NCCI=0x%x",
267 tag, CAPIMSG_COMMAND(data), CAPIMSG_SUBCOMMAND(data),
268 CAPIMSG_APPID(data), CAPIMSG_MSGID(data), l,
269 CAPIMSG_CONTROL(data));
270 l -= 12;
271 dbgline = kmalloc(3*l, GFP_ATOMIC);
272 if (!dbgline)
273 return;
274 for (i = 0; i < l; i++) {
275 dbgline[3*i] = hex_asc_hi(data[12+i]);
276 dbgline[3*i+1] = hex_asc_lo(data[12+i]);
277 dbgline[3*i+2] = ' ';
278 }
279 dbgline[3*l-1] = '\0';
280 gig_dbg(level, " %s", dbgline);
281 kfree(dbgline);
282 if (CAPIMSG_COMMAND(data) == CAPI_DATA_B3 &&
283 (CAPIMSG_SUBCOMMAND(data) == CAPI_REQ ||
284 CAPIMSG_SUBCOMMAND(data) == CAPI_IND) &&
285 CAPIMSG_DATALEN(data) > 0) {
286 l = CAPIMSG_DATALEN(data);
287 dbgline = kmalloc(3*l, GFP_ATOMIC);
288 if (!dbgline)
289 return;
290 data += CAPIMSG_LEN(data);
291 for (i = 0; i < l; i++) {
292 dbgline[3*i] = hex_asc_hi(data[i]);
293 dbgline[3*i+1] = hex_asc_lo(data[i]);
294 dbgline[3*i+2] = ' ';
295 }
296 dbgline[3*l-1] = '\0';
297 gig_dbg(level, " %s", dbgline);
298 kfree(dbgline);
299 }
300#endif
301}
302
303/*
304 * format CAPI IE as string
305 */
306
307static const char *format_ie(const char *ie)
308{
309 static char result[3*MAX_FMT_IE_LEN];
310 int len, count;
311 char *pout = result;
312
313 if (!ie)
314 return "NULL";
315
316 count = len = ie[0];
317 if (count > MAX_FMT_IE_LEN)
318 count = MAX_FMT_IE_LEN-1;
319 while (count--) {
320 *pout++ = hex_asc_hi(*++ie);
321 *pout++ = hex_asc_lo(*ie);
322 *pout++ = ' ';
323 }
324 if (len > MAX_FMT_IE_LEN) {
325 *pout++ = '.';
326 *pout++ = '.';
327 *pout++ = '.';
328 }
329 *--pout = 0;
330 return result;
331}
332
333
334/*
335 * driver interface functions
336 * ==========================
337 */
338
339/**
340 * gigaset_skb_sent() - acknowledge transmission of outgoing skb
341 * @bcs: B channel descriptor structure.
342 * @skb: sent data.
343 *
344 * Called by hardware module {bas,ser,usb}_gigaset when the data in a
345 * skb has been successfully sent, for signalling completion to the LL.
346 */
347void gigaset_skb_sent(struct bc_state *bcs, struct sk_buff *dskb)
348{
349 struct cardstate *cs = bcs->cs;
350 struct gigaset_capi_ctr *iif = cs->iif;
351 struct gigaset_capi_appl *ap = bcs->ap;
352 unsigned char *req = skb_mac_header(dskb);
353 struct sk_buff *cskb;
354 u16 flags;
355
356 /* update statistics */
357 ++bcs->trans_up;
358
359 if (!ap) {
360 dev_err(cs->dev, "%s: no application\n", __func__);
361 return;
362 }
363
364 /* don't send further B3 messages if disconnected */
365 if (ap->connected < APCONN_ACTIVE) {
366 gig_dbg(DEBUG_LLDATA, "disconnected, discarding ack");
367 return;
368 }
369
370 /* ToDo: honor unset "delivery confirmation" bit */
371 flags = CAPIMSG_FLAGS(req);
372
373 /* build DATA_B3_CONF message */
374 cskb = alloc_skb(CAPI_DATA_B3_CONF_LEN, GFP_ATOMIC);
375 if (!cskb) {
376 dev_err(cs->dev, "%s: out of memory\n", __func__);
377 return;
378 }
379 /* frequent message, avoid _cmsg overhead */
380 CAPIMSG_SETLEN(cskb->data, CAPI_DATA_B3_CONF_LEN);
381 CAPIMSG_SETAPPID(cskb->data, ap->id);
382 CAPIMSG_SETCOMMAND(cskb->data, CAPI_DATA_B3);
383 CAPIMSG_SETSUBCOMMAND(cskb->data, CAPI_CONF);
384 CAPIMSG_SETMSGID(cskb->data, CAPIMSG_MSGID(req));
385 CAPIMSG_SETCONTROLLER(cskb->data, iif->ctr.cnr);
386 CAPIMSG_SETPLCI_PART(cskb->data, bcs->channel + 1);
387 CAPIMSG_SETNCCI_PART(cskb->data, 1);
388 CAPIMSG_SETHANDLE_CONF(cskb->data, CAPIMSG_HANDLE_REQ(req));
389 if (flags & ~CAPI_FLAGS_DELIVERY_CONFIRMATION)
390 CAPIMSG_SETINFO_CONF(cskb->data,
391 CapiFlagsNotSupportedByProtocol);
392 else
393 CAPIMSG_SETINFO_CONF(cskb->data, CAPI_NOERROR);
394
395 /* emit message */
396 dump_rawmsg(DEBUG_LLDATA, "DATA_B3_CONF", cskb->data);
397 capi_ctr_handle_message(&iif->ctr, ap->id, cskb);
398}
399EXPORT_SYMBOL_GPL(gigaset_skb_sent);
400
401/**
402 * gigaset_skb_rcvd() - pass received skb to LL
403 * @bcs: B channel descriptor structure.
404 * @skb: received data.
405 *
406 * Called by hardware module {bas,ser,usb}_gigaset when user data has
407 * been successfully received, for passing to the LL.
408 * Warning: skb must not be accessed anymore!
409 */
410void gigaset_skb_rcvd(struct bc_state *bcs, struct sk_buff *skb)
411{
412 struct cardstate *cs = bcs->cs;
413 struct gigaset_capi_ctr *iif = cs->iif;
414 struct gigaset_capi_appl *ap = bcs->ap;
415 int len = skb->len;
416
417 /* update statistics */
418 bcs->trans_down++;
419
420 if (!ap) {
421 dev_err(cs->dev, "%s: no application\n", __func__);
422 return;
423 }
424
425 /* don't send further B3 messages if disconnected */
426 if (ap->connected < APCONN_ACTIVE) {
427 gig_dbg(DEBUG_LLDATA, "disconnected, discarding data");
428 dev_kfree_skb_any(skb);
429 return;
430 }
431
432 /*
433 * prepend DATA_B3_IND message to payload
434 * Parameters: NCCI = 1, all others 0/unused
435 * frequent message, avoid _cmsg overhead
436 */
437 skb_push(skb, CAPI_DATA_B3_REQ_LEN);
438 CAPIMSG_SETLEN(skb->data, CAPI_DATA_B3_REQ_LEN);
439 CAPIMSG_SETAPPID(skb->data, ap->id);
440 CAPIMSG_SETCOMMAND(skb->data, CAPI_DATA_B3);
441 CAPIMSG_SETSUBCOMMAND(skb->data, CAPI_IND);
442 CAPIMSG_SETMSGID(skb->data, ap->nextMessageNumber++);
443 CAPIMSG_SETCONTROLLER(skb->data, iif->ctr.cnr);
444 CAPIMSG_SETPLCI_PART(skb->data, bcs->channel + 1);
445 CAPIMSG_SETNCCI_PART(skb->data, 1);
446 /* Data parameter not used */
447 CAPIMSG_SETDATALEN(skb->data, len);
448 /* Data handle parameter not used */
449 CAPIMSG_SETFLAGS(skb->data, 0);
450 /* Data64 parameter not present */
451
452 /* emit message */
453 dump_rawmsg(DEBUG_LLDATA, "DATA_B3_IND", skb->data);
454 capi_ctr_handle_message(&iif->ctr, ap->id, skb);
455}
456EXPORT_SYMBOL_GPL(gigaset_skb_rcvd);
457
458/**
459 * gigaset_isdn_rcv_err() - signal receive error
460 * @bcs: B channel descriptor structure.
461 *
462 * Called by hardware module {bas,ser,usb}_gigaset when a receive error
463 * has occurred, for signalling to the LL.
464 */
465void gigaset_isdn_rcv_err(struct bc_state *bcs)
466{
467 /* if currently ignoring packets, just count down */
468 if (bcs->ignore) {
469 bcs->ignore--;
470 return;
471 }
472
473 /* update statistics */
474 bcs->corrupted++;
475
476 /* ToDo: signal error -> LL */
477}
478EXPORT_SYMBOL_GPL(gigaset_isdn_rcv_err);
479
480/**
481 * gigaset_isdn_icall() - signal incoming call
482 * @at_state: connection state structure.
483 *
484 * Called by main module at tasklet level to notify the LL that an incoming
485 * call has been received. @at_state contains the parameters of the call.
486 *
487 * Return value: call disposition (ICALL_*)
488 */
489int gigaset_isdn_icall(struct at_state_t *at_state)
490{
491 struct cardstate *cs = at_state->cs;
492 struct bc_state *bcs = at_state->bcs;
493 struct gigaset_capi_ctr *iif = cs->iif;
494 struct gigaset_capi_appl *ap;
495 u32 actCIPmask;
496 struct sk_buff *skb;
497 unsigned int msgsize;
498 int i;
499
500 /*
501 * ToDo: signal calls without a free B channel, too
502 * (requires a u8 handle for the at_state structure that can
503 * be stored in the PLCI and used in the CONNECT_RESP message
504 * handler to retrieve it)
505 */
506 if (!bcs)
507 return ICALL_IGNORE;
508
509 /* prepare CONNECT_IND message, using B channel number as PLCI */
510 capi_cmsg_header(&iif->hcmsg, 0, CAPI_CONNECT, CAPI_IND, 0,
511 iif->ctr.cnr | ((bcs->channel + 1) << 8));
512
513 /* minimum size, all structs empty */
514 msgsize = CAPI_CONNECT_IND_BASELEN;
515
516 /* Bearer Capability (mandatory) */
517 if (at_state->str_var[STR_ZBC]) {
518 /* pass on BC from Gigaset */
519 if (encode_ie(at_state->str_var[STR_ZBC], iif->bc_buf,
520 MAX_BC_OCTETS) < 0) {
521 dev_warn(cs->dev, "RING ignored - bad BC %s\n",
522 at_state->str_var[STR_ZBC]);
523 return ICALL_IGNORE;
524 }
525
526 /* look up corresponding CIP value */
527 iif->hcmsg.CIPValue = 0; /* default if nothing found */
528 for (i = 0; i < ARRAY_SIZE(cip2bchlc); i++)
529 if (cip2bchlc[i].bc != NULL &&
530 cip2bchlc[i].hlc == NULL &&
531 !strcmp(cip2bchlc[i].bc,
532 at_state->str_var[STR_ZBC])) {
533 iif->hcmsg.CIPValue = i;
534 break;
535 }
536 } else {
537 /* no BC (internal call): assume CIP 1 (speech, A-law) */
538 iif->hcmsg.CIPValue = 1;
539 encode_ie(cip2bchlc[1].bc, iif->bc_buf, MAX_BC_OCTETS);
540 }
541 iif->hcmsg.BC = iif->bc_buf;
542 msgsize += iif->hcmsg.BC[0];
543
544 /* High Layer Compatibility (optional) */
545 if (at_state->str_var[STR_ZHLC]) {
546 /* pass on HLC from Gigaset */
547 if (encode_ie(at_state->str_var[STR_ZHLC], iif->hlc_buf,
548 MAX_HLC_OCTETS) < 0) {
549 dev_warn(cs->dev, "RING ignored - bad HLC %s\n",
550 at_state->str_var[STR_ZHLC]);
551 return ICALL_IGNORE;
552 }
553 iif->hcmsg.HLC = iif->hlc_buf;
554 msgsize += iif->hcmsg.HLC[0];
555
556 /* look up corresponding CIP value */
557 /* keep BC based CIP value if none found */
558 if (at_state->str_var[STR_ZBC])
559 for (i = 0; i < ARRAY_SIZE(cip2bchlc); i++)
560 if (cip2bchlc[i].hlc != NULL &&
561 !strcmp(cip2bchlc[i].hlc,
562 at_state->str_var[STR_ZHLC]) &&
563 !strcmp(cip2bchlc[i].bc,
564 at_state->str_var[STR_ZBC])) {
565 iif->hcmsg.CIPValue = i;
566 break;
567 }
568 }
569
570 /* Called Party Number (optional) */
571 if (at_state->str_var[STR_ZCPN]) {
572 i = strlen(at_state->str_var[STR_ZCPN]);
573 if (i > MAX_NUMBER_DIGITS) {
574 dev_warn(cs->dev, "RING ignored - bad number %s\n",
575 at_state->str_var[STR_ZBC]);
576 return ICALL_IGNORE;
577 }
578 iif->cdpty_buf[0] = i + 1;
579 iif->cdpty_buf[1] = 0x80; /* type / numbering plan unknown */
580 memcpy(iif->cdpty_buf+2, at_state->str_var[STR_ZCPN], i);
581 iif->hcmsg.CalledPartyNumber = iif->cdpty_buf;
582 msgsize += iif->hcmsg.CalledPartyNumber[0];
583 }
584
585 /* Calling Party Number (optional) */
586 if (at_state->str_var[STR_NMBR]) {
587 i = strlen(at_state->str_var[STR_NMBR]);
588 if (i > MAX_NUMBER_DIGITS) {
589 dev_warn(cs->dev, "RING ignored - bad number %s\n",
590 at_state->str_var[STR_ZBC]);
591 return ICALL_IGNORE;
592 }
593 iif->cgpty_buf[0] = i + 2;
594 iif->cgpty_buf[1] = 0x00; /* type / numbering plan unknown */
595 iif->cgpty_buf[2] = 0x80; /* pres. allowed, not screened */
596 memcpy(iif->cgpty_buf+3, at_state->str_var[STR_NMBR], i);
597 iif->hcmsg.CallingPartyNumber = iif->cgpty_buf;
598 msgsize += iif->hcmsg.CallingPartyNumber[0];
599 }
600
601 /* remaining parameters (not supported, always left NULL):
602 * - CalledPartySubaddress
603 * - CallingPartySubaddress
604 * - AdditionalInfo
605 * - BChannelinformation
606 * - Keypadfacility
607 * - Useruserdata
608 * - Facilitydataarray
609 */
610
611 gig_dbg(DEBUG_CMD, "icall: PLCI %x CIP %d BC %s",
612 iif->hcmsg.adr.adrPLCI, iif->hcmsg.CIPValue,
613 format_ie(iif->hcmsg.BC));
614 gig_dbg(DEBUG_CMD, "icall: HLC %s",
615 format_ie(iif->hcmsg.HLC));
616 gig_dbg(DEBUG_CMD, "icall: CgPty %s",
617 format_ie(iif->hcmsg.CallingPartyNumber));
618 gig_dbg(DEBUG_CMD, "icall: CdPty %s",
619 format_ie(iif->hcmsg.CalledPartyNumber));
620
621 /* scan application list for matching listeners */
622 bcs->ap = NULL;
623 actCIPmask = 1 | (1 << iif->hcmsg.CIPValue);
624 list_for_each_entry(ap, &iif->appls, ctrlist)
625 if (actCIPmask & ap->listenCIPmask) {
626 /* build CONNECT_IND message for this application */
627 iif->hcmsg.ApplId = ap->id;
628 iif->hcmsg.Messagenumber = ap->nextMessageNumber++;
629
630 skb = alloc_skb(msgsize, GFP_ATOMIC);
631 if (!skb) {
632 dev_err(cs->dev, "%s: out of memory\n",
633 __func__);
634 break;
635 }
636 capi_cmsg2message(&iif->hcmsg, __skb_put(skb, msgsize));
637 dump_cmsg(DEBUG_CMD, __func__, &iif->hcmsg);
638
639 /* add to listeners on this B channel, update state */
640 ap->bcnext = bcs->ap;
641 bcs->ap = ap;
642 bcs->chstate |= CHS_NOTIFY_LL;
643 ap->connected = APCONN_SETUP;
644
645 /* emit message */
646 capi_ctr_handle_message(&iif->ctr, ap->id, skb);
647 }
648
649 /*
650 * Return "accept" if any listeners.
651 * Gigaset will send ALERTING.
652 * There doesn't seem to be a way to avoid this.
653 */
654 return bcs->ap ? ICALL_ACCEPT : ICALL_IGNORE;
655}
656
657/*
658 * send a DISCONNECT_IND message to an application
659 * does not sleep, clobbers the controller's hcmsg structure
660 */
661static void send_disconnect_ind(struct bc_state *bcs,
662 struct gigaset_capi_appl *ap, u16 reason)
663{
664 struct cardstate *cs = bcs->cs;
665 struct gigaset_capi_ctr *iif = cs->iif;
666 struct sk_buff *skb;
667
668 if (ap->connected == APCONN_NONE)
669 return;
670
671 capi_cmsg_header(&iif->hcmsg, ap->id, CAPI_DISCONNECT, CAPI_IND,
672 ap->nextMessageNumber++,
673 iif->ctr.cnr | ((bcs->channel + 1) << 8));
674 iif->hcmsg.Reason = reason;
675 skb = alloc_skb(CAPI_DISCONNECT_IND_LEN, GFP_ATOMIC);
676 if (!skb) {
677 dev_err(cs->dev, "%s: out of memory\n", __func__);
678 return;
679 }
680 capi_cmsg2message(&iif->hcmsg, __skb_put(skb, CAPI_DISCONNECT_IND_LEN));
681 dump_cmsg(DEBUG_CMD, __func__, &iif->hcmsg);
682 ap->connected = APCONN_NONE;
683 capi_ctr_handle_message(&iif->ctr, ap->id, skb);
684}
685
686/*
687 * send a DISCONNECT_B3_IND message to an application
688 * Parameters: NCCI = 1, NCPI empty, Reason_B3 = 0
689 * does not sleep, clobbers the controller's hcmsg structure
690 */
691static void send_disconnect_b3_ind(struct bc_state *bcs,
692 struct gigaset_capi_appl *ap)
693{
694 struct cardstate *cs = bcs->cs;
695 struct gigaset_capi_ctr *iif = cs->iif;
696 struct sk_buff *skb;
697
698 /* nothing to do if no logical connection active */
699 if (ap->connected < APCONN_ACTIVE)
700 return;
701 ap->connected = APCONN_SETUP;
702
703 capi_cmsg_header(&iif->hcmsg, ap->id, CAPI_DISCONNECT_B3, CAPI_IND,
704 ap->nextMessageNumber++,
705 iif->ctr.cnr | ((bcs->channel + 1) << 8) | (1 << 16));
706 skb = alloc_skb(CAPI_DISCONNECT_B3_IND_BASELEN, GFP_ATOMIC);
707 if (!skb) {
708 dev_err(cs->dev, "%s: out of memory\n", __func__);
709 return;
710 }
711 capi_cmsg2message(&iif->hcmsg,
712 __skb_put(skb, CAPI_DISCONNECT_B3_IND_BASELEN));
713 dump_cmsg(DEBUG_CMD, __func__, &iif->hcmsg);
714 capi_ctr_handle_message(&iif->ctr, ap->id, skb);
715}
716
717/**
718 * gigaset_isdn_connD() - signal D channel connect
719 * @bcs: B channel descriptor structure.
720 *
721 * Called by main module at tasklet level to notify the LL that the D channel
722 * connection has been established.
723 */
724void gigaset_isdn_connD(struct bc_state *bcs)
725{
726 struct cardstate *cs = bcs->cs;
727 struct gigaset_capi_ctr *iif = cs->iif;
728 struct gigaset_capi_appl *ap = bcs->ap;
729 struct sk_buff *skb;
730 unsigned int msgsize;
731
732 if (!ap) {
733 dev_err(cs->dev, "%s: no application\n", __func__);
734 return;
735 }
736 while (ap->bcnext) {
737 /* this should never happen */
738 dev_warn(cs->dev, "%s: dropping extra application %u\n",
739 __func__, ap->bcnext->id);
740 send_disconnect_ind(bcs, ap->bcnext,
741 CapiCallGivenToOtherApplication);
742 ap->bcnext = ap->bcnext->bcnext;
743 }
744 if (ap->connected == APCONN_NONE) {
745 dev_warn(cs->dev, "%s: application %u not connected\n",
746 __func__, ap->id);
747 return;
748 }
749
750 /* prepare CONNECT_ACTIVE_IND message
751 * Note: LLC not supported by device
752 */
753 capi_cmsg_header(&iif->hcmsg, ap->id, CAPI_CONNECT_ACTIVE, CAPI_IND,
754 ap->nextMessageNumber++,
755 iif->ctr.cnr | ((bcs->channel + 1) << 8));
756
757 /* minimum size, all structs empty */
758 msgsize = CAPI_CONNECT_ACTIVE_IND_BASELEN;
759
760 /* ToDo: set parameter: Connected number
761 * (requires ev-layer state machine extension to collect
762 * ZCON device reply)
763 */
764
765 /* build and emit CONNECT_ACTIVE_IND message */
766 skb = alloc_skb(msgsize, GFP_ATOMIC);
767 if (!skb) {
768 dev_err(cs->dev, "%s: out of memory\n", __func__);
769 return;
770 }
771 capi_cmsg2message(&iif->hcmsg, __skb_put(skb, msgsize));
772 dump_cmsg(DEBUG_CMD, __func__, &iif->hcmsg);
773 capi_ctr_handle_message(&iif->ctr, ap->id, skb);
774}
775
776/**
777 * gigaset_isdn_hupD() - signal D channel hangup
778 * @bcs: B channel descriptor structure.
779 *
780 * Called by main module at tasklet level to notify the LL that the D channel
781 * connection has been shut down.
782 */
783void gigaset_isdn_hupD(struct bc_state *bcs)
784{
785 struct gigaset_capi_appl *ap;
786
787 /*
788 * ToDo: pass on reason code reported by device
789 * (requires ev-layer state machine extension to collect
790 * ZCAU device reply)
791 */
792 for (ap = bcs->ap; ap != NULL; ap = ap->bcnext) {
793 send_disconnect_b3_ind(bcs, ap);
794 send_disconnect_ind(bcs, ap, 0);
795 }
796 bcs->ap = NULL;
797}
798
799/**
800 * gigaset_isdn_connB() - signal B channel connect
801 * @bcs: B channel descriptor structure.
802 *
803 * Called by main module at tasklet level to notify the LL that the B channel
804 * connection has been established.
805 */
806void gigaset_isdn_connB(struct bc_state *bcs)
807{
808 struct cardstate *cs = bcs->cs;
809 struct gigaset_capi_ctr *iif = cs->iif;
810 struct gigaset_capi_appl *ap = bcs->ap;
811 struct sk_buff *skb;
812 unsigned int msgsize;
813 u8 command;
814
815 if (!ap) {
816 dev_err(cs->dev, "%s: no application\n", __func__);
817 return;
818 }
819 while (ap->bcnext) {
820 /* this should never happen */
821 dev_warn(cs->dev, "%s: dropping extra application %u\n",
822 __func__, ap->bcnext->id);
823 send_disconnect_ind(bcs, ap->bcnext,
824 CapiCallGivenToOtherApplication);
825 ap->bcnext = ap->bcnext->bcnext;
826 }
827 if (!ap->connected) {
828 dev_warn(cs->dev, "%s: application %u not connected\n",
829 __func__, ap->id);
830 return;
831 }
832
833 /*
834 * emit CONNECT_B3_ACTIVE_IND if we already got CONNECT_B3_REQ;
835 * otherwise we have to emit CONNECT_B3_IND first, and follow up with
836 * CONNECT_B3_ACTIVE_IND in reply to CONNECT_B3_RESP
837 * Parameters in both cases always: NCCI = 1, NCPI empty
838 */
839 if (ap->connected >= APCONN_ACTIVE) {
840 command = CAPI_CONNECT_B3_ACTIVE;
841 msgsize = CAPI_CONNECT_B3_ACTIVE_IND_BASELEN;
842 } else {
843 command = CAPI_CONNECT_B3;
844 msgsize = CAPI_CONNECT_B3_IND_BASELEN;
845 }
846 capi_cmsg_header(&iif->hcmsg, ap->id, command, CAPI_IND,
847 ap->nextMessageNumber++,
848 iif->ctr.cnr | ((bcs->channel + 1) << 8) | (1 << 16));
849 skb = alloc_skb(msgsize, GFP_ATOMIC);
850 if (!skb) {
851 dev_err(cs->dev, "%s: out of memory\n", __func__);
852 return;
853 }
854 capi_cmsg2message(&iif->hcmsg, __skb_put(skb, msgsize));
855 dump_cmsg(DEBUG_CMD, __func__, &iif->hcmsg);
856 ap->connected = APCONN_ACTIVE;
857 capi_ctr_handle_message(&iif->ctr, ap->id, skb);
858}
859
860/**
861 * gigaset_isdn_hupB() - signal B channel hangup
862 * @bcs: B channel descriptor structure.
863 *
864 * Called by main module to notify the LL that the B channel connection has
865 * been shut down.
866 */
867void gigaset_isdn_hupB(struct bc_state *bcs)
868{
869 struct cardstate *cs = bcs->cs;
870 struct gigaset_capi_appl *ap = bcs->ap;
871
872 /* ToDo: assure order of DISCONNECT_B3_IND and DISCONNECT_IND ? */
873
874 if (!ap) {
875 dev_err(cs->dev, "%s: no application\n", __func__);
876 return;
877 }
878
879 send_disconnect_b3_ind(bcs, ap);
880}
881
882/**
883 * gigaset_isdn_start() - signal device availability
884 * @cs: device descriptor structure.
885 *
886 * Called by main module to notify the LL that the device is available for
887 * use.
888 */
889void gigaset_isdn_start(struct cardstate *cs)
890{
891 struct gigaset_capi_ctr *iif = cs->iif;
892
893 /* fill profile data: manufacturer name */
894 strcpy(iif->ctr.manu, "Siemens");
895 /* CAPI and device version */
896 iif->ctr.version.majorversion = 2; /* CAPI 2.0 */
897 iif->ctr.version.minorversion = 0;
898 /* ToDo: check/assert cs->gotfwver? */
899 iif->ctr.version.majormanuversion = cs->fwver[0];
900 iif->ctr.version.minormanuversion = cs->fwver[1];
901 /* number of B channels supported */
902 iif->ctr.profile.nbchannel = cs->channels;
903 /* global options: internal controller, supplementary services */
904 iif->ctr.profile.goptions = 0x11;
905 /* B1 protocols: 64 kbit/s HDLC or transparent */
906 iif->ctr.profile.support1 = 0x03;
907 /* B2 protocols: transparent only */
908 /* ToDo: X.75 SLP ? */
909 iif->ctr.profile.support2 = 0x02;
910 /* B3 protocols: transparent only */
911 iif->ctr.profile.support3 = 0x01;
912 /* no serial number */
913 strcpy(iif->ctr.serial, "0");
914 capi_ctr_ready(&iif->ctr);
915}
916
917/**
918 * gigaset_isdn_stop() - signal device unavailability
919 * @cs: device descriptor structure.
920 *
921 * Called by main module to notify the LL that the device is no longer
922 * available for use.
923 */
924void gigaset_isdn_stop(struct cardstate *cs)
925{
926 struct gigaset_capi_ctr *iif = cs->iif;
927 capi_ctr_down(&iif->ctr);
928}
929
930/*
931 * kernel CAPI callback methods
932 * ============================
933 */
934
935/*
936 * load firmware
937 */
938static int gigaset_load_firmware(struct capi_ctr *ctr, capiloaddata *data)
939{
940 struct cardstate *cs = ctr->driverdata;
941
942 /* AVM specific operation, not needed for Gigaset -- ignore */
943 dev_notice(cs->dev, "load_firmware ignored\n");
944
945 return 0;
946}
947
948/*
949 * reset (deactivate) controller
950 */
951static void gigaset_reset_ctr(struct capi_ctr *ctr)
952{
953 struct cardstate *cs = ctr->driverdata;
954
955 /* AVM specific operation, not needed for Gigaset -- ignore */
956 dev_notice(cs->dev, "reset_ctr ignored\n");
957}
958
959/*
960 * register CAPI application
961 */
962static void gigaset_register_appl(struct capi_ctr *ctr, u16 appl,
963 capi_register_params *rp)
964{
965 struct gigaset_capi_ctr *iif
966 = container_of(ctr, struct gigaset_capi_ctr, ctr);
967 struct cardstate *cs = ctr->driverdata;
968 struct gigaset_capi_appl *ap;
969
970 list_for_each_entry(ap, &iif->appls, ctrlist)
971 if (ap->id == appl) {
972 dev_notice(cs->dev,
973 "application %u already registered\n", appl);
974 return;
975 }
976
977 ap = kzalloc(sizeof(*ap), GFP_KERNEL);
978 if (!ap) {
979 dev_err(cs->dev, "%s: out of memory\n", __func__);
980 return;
981 }
982 ap->id = appl;
983
984 list_add(&ap->ctrlist, &iif->appls);
985}
986
987/*
988 * release CAPI application
989 */
990static void gigaset_release_appl(struct capi_ctr *ctr, u16 appl)
991{
992 struct gigaset_capi_ctr *iif
993 = container_of(ctr, struct gigaset_capi_ctr, ctr);
994 struct cardstate *cs = iif->ctr.driverdata;
995 struct gigaset_capi_appl *ap, *tmp;
996
997 list_for_each_entry_safe(ap, tmp, &iif->appls, ctrlist)
998 if (ap->id == appl) {
999 if (ap->connected != APCONN_NONE) {
1000 dev_err(cs->dev,
1001 "%s: application %u still connected\n",
1002 __func__, ap->id);
1003 /* ToDo: clear active connection */
1004 }
1005 list_del(&ap->ctrlist);
1006 kfree(ap);
1007 }
1008
1009}
1010
1011/*
1012 * =====================================================================
1013 * outgoing CAPI message handler
1014 * =====================================================================
1015 */
1016
1017/*
1018 * helper function: emit reply message with given Info value
1019 */
1020static void send_conf(struct gigaset_capi_ctr *iif,
1021 struct gigaset_capi_appl *ap,
1022 struct sk_buff *skb,
1023 u16 info)
1024{
1025 /*
1026 * _CONF replies always only have NCCI and Info parameters
1027 * so they'll fit into the _REQ message skb
1028 */
1029 capi_cmsg_answer(&iif->acmsg);
1030 iif->acmsg.Info = info;
1031 capi_cmsg2message(&iif->acmsg, skb->data);
1032 __skb_trim(skb, CAPI_STDCONF_LEN);
1033 dump_cmsg(DEBUG_CMD, __func__, &iif->acmsg);
1034 capi_ctr_handle_message(&iif->ctr, ap->id, skb);
1035}
1036
1037/*
1038 * process FACILITY_REQ message
1039 */
1040static void do_facility_req(struct gigaset_capi_ctr *iif,
1041 struct gigaset_capi_appl *ap,
1042 struct sk_buff *skb)
1043{
1044 struct cardstate *cs = iif->ctr.driverdata;
1045 _cmsg *cmsg = &iif->acmsg;
1046 struct sk_buff *cskb;
1047 u8 *pparam;
1048 unsigned int msgsize = CAPI_FACILITY_CONF_BASELEN;
1049 u16 function, info;
1050 static u8 confparam[10]; /* max. 9 octets + length byte */
1051
1052 /* decode message */
1053 capi_message2cmsg(cmsg, skb->data);
1054 dump_cmsg(DEBUG_CMD, __func__, cmsg);
1055
1056 /*
1057 * Facility Request Parameter is not decoded by capi_message2cmsg()
1058 * encoding depends on Facility Selector
1059 */
1060 switch (cmsg->FacilitySelector) {
1061 case CAPI_FACILITY_DTMF: /* ToDo */
1062 info = CapiFacilityNotSupported;
1063 confparam[0] = 2; /* length */
1064 /* DTMF information: Unknown DTMF request */
1065 capimsg_setu16(confparam, 1, 2);
1066 break;
1067
1068 case CAPI_FACILITY_V42BIS: /* not supported */
1069 info = CapiFacilityNotSupported;
1070 confparam[0] = 2; /* length */
1071 /* V.42 bis information: not available */
1072 capimsg_setu16(confparam, 1, 1);
1073 break;
1074
1075 case CAPI_FACILITY_SUPPSVC:
1076 /* decode Function parameter */
1077 pparam = cmsg->FacilityRequestParameter;
1078 if (pparam == NULL || *pparam < 2) {
1079 dev_notice(cs->dev, "%s: %s missing\n", "FACILITY_REQ",
1080 "Facility Request Parameter");
1081 send_conf(iif, ap, skb, CapiIllMessageParmCoding);
1082 return;
1083 }
1084 function = CAPIMSG_U16(pparam, 1);
1085 switch (function) {
1086 case CAPI_SUPPSVC_GETSUPPORTED:
1087 info = CapiSuccess;
1088 /* Supplementary Service specific parameter */
1089 confparam[3] = 6; /* length */
1090 /* Supplementary services info: Success */
1091 capimsg_setu16(confparam, 4, CapiSuccess);
1092 /* Supported Services: none */
1093 capimsg_setu32(confparam, 6, 0);
1094 break;
1095 /* ToDo: add supported services */
1096 default:
1097 info = CapiFacilitySpecificFunctionNotSupported;
1098 /* Supplementary Service specific parameter */
1099 confparam[3] = 2; /* length */
1100 /* Supplementary services info: not supported */
1101 capimsg_setu16(confparam, 4,
1102 CapiSupplementaryServiceNotSupported);
1103 }
1104
1105 /* Facility confirmation parameter */
1106 confparam[0] = confparam[3] + 3; /* total length */
1107 /* Function: copy from _REQ message */
1108 capimsg_setu16(confparam, 1, function);
1109 /* Supplementary Service specific parameter already set above */
1110 break;
1111
1112 case CAPI_FACILITY_WAKEUP: /* ToDo */
1113 info = CapiFacilityNotSupported;
1114 confparam[0] = 2; /* length */
1115 /* Number of accepted awake request parameters: 0 */
1116 capimsg_setu16(confparam, 1, 0);
1117 break;
1118
1119 default:
1120 info = CapiFacilityNotSupported;
1121 confparam[0] = 0; /* empty struct */
1122 }
1123
1124 /* send FACILITY_CONF with given Info and confirmation parameter */
1125 capi_cmsg_answer(cmsg);
1126 cmsg->Info = info;
1127 cmsg->FacilityConfirmationParameter = confparam;
1128 msgsize += confparam[0]; /* length */
1129 cskb = alloc_skb(msgsize, GFP_ATOMIC);
1130 if (!cskb) {
1131 dev_err(cs->dev, "%s: out of memory\n", __func__);
1132 return;
1133 }
1134 capi_cmsg2message(cmsg, __skb_put(cskb, msgsize));
1135 dump_cmsg(DEBUG_CMD, __func__, cmsg);
1136 capi_ctr_handle_message(&iif->ctr, ap->id, cskb);
1137}
1138
1139
1140/*
1141 * process LISTEN_REQ message
1142 * just store the masks in the application data structure
1143 */
1144static void do_listen_req(struct gigaset_capi_ctr *iif,
1145 struct gigaset_capi_appl *ap,
1146 struct sk_buff *skb)
1147{
1148 /* decode message */
1149 capi_message2cmsg(&iif->acmsg, skb->data);
1150 dump_cmsg(DEBUG_CMD, __func__, &iif->acmsg);
1151
1152 /* store listening parameters */
1153 ap->listenInfoMask = iif->acmsg.InfoMask;
1154 ap->listenCIPmask = iif->acmsg.CIPmask;
1155 send_conf(iif, ap, skb, CapiSuccess);
1156}
1157
1158/*
1159 * process ALERT_REQ message
1160 * nothing to do, Gigaset always alerts anyway
1161 */
1162static void do_alert_req(struct gigaset_capi_ctr *iif,
1163 struct gigaset_capi_appl *ap,
1164 struct sk_buff *skb)
1165{
1166 /* decode message */
1167 capi_message2cmsg(&iif->acmsg, skb->data);
1168 dump_cmsg(DEBUG_CMD, __func__, &iif->acmsg);
1169 send_conf(iif, ap, skb, CapiAlertAlreadySent);
1170}
1171
1172/*
1173 * process CONNECT_REQ message
1174 * allocate a B channel, prepare dial commands, queue a DIAL event,
1175 * emit CONNECT_CONF reply
1176 */
1177static void do_connect_req(struct gigaset_capi_ctr *iif,
1178 struct gigaset_capi_appl *ap,
1179 struct sk_buff *skb)
1180{
1181 struct cardstate *cs = iif->ctr.driverdata;
1182 _cmsg *cmsg = &iif->acmsg;
1183 struct bc_state *bcs;
1184 char **commands;
1185 char *s;
1186 u8 *pp;
1187 int i, l;
1188 u16 info;
1189
1190 /* decode message */
1191 capi_message2cmsg(cmsg, skb->data);
1192 dump_cmsg(DEBUG_CMD, __func__, cmsg);
1193
1194 /* get free B channel & construct PLCI */
1195 bcs = gigaset_get_free_channel(cs);
1196 if (!bcs) {
1197 dev_notice(cs->dev, "%s: no B channel available\n",
1198 "CONNECT_REQ");
1199 send_conf(iif, ap, skb, CapiNoPlciAvailable);
1200 return;
1201 }
1202 ap->bcnext = NULL;
1203 bcs->ap = ap;
1204 cmsg->adr.adrPLCI |= (bcs->channel + 1) << 8;
1205
1206 /* build command table */
1207 commands = kzalloc(AT_NUM*(sizeof *commands), GFP_KERNEL);
1208 if (!commands)
1209 goto oom;
1210
1211 /* encode parameter: Called party number */
1212 pp = cmsg->CalledPartyNumber;
1213 if (pp == NULL || *pp == 0) {
1214 dev_notice(cs->dev, "%s: %s missing\n",
1215 "CONNECT_REQ", "Called party number");
1216 info = CapiIllMessageParmCoding;
1217 goto error;
1218 }
1219 l = *pp++;
1220 /* check type of number/numbering plan byte */
1221 switch (*pp) {
1222 case 0x80: /* unknown type / unknown numbering plan */
1223 case 0x81: /* unknown type / ISDN/Telephony numbering plan */
1224 break;
1225 default: /* others: warn about potential misinterpretation */
1226 dev_notice(cs->dev, "%s: %s type/plan 0x%02x unsupported\n",
1227 "CONNECT_REQ", "Called party number", *pp);
1228 }
1229 pp++;
1230 l--;
1231 /* translate "**" internal call prefix to CTP value */
1232 if (l >= 2 && pp[0] == '*' && pp[1] == '*') {
1233 s = "^SCTP=0\r";
1234 pp += 2;
1235 l -= 2;
1236 } else {
1237 s = "^SCTP=1\r";
1238 }
1239 commands[AT_TYPE] = kstrdup(s, GFP_KERNEL);
1240 if (!commands[AT_TYPE])
1241 goto oom;
1242 commands[AT_DIAL] = kmalloc(l+3, GFP_KERNEL);
1243 if (!commands[AT_DIAL])
1244 goto oom;
1245 snprintf(commands[AT_DIAL], l+3, "D%.*s\r", l, pp);
1246
1247 /* encode parameter: Calling party number */
1248 pp = cmsg->CallingPartyNumber;
1249 if (pp != NULL && *pp > 0) {
1250 l = *pp++;
1251
1252 /* check type of number/numbering plan byte */
1253 /* ToDo: allow for/handle Ext=1? */
1254 switch (*pp) {
1255 case 0x00: /* unknown type / unknown numbering plan */
1256 case 0x01: /* unknown type / ISDN/Telephony num. plan */
1257 break;
1258 default:
1259 dev_notice(cs->dev,
1260 "%s: %s type/plan 0x%02x unsupported\n",
1261 "CONNECT_REQ", "Calling party number", *pp);
1262 }
1263 pp++;
1264 l--;
1265
1266 /* check presentation indicator */
1267 if (!l) {
1268 dev_notice(cs->dev, "%s: %s IE truncated\n",
1269 "CONNECT_REQ", "Calling party number");
1270 info = CapiIllMessageParmCoding;
1271 goto error;
1272 }
1273 switch (*pp & 0xfc) { /* ignore Screening indicator */
1274 case 0x80: /* Presentation allowed */
1275 s = "^SCLIP=1\r";
1276 break;
1277 case 0xa0: /* Presentation restricted */
1278 s = "^SCLIP=0\r";
1279 break;
1280 default:
1281 dev_notice(cs->dev, "%s: invalid %s 0x%02x\n",
1282 "CONNECT_REQ",
1283 "Presentation/Screening indicator",
1284 *pp);
1285 s = "^SCLIP=1\r";
1286 }
1287 commands[AT_CLIP] = kstrdup(s, GFP_KERNEL);
1288 if (!commands[AT_CLIP])
1289 goto oom;
1290 pp++;
1291 l--;
1292
1293 if (l) {
1294 /* number */
1295 commands[AT_MSN] = kmalloc(l+8, GFP_KERNEL);
1296 if (!commands[AT_MSN])
1297 goto oom;
1298 snprintf(commands[AT_MSN], l+8, "^SMSN=%*s\r", l, pp);
1299 }
1300 }
1301
1302 /* check parameter: CIP Value */
1303 if (cmsg->CIPValue >= ARRAY_SIZE(cip2bchlc) ||
1304 (cmsg->CIPValue > 0 && cip2bchlc[cmsg->CIPValue].bc == NULL)) {
1305 dev_notice(cs->dev, "%s: unknown CIP value %d\n",
1306 "CONNECT_REQ", cmsg->CIPValue);
1307 info = CapiCipValueUnknown;
1308 goto error;
1309 }
1310
1311 /* check/encode parameter: BC */
1312 if (cmsg->BC && cmsg->BC[0]) {
1313 /* explicit BC overrides CIP */
1314 l = 2*cmsg->BC[0] + 7;
1315 commands[AT_BC] = kmalloc(l, GFP_KERNEL);
1316 if (!commands[AT_BC])
1317 goto oom;
1318 strcpy(commands[AT_BC], "^SBC=");
1319 decode_ie(cmsg->BC, commands[AT_BC]+5);
1320 strcpy(commands[AT_BC] + l - 2, "\r");
1321 } else if (cip2bchlc[cmsg->CIPValue].bc) {
1322 l = strlen(cip2bchlc[cmsg->CIPValue].bc) + 7;
1323 commands[AT_BC] = kmalloc(l, GFP_KERNEL);
1324 if (!commands[AT_BC])
1325 goto oom;
1326 snprintf(commands[AT_BC], l, "^SBC=%s\r",
1327 cip2bchlc[cmsg->CIPValue].bc);
1328 }
1329
1330 /* check/encode parameter: HLC */
1331 if (cmsg->HLC && cmsg->HLC[0]) {
1332 /* explicit HLC overrides CIP */
1333 l = 2*cmsg->HLC[0] + 7;
1334 commands[AT_HLC] = kmalloc(l, GFP_KERNEL);
1335 if (!commands[AT_HLC])
1336 goto oom;
1337 strcpy(commands[AT_HLC], "^SHLC=");
1338 decode_ie(cmsg->HLC, commands[AT_HLC]+5);
1339 strcpy(commands[AT_HLC] + l - 2, "\r");
1340 } else if (cip2bchlc[cmsg->CIPValue].hlc) {
1341 l = strlen(cip2bchlc[cmsg->CIPValue].hlc) + 7;
1342 commands[AT_HLC] = kmalloc(l, GFP_KERNEL);
1343 if (!commands[AT_HLC])
1344 goto oom;
1345 snprintf(commands[AT_HLC], l, "^SHLC=%s\r",
1346 cip2bchlc[cmsg->CIPValue].hlc);
1347 }
1348
1349 /* check/encode parameter: B Protocol */
1350 if (cmsg->BProtocol == CAPI_DEFAULT) {
1351 bcs->proto2 = L2_HDLC;
1352 dev_warn(cs->dev,
1353 "B2 Protocol X.75 SLP unsupported, using Transparent\n");
1354 } else {
1355 switch (cmsg->B1protocol) {
1356 case 0:
1357 bcs->proto2 = L2_HDLC;
1358 break;
1359 case 1:
1360 bcs->proto2 = L2_BITSYNC;
1361 break;
1362 default:
1363 dev_warn(cs->dev,
1364 "B1 Protocol %u unsupported, using Transparent\n",
1365 cmsg->B1protocol);
1366 bcs->proto2 = L2_BITSYNC;
1367 }
1368 if (cmsg->B2protocol != 1)
1369 dev_warn(cs->dev,
1370 "B2 Protocol %u unsupported, using Transparent\n",
1371 cmsg->B2protocol);
1372 if (cmsg->B3protocol != 0)
1373 dev_warn(cs->dev,
1374 "B3 Protocol %u unsupported, using Transparent\n",
1375 cmsg->B3protocol);
1376 ignore_cstruct_param(cs, cmsg->B1configuration,
1377 "CONNECT_REQ", "B1 Configuration");
1378 ignore_cstruct_param(cs, cmsg->B2configuration,
1379 "CONNECT_REQ", "B2 Configuration");
1380 ignore_cstruct_param(cs, cmsg->B3configuration,
1381 "CONNECT_REQ", "B3 Configuration");
1382 }
1383 commands[AT_PROTO] = kmalloc(9, GFP_KERNEL);
1384 if (!commands[AT_PROTO])
1385 goto oom;
1386 snprintf(commands[AT_PROTO], 9, "^SBPR=%u\r", bcs->proto2);
1387
1388 /* ToDo: check/encode remaining parameters */
1389 ignore_cstruct_param(cs, cmsg->CalledPartySubaddress,
1390 "CONNECT_REQ", "Called pty subaddr");
1391 ignore_cstruct_param(cs, cmsg->CallingPartySubaddress,
1392 "CONNECT_REQ", "Calling pty subaddr");
1393 ignore_cstruct_param(cs, cmsg->LLC,
1394 "CONNECT_REQ", "LLC");
1395 if (cmsg->AdditionalInfo != CAPI_DEFAULT) {
1396 ignore_cstruct_param(cs, cmsg->BChannelinformation,
1397 "CONNECT_REQ", "B Channel Information");
1398 ignore_cstruct_param(cs, cmsg->Keypadfacility,
1399 "CONNECT_REQ", "Keypad Facility");
1400 ignore_cstruct_param(cs, cmsg->Useruserdata,
1401 "CONNECT_REQ", "User-User Data");
1402 ignore_cstruct_param(cs, cmsg->Facilitydataarray,
1403 "CONNECT_REQ", "Facility Data Array");
1404 }
1405
1406 /* encode parameter: B channel to use */
1407 commands[AT_ISO] = kmalloc(9, GFP_KERNEL);
1408 if (!commands[AT_ISO])
1409 goto oom;
1410 snprintf(commands[AT_ISO], 9, "^SISO=%u\r",
1411 (unsigned) bcs->channel + 1);
1412
1413 /* queue & schedule EV_DIAL event */
1414 if (!gigaset_add_event(cs, &bcs->at_state, EV_DIAL, commands,
1415 bcs->at_state.seq_index, NULL)) {
1416 info = CAPI_MSGOSRESOURCEERR;
1417 goto error;
1418 }
1419 gigaset_schedule_event(cs);
1420 ap->connected = APCONN_SETUP;
1421 send_conf(iif, ap, skb, CapiSuccess);
1422 return;
1423
1424oom:
1425 dev_err(cs->dev, "%s: out of memory\n", __func__);
1426 info = CAPI_MSGOSRESOURCEERR;
1427error:
1428 if (commands)
1429 for (i = 0; i < AT_NUM; i++)
1430 kfree(commands[i]);
1431 kfree(commands);
1432 gigaset_free_channel(bcs);
1433 send_conf(iif, ap, skb, info);
1434}
1435
1436/*
1437 * process CONNECT_RESP message
1438 * checks protocol parameters and queues an ACCEPT or HUP event
1439 */
1440static void do_connect_resp(struct gigaset_capi_ctr *iif,
1441 struct gigaset_capi_appl *ap,
1442 struct sk_buff *skb)
1443{
1444 struct cardstate *cs = iif->ctr.driverdata;
1445 _cmsg *cmsg = &iif->acmsg;
1446 struct bc_state *bcs;
1447 struct gigaset_capi_appl *oap;
1448 int channel;
1449
1450 /* decode message */
1451 capi_message2cmsg(cmsg, skb->data);
1452 dump_cmsg(DEBUG_CMD, __func__, cmsg);
1453 dev_kfree_skb_any(skb);
1454
1455 /* extract and check channel number from PLCI */
1456 channel = (cmsg->adr.adrPLCI >> 8) & 0xff;
1457 if (!channel || channel > cs->channels) {
1458 dev_notice(cs->dev, "%s: invalid %s 0x%02x\n",
1459 "CONNECT_RESP", "PLCI", cmsg->adr.adrPLCI);
1460 return;
1461 }
1462 bcs = cs->bcs + channel - 1;
1463
1464 switch (cmsg->Reject) {
1465 case 0: /* Accept */
1466 /* drop all competing applications, keep only this one */
1467 for (oap = bcs->ap; oap != NULL; oap = oap->bcnext)
1468 if (oap != ap)
1469 send_disconnect_ind(bcs, oap,
1470 CapiCallGivenToOtherApplication);
1471 ap->bcnext = NULL;
1472 bcs->ap = ap;
1473 bcs->chstate |= CHS_NOTIFY_LL;
1474
1475 /* check/encode B channel protocol */
1476 if (cmsg->BProtocol == CAPI_DEFAULT) {
1477 bcs->proto2 = L2_HDLC;
1478 dev_warn(cs->dev,
1479 "B2 Protocol X.75 SLP unsupported, using Transparent\n");
1480 } else {
1481 switch (cmsg->B1protocol) {
1482 case 0:
1483 bcs->proto2 = L2_HDLC;
1484 break;
1485 case 1:
1486 bcs->proto2 = L2_BITSYNC;
1487 break;
1488 default:
1489 dev_warn(cs->dev,
1490 "B1 Protocol %u unsupported, using Transparent\n",
1491 cmsg->B1protocol);
1492 bcs->proto2 = L2_BITSYNC;
1493 }
1494 if (cmsg->B2protocol != 1)
1495 dev_warn(cs->dev,
1496 "B2 Protocol %u unsupported, using Transparent\n",
1497 cmsg->B2protocol);
1498 if (cmsg->B3protocol != 0)
1499 dev_warn(cs->dev,
1500 "B3 Protocol %u unsupported, using Transparent\n",
1501 cmsg->B3protocol);
1502 ignore_cstruct_param(cs, cmsg->B1configuration,
1503 "CONNECT_RESP", "B1 Configuration");
1504 ignore_cstruct_param(cs, cmsg->B2configuration,
1505 "CONNECT_RESP", "B2 Configuration");
1506 ignore_cstruct_param(cs, cmsg->B3configuration,
1507 "CONNECT_RESP", "B3 Configuration");
1508 }
1509
1510 /* ToDo: check/encode remaining parameters */
1511 ignore_cstruct_param(cs, cmsg->ConnectedNumber,
1512 "CONNECT_RESP", "Connected Number");
1513 ignore_cstruct_param(cs, cmsg->ConnectedSubaddress,
1514 "CONNECT_RESP", "Connected Subaddress");
1515 ignore_cstruct_param(cs, cmsg->LLC,
1516 "CONNECT_RESP", "LLC");
1517 if (cmsg->AdditionalInfo != CAPI_DEFAULT) {
1518 ignore_cstruct_param(cs, cmsg->BChannelinformation,
1519 "CONNECT_RESP", "BChannel Information");
1520 ignore_cstruct_param(cs, cmsg->Keypadfacility,
1521 "CONNECT_RESP", "Keypad Facility");
1522 ignore_cstruct_param(cs, cmsg->Useruserdata,
1523 "CONNECT_RESP", "User-User Data");
1524 ignore_cstruct_param(cs, cmsg->Facilitydataarray,
1525 "CONNECT_RESP", "Facility Data Array");
1526 }
1527
1528 /* Accept call */
1529 if (!gigaset_add_event(cs, &cs->bcs[channel-1].at_state,
1530 EV_ACCEPT, NULL, 0, NULL))
1531 return;
1532 gigaset_schedule_event(cs);
1533 return;
1534
1535 case 1: /* Ignore */
1536 /* send DISCONNECT_IND to this application */
1537 send_disconnect_ind(bcs, ap, 0);
1538
1539 /* remove it from the list of listening apps */
1540 if (bcs->ap == ap) {
1541 bcs->ap = ap->bcnext;
1542 if (bcs->ap == NULL)
1543 /* last one: stop ev-layer hupD notifications */
1544 bcs->chstate &= ~CHS_NOTIFY_LL;
1545 return;
1546 }
1547 for (oap = bcs->ap; oap != NULL; oap = oap->bcnext) {
1548 if (oap->bcnext == ap) {
1549 oap->bcnext = oap->bcnext->bcnext;
1550 return;
1551 }
1552 }
1553 dev_err(cs->dev, "%s: application %u not found\n",
1554 __func__, ap->id);
1555 return;
1556
1557 default: /* Reject */
1558 /* drop all competing applications, keep only this one */
1559 for (oap = bcs->ap; oap != NULL; oap = oap->bcnext)
1560 if (oap != ap)
1561 send_disconnect_ind(bcs, oap,
1562 CapiCallGivenToOtherApplication);
1563 ap->bcnext = NULL;
1564 bcs->ap = ap;
1565
1566 /* reject call - will trigger DISCONNECT_IND for this app */
1567 dev_info(cs->dev, "%s: Reject=%x\n",
1568 "CONNECT_RESP", cmsg->Reject);
1569 if (!gigaset_add_event(cs, &cs->bcs[channel-1].at_state,
1570 EV_HUP, NULL, 0, NULL))
1571 return;
1572 gigaset_schedule_event(cs);
1573 return;
1574 }
1575}
1576
1577/*
1578 * process CONNECT_B3_REQ message
1579 * build NCCI and emit CONNECT_B3_CONF reply
1580 */
1581static void do_connect_b3_req(struct gigaset_capi_ctr *iif,
1582 struct gigaset_capi_appl *ap,
1583 struct sk_buff *skb)
1584{
1585 struct cardstate *cs = iif->ctr.driverdata;
1586 _cmsg *cmsg = &iif->acmsg;
1587 int channel;
1588
1589 /* decode message */
1590 capi_message2cmsg(cmsg, skb->data);
1591 dump_cmsg(DEBUG_CMD, __func__, cmsg);
1592
1593 /* extract and check channel number from PLCI */
1594 channel = (cmsg->adr.adrPLCI >> 8) & 0xff;
1595 if (!channel || channel > cs->channels) {
1596 dev_notice(cs->dev, "%s: invalid %s 0x%02x\n",
1597 "CONNECT_B3_REQ", "PLCI", cmsg->adr.adrPLCI);
1598 send_conf(iif, ap, skb, CapiIllContrPlciNcci);
1599 return;
1600 }
1601
1602 /* mark logical connection active */
1603 ap->connected = APCONN_ACTIVE;
1604
1605 /* build NCCI: always 1 (one B3 connection only) */
1606 cmsg->adr.adrNCCI |= 1 << 16;
1607
1608 /* NCPI parameter: not applicable for B3 Transparent */
1609 ignore_cstruct_param(cs, cmsg->NCPI, "CONNECT_B3_REQ", "NCPI");
1610 send_conf(iif, ap, skb, (cmsg->NCPI && cmsg->NCPI[0]) ?
1611 CapiNcpiNotSupportedByProtocol : CapiSuccess);
1612}
1613
1614/*
1615 * process CONNECT_B3_RESP message
1616 * Depending on the Reject parameter, either emit CONNECT_B3_ACTIVE_IND
1617 * or queue EV_HUP and emit DISCONNECT_B3_IND.
1618 * The emitted message is always shorter than the received one,
1619 * allowing to reuse the skb.
1620 */
1621static void do_connect_b3_resp(struct gigaset_capi_ctr *iif,
1622 struct gigaset_capi_appl *ap,
1623 struct sk_buff *skb)
1624{
1625 struct cardstate *cs = iif->ctr.driverdata;
1626 _cmsg *cmsg = &iif->acmsg;
1627 struct bc_state *bcs;
1628 int channel;
1629 unsigned int msgsize;
1630 u8 command;
1631
1632 /* decode message */
1633 capi_message2cmsg(cmsg, skb->data);
1634 dump_cmsg(DEBUG_CMD, __func__, cmsg);
1635
1636 /* extract and check channel number and NCCI */
1637 channel = (cmsg->adr.adrNCCI >> 8) & 0xff;
1638 if (!channel || channel > cs->channels ||
1639 ((cmsg->adr.adrNCCI >> 16) & 0xffff) != 1) {
1640 dev_notice(cs->dev, "%s: invalid %s 0x%02x\n",
1641 "CONNECT_B3_RESP", "NCCI", cmsg->adr.adrNCCI);
1642 dev_kfree_skb_any(skb);
1643 return;
1644 }
1645 bcs = &cs->bcs[channel-1];
1646
1647 if (cmsg->Reject) {
1648 /* Reject: clear B3 connect received flag */
1649 ap->connected = APCONN_SETUP;
1650
1651 /* trigger hangup, causing eventual DISCONNECT_IND */
1652 if (!gigaset_add_event(cs, &bcs->at_state,
1653 EV_HUP, NULL, 0, NULL)) {
1654 dev_kfree_skb_any(skb);
1655 return;
1656 }
1657 gigaset_schedule_event(cs);
1658
1659 /* emit DISCONNECT_B3_IND */
1660 command = CAPI_DISCONNECT_B3;
1661 msgsize = CAPI_DISCONNECT_B3_IND_BASELEN;
1662 } else {
1663 /*
1664 * Accept: emit CONNECT_B3_ACTIVE_IND immediately, as
1665 * we only send CONNECT_B3_IND if the B channel is up
1666 */
1667 command = CAPI_CONNECT_B3_ACTIVE;
1668 msgsize = CAPI_CONNECT_B3_ACTIVE_IND_BASELEN;
1669 }
1670 capi_cmsg_header(cmsg, ap->id, command, CAPI_IND,
1671 ap->nextMessageNumber++, cmsg->adr.adrNCCI);
1672 __skb_trim(skb, msgsize);
1673 capi_cmsg2message(cmsg, skb->data);
1674 dump_cmsg(DEBUG_CMD, __func__, cmsg);
1675 capi_ctr_handle_message(&iif->ctr, ap->id, skb);
1676}
1677
1678/*
1679 * process DISCONNECT_REQ message
1680 * schedule EV_HUP and emit DISCONNECT_B3_IND if necessary,
1681 * emit DISCONNECT_CONF reply
1682 */
1683static void do_disconnect_req(struct gigaset_capi_ctr *iif,
1684 struct gigaset_capi_appl *ap,
1685 struct sk_buff *skb)
1686{
1687 struct cardstate *cs = iif->ctr.driverdata;
1688 _cmsg *cmsg = &iif->acmsg;
1689 struct bc_state *bcs;
1690 _cmsg *b3cmsg;
1691 struct sk_buff *b3skb;
1692 int channel;
1693
1694 /* decode message */
1695 capi_message2cmsg(cmsg, skb->data);
1696 dump_cmsg(DEBUG_CMD, __func__, cmsg);
1697
1698 /* extract and check channel number from PLCI */
1699 channel = (cmsg->adr.adrPLCI >> 8) & 0xff;
1700 if (!channel || channel > cs->channels) {
1701 dev_notice(cs->dev, "%s: invalid %s 0x%02x\n",
1702 "DISCONNECT_REQ", "PLCI", cmsg->adr.adrPLCI);
1703 send_conf(iif, ap, skb, CapiIllContrPlciNcci);
1704 return;
1705 }
1706 bcs = cs->bcs + channel - 1;
1707
1708 /* ToDo: process parameter: Additional info */
1709 if (cmsg->AdditionalInfo != CAPI_DEFAULT) {
1710 ignore_cstruct_param(cs, cmsg->BChannelinformation,
1711 "DISCONNECT_REQ", "B Channel Information");
1712 ignore_cstruct_param(cs, cmsg->Keypadfacility,
1713 "DISCONNECT_REQ", "Keypad Facility");
1714 ignore_cstruct_param(cs, cmsg->Useruserdata,
1715 "DISCONNECT_REQ", "User-User Data");
1716 ignore_cstruct_param(cs, cmsg->Facilitydataarray,
1717 "DISCONNECT_REQ", "Facility Data Array");
1718 }
1719
1720 /* skip if DISCONNECT_IND already sent */
1721 if (!ap->connected)
1722 return;
1723
1724 /* check for active logical connection */
1725 if (ap->connected >= APCONN_ACTIVE) {
1726 /*
1727 * emit DISCONNECT_B3_IND with cause 0x3301
1728 * use separate cmsg structure, as the content of iif->acmsg
1729 * is still needed for creating the _CONF message
1730 */
1731 b3cmsg = kmalloc(sizeof(*b3cmsg), GFP_KERNEL);
1732 if (!b3cmsg) {
1733 dev_err(cs->dev, "%s: out of memory\n", __func__);
1734 send_conf(iif, ap, skb, CAPI_MSGOSRESOURCEERR);
1735 return;
1736 }
1737 capi_cmsg_header(b3cmsg, ap->id, CAPI_DISCONNECT_B3, CAPI_IND,
1738 ap->nextMessageNumber++,
1739 cmsg->adr.adrPLCI | (1 << 16));
1740 b3cmsg->Reason_B3 = CapiProtocolErrorLayer1;
1741 b3skb = alloc_skb(CAPI_DISCONNECT_B3_IND_BASELEN, GFP_KERNEL);
1742 if (b3skb == NULL) {
1743 dev_err(cs->dev, "%s: out of memory\n", __func__);
1744 send_conf(iif, ap, skb, CAPI_MSGOSRESOURCEERR);
1745 return;
1746 }
1747 capi_cmsg2message(b3cmsg,
1748 __skb_put(b3skb, CAPI_DISCONNECT_B3_IND_BASELEN));
1749 kfree(b3cmsg);
1750 capi_ctr_handle_message(&iif->ctr, ap->id, b3skb);
1751 }
1752
1753 /* trigger hangup, causing eventual DISCONNECT_IND */
1754 if (!gigaset_add_event(cs, &bcs->at_state, EV_HUP, NULL, 0, NULL)) {
1755 send_conf(iif, ap, skb, CAPI_MSGOSRESOURCEERR);
1756 return;
1757 }
1758 gigaset_schedule_event(cs);
1759
1760 /* emit reply */
1761 send_conf(iif, ap, skb, CapiSuccess);
1762}
1763
1764/*
1765 * process DISCONNECT_B3_REQ message
1766 * schedule EV_HUP and emit DISCONNECT_B3_CONF reply
1767 */
1768static void do_disconnect_b3_req(struct gigaset_capi_ctr *iif,
1769 struct gigaset_capi_appl *ap,
1770 struct sk_buff *skb)
1771{
1772 struct cardstate *cs = iif->ctr.driverdata;
1773 _cmsg *cmsg = &iif->acmsg;
1774 int channel;
1775
1776 /* decode message */
1777 capi_message2cmsg(cmsg, skb->data);
1778 dump_cmsg(DEBUG_CMD, __func__, cmsg);
1779
1780 /* extract and check channel number and NCCI */
1781 channel = (cmsg->adr.adrNCCI >> 8) & 0xff;
1782 if (!channel || channel > cs->channels ||
1783 ((cmsg->adr.adrNCCI >> 16) & 0xffff) != 1) {
1784 dev_notice(cs->dev, "%s: invalid %s 0x%02x\n",
1785 "DISCONNECT_B3_REQ", "NCCI", cmsg->adr.adrNCCI);
1786 send_conf(iif, ap, skb, CapiIllContrPlciNcci);
1787 return;
1788 }
1789
1790 /* reject if logical connection not active */
1791 if (ap->connected < APCONN_ACTIVE) {
1792 send_conf(iif, ap, skb,
1793 CapiMessageNotSupportedInCurrentState);
1794 return;
1795 }
1796
1797 /* trigger hangup, causing eventual DISCONNECT_B3_IND */
1798 if (!gigaset_add_event(cs, &cs->bcs[channel-1].at_state,
1799 EV_HUP, NULL, 0, NULL)) {
1800 send_conf(iif, ap, skb, CAPI_MSGOSRESOURCEERR);
1801 return;
1802 }
1803 gigaset_schedule_event(cs);
1804
1805 /* NCPI parameter: not applicable for B3 Transparent */
1806 ignore_cstruct_param(cs, cmsg->NCPI,
1807 "DISCONNECT_B3_REQ", "NCPI");
1808 send_conf(iif, ap, skb, (cmsg->NCPI && cmsg->NCPI[0]) ?
1809 CapiNcpiNotSupportedByProtocol : CapiSuccess);
1810}
1811
1812/*
1813 * process DATA_B3_REQ message
1814 */
1815static void do_data_b3_req(struct gigaset_capi_ctr *iif,
1816 struct gigaset_capi_appl *ap,
1817 struct sk_buff *skb)
1818{
1819 struct cardstate *cs = iif->ctr.driverdata;
1820 int channel = CAPIMSG_PLCI_PART(skb->data);
1821 u16 ncci = CAPIMSG_NCCI_PART(skb->data);
1822 u16 msglen = CAPIMSG_LEN(skb->data);
1823 u16 datalen = CAPIMSG_DATALEN(skb->data);
1824 u16 flags = CAPIMSG_FLAGS(skb->data);
1825
1826 /* frequent message, avoid _cmsg overhead */
1827 dump_rawmsg(DEBUG_LLDATA, "DATA_B3_REQ", skb->data);
1828
1829 gig_dbg(DEBUG_LLDATA,
1830 "Receiving data from LL (ch: %d, flg: %x, sz: %d|%d)",
1831 channel, flags, msglen, datalen);
1832
1833 /* check parameters */
1834 if (channel == 0 || channel > cs->channels || ncci != 1) {
1835 dev_notice(cs->dev, "%s: invalid %s 0x%02x\n",
1836 "DATA_B3_REQ", "NCCI", CAPIMSG_NCCI(skb->data));
1837 send_conf(iif, ap, skb, CapiIllContrPlciNcci);
1838 return;
1839 }
1840 if (msglen != CAPI_DATA_B3_REQ_LEN && msglen != CAPI_DATA_B3_REQ_LEN64)
1841 dev_notice(cs->dev, "%s: unexpected length %d\n",
1842 "DATA_B3_REQ", msglen);
1843 if (msglen + datalen != skb->len)
1844 dev_notice(cs->dev, "%s: length mismatch (%d+%d!=%d)\n",
1845 "DATA_B3_REQ", msglen, datalen, skb->len);
1846 if (msglen + datalen > skb->len) {
1847 /* message too short for announced data length */
1848 send_conf(iif, ap, skb, CapiIllMessageParmCoding); /* ? */
1849 return;
1850 }
1851 if (flags & CAPI_FLAGS_RESERVED) {
1852 dev_notice(cs->dev, "%s: reserved flags set (%x)\n",
1853 "DATA_B3_REQ", flags);
1854 send_conf(iif, ap, skb, CapiIllMessageParmCoding);
1855 return;
1856 }
1857
1858 /* reject if logical connection not active */
1859 if (ap->connected < APCONN_ACTIVE) {
1860 send_conf(iif, ap, skb, CapiMessageNotSupportedInCurrentState);
1861 return;
1862 }
1863
1864 /* pull CAPI message into link layer header */
1865 skb_reset_mac_header(skb);
1866 skb->mac_len = msglen;
1867 skb_pull(skb, msglen);
1868
1869 /* pass to device-specific module */
1870 if (cs->ops->send_skb(&cs->bcs[channel-1], skb) < 0) {
1871 send_conf(iif, ap, skb, CAPI_MSGOSRESOURCEERR);
1872 return;
1873 }
1874
1875 /* DATA_B3_CONF reply will be sent by gigaset_skb_sent() */
1876
1877 /*
1878 * ToDo: honor unset "delivery confirmation" bit
1879 * (send DATA_B3_CONF immediately?)
1880 */
1881}
1882
1883/*
1884 * process RESET_B3_REQ message
1885 * just always reply "not supported by current protocol"
1886 */
1887static void do_reset_b3_req(struct gigaset_capi_ctr *iif,
1888 struct gigaset_capi_appl *ap,
1889 struct sk_buff *skb)
1890{
1891 /* decode message */
1892 capi_message2cmsg(&iif->acmsg, skb->data);
1893 dump_cmsg(DEBUG_CMD, __func__, &iif->acmsg);
1894 send_conf(iif, ap, skb,
1895 CapiResetProcedureNotSupportedByCurrentProtocol);
1896}
1897
1898/*
1899 * dump unsupported/ignored messages at most twice per minute,
1900 * some apps send those very frequently
1901 */
1902static unsigned long ignored_msg_dump_time;
1903
1904/*
1905 * unsupported CAPI message handler
1906 */
1907static void do_unsupported(struct gigaset_capi_ctr *iif,
1908 struct gigaset_capi_appl *ap,
1909 struct sk_buff *skb)
1910{
1911 /* decode message */
1912 capi_message2cmsg(&iif->acmsg, skb->data);
1913 if (printk_timed_ratelimit(&ignored_msg_dump_time, 30 * 1000))
1914 dump_cmsg(DEBUG_CMD, __func__, &iif->acmsg);
1915 send_conf(iif, ap, skb, CapiMessageNotSupportedInCurrentState);
1916}
1917
1918/*
1919 * CAPI message handler: no-op
1920 */
1921static void do_nothing(struct gigaset_capi_ctr *iif,
1922 struct gigaset_capi_appl *ap,
1923 struct sk_buff *skb)
1924{
1925 if (printk_timed_ratelimit(&ignored_msg_dump_time, 30 * 1000)) {
1926 /* decode message */
1927 capi_message2cmsg(&iif->acmsg, skb->data);
1928 dump_cmsg(DEBUG_CMD, __func__, &iif->acmsg);
1929 }
1930 dev_kfree_skb_any(skb);
1931}
1932
1933static void do_data_b3_resp(struct gigaset_capi_ctr *iif,
1934 struct gigaset_capi_appl *ap,
1935 struct sk_buff *skb)
1936{
1937 dump_rawmsg(DEBUG_LLDATA, __func__, skb->data);
1938 dev_kfree_skb_any(skb);
1939}
1940
1941/* table of outgoing CAPI message handlers with lookup function */
1942typedef void (*capi_send_handler_t)(struct gigaset_capi_ctr *,
1943 struct gigaset_capi_appl *,
1944 struct sk_buff *);
1945
1946static struct {
1947 u16 cmd;
1948 capi_send_handler_t handler;
1949} capi_send_handler_table[] = {
1950 /* most frequent messages first for faster lookup */
1951 { CAPI_DATA_B3_REQ, do_data_b3_req },
1952 { CAPI_DATA_B3_RESP, do_data_b3_resp },
1953
1954 { CAPI_ALERT_REQ, do_alert_req },
1955 { CAPI_CONNECT_ACTIVE_RESP, do_nothing },
1956 { CAPI_CONNECT_B3_ACTIVE_RESP, do_nothing },
1957 { CAPI_CONNECT_B3_REQ, do_connect_b3_req },
1958 { CAPI_CONNECT_B3_RESP, do_connect_b3_resp },
1959 { CAPI_CONNECT_B3_T90_ACTIVE_RESP, do_nothing },
1960 { CAPI_CONNECT_REQ, do_connect_req },
1961 { CAPI_CONNECT_RESP, do_connect_resp },
1962 { CAPI_DISCONNECT_B3_REQ, do_disconnect_b3_req },
1963 { CAPI_DISCONNECT_B3_RESP, do_nothing },
1964 { CAPI_DISCONNECT_REQ, do_disconnect_req },
1965 { CAPI_DISCONNECT_RESP, do_nothing },
1966 { CAPI_FACILITY_REQ, do_facility_req },
1967 { CAPI_FACILITY_RESP, do_nothing },
1968 { CAPI_LISTEN_REQ, do_listen_req },
1969 { CAPI_SELECT_B_PROTOCOL_REQ, do_unsupported },
1970 { CAPI_RESET_B3_REQ, do_reset_b3_req },
1971 { CAPI_RESET_B3_RESP, do_nothing },
1972
1973 /*
1974 * ToDo: support overlap sending (requires ev-layer state
1975 * machine extension to generate additional ATD commands)
1976 */
1977 { CAPI_INFO_REQ, do_unsupported },
1978 { CAPI_INFO_RESP, do_nothing },
1979
1980 /*
1981 * ToDo: what's the proper response for these?
1982 */
1983 { CAPI_MANUFACTURER_REQ, do_nothing },
1984 { CAPI_MANUFACTURER_RESP, do_nothing },
1985};
1986
1987/* look up handler */
1988static inline capi_send_handler_t lookup_capi_send_handler(const u16 cmd)
1989{
1990 size_t i;
1991
1992 for (i = 0; i < ARRAY_SIZE(capi_send_handler_table); i++)
1993 if (capi_send_handler_table[i].cmd == cmd)
1994 return capi_send_handler_table[i].handler;
1995 return NULL;
1996}
1997
1998
1999/**
2000 * gigaset_send_message() - accept a CAPI message from an application
2001 * @ctr: controller descriptor structure.
2002 * @skb: CAPI message.
2003 *
2004 * Return value: CAPI error code
2005 * Note: capidrv (and probably others, too) only uses the return value to
2006 * decide whether it has to free the skb (only if result != CAPI_NOERROR (0))
2007 */
2008static u16 gigaset_send_message(struct capi_ctr *ctr, struct sk_buff *skb)
2009{
2010 struct gigaset_capi_ctr *iif
2011 = container_of(ctr, struct gigaset_capi_ctr, ctr);
2012 struct cardstate *cs = ctr->driverdata;
2013 struct gigaset_capi_appl *ap;
2014 capi_send_handler_t handler;
2015
2016 /* can only handle linear sk_buffs */
2017 if (skb_linearize(skb) < 0) {
2018 dev_warn(cs->dev, "%s: skb_linearize failed\n", __func__);
2019 return CAPI_MSGOSRESOURCEERR;
2020 }
2021
2022 /* retrieve application data structure */
2023 ap = get_appl(iif, CAPIMSG_APPID(skb->data));
2024 if (!ap) {
2025 dev_notice(cs->dev, "%s: application %u not registered\n",
2026 __func__, CAPIMSG_APPID(skb->data));
2027 return CAPI_ILLAPPNR;
2028 }
2029
2030 /* look up command */
2031 handler = lookup_capi_send_handler(CAPIMSG_CMD(skb->data));
2032 if (!handler) {
2033 /* unknown/unsupported message type */
2034 if (printk_ratelimit())
2035 dev_notice(cs->dev, "%s: unsupported message %u\n",
2036 __func__, CAPIMSG_CMD(skb->data));
2037 return CAPI_ILLCMDORSUBCMDORMSGTOSMALL;
2038 }
2039
2040 /* serialize */
2041 if (atomic_add_return(1, &iif->sendqlen) > 1) {
2042 /* queue behind other messages */
2043 skb_queue_tail(&iif->sendqueue, skb);
2044 return CAPI_NOERROR;
2045 }
2046
2047 /* process message */
2048 handler(iif, ap, skb);
2049
2050 /* process other messages arrived in the meantime */
2051 while (atomic_sub_return(1, &iif->sendqlen) > 0) {
2052 skb = skb_dequeue(&iif->sendqueue);
2053 if (!skb) {
2054 /* should never happen */
2055 dev_err(cs->dev, "%s: send queue empty\n", __func__);
2056 continue;
2057 }
2058 ap = get_appl(iif, CAPIMSG_APPID(skb->data));
2059 if (!ap) {
2060 /* could that happen? */
2061 dev_warn(cs->dev, "%s: application %u vanished\n",
2062 __func__, CAPIMSG_APPID(skb->data));
2063 continue;
2064 }
2065 handler = lookup_capi_send_handler(CAPIMSG_CMD(skb->data));
2066 if (!handler) {
2067 /* should never happen */
2068 dev_err(cs->dev, "%s: handler %x vanished\n",
2069 __func__, CAPIMSG_CMD(skb->data));
2070 continue;
2071 }
2072 handler(iif, ap, skb);
2073 }
2074
2075 return CAPI_NOERROR;
2076}
2077
2078/**
2079 * gigaset_procinfo() - build single line description for controller
2080 * @ctr: controller descriptor structure.
2081 *
2082 * Return value: pointer to generated string (null terminated)
2083 */
2084static char *gigaset_procinfo(struct capi_ctr *ctr)
2085{
2086 return ctr->name; /* ToDo: more? */
2087}
2088
2089static int gigaset_proc_show(struct seq_file *m, void *v)
2090{
2091 struct capi_ctr *ctr = m->private;
2092 struct cardstate *cs = ctr->driverdata;
2093 char *s;
2094 int i;
2095
2096 seq_printf(m, "%-16s %s\n", "name", ctr->name);
2097 seq_printf(m, "%-16s %s %s\n", "dev",
2098 dev_driver_string(cs->dev), dev_name(cs->dev));
2099 seq_printf(m, "%-16s %d\n", "id", cs->myid);
2100 if (cs->gotfwver)
2101 seq_printf(m, "%-16s %d.%d.%d.%d\n", "firmware",
2102 cs->fwver[0], cs->fwver[1], cs->fwver[2], cs->fwver[3]);
2103 seq_printf(m, "%-16s %d\n", "channels", cs->channels);
2104 seq_printf(m, "%-16s %s\n", "onechannel", cs->onechannel ? "yes" : "no");
2105
2106 switch (cs->mode) {
2107 case M_UNKNOWN:
2108 s = "unknown";
2109 break;
2110 case M_CONFIG:
2111 s = "config";
2112 break;
2113 case M_UNIMODEM:
2114 s = "Unimodem";
2115 break;
2116 case M_CID:
2117 s = "CID";
2118 break;
2119 default:
2120 s = "??";
2121 }
2122 seq_printf(m, "%-16s %s\n", "mode", s);
2123
2124 switch (cs->mstate) {
2125 case MS_UNINITIALIZED:
2126 s = "uninitialized";
2127 break;
2128 case MS_INIT:
2129 s = "init";
2130 break;
2131 case MS_LOCKED:
2132 s = "locked";
2133 break;
2134 case MS_SHUTDOWN:
2135 s = "shutdown";
2136 break;
2137 case MS_RECOVER:
2138 s = "recover";
2139 break;
2140 case MS_READY:
2141 s = "ready";
2142 break;
2143 default:
2144 s = "??";
2145 }
2146 seq_printf(m, "%-16s %s\n", "mstate", s);
2147
2148 seq_printf(m, "%-16s %s\n", "running", cs->running ? "yes" : "no");
2149 seq_printf(m, "%-16s %s\n", "connected", cs->connected ? "yes" : "no");
2150 seq_printf(m, "%-16s %s\n", "isdn_up", cs->isdn_up ? "yes" : "no");
2151 seq_printf(m, "%-16s %s\n", "cidmode", cs->cidmode ? "yes" : "no");
2152
2153 for (i = 0; i < cs->channels; i++) {
2154 seq_printf(m, "[%d]%-13s %d\n", i, "corrupted",
2155 cs->bcs[i].corrupted);
2156 seq_printf(m, "[%d]%-13s %d\n", i, "trans_down",
2157 cs->bcs[i].trans_down);
2158 seq_printf(m, "[%d]%-13s %d\n", i, "trans_up",
2159 cs->bcs[i].trans_up);
2160 seq_printf(m, "[%d]%-13s %d\n", i, "chstate",
2161 cs->bcs[i].chstate);
2162 switch (cs->bcs[i].proto2) {
2163 case L2_BITSYNC:
2164 s = "bitsync";
2165 break;
2166 case L2_HDLC:
2167 s = "HDLC";
2168 break;
2169 case L2_VOICE:
2170 s = "voice";
2171 break;
2172 default:
2173 s = "??";
2174 }
2175 seq_printf(m, "[%d]%-13s %s\n", i, "proto2", s);
2176 }
2177 return 0;
2178}
2179
2180static int gigaset_proc_open(struct inode *inode, struct file *file)
2181{
2182 return single_open(file, gigaset_proc_show, PDE(inode)->data);
2183}
2184
2185static const struct file_operations gigaset_proc_fops = {
2186 .owner = THIS_MODULE,
2187 .open = gigaset_proc_open,
2188 .read = seq_read,
2189 .llseek = seq_lseek,
2190 .release = single_release,
2191};
2192
2193/**
2194 * gigaset_isdn_regdev() - register device to LL
2195 * @cs: device descriptor structure.
2196 * @isdnid: device name.
2197 *
2198 * Return value: 1 for success, 0 for failure
2199 */
2200int gigaset_isdn_regdev(struct cardstate *cs, const char *isdnid)
2201{
2202 struct gigaset_capi_ctr *iif;
2203 int rc;
2204
2205 iif = kmalloc(sizeof(*iif), GFP_KERNEL);
2206 if (!iif) {
2207 pr_err("%s: out of memory\n", __func__);
2208 return 0;
2209 }
2210
2211 /* prepare controller structure */
2212 iif->ctr.owner = THIS_MODULE;
2213 iif->ctr.driverdata = cs;
2214 strncpy(iif->ctr.name, isdnid, sizeof(iif->ctr.name));
2215 iif->ctr.driver_name = "gigaset";
2216 iif->ctr.load_firmware = gigaset_load_firmware;
2217 iif->ctr.reset_ctr = gigaset_reset_ctr;
2218 iif->ctr.register_appl = gigaset_register_appl;
2219 iif->ctr.release_appl = gigaset_release_appl;
2220 iif->ctr.send_message = gigaset_send_message;
2221 iif->ctr.procinfo = gigaset_procinfo;
2222 iif->ctr.proc_fops = &gigaset_proc_fops;
2223 INIT_LIST_HEAD(&iif->appls);
2224 skb_queue_head_init(&iif->sendqueue);
2225 atomic_set(&iif->sendqlen, 0);
2226
2227 /* register controller with CAPI */
2228 rc = attach_capi_ctr(&iif->ctr);
2229 if (rc) {
2230 pr_err("attach_capi_ctr failed (%d)\n", rc);
2231 kfree(iif);
2232 return 0;
2233 }
2234
2235 cs->iif = iif;
2236 cs->hw_hdr_len = CAPI_DATA_B3_REQ_LEN;
2237 return 1;
2238}
2239
2240/**
2241 * gigaset_isdn_unregdev() - unregister device from LL
2242 * @cs: device descriptor structure.
2243 */
2244void gigaset_isdn_unregdev(struct cardstate *cs)
2245{
2246 struct gigaset_capi_ctr *iif = cs->iif;
2247
2248 detach_capi_ctr(&iif->ctr);
2249 kfree(iif);
2250 cs->iif = NULL;
2251}
2252
2253static struct capi_driver capi_driver_gigaset = {
2254 .name = "gigaset",
2255 .revision = "1.0",
2256};
2257
2258/**
2259 * gigaset_isdn_regdrv() - register driver to LL
2260 */
2261void gigaset_isdn_regdrv(void)
2262{
2263 pr_info("Kernel CAPI interface\n");
2264 register_capi_driver(&capi_driver_gigaset);
2265}
2266
2267/**
2268 * gigaset_isdn_unregdrv() - unregister driver from LL
2269 */
2270void gigaset_isdn_unregdrv(void)
2271{
2272 unregister_capi_driver(&capi_driver_gigaset);
2273}
diff --git a/drivers/isdn/gigaset/common.c b/drivers/isdn/gigaset/common.c
index 33dcd8d72b7c..f6f45f221920 100644
--- a/drivers/isdn/gigaset/common.c
+++ b/drivers/isdn/gigaset/common.c
@@ -14,7 +14,6 @@
14 */ 14 */
15 15
16#include "gigaset.h" 16#include "gigaset.h"
17#include <linux/ctype.h>
18#include <linux/module.h> 17#include <linux/module.h>
19#include <linux/moduleparam.h> 18#include <linux/moduleparam.h>
20 19
@@ -29,7 +28,7 @@
29#endif 28#endif
30 29
31/* Module parameters */ 30/* Module parameters */
32int gigaset_debuglevel = DEBUG_DEFAULT; 31int gigaset_debuglevel;
33EXPORT_SYMBOL_GPL(gigaset_debuglevel); 32EXPORT_SYMBOL_GPL(gigaset_debuglevel);
34module_param_named(debug, gigaset_debuglevel, int, S_IRUGO|S_IWUSR); 33module_param_named(debug, gigaset_debuglevel, int, S_IRUGO|S_IWUSR);
35MODULE_PARM_DESC(debug, "debug level"); 34MODULE_PARM_DESC(debug, "debug level");
@@ -108,7 +107,7 @@ int gigaset_enterconfigmode(struct cardstate *cs)
108{ 107{
109 int i, r; 108 int i, r;
110 109
111 cs->control_state = TIOCM_RTS; //FIXME 110 cs->control_state = TIOCM_RTS;
112 111
113 r = setflags(cs, TIOCM_DTR, 200); 112 r = setflags(cs, TIOCM_DTR, 200);
114 if (r < 0) 113 if (r < 0)
@@ -132,10 +131,10 @@ int gigaset_enterconfigmode(struct cardstate *cs)
132 131
133error: 132error:
134 dev_err(cs->dev, "error %d on setuartbits\n", -r); 133 dev_err(cs->dev, "error %d on setuartbits\n", -r);
135 cs->control_state = TIOCM_RTS|TIOCM_DTR; // FIXME is this a good value? 134 cs->control_state = TIOCM_RTS|TIOCM_DTR;
136 cs->ops->set_modem_ctrl(cs, 0, TIOCM_RTS|TIOCM_DTR); 135 cs->ops->set_modem_ctrl(cs, 0, TIOCM_RTS|TIOCM_DTR);
137 136
138 return -1; //r 137 return -1;
139} 138}
140 139
141static int test_timeout(struct at_state_t *at_state) 140static int test_timeout(struct at_state_t *at_state)
@@ -149,11 +148,8 @@ static int test_timeout(struct at_state_t *at_state)
149 return 0; 148 return 0;
150 } 149 }
151 150
152 if (!gigaset_add_event(at_state->cs, at_state, EV_TIMEOUT, NULL, 151 gigaset_add_event(at_state->cs, at_state, EV_TIMEOUT, NULL,
153 at_state->timer_index, NULL)) { 152 at_state->timer_index, NULL);
154 //FIXME what should we do?
155 }
156
157 return 1; 153 return 1;
158} 154}
159 155
@@ -181,7 +177,7 @@ static void timer_tick(unsigned long data)
181 if (cs->running) { 177 if (cs->running) {
182 mod_timer(&cs->timer, jiffies + msecs_to_jiffies(GIG_TICK)); 178 mod_timer(&cs->timer, jiffies + msecs_to_jiffies(GIG_TICK));
183 if (timeout) { 179 if (timeout) {
184 gig_dbg(DEBUG_CMD, "scheduling timeout"); 180 gig_dbg(DEBUG_EVENT, "scheduling timeout");
185 tasklet_schedule(&cs->event_tasklet); 181 tasklet_schedule(&cs->event_tasklet);
186 } 182 }
187 } 183 }
@@ -195,32 +191,59 @@ int gigaset_get_channel(struct bc_state *bcs)
195 191
196 spin_lock_irqsave(&bcs->cs->lock, flags); 192 spin_lock_irqsave(&bcs->cs->lock, flags);
197 if (bcs->use_count || !try_module_get(bcs->cs->driver->owner)) { 193 if (bcs->use_count || !try_module_get(bcs->cs->driver->owner)) {
198 gig_dbg(DEBUG_ANY, "could not allocate channel %d", 194 gig_dbg(DEBUG_CHANNEL, "could not allocate channel %d",
199 bcs->channel); 195 bcs->channel);
200 spin_unlock_irqrestore(&bcs->cs->lock, flags); 196 spin_unlock_irqrestore(&bcs->cs->lock, flags);
201 return 0; 197 return 0;
202 } 198 }
203 ++bcs->use_count; 199 ++bcs->use_count;
204 bcs->busy = 1; 200 bcs->busy = 1;
205 gig_dbg(DEBUG_ANY, "allocated channel %d", bcs->channel); 201 gig_dbg(DEBUG_CHANNEL, "allocated channel %d", bcs->channel);
206 spin_unlock_irqrestore(&bcs->cs->lock, flags); 202 spin_unlock_irqrestore(&bcs->cs->lock, flags);
207 return 1; 203 return 1;
208} 204}
209 205
206struct bc_state *gigaset_get_free_channel(struct cardstate *cs)
207{
208 unsigned long flags;
209 int i;
210
211 spin_lock_irqsave(&cs->lock, flags);
212 if (!try_module_get(cs->driver->owner)) {
213 gig_dbg(DEBUG_CHANNEL,
214 "could not get module for allocating channel");
215 spin_unlock_irqrestore(&cs->lock, flags);
216 return NULL;
217 }
218 for (i = 0; i < cs->channels; ++i)
219 if (!cs->bcs[i].use_count) {
220 ++cs->bcs[i].use_count;
221 cs->bcs[i].busy = 1;
222 spin_unlock_irqrestore(&cs->lock, flags);
223 gig_dbg(DEBUG_CHANNEL, "allocated channel %d", i);
224 return cs->bcs + i;
225 }
226 module_put(cs->driver->owner);
227 spin_unlock_irqrestore(&cs->lock, flags);
228 gig_dbg(DEBUG_CHANNEL, "no free channel");
229 return NULL;
230}
231
210void gigaset_free_channel(struct bc_state *bcs) 232void gigaset_free_channel(struct bc_state *bcs)
211{ 233{
212 unsigned long flags; 234 unsigned long flags;
213 235
214 spin_lock_irqsave(&bcs->cs->lock, flags); 236 spin_lock_irqsave(&bcs->cs->lock, flags);
215 if (!bcs->busy) { 237 if (!bcs->busy) {
216 gig_dbg(DEBUG_ANY, "could not free channel %d", bcs->channel); 238 gig_dbg(DEBUG_CHANNEL, "could not free channel %d",
239 bcs->channel);
217 spin_unlock_irqrestore(&bcs->cs->lock, flags); 240 spin_unlock_irqrestore(&bcs->cs->lock, flags);
218 return; 241 return;
219 } 242 }
220 --bcs->use_count; 243 --bcs->use_count;
221 bcs->busy = 0; 244 bcs->busy = 0;
222 module_put(bcs->cs->driver->owner); 245 module_put(bcs->cs->driver->owner);
223 gig_dbg(DEBUG_ANY, "freed channel %d", bcs->channel); 246 gig_dbg(DEBUG_CHANNEL, "freed channel %d", bcs->channel);
224 spin_unlock_irqrestore(&bcs->cs->lock, flags); 247 spin_unlock_irqrestore(&bcs->cs->lock, flags);
225} 248}
226 249
@@ -233,14 +256,15 @@ int gigaset_get_channels(struct cardstate *cs)
233 for (i = 0; i < cs->channels; ++i) 256 for (i = 0; i < cs->channels; ++i)
234 if (cs->bcs[i].use_count) { 257 if (cs->bcs[i].use_count) {
235 spin_unlock_irqrestore(&cs->lock, flags); 258 spin_unlock_irqrestore(&cs->lock, flags);
236 gig_dbg(DEBUG_ANY, "could not allocate all channels"); 259 gig_dbg(DEBUG_CHANNEL,
260 "could not allocate all channels");
237 return 0; 261 return 0;
238 } 262 }
239 for (i = 0; i < cs->channels; ++i) 263 for (i = 0; i < cs->channels; ++i)
240 ++cs->bcs[i].use_count; 264 ++cs->bcs[i].use_count;
241 spin_unlock_irqrestore(&cs->lock, flags); 265 spin_unlock_irqrestore(&cs->lock, flags);
242 266
243 gig_dbg(DEBUG_ANY, "allocated all channels"); 267 gig_dbg(DEBUG_CHANNEL, "allocated all channels");
244 268
245 return 1; 269 return 1;
246} 270}
@@ -250,7 +274,7 @@ void gigaset_free_channels(struct cardstate *cs)
250 unsigned long flags; 274 unsigned long flags;
251 int i; 275 int i;
252 276
253 gig_dbg(DEBUG_ANY, "unblocking all channels"); 277 gig_dbg(DEBUG_CHANNEL, "unblocking all channels");
254 spin_lock_irqsave(&cs->lock, flags); 278 spin_lock_irqsave(&cs->lock, flags);
255 for (i = 0; i < cs->channels; ++i) 279 for (i = 0; i < cs->channels; ++i)
256 --cs->bcs[i].use_count; 280 --cs->bcs[i].use_count;
@@ -262,7 +286,7 @@ void gigaset_block_channels(struct cardstate *cs)
262 unsigned long flags; 286 unsigned long flags;
263 int i; 287 int i;
264 288
265 gig_dbg(DEBUG_ANY, "blocking all channels"); 289 gig_dbg(DEBUG_CHANNEL, "blocking all channels");
266 spin_lock_irqsave(&cs->lock, flags); 290 spin_lock_irqsave(&cs->lock, flags);
267 for (i = 0; i < cs->channels; ++i) 291 for (i = 0; i < cs->channels; ++i)
268 ++cs->bcs[i].use_count; 292 ++cs->bcs[i].use_count;
@@ -313,6 +337,8 @@ struct event_t *gigaset_add_event(struct cardstate *cs,
313 unsigned next, tail; 337 unsigned next, tail;
314 struct event_t *event = NULL; 338 struct event_t *event = NULL;
315 339
340 gig_dbg(DEBUG_EVENT, "queueing event %d", type);
341
316 spin_lock_irqsave(&cs->ev_lock, flags); 342 spin_lock_irqsave(&cs->ev_lock, flags);
317 343
318 tail = cs->ev_tail; 344 tail = cs->ev_tail;
@@ -367,16 +393,15 @@ static void gigaset_freebcs(struct bc_state *bcs)
367 int i; 393 int i;
368 394
369 gig_dbg(DEBUG_INIT, "freeing bcs[%d]->hw", bcs->channel); 395 gig_dbg(DEBUG_INIT, "freeing bcs[%d]->hw", bcs->channel);
370 if (!bcs->cs->ops->freebcshw(bcs)) { 396 if (!bcs->cs->ops->freebcshw(bcs))
371 gig_dbg(DEBUG_INIT, "failed"); 397 gig_dbg(DEBUG_INIT, "failed");
372 }
373 398
374 gig_dbg(DEBUG_INIT, "clearing bcs[%d]->at_state", bcs->channel); 399 gig_dbg(DEBUG_INIT, "clearing bcs[%d]->at_state", bcs->channel);
375 clear_at_state(&bcs->at_state); 400 clear_at_state(&bcs->at_state);
376 gig_dbg(DEBUG_INIT, "freeing bcs[%d]->skb", bcs->channel); 401 gig_dbg(DEBUG_INIT, "freeing bcs[%d]->skb", bcs->channel);
402 dev_kfree_skb(bcs->skb);
403 bcs->skb = NULL;
377 404
378 if (bcs->skb)
379 dev_kfree_skb(bcs->skb);
380 for (i = 0; i < AT_NUM; ++i) { 405 for (i = 0; i < AT_NUM; ++i) {
381 kfree(bcs->commands[i]); 406 kfree(bcs->commands[i]);
382 bcs->commands[i] = NULL; 407 bcs->commands[i] = NULL;
@@ -463,6 +488,12 @@ void gigaset_freecs(struct cardstate *cs)
463 488
464 switch (cs->cs_init) { 489 switch (cs->cs_init) {
465 default: 490 default:
491 /* clear B channel structures */
492 for (i = 0; i < cs->channels; ++i) {
493 gig_dbg(DEBUG_INIT, "clearing bcs[%d]", i);
494 gigaset_freebcs(cs->bcs + i);
495 }
496
466 /* clear device sysfs */ 497 /* clear device sysfs */
467 gigaset_free_dev_sysfs(cs); 498 gigaset_free_dev_sysfs(cs);
468 499
@@ -471,28 +502,20 @@ void gigaset_freecs(struct cardstate *cs)
471 gig_dbg(DEBUG_INIT, "clearing hw"); 502 gig_dbg(DEBUG_INIT, "clearing hw");
472 cs->ops->freecshw(cs); 503 cs->ops->freecshw(cs);
473 504
474 //FIXME cmdbuf
475
476 /* fall through */ 505 /* fall through */
477 case 2: /* error in initcshw */ 506 case 2: /* error in initcshw */
478 /* Deregister from LL */ 507 /* Deregister from LL */
479 make_invalid(cs, VALID_ID); 508 make_invalid(cs, VALID_ID);
480 gig_dbg(DEBUG_INIT, "clearing iif"); 509 gigaset_isdn_unregdev(cs);
481 gigaset_i4l_cmd(cs, ISDN_STAT_UNLOAD);
482 510
483 /* fall through */ 511 /* fall through */
484 case 1: /* error when regestering to LL */ 512 case 1: /* error when registering to LL */
485 gig_dbg(DEBUG_INIT, "clearing at_state"); 513 gig_dbg(DEBUG_INIT, "clearing at_state");
486 clear_at_state(&cs->at_state); 514 clear_at_state(&cs->at_state);
487 dealloc_at_states(cs); 515 dealloc_at_states(cs);
488 516
489 /* fall through */ 517 /* fall through */
490 case 0: /* error in one call to initbcs */ 518 case 0: /* error in basic setup */
491 for (i = 0; i < cs->channels; ++i) {
492 gig_dbg(DEBUG_INIT, "clearing bcs[%d]", i);
493 gigaset_freebcs(cs->bcs + i);
494 }
495
496 clear_events(cs); 519 clear_events(cs);
497 gig_dbg(DEBUG_INIT, "freeing inbuf"); 520 gig_dbg(DEBUG_INIT, "freeing inbuf");
498 kfree(cs->inbuf); 521 kfree(cs->inbuf);
@@ -534,16 +557,13 @@ void gigaset_at_init(struct at_state_t *at_state, struct bc_state *bcs,
534} 557}
535 558
536 559
537static void gigaset_inbuf_init(struct inbuf_t *inbuf, struct bc_state *bcs, 560static void gigaset_inbuf_init(struct inbuf_t *inbuf, struct cardstate *cs)
538 struct cardstate *cs, int inputstate)
539/* inbuf->read must be allocated before! */ 561/* inbuf->read must be allocated before! */
540{ 562{
541 inbuf->head = 0; 563 inbuf->head = 0;
542 inbuf->tail = 0; 564 inbuf->tail = 0;
543 inbuf->cs = cs; 565 inbuf->cs = cs;
544 inbuf->bcs = bcs; /*base driver: NULL*/ 566 inbuf->inputstate = INS_command;
545 inbuf->rcvbuf = NULL;
546 inbuf->inputstate = inputstate;
547} 567}
548 568
549/** 569/**
@@ -599,7 +619,7 @@ static struct bc_state *gigaset_initbcs(struct bc_state *bcs,
599{ 619{
600 int i; 620 int i;
601 621
602 bcs->tx_skb = NULL; //FIXME -> hw part 622 bcs->tx_skb = NULL;
603 623
604 skb_queue_head_init(&bcs->squeue); 624 skb_queue_head_init(&bcs->squeue);
605 625
@@ -618,13 +638,13 @@ static struct bc_state *gigaset_initbcs(struct bc_state *bcs,
618 bcs->fcs = PPP_INITFCS; 638 bcs->fcs = PPP_INITFCS;
619 bcs->inputstate = 0; 639 bcs->inputstate = 0;
620 if (cs->ignoreframes) { 640 if (cs->ignoreframes) {
621 bcs->inputstate |= INS_skip_frame;
622 bcs->skb = NULL; 641 bcs->skb = NULL;
623 } else if ((bcs->skb = dev_alloc_skb(SBUFSIZE + HW_HDR_LEN)) != NULL) 642 } else {
624 skb_reserve(bcs->skb, HW_HDR_LEN); 643 bcs->skb = dev_alloc_skb(SBUFSIZE + cs->hw_hdr_len);
625 else { 644 if (bcs->skb != NULL)
626 pr_err("out of memory\n"); 645 skb_reserve(bcs->skb, cs->hw_hdr_len);
627 bcs->inputstate |= INS_skip_frame; 646 else
647 pr_err("out of memory\n");
628 } 648 }
629 649
630 bcs->channel = channel; 650 bcs->channel = channel;
@@ -645,8 +665,8 @@ static struct bc_state *gigaset_initbcs(struct bc_state *bcs,
645 gig_dbg(DEBUG_INIT, " failed"); 665 gig_dbg(DEBUG_INIT, " failed");
646 666
647 gig_dbg(DEBUG_INIT, " freeing bcs[%d]->skb", channel); 667 gig_dbg(DEBUG_INIT, " freeing bcs[%d]->skb", channel);
648 if (bcs->skb) 668 dev_kfree_skb(bcs->skb);
649 dev_kfree_skb(bcs->skb); 669 bcs->skb = NULL;
650 670
651 return NULL; 671 return NULL;
652} 672}
@@ -673,12 +693,13 @@ struct cardstate *gigaset_initcs(struct gigaset_driver *drv, int channels,
673 int onechannel, int ignoreframes, 693 int onechannel, int ignoreframes,
674 int cidmode, const char *modulename) 694 int cidmode, const char *modulename)
675{ 695{
676 struct cardstate *cs = NULL; 696 struct cardstate *cs;
677 unsigned long flags; 697 unsigned long flags;
678 int i; 698 int i;
679 699
680 gig_dbg(DEBUG_INIT, "allocating cs"); 700 gig_dbg(DEBUG_INIT, "allocating cs");
681 if (!(cs = alloc_cs(drv))) { 701 cs = alloc_cs(drv);
702 if (!cs) {
682 pr_err("maximum number of devices exceeded\n"); 703 pr_err("maximum number of devices exceeded\n");
683 return NULL; 704 return NULL;
684 } 705 }
@@ -707,7 +728,7 @@ struct cardstate *gigaset_initcs(struct gigaset_driver *drv, int channels,
707 cs->ev_tail = 0; 728 cs->ev_tail = 0;
708 cs->ev_head = 0; 729 cs->ev_head = 0;
709 730
710 tasklet_init(&cs->event_tasklet, &gigaset_handle_event, 731 tasklet_init(&cs->event_tasklet, gigaset_handle_event,
711 (unsigned long) cs); 732 (unsigned long) cs);
712 cs->commands_pending = 0; 733 cs->commands_pending = 0;
713 cs->cur_at_seq = 0; 734 cs->cur_at_seq = 0;
@@ -726,14 +747,6 @@ struct cardstate *gigaset_initcs(struct gigaset_driver *drv, int channels,
726 cs->mode = M_UNKNOWN; 747 cs->mode = M_UNKNOWN;
727 cs->mstate = MS_UNINITIALIZED; 748 cs->mstate = MS_UNINITIALIZED;
728 749
729 for (i = 0; i < channels; ++i) {
730 gig_dbg(DEBUG_INIT, "setting up bcs[%d].read", i);
731 if (!gigaset_initbcs(cs->bcs + i, cs, i)) {
732 pr_err("could not allocate channel %d data\n", i);
733 goto error;
734 }
735 }
736
737 ++cs->cs_init; 750 ++cs->cs_init;
738 751
739 gig_dbg(DEBUG_INIT, "setting up at_state"); 752 gig_dbg(DEBUG_INIT, "setting up at_state");
@@ -743,10 +756,7 @@ struct cardstate *gigaset_initcs(struct gigaset_driver *drv, int channels,
743 cs->cbytes = 0; 756 cs->cbytes = 0;
744 757
745 gig_dbg(DEBUG_INIT, "setting up inbuf"); 758 gig_dbg(DEBUG_INIT, "setting up inbuf");
746 if (onechannel) { //FIXME distinction necessary? 759 gigaset_inbuf_init(cs->inbuf, cs);
747 gigaset_inbuf_init(cs->inbuf, cs->bcs, cs, INS_command);
748 } else
749 gigaset_inbuf_init(cs->inbuf, NULL, cs, INS_command);
750 760
751 cs->connected = 0; 761 cs->connected = 0;
752 cs->isdn_up = 0; 762 cs->isdn_up = 0;
@@ -758,7 +768,7 @@ struct cardstate *gigaset_initcs(struct gigaset_driver *drv, int channels,
758 cs->cmdbytes = 0; 768 cs->cmdbytes = 0;
759 769
760 gig_dbg(DEBUG_INIT, "setting up iif"); 770 gig_dbg(DEBUG_INIT, "setting up iif");
761 if (!gigaset_register_to_LL(cs, modulename)) { 771 if (!gigaset_isdn_regdev(cs, modulename)) {
762 pr_err("error registering ISDN device\n"); 772 pr_err("error registering ISDN device\n");
763 goto error; 773 goto error;
764 } 774 }
@@ -777,6 +787,15 @@ struct cardstate *gigaset_initcs(struct gigaset_driver *drv, int channels,
777 /* set up device sysfs */ 787 /* set up device sysfs */
778 gigaset_init_dev_sysfs(cs); 788 gigaset_init_dev_sysfs(cs);
779 789
790 /* set up channel data structures */
791 for (i = 0; i < channels; ++i) {
792 gig_dbg(DEBUG_INIT, "setting up bcs[%d]", i);
793 if (!gigaset_initbcs(cs->bcs + i, cs, i)) {
794 pr_err("could not allocate channel %d data\n", i);
795 goto error;
796 }
797 }
798
780 spin_lock_irqsave(&cs->lock, flags); 799 spin_lock_irqsave(&cs->lock, flags);
781 cs->running = 1; 800 cs->running = 1;
782 spin_unlock_irqrestore(&cs->lock, flags); 801 spin_unlock_irqrestore(&cs->lock, flags);
@@ -824,9 +843,10 @@ void gigaset_bcs_reinit(struct bc_state *bcs)
824 bcs->chstate = 0; 843 bcs->chstate = 0;
825 844
826 bcs->ignore = cs->ignoreframes; 845 bcs->ignore = cs->ignoreframes;
827 if (bcs->ignore) 846 if (bcs->ignore) {
828 bcs->inputstate |= INS_skip_frame; 847 dev_kfree_skb(bcs->skb);
829 848 bcs->skb = NULL;
849 }
830 850
831 cs->ops->reinitbcshw(bcs); 851 cs->ops->reinitbcshw(bcs);
832} 852}
@@ -847,8 +867,6 @@ static void cleanup_cs(struct cardstate *cs)
847 free_strings(&cs->at_state); 867 free_strings(&cs->at_state);
848 gigaset_at_init(&cs->at_state, NULL, cs, 0); 868 gigaset_at_init(&cs->at_state, NULL, cs, 0);
849 869
850 kfree(cs->inbuf->rcvbuf);
851 cs->inbuf->rcvbuf = NULL;
852 cs->inbuf->inputstate = INS_command; 870 cs->inbuf->inputstate = INS_command;
853 cs->inbuf->head = 0; 871 cs->inbuf->head = 0;
854 cs->inbuf->tail = 0; 872 cs->inbuf->tail = 0;
@@ -911,19 +929,14 @@ int gigaset_start(struct cardstate *cs)
911 cs->ops->baud_rate(cs, B115200); 929 cs->ops->baud_rate(cs, B115200);
912 cs->ops->set_line_ctrl(cs, CS8); 930 cs->ops->set_line_ctrl(cs, CS8);
913 cs->control_state = TIOCM_DTR|TIOCM_RTS; 931 cs->control_state = TIOCM_DTR|TIOCM_RTS;
914 } else {
915 //FIXME use some saved values?
916 } 932 }
917 933
918 cs->waiting = 1; 934 cs->waiting = 1;
919 935
920 if (!gigaset_add_event(cs, &cs->at_state, EV_START, NULL, 0, NULL)) { 936 if (!gigaset_add_event(cs, &cs->at_state, EV_START, NULL, 0, NULL)) {
921 cs->waiting = 0; 937 cs->waiting = 0;
922 //FIXME what should we do?
923 goto error; 938 goto error;
924 } 939 }
925
926 gig_dbg(DEBUG_CMD, "scheduling START");
927 gigaset_schedule_event(cs); 940 gigaset_schedule_event(cs);
928 941
929 wait_event(cs->waitqueue, !cs->waiting); 942 wait_event(cs->waitqueue, !cs->waiting);
@@ -958,12 +971,8 @@ int gigaset_shutdown(struct cardstate *cs)
958 971
959 cs->waiting = 1; 972 cs->waiting = 1;
960 973
961 if (!gigaset_add_event(cs, &cs->at_state, EV_SHUTDOWN, NULL, 0, NULL)) { 974 if (!gigaset_add_event(cs, &cs->at_state, EV_SHUTDOWN, NULL, 0, NULL))
962 //FIXME what should we do?
963 goto exit; 975 goto exit;
964 }
965
966 gig_dbg(DEBUG_CMD, "scheduling SHUTDOWN");
967 gigaset_schedule_event(cs); 976 gigaset_schedule_event(cs);
968 977
969 wait_event(cs->waitqueue, !cs->waiting); 978 wait_event(cs->waitqueue, !cs->waiting);
@@ -989,12 +998,8 @@ void gigaset_stop(struct cardstate *cs)
989 998
990 cs->waiting = 1; 999 cs->waiting = 1;
991 1000
992 if (!gigaset_add_event(cs, &cs->at_state, EV_STOP, NULL, 0, NULL)) { 1001 if (!gigaset_add_event(cs, &cs->at_state, EV_STOP, NULL, 0, NULL))
993 //FIXME what should we do?
994 goto exit; 1002 goto exit;
995 }
996
997 gig_dbg(DEBUG_CMD, "scheduling STOP");
998 gigaset_schedule_event(cs); 1003 gigaset_schedule_event(cs);
999 1004
1000 wait_event(cs->waitqueue, !cs->waiting); 1005 wait_event(cs->waitqueue, !cs->waiting);
@@ -1199,11 +1204,13 @@ static int __init gigaset_init_module(void)
1199 gigaset_debuglevel = DEBUG_DEFAULT; 1204 gigaset_debuglevel = DEBUG_DEFAULT;
1200 1205
1201 pr_info(DRIVER_DESC DRIVER_DESC_DEBUG "\n"); 1206 pr_info(DRIVER_DESC DRIVER_DESC_DEBUG "\n");
1207 gigaset_isdn_regdrv();
1202 return 0; 1208 return 0;
1203} 1209}
1204 1210
1205static void __exit gigaset_exit_module(void) 1211static void __exit gigaset_exit_module(void)
1206{ 1212{
1213 gigaset_isdn_unregdrv();
1207} 1214}
1208 1215
1209module_init(gigaset_init_module); 1216module_init(gigaset_init_module);
diff --git a/drivers/isdn/gigaset/dummyll.c b/drivers/isdn/gigaset/dummyll.c
new file mode 100644
index 000000000000..bd0b1eaa7572
--- /dev/null
+++ b/drivers/isdn/gigaset/dummyll.c
@@ -0,0 +1,76 @@
1/*
2 * Dummy LL interface for the Gigaset driver
3 *
4 * Copyright (c) 2009 by Tilman Schmidt <tilman@imap.cc>.
5 *
6 * =====================================================================
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License as
9 * published by the Free Software Foundation; either version 2 of
10 * the License, or (at your option) any later version.
11 * =====================================================================
12 */
13
14#include "gigaset.h"
15
16void gigaset_skb_sent(struct bc_state *bcs, struct sk_buff *skb)
17{
18}
19EXPORT_SYMBOL_GPL(gigaset_skb_sent);
20
21void gigaset_skb_rcvd(struct bc_state *bcs, struct sk_buff *skb)
22{
23}
24EXPORT_SYMBOL_GPL(gigaset_skb_rcvd);
25
26void gigaset_isdn_rcv_err(struct bc_state *bcs)
27{
28}
29EXPORT_SYMBOL_GPL(gigaset_isdn_rcv_err);
30
31int gigaset_isdn_icall(struct at_state_t *at_state)
32{
33 return ICALL_IGNORE;
34}
35
36void gigaset_isdn_connD(struct bc_state *bcs)
37{
38}
39
40void gigaset_isdn_hupD(struct bc_state *bcs)
41{
42}
43
44void gigaset_isdn_connB(struct bc_state *bcs)
45{
46}
47
48void gigaset_isdn_hupB(struct bc_state *bcs)
49{
50}
51
52void gigaset_isdn_start(struct cardstate *cs)
53{
54}
55
56void gigaset_isdn_stop(struct cardstate *cs)
57{
58}
59
60int gigaset_isdn_regdev(struct cardstate *cs, const char *isdnid)
61{
62 return 1;
63}
64
65void gigaset_isdn_unregdev(struct cardstate *cs)
66{
67}
68
69void gigaset_isdn_regdrv(void)
70{
71 pr_info("no ISDN subsystem interface\n");
72}
73
74void gigaset_isdn_unregdrv(void)
75{
76}
diff --git a/drivers/isdn/gigaset/ev-layer.c b/drivers/isdn/gigaset/ev-layer.c
index cc768caa38f5..206c380c5235 100644
--- a/drivers/isdn/gigaset/ev-layer.c
+++ b/drivers/isdn/gigaset/ev-layer.c
@@ -40,8 +40,8 @@
40 40
41/* Possible ASCII responses */ 41/* Possible ASCII responses */
42#define RSP_OK 0 42#define RSP_OK 0
43//#define RSP_BUSY 1 43#define RSP_BUSY 1
44//#define RSP_CONNECT 2 44#define RSP_CONNECT 2
45#define RSP_ZGCI 3 45#define RSP_ZGCI 3
46#define RSP_RING 4 46#define RSP_RING 4
47#define RSP_ZAOC 5 47#define RSP_ZAOC 5
@@ -68,7 +68,6 @@
68#define RSP_ZHLC (RSP_STR + STR_ZHLC) 68#define RSP_ZHLC (RSP_STR + STR_ZHLC)
69#define RSP_ERROR -1 /* ERROR */ 69#define RSP_ERROR -1 /* ERROR */
70#define RSP_WRONG_CID -2 /* unknown cid in cmd */ 70#define RSP_WRONG_CID -2 /* unknown cid in cmd */
71//#define RSP_EMPTY -3
72#define RSP_UNKNOWN -4 /* unknown response */ 71#define RSP_UNKNOWN -4 /* unknown response */
73#define RSP_FAIL -5 /* internal error */ 72#define RSP_FAIL -5 /* internal error */
74#define RSP_INVAL -6 /* invalid response */ 73#define RSP_INVAL -6 /* invalid response */
@@ -76,9 +75,9 @@
76#define RSP_NONE -19 75#define RSP_NONE -19
77#define RSP_STRING -20 76#define RSP_STRING -20
78#define RSP_NULL -21 77#define RSP_NULL -21
79//#define RSP_RETRYFAIL -22 78#define RSP_RETRYFAIL -22
80//#define RSP_RETRY -23 79#define RSP_RETRY -23
81//#define RSP_SKIP -24 80#define RSP_SKIP -24
82#define RSP_INIT -27 81#define RSP_INIT -27
83#define RSP_ANY -26 82#define RSP_ANY -26
84#define RSP_LAST -28 83#define RSP_LAST -28
@@ -127,7 +126,6 @@
127#define ACT_NOTIFY_BC_UP 39 126#define ACT_NOTIFY_BC_UP 39
128#define ACT_DIAL 40 127#define ACT_DIAL 40
129#define ACT_ACCEPT 41 128#define ACT_ACCEPT 41
130#define ACT_PROTO_L2 42
131#define ACT_HUP 43 129#define ACT_HUP 43
132#define ACT_IF_LOCK 44 130#define ACT_IF_LOCK 44
133#define ACT_START 45 131#define ACT_START 45
@@ -159,229 +157,229 @@
159#define SEQ_UMMODE 11 157#define SEQ_UMMODE 11
160 158
161 159
162// 100: init, 200: dle0, 250:dle1, 300: get cid (dial), 350: "hup" (no cid), 400: hup, 500: reset, 600: dial, 700: ring 160/* 100: init, 200: dle0, 250:dle1, 300: get cid (dial), 350: "hup" (no cid),
161 * 400: hup, 500: reset, 600: dial, 700: ring */
163struct reply_t gigaset_tab_nocid[] = 162struct reply_t gigaset_tab_nocid[] =
164{ 163{
165 /* resp_code, min_ConState, max_ConState, parameter, new_ConState, timeout, action, command */ 164/* resp_code, min_ConState, max_ConState, parameter, new_ConState, timeout,
166 165 * action, command */
167 /* initialize device, set cid mode if possible */ 166
168 //{RSP_INIT, -1, -1,100, 900, 0, {ACT_TEST}}, 167/* initialize device, set cid mode if possible */
169 //{RSP_ERROR, 900,900, -1, 0, 0, {ACT_FAILINIT}}, 168{RSP_INIT, -1, -1, SEQ_INIT, 100, 1, {ACT_TIMEOUT} },
170 //{RSP_OK, 900,900, -1, 100, INIT_TIMEOUT, 169
171 // {ACT_TIMEOUT}}, 170{EV_TIMEOUT, 100, 100, -1, 101, 3, {0}, "Z\r"},
172 171{RSP_OK, 101, 103, -1, 120, 5, {ACT_GETSTRING},
173 {RSP_INIT, -1, -1,SEQ_INIT, 100, INIT_TIMEOUT, 172 "+GMR\r"},
174 {ACT_TIMEOUT}}, /* wait until device is ready */ 173
175 174{EV_TIMEOUT, 101, 101, -1, 102, 5, {0}, "Z\r"},
176 {EV_TIMEOUT, 100,100, -1, 101, 3, {0}, "Z\r"}, /* device in transparent mode? try to initialize it. */ 175{RSP_ERROR, 101, 101, -1, 102, 5, {0}, "Z\r"},
177 {RSP_OK, 101,103, -1, 120, 5, {ACT_GETSTRING}, "+GMR\r"}, /* get version */ 176
178 177{EV_TIMEOUT, 102, 102, -1, 108, 5, {ACT_SETDLE1},
179 {EV_TIMEOUT, 101,101, -1, 102, 5, {0}, "Z\r"}, /* timeout => try once again. */ 178 "^SDLE=0\r"},
180 {RSP_ERROR, 101,101, -1, 102, 5, {0}, "Z\r"}, /* error => try once again. */ 179{RSP_OK, 108, 108, -1, 104, -1},
181 180{RSP_ZDLE, 104, 104, 0, 103, 5, {0}, "Z\r"},
182 {EV_TIMEOUT, 102,102, -1, 108, 5, {ACT_SETDLE1}, "^SDLE=0\r"}, /* timeout => try again in DLE mode. */ 181{EV_TIMEOUT, 104, 104, -1, 0, 0, {ACT_FAILINIT} },
183 {RSP_OK, 108,108, -1, 104,-1}, 182{RSP_ERROR, 108, 108, -1, 0, 0, {ACT_FAILINIT} },
184 {RSP_ZDLE, 104,104, 0, 103, 5, {0}, "Z\r"}, 183
185 {EV_TIMEOUT, 104,104, -1, 0, 0, {ACT_FAILINIT}}, 184{EV_TIMEOUT, 108, 108, -1, 105, 2, {ACT_SETDLE0,
186 {RSP_ERROR, 108,108, -1, 0, 0, {ACT_FAILINIT}}, 185 ACT_HUPMODEM,
187 186 ACT_TIMEOUT} },
188 {EV_TIMEOUT, 108,108, -1, 105, 2, {ACT_SETDLE0, 187{EV_TIMEOUT, 105, 105, -1, 103, 5, {0}, "Z\r"},
189 ACT_HUPMODEM, 188
190 ACT_TIMEOUT}}, /* still timeout => connection in unimodem mode? */ 189{RSP_ERROR, 102, 102, -1, 107, 5, {0}, "^GETPRE\r"},
191 {EV_TIMEOUT, 105,105, -1, 103, 5, {0}, "Z\r"}, 190{RSP_OK, 107, 107, -1, 0, 0, {ACT_CONFIGMODE} },
192 191{RSP_ERROR, 107, 107, -1, 0, 0, {ACT_FAILINIT} },
193 {RSP_ERROR, 102,102, -1, 107, 5, {0}, "^GETPRE\r"}, /* ERROR on ATZ => maybe in config mode? */ 192{EV_TIMEOUT, 107, 107, -1, 0, 0, {ACT_FAILINIT} },
194 {RSP_OK, 107,107, -1, 0, 0, {ACT_CONFIGMODE}}, 193
195 {RSP_ERROR, 107,107, -1, 0, 0, {ACT_FAILINIT}}, 194{RSP_ERROR, 103, 103, -1, 0, 0, {ACT_FAILINIT} },
196 {EV_TIMEOUT, 107,107, -1, 0, 0, {ACT_FAILINIT}}, 195{EV_TIMEOUT, 103, 103, -1, 0, 0, {ACT_FAILINIT} },
197 196
198 {RSP_ERROR, 103,103, -1, 0, 0, {ACT_FAILINIT}}, 197{RSP_STRING, 120, 120, -1, 121, -1, {ACT_SETVER} },
199 {EV_TIMEOUT, 103,103, -1, 0, 0, {ACT_FAILINIT}}, 198
200 199{EV_TIMEOUT, 120, 121, -1, 0, 0, {ACT_FAILVER,
201 {RSP_STRING, 120,120, -1, 121,-1, {ACT_SETVER}}, 200 ACT_INIT} },
202 201{RSP_ERROR, 120, 121, -1, 0, 0, {ACT_FAILVER,
203 {EV_TIMEOUT, 120,121, -1, 0, 0, {ACT_FAILVER, ACT_INIT}}, 202 ACT_INIT} },
204 {RSP_ERROR, 120,121, -1, 0, 0, {ACT_FAILVER, ACT_INIT}}, 203{RSP_OK, 121, 121, -1, 0, 0, {ACT_GOTVER,
205 {RSP_OK, 121,121, -1, 0, 0, {ACT_GOTVER, ACT_INIT}}, 204 ACT_INIT} },
206 205
207 /* leave dle mode */ 206/* leave dle mode */
208 {RSP_INIT, 0, 0,SEQ_DLE0, 201, 5, {0}, "^SDLE=0\r"}, 207{RSP_INIT, 0, 0, SEQ_DLE0, 201, 5, {0}, "^SDLE=0\r"},
209 {RSP_OK, 201,201, -1, 202,-1}, 208{RSP_OK, 201, 201, -1, 202, -1},
210 {RSP_ZDLE, 202,202, 0, 0, 0, {ACT_DLE0}}, 209{RSP_ZDLE, 202, 202, 0, 0, 0, {ACT_DLE0} },
211 {RSP_NODEV, 200,249, -1, 0, 0, {ACT_FAKEDLE0}}, 210{RSP_NODEV, 200, 249, -1, 0, 0, {ACT_FAKEDLE0} },
212 {RSP_ERROR, 200,249, -1, 0, 0, {ACT_FAILDLE0}}, 211{RSP_ERROR, 200, 249, -1, 0, 0, {ACT_FAILDLE0} },
213 {EV_TIMEOUT, 200,249, -1, 0, 0, {ACT_FAILDLE0}}, 212{EV_TIMEOUT, 200, 249, -1, 0, 0, {ACT_FAILDLE0} },
214 213
215 /* enter dle mode */ 214/* enter dle mode */
216 {RSP_INIT, 0, 0,SEQ_DLE1, 251, 5, {0}, "^SDLE=1\r"}, 215{RSP_INIT, 0, 0, SEQ_DLE1, 251, 5, {0}, "^SDLE=1\r"},
217 {RSP_OK, 251,251, -1, 252,-1}, 216{RSP_OK, 251, 251, -1, 252, -1},
218 {RSP_ZDLE, 252,252, 1, 0, 0, {ACT_DLE1}}, 217{RSP_ZDLE, 252, 252, 1, 0, 0, {ACT_DLE1} },
219 {RSP_ERROR, 250,299, -1, 0, 0, {ACT_FAILDLE1}}, 218{RSP_ERROR, 250, 299, -1, 0, 0, {ACT_FAILDLE1} },
220 {EV_TIMEOUT, 250,299, -1, 0, 0, {ACT_FAILDLE1}}, 219{EV_TIMEOUT, 250, 299, -1, 0, 0, {ACT_FAILDLE1} },
221 220
222 /* incoming call */ 221/* incoming call */
223 {RSP_RING, -1, -1, -1, -1,-1, {ACT_RING}}, 222{RSP_RING, -1, -1, -1, -1, -1, {ACT_RING} },
224 223
225 /* get cid */ 224/* get cid */
226 //{RSP_INIT, 0, 0,300, 901, 0, {ACT_TEST}}, 225{RSP_INIT, 0, 0, SEQ_CID, 301, 5, {0}, "^SGCI?\r"},
227 //{RSP_ERROR, 901,901, -1, 0, 0, {ACT_FAILCID}}, 226{RSP_OK, 301, 301, -1, 302, -1},
228 //{RSP_OK, 901,901, -1, 301, 5, {0}, "^SGCI?\r"}, 227{RSP_ZGCI, 302, 302, -1, 0, 0, {ACT_CID} },
229 228{RSP_ERROR, 301, 349, -1, 0, 0, {ACT_FAILCID} },
230 {RSP_INIT, 0, 0,SEQ_CID, 301, 5, {0}, "^SGCI?\r"}, 229{EV_TIMEOUT, 301, 349, -1, 0, 0, {ACT_FAILCID} },
231 {RSP_OK, 301,301, -1, 302,-1}, 230
232 {RSP_ZGCI, 302,302, -1, 0, 0, {ACT_CID}}, 231/* enter cid mode */
233 {RSP_ERROR, 301,349, -1, 0, 0, {ACT_FAILCID}}, 232{RSP_INIT, 0, 0, SEQ_CIDMODE, 150, 5, {0}, "^SGCI=1\r"},
234 {EV_TIMEOUT, 301,349, -1, 0, 0, {ACT_FAILCID}}, 233{RSP_OK, 150, 150, -1, 0, 0, {ACT_CMODESET} },
235 234{RSP_ERROR, 150, 150, -1, 0, 0, {ACT_FAILCMODE} },
236 /* enter cid mode */ 235{EV_TIMEOUT, 150, 150, -1, 0, 0, {ACT_FAILCMODE} },
237 {RSP_INIT, 0, 0,SEQ_CIDMODE, 150, 5, {0}, "^SGCI=1\r"}, 236
238 {RSP_OK, 150,150, -1, 0, 0, {ACT_CMODESET}}, 237/* leave cid mode */
239 {RSP_ERROR, 150,150, -1, 0, 0, {ACT_FAILCMODE}}, 238{RSP_INIT, 0, 0, SEQ_UMMODE, 160, 5, {0}, "Z\r"},
240 {EV_TIMEOUT, 150,150, -1, 0, 0, {ACT_FAILCMODE}}, 239{RSP_OK, 160, 160, -1, 0, 0, {ACT_UMODESET} },
241 240{RSP_ERROR, 160, 160, -1, 0, 0, {ACT_FAILUMODE} },
242 /* leave cid mode */ 241{EV_TIMEOUT, 160, 160, -1, 0, 0, {ACT_FAILUMODE} },
243 //{RSP_INIT, 0, 0,SEQ_UMMODE, 160, 5, {0}, "^SGCI=0\r"}, 242
244 {RSP_INIT, 0, 0,SEQ_UMMODE, 160, 5, {0}, "Z\r"}, 243/* abort getting cid */
245 {RSP_OK, 160,160, -1, 0, 0, {ACT_UMODESET}}, 244{RSP_INIT, 0, 0, SEQ_NOCID, 0, 0, {ACT_ABORTCID} },
246 {RSP_ERROR, 160,160, -1, 0, 0, {ACT_FAILUMODE}}, 245
247 {EV_TIMEOUT, 160,160, -1, 0, 0, {ACT_FAILUMODE}}, 246/* reset */
248 247{RSP_INIT, 0, 0, SEQ_SHUTDOWN, 504, 5, {0}, "Z\r"},
249 /* abort getting cid */ 248{RSP_OK, 504, 504, -1, 0, 0, {ACT_SDOWN} },
250 {RSP_INIT, 0, 0,SEQ_NOCID, 0, 0, {ACT_ABORTCID}}, 249{RSP_ERROR, 501, 599, -1, 0, 0, {ACT_FAILSDOWN} },
251 250{EV_TIMEOUT, 501, 599, -1, 0, 0, {ACT_FAILSDOWN} },
252 /* reset */ 251{RSP_NODEV, 501, 599, -1, 0, 0, {ACT_FAKESDOWN} },
253 {RSP_INIT, 0, 0,SEQ_SHUTDOWN, 504, 5, {0}, "Z\r"}, 252
254 {RSP_OK, 504,504, -1, 0, 0, {ACT_SDOWN}}, 253{EV_PROC_CIDMODE, -1, -1, -1, -1, -1, {ACT_PROC_CIDMODE} },
255 {RSP_ERROR, 501,599, -1, 0, 0, {ACT_FAILSDOWN}}, 254{EV_IF_LOCK, -1, -1, -1, -1, -1, {ACT_IF_LOCK} },
256 {EV_TIMEOUT, 501,599, -1, 0, 0, {ACT_FAILSDOWN}}, 255{EV_IF_VER, -1, -1, -1, -1, -1, {ACT_IF_VER} },
257 {RSP_NODEV, 501,599, -1, 0, 0, {ACT_FAKESDOWN}}, 256{EV_START, -1, -1, -1, -1, -1, {ACT_START} },
258 257{EV_STOP, -1, -1, -1, -1, -1, {ACT_STOP} },
259 {EV_PROC_CIDMODE,-1, -1, -1, -1,-1, {ACT_PROC_CIDMODE}}, //FIXME 258{EV_SHUTDOWN, -1, -1, -1, -1, -1, {ACT_SHUTDOWN} },
260 {EV_IF_LOCK, -1, -1, -1, -1,-1, {ACT_IF_LOCK}}, //FIXME 259
261 {EV_IF_VER, -1, -1, -1, -1,-1, {ACT_IF_VER}}, //FIXME 260/* misc. */
262 {EV_START, -1, -1, -1, -1,-1, {ACT_START}}, //FIXME 261{RSP_ERROR, -1, -1, -1, -1, -1, {ACT_ERROR} },
263 {EV_STOP, -1, -1, -1, -1,-1, {ACT_STOP}}, //FIXME 262{RSP_ZCFGT, -1, -1, -1, -1, -1, {ACT_DEBUG} },
264 {EV_SHUTDOWN, -1, -1, -1, -1,-1, {ACT_SHUTDOWN}}, //FIXME 263{RSP_ZCFG, -1, -1, -1, -1, -1, {ACT_DEBUG} },
265 264{RSP_ZLOG, -1, -1, -1, -1, -1, {ACT_DEBUG} },
266 /* misc. */ 265{RSP_ZMWI, -1, -1, -1, -1, -1, {ACT_DEBUG} },
267 {RSP_ERROR, -1, -1, -1, -1, -1, {ACT_ERROR} }, 266{RSP_ZABINFO, -1, -1, -1, -1, -1, {ACT_DEBUG} },
268 {RSP_EMPTY, -1, -1, -1, -1,-1, {ACT_DEBUG}}, //FIXME 267{RSP_ZSMLSTCHG, -1, -1, -1, -1, -1, {ACT_DEBUG} },
269 {RSP_ZCFGT, -1, -1, -1, -1,-1, {ACT_DEBUG}}, //FIXME 268
270 {RSP_ZCFG, -1, -1, -1, -1,-1, {ACT_DEBUG}}, //FIXME 269{RSP_ZCAU, -1, -1, -1, -1, -1, {ACT_ZCAU} },
271 {RSP_ZLOG, -1, -1, -1, -1,-1, {ACT_DEBUG}}, //FIXME 270{RSP_NONE, -1, -1, -1, -1, -1, {ACT_DEBUG} },
272 {RSP_ZMWI, -1, -1, -1, -1,-1, {ACT_DEBUG}}, //FIXME 271{RSP_ANY, -1, -1, -1, -1, -1, {ACT_WARN} },
273 {RSP_ZABINFO, -1, -1, -1, -1,-1, {ACT_DEBUG}}, //FIXME 272{RSP_LAST}
274 {RSP_ZSMLSTCHG,-1, -1, -1, -1,-1, {ACT_DEBUG}}, //FIXME
275
276 {RSP_ZCAU, -1, -1, -1, -1,-1, {ACT_ZCAU}},
277 {RSP_NONE, -1, -1, -1, -1,-1, {ACT_DEBUG}},
278 {RSP_ANY, -1, -1, -1, -1,-1, {ACT_WARN}},
279 {RSP_LAST}
280}; 273};
281 274
282// 600: start dialing, 650: dial in progress, 800: connection is up, 700: ring, 400: hup, 750: accepted icall 275/* 600: start dialing, 650: dial in progress, 800: connection is up, 700: ring,
276 * 400: hup, 750: accepted icall */
283struct reply_t gigaset_tab_cid[] = 277struct reply_t gigaset_tab_cid[] =
284{ 278{
285 /* resp_code, min_ConState, max_ConState, parameter, new_ConState, timeout, action, command */ 279/* resp_code, min_ConState, max_ConState, parameter, new_ConState, timeout,
286 280 * action, command */
287 /* dial */ 281
288 {EV_DIAL, -1, -1, -1, -1,-1, {ACT_DIAL}}, //FIXME 282/* dial */
289 {RSP_INIT, 0, 0,SEQ_DIAL, 601, 5, {ACT_CMD+AT_BC}}, 283{EV_DIAL, -1, -1, -1, -1, -1, {ACT_DIAL} },
290 {RSP_OK, 601,601, -1, 602, 5, {ACT_CMD+AT_HLC}}, 284{RSP_INIT, 0, 0, SEQ_DIAL, 601, 5, {ACT_CMD+AT_BC} },
291 {RSP_NULL, 602,602, -1, 603, 5, {ACT_CMD+AT_PROTO}}, 285{RSP_OK, 601, 601, -1, 602, 5, {ACT_CMD+AT_HLC} },
292 {RSP_OK, 602,602, -1, 603, 5, {ACT_CMD+AT_PROTO}}, 286{RSP_NULL, 602, 602, -1, 603, 5, {ACT_CMD+AT_PROTO} },
293 {RSP_OK, 603,603, -1, 604, 5, {ACT_CMD+AT_TYPE}}, 287{RSP_OK, 602, 602, -1, 603, 5, {ACT_CMD+AT_PROTO} },
294 {RSP_OK, 604,604, -1, 605, 5, {ACT_CMD+AT_MSN}}, 288{RSP_OK, 603, 603, -1, 604, 5, {ACT_CMD+AT_TYPE} },
295 {RSP_OK, 605,605, -1, 606, 5, {ACT_CMD+AT_ISO}}, 289{RSP_OK, 604, 604, -1, 605, 5, {ACT_CMD+AT_MSN} },
296 {RSP_NULL, 605,605, -1, 606, 5, {ACT_CMD+AT_ISO}}, 290{RSP_NULL, 605, 605, -1, 606, 5, {ACT_CMD+AT_CLIP} },
297 {RSP_OK, 606,606, -1, 607, 5, {0}, "+VLS=17\r"}, 291{RSP_OK, 605, 605, -1, 606, 5, {ACT_CMD+AT_CLIP} },
298 {RSP_OK, 607,607, -1, 608,-1}, 292{RSP_NULL, 606, 606, -1, 607, 5, {ACT_CMD+AT_ISO} },
299 {RSP_ZSAU, 608,608,ZSAU_PROCEEDING, 609, 5, {ACT_CMD+AT_DIAL}}, 293{RSP_OK, 606, 606, -1, 607, 5, {ACT_CMD+AT_ISO} },
300 {RSP_OK, 609,609, -1, 650, 0, {ACT_DIALING}}, 294{RSP_OK, 607, 607, -1, 608, 5, {0}, "+VLS=17\r"},
301 295{RSP_OK, 608, 608, -1, 609, -1},
302 {RSP_ERROR, 601,609, -1, 0, 0, {ACT_ABORTDIAL}}, 296{RSP_ZSAU, 609, 609, ZSAU_PROCEEDING, 610, 5, {ACT_CMD+AT_DIAL} },
303 {EV_TIMEOUT, 601,609, -1, 0, 0, {ACT_ABORTDIAL}}, 297{RSP_OK, 610, 610, -1, 650, 0, {ACT_DIALING} },
304 298
305 /* optional dialing responses */ 299{RSP_ERROR, 601, 610, -1, 0, 0, {ACT_ABORTDIAL} },
306 {EV_BC_OPEN, 650,650, -1, 651,-1}, 300{EV_TIMEOUT, 601, 610, -1, 0, 0, {ACT_ABORTDIAL} },
307 {RSP_ZVLS, 608,651, 17, -1,-1, {ACT_DEBUG}}, 301
308 {RSP_ZCTP, 609,651, -1, -1,-1, {ACT_DEBUG}}, 302/* optional dialing responses */
309 {RSP_ZCPN, 609,651, -1, -1,-1, {ACT_DEBUG}}, 303{EV_BC_OPEN, 650, 650, -1, 651, -1},
310 {RSP_ZSAU, 650,651,ZSAU_CALL_DELIVERED, -1,-1, {ACT_DEBUG}}, 304{RSP_ZVLS, 609, 651, 17, -1, -1, {ACT_DEBUG} },
311 305{RSP_ZCTP, 610, 651, -1, -1, -1, {ACT_DEBUG} },
312 /* connect */ 306{RSP_ZCPN, 610, 651, -1, -1, -1, {ACT_DEBUG} },
313 {RSP_ZSAU, 650,650,ZSAU_ACTIVE, 800,-1, {ACT_CONNECT}}, 307{RSP_ZSAU, 650, 651, ZSAU_CALL_DELIVERED, -1, -1, {ACT_DEBUG} },
314 {RSP_ZSAU, 651,651,ZSAU_ACTIVE, 800,-1, {ACT_CONNECT, 308
315 ACT_NOTIFY_BC_UP}}, 309/* connect */
316 {RSP_ZSAU, 750,750,ZSAU_ACTIVE, 800,-1, {ACT_CONNECT}}, 310{RSP_ZSAU, 650, 650, ZSAU_ACTIVE, 800, -1, {ACT_CONNECT} },
317 {RSP_ZSAU, 751,751,ZSAU_ACTIVE, 800,-1, {ACT_CONNECT, 311{RSP_ZSAU, 651, 651, ZSAU_ACTIVE, 800, -1, {ACT_CONNECT,
318 ACT_NOTIFY_BC_UP}}, 312 ACT_NOTIFY_BC_UP} },
319 {EV_BC_OPEN, 800,800, -1, 800,-1, {ACT_NOTIFY_BC_UP}}, 313{RSP_ZSAU, 750, 750, ZSAU_ACTIVE, 800, -1, {ACT_CONNECT} },
320 314{RSP_ZSAU, 751, 751, ZSAU_ACTIVE, 800, -1, {ACT_CONNECT,
321 /* remote hangup */ 315 ACT_NOTIFY_BC_UP} },
322 {RSP_ZSAU, 650,651,ZSAU_DISCONNECT_IND, 0, 0, {ACT_REMOTEREJECT}}, 316{EV_BC_OPEN, 800, 800, -1, 800, -1, {ACT_NOTIFY_BC_UP} },
323 {RSP_ZSAU, 750,751,ZSAU_DISCONNECT_IND, 0, 0, {ACT_REMOTEHUP}}, 317
324 {RSP_ZSAU, 800,800,ZSAU_DISCONNECT_IND, 0, 0, {ACT_REMOTEHUP}}, 318/* remote hangup */
325 319{RSP_ZSAU, 650, 651, ZSAU_DISCONNECT_IND, 0, 0, {ACT_REMOTEREJECT} },
326 /* hangup */ 320{RSP_ZSAU, 750, 751, ZSAU_DISCONNECT_IND, 0, 0, {ACT_REMOTEHUP} },
327 {EV_HUP, -1, -1, -1, -1,-1, {ACT_HUP}}, //FIXME 321{RSP_ZSAU, 800, 800, ZSAU_DISCONNECT_IND, 0, 0, {ACT_REMOTEHUP} },
328 {RSP_INIT, -1, -1,SEQ_HUP, 401, 5, {0}, "+VLS=0\r"}, /* hang up */ //-1,-1? 322
329 {RSP_OK, 401,401, -1, 402, 5}, 323/* hangup */
330 {RSP_ZVLS, 402,402, 0, 403, 5}, 324{EV_HUP, -1, -1, -1, -1, -1, {ACT_HUP} },
331 {RSP_ZSAU, 403, 403, ZSAU_DISCONNECT_REQ, -1, -1, {ACT_DEBUG} }, 325{RSP_INIT, -1, -1, SEQ_HUP, 401, 5, {0}, "+VLS=0\r"},
332 {RSP_ZSAU, 403, 403, ZSAU_NULL, 0, 0, {ACT_DISCONNECT} }, 326{RSP_OK, 401, 401, -1, 402, 5},
333 {RSP_NODEV, 401, 403, -1, 0, 0, {ACT_FAKEHUP} }, 327{RSP_ZVLS, 402, 402, 0, 403, 5},
334 {RSP_ERROR, 401,401, -1, 0, 0, {ACT_ABORTHUP}}, 328{RSP_ZSAU, 403, 403, ZSAU_DISCONNECT_REQ, -1, -1, {ACT_DEBUG} },
335 {EV_TIMEOUT, 401,403, -1, 0, 0, {ACT_ABORTHUP}}, 329{RSP_ZSAU, 403, 403, ZSAU_NULL, 0, 0, {ACT_DISCONNECT} },
336 330{RSP_NODEV, 401, 403, -1, 0, 0, {ACT_FAKEHUP} },
337 {EV_BC_CLOSED, 0, 0, -1, 0,-1, {ACT_NOTIFY_BC_DOWN}}, //FIXME new constate + timeout 331{RSP_ERROR, 401, 401, -1, 0, 0, {ACT_ABORTHUP} },
338 332{EV_TIMEOUT, 401, 403, -1, 0, 0, {ACT_ABORTHUP} },
339 /* ring */ 333
340 {RSP_ZBC, 700,700, -1, -1,-1, {0}}, 334{EV_BC_CLOSED, 0, 0, -1, 0, -1, {ACT_NOTIFY_BC_DOWN} },
341 {RSP_ZHLC, 700,700, -1, -1,-1, {0}}, 335
342 {RSP_NMBR, 700,700, -1, -1,-1, {0}}, 336/* ring */
343 {RSP_ZCPN, 700,700, -1, -1,-1, {0}}, 337{RSP_ZBC, 700, 700, -1, -1, -1, {0} },
344 {RSP_ZCTP, 700,700, -1, -1,-1, {0}}, 338{RSP_ZHLC, 700, 700, -1, -1, -1, {0} },
345 {EV_TIMEOUT, 700,700, -1, 720,720, {ACT_ICALL}}, 339{RSP_NMBR, 700, 700, -1, -1, -1, {0} },
346 {EV_BC_CLOSED,720,720, -1, 0,-1, {ACT_NOTIFY_BC_DOWN}}, 340{RSP_ZCPN, 700, 700, -1, -1, -1, {0} },
347 341{RSP_ZCTP, 700, 700, -1, -1, -1, {0} },
348 /*accept icall*/ 342{EV_TIMEOUT, 700, 700, -1, 720, 720, {ACT_ICALL} },
349 {EV_ACCEPT, -1, -1, -1, -1,-1, {ACT_ACCEPT}}, //FIXME 343{EV_BC_CLOSED, 720, 720, -1, 0, -1, {ACT_NOTIFY_BC_DOWN} },
350 {RSP_INIT, 720,720,SEQ_ACCEPT, 721, 5, {ACT_CMD+AT_PROTO}}, 344
351 {RSP_OK, 721,721, -1, 722, 5, {ACT_CMD+AT_ISO}}, 345/*accept icall*/
352 {RSP_OK, 722,722, -1, 723, 5, {0}, "+VLS=17\r"}, /* set "Endgeraetemodus" */ 346{EV_ACCEPT, -1, -1, -1, -1, -1, {ACT_ACCEPT} },
353 {RSP_OK, 723,723, -1, 724, 5, {0}}, 347{RSP_INIT, 720, 720, SEQ_ACCEPT, 721, 5, {ACT_CMD+AT_PROTO} },
354 {RSP_ZVLS, 724,724, 17, 750,50, {ACT_ACCEPTED}}, 348{RSP_OK, 721, 721, -1, 722, 5, {ACT_CMD+AT_ISO} },
355 {RSP_ERROR, 721,729, -1, 0, 0, {ACT_ABORTACCEPT}}, 349{RSP_OK, 722, 722, -1, 723, 5, {0}, "+VLS=17\r"},
356 {EV_TIMEOUT, 721,729, -1, 0, 0, {ACT_ABORTACCEPT}}, 350{RSP_OK, 723, 723, -1, 724, 5, {0} },
357 {RSP_ZSAU, 700,729,ZSAU_NULL, 0, 0, {ACT_ABORTACCEPT}}, 351{RSP_ZVLS, 724, 724, 17, 750, 50, {ACT_ACCEPTED} },
358 {RSP_ZSAU, 700,729,ZSAU_ACTIVE, 0, 0, {ACT_ABORTACCEPT}}, 352{RSP_ERROR, 721, 729, -1, 0, 0, {ACT_ABORTACCEPT} },
359 {RSP_ZSAU, 700,729,ZSAU_DISCONNECT_IND, 0, 0, {ACT_ABORTACCEPT}}, 353{EV_TIMEOUT, 721, 729, -1, 0, 0, {ACT_ABORTACCEPT} },
360 354{RSP_ZSAU, 700, 729, ZSAU_NULL, 0, 0, {ACT_ABORTACCEPT} },
361 {EV_BC_OPEN, 750,750, -1, 751,-1}, 355{RSP_ZSAU, 700, 729, ZSAU_ACTIVE, 0, 0, {ACT_ABORTACCEPT} },
362 {EV_TIMEOUT, 750,751, -1, 0, 0, {ACT_CONNTIMEOUT}}, 356{RSP_ZSAU, 700, 729, ZSAU_DISCONNECT_IND, 0, 0, {ACT_ABORTACCEPT} },
363 357
364 /* B channel closed (general case) */ 358{EV_BC_OPEN, 750, 750, -1, 751, -1},
365 {EV_BC_CLOSED, -1, -1, -1, -1,-1, {ACT_NOTIFY_BC_DOWN}}, //FIXME 359{EV_TIMEOUT, 750, 751, -1, 0, 0, {ACT_CONNTIMEOUT} },
366 360
367 /* misc. */ 361/* B channel closed (general case) */
368 {EV_PROTO_L2, -1, -1, -1, -1,-1, {ACT_PROTO_L2}}, //FIXME 362{EV_BC_CLOSED, -1, -1, -1, -1, -1, {ACT_NOTIFY_BC_DOWN} },
369 363
370 {RSP_ZCON, -1, -1, -1, -1,-1, {ACT_DEBUG}}, //FIXME 364/* misc. */
371 {RSP_ZCCR, -1, -1, -1, -1,-1, {ACT_DEBUG}}, //FIXME 365{RSP_ZCON, -1, -1, -1, -1, -1, {ACT_DEBUG} },
372 {RSP_ZAOC, -1, -1, -1, -1,-1, {ACT_DEBUG}}, //FIXME 366{RSP_ZCCR, -1, -1, -1, -1, -1, {ACT_DEBUG} },
373 {RSP_ZCSTR, -1, -1, -1, -1,-1, {ACT_DEBUG}}, //FIXME 367{RSP_ZAOC, -1, -1, -1, -1, -1, {ACT_DEBUG} },
374 368{RSP_ZCSTR, -1, -1, -1, -1, -1, {ACT_DEBUG} },
375 {RSP_ZCAU, -1, -1, -1, -1,-1, {ACT_ZCAU}}, 369
376 {RSP_NONE, -1, -1, -1, -1,-1, {ACT_DEBUG}}, 370{RSP_ZCAU, -1, -1, -1, -1, -1, {ACT_ZCAU} },
377 {RSP_ANY, -1, -1, -1, -1,-1, {ACT_WARN}}, 371{RSP_NONE, -1, -1, -1, -1, -1, {ACT_DEBUG} },
378 {RSP_LAST} 372{RSP_ANY, -1, -1, -1, -1, -1, {ACT_WARN} },
373{RSP_LAST}
379}; 374};
380 375
381 376
382static const struct resp_type_t resp_type[] = 377static const struct resp_type_t {
378 unsigned char *response;
379 int resp_code;
380 int type;
381} resp_type[] =
383{ 382{
384 /*{"", RSP_EMPTY, RT_NOTHING},*/
385 {"OK", RSP_OK, RT_NOTHING}, 383 {"OK", RSP_OK, RT_NOTHING},
386 {"ERROR", RSP_ERROR, RT_NOTHING}, 384 {"ERROR", RSP_ERROR, RT_NOTHING},
387 {"ZSAU", RSP_ZSAU, RT_ZSAU}, 385 {"ZSAU", RSP_ZSAU, RT_ZSAU},
@@ -405,7 +403,21 @@ static const struct resp_type_t resp_type[] =
405 {"ZLOG", RSP_ZLOG, RT_NOTHING}, 403 {"ZLOG", RSP_ZLOG, RT_NOTHING},
406 {"ZABINFO", RSP_ZABINFO, RT_NOTHING}, 404 {"ZABINFO", RSP_ZABINFO, RT_NOTHING},
407 {"ZSMLSTCHG", RSP_ZSMLSTCHG, RT_NOTHING}, 405 {"ZSMLSTCHG", RSP_ZSMLSTCHG, RT_NOTHING},
408 {NULL,0,0} 406 {NULL, 0, 0}
407};
408
409static const struct zsau_resp_t {
410 unsigned char *str;
411 int code;
412} zsau_resp[] =
413{
414 {"OUTGOING_CALL_PROCEEDING", ZSAU_OUTGOING_CALL_PROCEEDING},
415 {"CALL_DELIVERED", ZSAU_CALL_DELIVERED},
416 {"ACTIVE", ZSAU_ACTIVE},
417 {"DISCONNECT_IND", ZSAU_DISCONNECT_IND},
418 {"NULL", ZSAU_NULL},
419 {"DISCONNECT_REQ", ZSAU_DISCONNECT_REQ},
420 {NULL, ZSAU_UNKNOWN}
409}; 421};
410 422
411/* 423/*
@@ -415,7 +427,7 @@ static int isdn_getnum(char *p)
415{ 427{
416 int v = -1; 428 int v = -1;
417 429
418 gig_dbg(DEBUG_TRANSCMD, "string: %s", p); 430 gig_dbg(DEBUG_EVENT, "string: %s", p);
419 431
420 while (*p >= '0' && *p <= '9') 432 while (*p >= '0' && *p <= '9')
421 v = ((v < 0) ? 0 : (v * 10)) + (int) ((*p++) - '0'); 433 v = ((v < 0) ? 0 : (v * 10)) + (int) ((*p++) - '0');
@@ -432,7 +444,7 @@ static int isdn_gethex(char *p)
432 int v = 0; 444 int v = 0;
433 int c; 445 int c;
434 446
435 gig_dbg(DEBUG_TRANSCMD, "string: %s", p); 447 gig_dbg(DEBUG_EVENT, "string: %s", p);
436 448
437 if (!*p) 449 if (!*p)
438 return -1; 450 return -1;
@@ -470,7 +482,6 @@ static int cid_of_response(char *s)
470 if (cid < 1 || cid > 65535) 482 if (cid < 1 || cid > 65535)
471 return -1; /* CID out of range */ 483 return -1; /* CID out of range */
472 return cid; 484 return cid;
473 //FIXME is ;<digit>+ at end of non-CID response really impossible?
474} 485}
475 486
476/** 487/**
@@ -487,6 +498,7 @@ void gigaset_handle_modem_response(struct cardstate *cs)
487 int params; 498 int params;
488 int i, j; 499 int i, j;
489 const struct resp_type_t *rt; 500 const struct resp_type_t *rt;
501 const struct zsau_resp_t *zr;
490 int curarg; 502 int curarg;
491 unsigned long flags; 503 unsigned long flags;
492 unsigned next, tail, head; 504 unsigned next, tail, head;
@@ -505,7 +517,6 @@ void gigaset_handle_modem_response(struct cardstate *cs)
505 return; 517 return;
506 } 518 }
507 cs->respdata[len] = 0; 519 cs->respdata[len] = 0;
508 gig_dbg(DEBUG_TRANSCMD, "raw string: '%s'", cs->respdata);
509 argv[0] = cs->respdata; 520 argv[0] = cs->respdata;
510 params = 1; 521 params = 1;
511 if (cs->at_state.getstring) { 522 if (cs->at_state.getstring) {
@@ -540,14 +551,14 @@ void gigaset_handle_modem_response(struct cardstate *cs)
540 for (j = 1; j < params; ++j) 551 for (j = 1; j < params; ++j)
541 argv[j][-1] = 0; 552 argv[j][-1] = 0;
542 553
543 gig_dbg(DEBUG_TRANSCMD, "CMD received: %s", argv[0]); 554 gig_dbg(DEBUG_EVENT, "CMD received: %s", argv[0]);
544 if (cid) { 555 if (cid) {
545 --params; 556 --params;
546 gig_dbg(DEBUG_TRANSCMD, "CID: %s", argv[params]); 557 gig_dbg(DEBUG_EVENT, "CID: %s", argv[params]);
547 } 558 }
548 gig_dbg(DEBUG_TRANSCMD, "available params: %d", params - 1); 559 gig_dbg(DEBUG_EVENT, "available params: %d", params - 1);
549 for (j = 1; j < params; j++) 560 for (j = 1; j < params; j++)
550 gig_dbg(DEBUG_TRANSCMD, "param %d: %s", j, argv[j]); 561 gig_dbg(DEBUG_EVENT, "param %d: %s", j, argv[j]);
551 } 562 }
552 563
553 spin_lock_irqsave(&cs->ev_lock, flags); 564 spin_lock_irqsave(&cs->ev_lock, flags);
@@ -613,24 +624,14 @@ void gigaset_handle_modem_response(struct cardstate *cs)
613 event->parameter = ZSAU_NONE; 624 event->parameter = ZSAU_NONE;
614 break; 625 break;
615 } 626 }
616 if (!strcmp(argv[curarg], "OUTGOING_CALL_PROCEEDING")) 627 for (zr = zsau_resp; zr->str; ++zr)
617 event->parameter = ZSAU_OUTGOING_CALL_PROCEEDING; 628 if (!strcmp(argv[curarg], zr->str))
618 else if (!strcmp(argv[curarg], "CALL_DELIVERED")) 629 break;
619 event->parameter = ZSAU_CALL_DELIVERED; 630 event->parameter = zr->code;
620 else if (!strcmp(argv[curarg], "ACTIVE")) 631 if (!zr->str)
621 event->parameter = ZSAU_ACTIVE;
622 else if (!strcmp(argv[curarg], "DISCONNECT_IND"))
623 event->parameter = ZSAU_DISCONNECT_IND;
624 else if (!strcmp(argv[curarg], "NULL"))
625 event->parameter = ZSAU_NULL;
626 else if (!strcmp(argv[curarg], "DISCONNECT_REQ"))
627 event->parameter = ZSAU_DISCONNECT_REQ;
628 else {
629 event->parameter = ZSAU_UNKNOWN;
630 dev_warn(cs->dev, 632 dev_warn(cs->dev,
631 "%s: unknown parameter %s after ZSAU\n", 633 "%s: unknown parameter %s after ZSAU\n",
632 __func__, argv[curarg]); 634 __func__, argv[curarg]);
633 }
634 ++curarg; 635 ++curarg;
635 break; 636 break;
636 case RT_STRING: 637 case RT_STRING:
@@ -640,7 +641,7 @@ void gigaset_handle_modem_response(struct cardstate *cs)
640 dev_err(cs->dev, "out of memory\n"); 641 dev_err(cs->dev, "out of memory\n");
641 ++curarg; 642 ++curarg;
642 } 643 }
643 gig_dbg(DEBUG_CMD, "string==%s", 644 gig_dbg(DEBUG_EVENT, "string==%s",
644 event->ptr ? (char *) event->ptr : "NULL"); 645 event->ptr ? (char *) event->ptr : "NULL");
645 break; 646 break;
646 case RT_ZCAU: 647 case RT_ZCAU:
@@ -667,7 +668,7 @@ void gigaset_handle_modem_response(struct cardstate *cs)
667 ++curarg; 668 ++curarg;
668 } else 669 } else
669 event->parameter = -1; 670 event->parameter = -1;
670 gig_dbg(DEBUG_CMD, "parameter==%d", event->parameter); 671 gig_dbg(DEBUG_EVENT, "parameter==%d", event->parameter);
671 break; 672 break;
672 } 673 }
673 674
@@ -682,7 +683,7 @@ void gigaset_handle_modem_response(struct cardstate *cs)
682 spin_unlock_irqrestore(&cs->ev_lock, flags); 683 spin_unlock_irqrestore(&cs->ev_lock, flags);
683 684
684 if (curarg != params) 685 if (curarg != params)
685 gig_dbg(DEBUG_ANY, 686 gig_dbg(DEBUG_EVENT,
686 "invalid number of processed parameters: %d/%d", 687 "invalid number of processed parameters: %d/%d",
687 curarg, params); 688 curarg, params);
688} 689}
@@ -703,8 +704,8 @@ static void disconnect(struct at_state_t **at_state_p)
703 /* revert to selected idle mode */ 704 /* revert to selected idle mode */
704 if (!cs->cidmode) { 705 if (!cs->cidmode) {
705 cs->at_state.pending_commands |= PC_UMMODE; 706 cs->at_state.pending_commands |= PC_UMMODE;
707 gig_dbg(DEBUG_EVENT, "Scheduling PC_UMMODE");
706 cs->commands_pending = 1; 708 cs->commands_pending = 1;
707 gig_dbg(DEBUG_CMD, "Scheduling PC_UMMODE");
708 } 709 }
709 spin_unlock_irqrestore(&cs->lock, flags); 710 spin_unlock_irqrestore(&cs->lock, flags);
710 711
@@ -714,7 +715,7 @@ static void disconnect(struct at_state_t **at_state_p)
714 /* notify LL */ 715 /* notify LL */
715 if (bcs->chstate & (CHS_D_UP | CHS_NOTIFY_LL)) { 716 if (bcs->chstate & (CHS_D_UP | CHS_NOTIFY_LL)) {
716 bcs->chstate &= ~(CHS_D_UP | CHS_NOTIFY_LL); 717 bcs->chstate &= ~(CHS_D_UP | CHS_NOTIFY_LL);
717 gigaset_i4l_channel_cmd(bcs, ISDN_STAT_DHUP); 718 gigaset_isdn_hupD(bcs);
718 } 719 }
719 } else { 720 } else {
720 /* no B channel assigned: just deallocate */ 721 /* no B channel assigned: just deallocate */
@@ -782,15 +783,15 @@ static void init_failed(struct cardstate *cs, int mode)
782static void schedule_init(struct cardstate *cs, int state) 783static void schedule_init(struct cardstate *cs, int state)
783{ 784{
784 if (cs->at_state.pending_commands & PC_INIT) { 785 if (cs->at_state.pending_commands & PC_INIT) {
785 gig_dbg(DEBUG_CMD, "not scheduling PC_INIT again"); 786 gig_dbg(DEBUG_EVENT, "not scheduling PC_INIT again");
786 return; 787 return;
787 } 788 }
788 cs->mstate = state; 789 cs->mstate = state;
789 cs->mode = M_UNKNOWN; 790 cs->mode = M_UNKNOWN;
790 gigaset_block_channels(cs); 791 gigaset_block_channels(cs);
791 cs->at_state.pending_commands |= PC_INIT; 792 cs->at_state.pending_commands |= PC_INIT;
793 gig_dbg(DEBUG_EVENT, "Scheduling PC_INIT");
792 cs->commands_pending = 1; 794 cs->commands_pending = 1;
793 gig_dbg(DEBUG_CMD, "Scheduling PC_INIT");
794} 795}
795 796
796/* Add "AT" to a command, add the cid, dle encode it, send the result to the 797/* Add "AT" to a command, add the cid, dle encode it, send the result to the
@@ -872,12 +873,12 @@ static void bchannel_down(struct bc_state *bcs)
872{ 873{
873 if (bcs->chstate & CHS_B_UP) { 874 if (bcs->chstate & CHS_B_UP) {
874 bcs->chstate &= ~CHS_B_UP; 875 bcs->chstate &= ~CHS_B_UP;
875 gigaset_i4l_channel_cmd(bcs, ISDN_STAT_BHUP); 876 gigaset_isdn_hupB(bcs);
876 } 877 }
877 878
878 if (bcs->chstate & (CHS_D_UP | CHS_NOTIFY_LL)) { 879 if (bcs->chstate & (CHS_D_UP | CHS_NOTIFY_LL)) {
879 bcs->chstate &= ~(CHS_D_UP | CHS_NOTIFY_LL); 880 bcs->chstate &= ~(CHS_D_UP | CHS_NOTIFY_LL);
880 gigaset_i4l_channel_cmd(bcs, ISDN_STAT_DHUP); 881 gigaset_isdn_hupD(bcs);
881 } 882 }
882 883
883 gigaset_free_channel(bcs); 884 gigaset_free_channel(bcs);
@@ -894,15 +895,17 @@ static void bchannel_up(struct bc_state *bcs)
894 } 895 }
895 896
896 bcs->chstate |= CHS_B_UP; 897 bcs->chstate |= CHS_B_UP;
897 gigaset_i4l_channel_cmd(bcs, ISDN_STAT_BCONN); 898 gigaset_isdn_connB(bcs);
898} 899}
899 900
900static void start_dial(struct at_state_t *at_state, void *data, unsigned seq_index) 901static void start_dial(struct at_state_t *at_state, void *data,
902 unsigned seq_index)
901{ 903{
902 struct bc_state *bcs = at_state->bcs; 904 struct bc_state *bcs = at_state->bcs;
903 struct cardstate *cs = at_state->cs; 905 struct cardstate *cs = at_state->cs;
904 int retval; 906 char **commands = data;
905 unsigned long flags; 907 unsigned long flags;
908 int i;
906 909
907 bcs->chstate |= CHS_NOTIFY_LL; 910 bcs->chstate |= CHS_NOTIFY_LL;
908 911
@@ -913,19 +916,23 @@ static void start_dial(struct at_state_t *at_state, void *data, unsigned seq_ind
913 } 916 }
914 spin_unlock_irqrestore(&cs->lock, flags); 917 spin_unlock_irqrestore(&cs->lock, flags);
915 918
916 retval = gigaset_isdn_setup_dial(at_state, data); 919 for (i = 0; i < AT_NUM; ++i) {
917 if (retval != 0) 920 kfree(bcs->commands[i]);
918 goto error; 921 bcs->commands[i] = commands[i];
919 922 }
920 923
921 at_state->pending_commands |= PC_CID; 924 at_state->pending_commands |= PC_CID;
922 gig_dbg(DEBUG_CMD, "Scheduling PC_CID"); 925 gig_dbg(DEBUG_EVENT, "Scheduling PC_CID");
923 cs->commands_pending = 1; 926 cs->commands_pending = 1;
924 return; 927 return;
925 928
926error: 929error:
930 for (i = 0; i < AT_NUM; ++i) {
931 kfree(commands[i]);
932 commands[i] = NULL;
933 }
927 at_state->pending_commands |= PC_NOCID; 934 at_state->pending_commands |= PC_NOCID;
928 gig_dbg(DEBUG_CMD, "Scheduling PC_NOCID"); 935 gig_dbg(DEBUG_EVENT, "Scheduling PC_NOCID");
929 cs->commands_pending = 1; 936 cs->commands_pending = 1;
930 return; 937 return;
931} 938}
@@ -933,20 +940,31 @@ error:
933static void start_accept(struct at_state_t *at_state) 940static void start_accept(struct at_state_t *at_state)
934{ 941{
935 struct cardstate *cs = at_state->cs; 942 struct cardstate *cs = at_state->cs;
936 int retval; 943 struct bc_state *bcs = at_state->bcs;
944 int i;
937 945
938 retval = gigaset_isdn_setup_accept(at_state); 946 for (i = 0; i < AT_NUM; ++i) {
947 kfree(bcs->commands[i]);
948 bcs->commands[i] = NULL;
949 }
939 950
940 if (retval == 0) { 951 bcs->commands[AT_PROTO] = kmalloc(9, GFP_ATOMIC);
941 at_state->pending_commands |= PC_ACCEPT; 952 bcs->commands[AT_ISO] = kmalloc(9, GFP_ATOMIC);
942 gig_dbg(DEBUG_CMD, "Scheduling PC_ACCEPT"); 953 if (!bcs->commands[AT_PROTO] || !bcs->commands[AT_ISO]) {
943 cs->commands_pending = 1; 954 dev_err(at_state->cs->dev, "out of memory\n");
944 } else {
945 /* error reset */ 955 /* error reset */
946 at_state->pending_commands |= PC_HUP; 956 at_state->pending_commands |= PC_HUP;
947 gig_dbg(DEBUG_CMD, "Scheduling PC_HUP"); 957 gig_dbg(DEBUG_EVENT, "Scheduling PC_HUP");
948 cs->commands_pending = 1; 958 cs->commands_pending = 1;
959 return;
949 } 960 }
961
962 snprintf(bcs->commands[AT_PROTO], 9, "^SBPR=%u\r", bcs->proto2);
963 snprintf(bcs->commands[AT_ISO], 9, "^SISO=%u\r", bcs->channel + 1);
964
965 at_state->pending_commands |= PC_ACCEPT;
966 gig_dbg(DEBUG_EVENT, "Scheduling PC_ACCEPT");
967 cs->commands_pending = 1;
950} 968}
951 969
952static void do_start(struct cardstate *cs) 970static void do_start(struct cardstate *cs)
@@ -957,9 +975,7 @@ static void do_start(struct cardstate *cs)
957 schedule_init(cs, MS_INIT); 975 schedule_init(cs, MS_INIT);
958 976
959 cs->isdn_up = 1; 977 cs->isdn_up = 1;
960 gigaset_i4l_cmd(cs, ISDN_STAT_RUN); 978 gigaset_isdn_start(cs);
961 // FIXME: not in locked mode
962 // FIXME 2: only after init sequence
963 979
964 cs->waiting = 0; 980 cs->waiting = 0;
965 wake_up(&cs->waitqueue); 981 wake_up(&cs->waitqueue);
@@ -975,7 +991,7 @@ static void finish_shutdown(struct cardstate *cs)
975 /* Tell the LL that the device is not available .. */ 991 /* Tell the LL that the device is not available .. */
976 if (cs->isdn_up) { 992 if (cs->isdn_up) {
977 cs->isdn_up = 0; 993 cs->isdn_up = 0;
978 gigaset_i4l_cmd(cs, ISDN_STAT_STOP); 994 gigaset_isdn_stop(cs);
979 } 995 }
980 996
981 /* The rest is done by cleanup_cs () in user mode. */ 997 /* The rest is done by cleanup_cs () in user mode. */
@@ -992,8 +1008,8 @@ static void do_shutdown(struct cardstate *cs)
992 if (cs->mstate == MS_READY) { 1008 if (cs->mstate == MS_READY) {
993 cs->mstate = MS_SHUTDOWN; 1009 cs->mstate = MS_SHUTDOWN;
994 cs->at_state.pending_commands |= PC_SHUTDOWN; 1010 cs->at_state.pending_commands |= PC_SHUTDOWN;
1011 gig_dbg(DEBUG_EVENT, "Scheduling PC_SHUTDOWN");
995 cs->commands_pending = 1; 1012 cs->commands_pending = 1;
996 gig_dbg(DEBUG_CMD, "Scheduling PC_SHUTDOWN");
997 } else 1013 } else
998 finish_shutdown(cs); 1014 finish_shutdown(cs);
999} 1015}
@@ -1113,7 +1129,6 @@ static int do_lock(struct cardstate *cs)
1113 1129
1114 break; 1130 break;
1115 case MS_LOCKED: 1131 case MS_LOCKED:
1116 //retval = -EACCES;
1117 break; 1132 break;
1118 default: 1133 default:
1119 return -EBUSY; 1134 return -EBUSY;
@@ -1175,8 +1190,8 @@ static void do_action(int action, struct cardstate *cs,
1175 } 1190 }
1176 spin_unlock_irqrestore(&cs->lock, flags); 1191 spin_unlock_irqrestore(&cs->lock, flags);
1177 cs->at_state.pending_commands |= PC_CIDMODE; 1192 cs->at_state.pending_commands |= PC_CIDMODE;
1193 gig_dbg(DEBUG_EVENT, "Scheduling PC_CIDMODE");
1178 cs->commands_pending = 1; 1194 cs->commands_pending = 1;
1179 gig_dbg(DEBUG_CMD, "Scheduling PC_CIDMODE");
1180 break; 1195 break;
1181 case ACT_FAILINIT: 1196 case ACT_FAILINIT:
1182 dev_warn(cs->dev, "Could not initialize the device.\n"); 1197 dev_warn(cs->dev, "Could not initialize the device.\n");
@@ -1243,14 +1258,10 @@ static void do_action(int action, struct cardstate *cs,
1243 * note that bcs may be NULL if no B channel is free 1258 * note that bcs may be NULL if no B channel is free
1244 */ 1259 */
1245 at_state2->ConState = 700; 1260 at_state2->ConState = 700;
1246 kfree(at_state2->str_var[STR_NMBR]); 1261 for (i = 0; i < STR_NUM; ++i) {
1247 at_state2->str_var[STR_NMBR] = NULL; 1262 kfree(at_state2->str_var[i]);
1248 kfree(at_state2->str_var[STR_ZCPN]); 1263 at_state2->str_var[i] = NULL;
1249 at_state2->str_var[STR_ZCPN] = NULL; 1264 }
1250 kfree(at_state2->str_var[STR_ZBC]);
1251 at_state2->str_var[STR_ZBC] = NULL;
1252 kfree(at_state2->str_var[STR_ZHLC]);
1253 at_state2->str_var[STR_ZHLC] = NULL;
1254 at_state2->int_var[VAR_ZCTP] = -1; 1265 at_state2->int_var[VAR_ZCTP] = -1;
1255 1266
1256 spin_lock_irqsave(&cs->lock, flags); 1267 spin_lock_irqsave(&cs->lock, flags);
@@ -1276,7 +1287,7 @@ static void do_action(int action, struct cardstate *cs,
1276 break; 1287 break;
1277 } 1288 }
1278 bcs->chstate |= CHS_D_UP; 1289 bcs->chstate |= CHS_D_UP;
1279 gigaset_i4l_channel_cmd(bcs, ISDN_STAT_DCONN); 1290 gigaset_isdn_connD(bcs);
1280 cs->ops->init_bchannel(bcs); 1291 cs->ops->init_bchannel(bcs);
1281 break; 1292 break;
1282 case ACT_DLE1: 1293 case ACT_DLE1:
@@ -1284,7 +1295,7 @@ static void do_action(int action, struct cardstate *cs,
1284 bcs = cs->bcs + cs->curchannel; 1295 bcs = cs->bcs + cs->curchannel;
1285 1296
1286 bcs->chstate |= CHS_D_UP; 1297 bcs->chstate |= CHS_D_UP;
1287 gigaset_i4l_channel_cmd(bcs, ISDN_STAT_DCONN); 1298 gigaset_isdn_connD(bcs);
1288 cs->ops->init_bchannel(bcs); 1299 cs->ops->init_bchannel(bcs);
1289 break; 1300 break;
1290 case ACT_FAKEHUP: 1301 case ACT_FAKEHUP:
@@ -1369,7 +1380,7 @@ static void do_action(int action, struct cardstate *cs,
1369 cs->cur_at_seq = SEQ_NONE; 1380 cs->cur_at_seq = SEQ_NONE;
1370 break; 1381 break;
1371 1382
1372 case ACT_ABORTACCEPT: /* hangup/error/timeout during ICALL processing */ 1383 case ACT_ABORTACCEPT: /* hangup/error/timeout during ICALL procssng */
1373 disconnect(p_at_state); 1384 disconnect(p_at_state);
1374 break; 1385 break;
1375 1386
@@ -1427,7 +1438,7 @@ static void do_action(int action, struct cardstate *cs,
1427 case ACT_GOTVER: 1438 case ACT_GOTVER:
1428 if (cs->gotfwver == 0) { 1439 if (cs->gotfwver == 0) {
1429 cs->gotfwver = 1; 1440 cs->gotfwver = 1;
1430 gig_dbg(DEBUG_ANY, 1441 gig_dbg(DEBUG_EVENT,
1431 "firmware version %02d.%03d.%02d.%02d", 1442 "firmware version %02d.%03d.%02d.%02d",
1432 cs->fwver[0], cs->fwver[1], 1443 cs->fwver[0], cs->fwver[1],
1433 cs->fwver[2], cs->fwver[3]); 1444 cs->fwver[2], cs->fwver[3]);
@@ -1443,17 +1454,6 @@ static void do_action(int action, struct cardstate *cs,
1443 __func__, at_state->ConState); 1454 __func__, at_state->ConState);
1444 cs->cur_at_seq = SEQ_NONE; 1455 cs->cur_at_seq = SEQ_NONE;
1445 break; 1456 break;
1446#ifdef CONFIG_GIGASET_DEBUG
1447 case ACT_TEST:
1448 {
1449 static int count = 3; //2; //1;
1450 *p_genresp = 1;
1451 *p_resp_code = count ? RSP_ERROR : RSP_OK;
1452 if (count > 0)
1453 --count;
1454 }
1455 break;
1456#endif
1457 case ACT_DEBUG: 1457 case ACT_DEBUG:
1458 gig_dbg(DEBUG_ANY, "%s: resp_code %d in ConState %d", 1458 gig_dbg(DEBUG_ANY, "%s: resp_code %d in ConState %d",
1459 __func__, ev->type, at_state->ConState); 1459 __func__, ev->type, at_state->ConState);
@@ -1474,15 +1474,10 @@ static void do_action(int action, struct cardstate *cs,
1474 case ACT_ACCEPT: 1474 case ACT_ACCEPT:
1475 start_accept(at_state); 1475 start_accept(at_state);
1476 break; 1476 break;
1477 case ACT_PROTO_L2:
1478 gig_dbg(DEBUG_CMD, "set protocol to %u",
1479 (unsigned) ev->parameter);
1480 at_state->bcs->proto2 = ev->parameter;
1481 break;
1482 case ACT_HUP: 1477 case ACT_HUP:
1483 at_state->pending_commands |= PC_HUP; 1478 at_state->pending_commands |= PC_HUP;
1479 gig_dbg(DEBUG_EVENT, "Scheduling PC_HUP");
1484 cs->commands_pending = 1; 1480 cs->commands_pending = 1;
1485 gig_dbg(DEBUG_CMD, "Scheduling PC_HUP");
1486 break; 1481 break;
1487 1482
1488 /* hotplug events */ 1483 /* hotplug events */
@@ -1493,7 +1488,7 @@ static void do_action(int action, struct cardstate *cs,
1493 do_start(cs); 1488 do_start(cs);
1494 break; 1489 break;
1495 1490
1496 /* events from the interface */ // FIXME without ACT_xxxx? 1491 /* events from the interface */
1497 case ACT_IF_LOCK: 1492 case ACT_IF_LOCK:
1498 cs->cmd_result = ev->parameter ? do_lock(cs) : do_unlock(cs); 1493 cs->cmd_result = ev->parameter ? do_lock(cs) : do_unlock(cs);
1499 cs->waiting = 0; 1494 cs->waiting = 0;
@@ -1512,17 +1507,17 @@ static void do_action(int action, struct cardstate *cs,
1512 wake_up(&cs->waitqueue); 1507 wake_up(&cs->waitqueue);
1513 break; 1508 break;
1514 1509
1515 /* events from the proc file system */ // FIXME without ACT_xxxx? 1510 /* events from the proc file system */
1516 case ACT_PROC_CIDMODE: 1511 case ACT_PROC_CIDMODE:
1517 spin_lock_irqsave(&cs->lock, flags); 1512 spin_lock_irqsave(&cs->lock, flags);
1518 if (ev->parameter != cs->cidmode) { 1513 if (ev->parameter != cs->cidmode) {
1519 cs->cidmode = ev->parameter; 1514 cs->cidmode = ev->parameter;
1520 if (ev->parameter) { 1515 if (ev->parameter) {
1521 cs->at_state.pending_commands |= PC_CIDMODE; 1516 cs->at_state.pending_commands |= PC_CIDMODE;
1522 gig_dbg(DEBUG_CMD, "Scheduling PC_CIDMODE"); 1517 gig_dbg(DEBUG_EVENT, "Scheduling PC_CIDMODE");
1523 } else { 1518 } else {
1524 cs->at_state.pending_commands |= PC_UMMODE; 1519 cs->at_state.pending_commands |= PC_UMMODE;
1525 gig_dbg(DEBUG_CMD, "Scheduling PC_UMMODE"); 1520 gig_dbg(DEBUG_EVENT, "Scheduling PC_UMMODE");
1526 } 1521 }
1527 cs->commands_pending = 1; 1522 cs->commands_pending = 1;
1528 } 1523 }
@@ -1573,6 +1568,8 @@ static void process_event(struct cardstate *cs, struct event_t *ev)
1573 if (ev->cid >= 0) { 1568 if (ev->cid >= 0) {
1574 at_state = at_state_from_cid(cs, ev->cid); 1569 at_state = at_state_from_cid(cs, ev->cid);
1575 if (!at_state) { 1570 if (!at_state) {
1571 gig_dbg(DEBUG_EVENT, "event %d for invalid cid %d",
1572 ev->type, ev->cid);
1576 gigaset_add_event(cs, &cs->at_state, RSP_WRONG_CID, 1573 gigaset_add_event(cs, &cs->at_state, RSP_WRONG_CID,
1577 NULL, 0, NULL); 1574 NULL, 0, NULL);
1578 return; 1575 return;
@@ -1580,13 +1577,13 @@ static void process_event(struct cardstate *cs, struct event_t *ev)
1580 } else { 1577 } else {
1581 at_state = ev->at_state; 1578 at_state = ev->at_state;
1582 if (at_state_invalid(cs, at_state)) { 1579 if (at_state_invalid(cs, at_state)) {
1583 gig_dbg(DEBUG_ANY, "event for invalid at_state %p", 1580 gig_dbg(DEBUG_EVENT, "event for invalid at_state %p",
1584 at_state); 1581 at_state);
1585 return; 1582 return;
1586 } 1583 }
1587 } 1584 }
1588 1585
1589 gig_dbg(DEBUG_CMD, "connection state %d, event %d", 1586 gig_dbg(DEBUG_EVENT, "connection state %d, event %d",
1590 at_state->ConState, ev->type); 1587 at_state->ConState, ev->type);
1591 1588
1592 bcs = at_state->bcs; 1589 bcs = at_state->bcs;
@@ -1600,11 +1597,11 @@ static void process_event(struct cardstate *cs, struct event_t *ev)
1600 if (ev->parameter != at_state->timer_index 1597 if (ev->parameter != at_state->timer_index
1601 || !at_state->timer_active) { 1598 || !at_state->timer_active) {
1602 ev->type = RSP_NONE; /* old timeout */ 1599 ev->type = RSP_NONE; /* old timeout */
1603 gig_dbg(DEBUG_ANY, "old timeout"); 1600 gig_dbg(DEBUG_EVENT, "old timeout");
1604 } else if (!at_state->waiting) 1601 } else if (!at_state->waiting)
1605 gig_dbg(DEBUG_ANY, "timeout occurred"); 1602 gig_dbg(DEBUG_EVENT, "timeout occurred");
1606 else 1603 else
1607 gig_dbg(DEBUG_ANY, "stopped waiting"); 1604 gig_dbg(DEBUG_EVENT, "stopped waiting");
1608 } 1605 }
1609 spin_unlock_irqrestore(&cs->lock, flags); 1606 spin_unlock_irqrestore(&cs->lock, flags);
1610 1607
@@ -1649,7 +1646,8 @@ static void process_event(struct cardstate *cs, struct event_t *ev)
1649 for (curact = 0; curact < MAXACT; ++curact) { 1646 for (curact = 0; curact < MAXACT; ++curact) {
1650 /* The row tells us what we should do .. 1647 /* The row tells us what we should do ..
1651 */ 1648 */
1652 do_action(rep->action[curact], cs, bcs, &at_state, &p_command, &genresp, &resp_code, ev); 1649 do_action(rep->action[curact], cs, bcs, &at_state, &p_command,
1650 &genresp, &resp_code, ev);
1653 if (!at_state) 1651 if (!at_state)
1654 break; /* may be freed after disconnect */ 1652 break; /* may be freed after disconnect */
1655 } 1653 }
@@ -1661,13 +1659,14 @@ static void process_event(struct cardstate *cs, struct event_t *ev)
1661 1659
1662 if (genresp) { 1660 if (genresp) {
1663 spin_lock_irqsave(&cs->lock, flags); 1661 spin_lock_irqsave(&cs->lock, flags);
1664 at_state->timer_expires = 0; //FIXME 1662 at_state->timer_expires = 0;
1665 at_state->timer_active = 0; //FIXME 1663 at_state->timer_active = 0;
1666 spin_unlock_irqrestore(&cs->lock, flags); 1664 spin_unlock_irqrestore(&cs->lock, flags);
1667 gigaset_add_event(cs, at_state, resp_code, NULL, 0, NULL); 1665 gigaset_add_event(cs, at_state, resp_code,
1666 NULL, 0, NULL);
1668 } else { 1667 } else {
1669 /* Send command to modem if not NULL... */ 1668 /* Send command to modem if not NULL... */
1670 if (p_command/*rep->command*/) { 1669 if (p_command) {
1671 if (cs->connected) 1670 if (cs->connected)
1672 send_command(cs, p_command, 1671 send_command(cs, p_command,
1673 sendcid, cs->dle, 1672 sendcid, cs->dle,
@@ -1710,11 +1709,11 @@ static void process_command_flags(struct cardstate *cs)
1710 cs->commands_pending = 0; 1709 cs->commands_pending = 0;
1711 1710
1712 if (cs->cur_at_seq) { 1711 if (cs->cur_at_seq) {
1713 gig_dbg(DEBUG_CMD, "not searching scheduled commands: busy"); 1712 gig_dbg(DEBUG_EVENT, "not searching scheduled commands: busy");
1714 return; 1713 return;
1715 } 1714 }
1716 1715
1717 gig_dbg(DEBUG_CMD, "searching scheduled commands"); 1716 gig_dbg(DEBUG_EVENT, "searching scheduled commands");
1718 1717
1719 sequence = SEQ_NONE; 1718 sequence = SEQ_NONE;
1720 1719
@@ -1754,7 +1753,8 @@ static void process_command_flags(struct cardstate *cs)
1754 } 1753 }
1755 } 1754 }
1756 1755
1757 /* only switch back to unimodem mode, if no commands are pending and no channels are up */ 1756 /* only switch back to unimodem mode if no commands are pending and
1757 * no channels are up */
1758 spin_lock_irqsave(&cs->lock, flags); 1758 spin_lock_irqsave(&cs->lock, flags);
1759 if (cs->at_state.pending_commands == PC_UMMODE 1759 if (cs->at_state.pending_commands == PC_UMMODE
1760 && !cs->cidmode 1760 && !cs->cidmode
@@ -1813,9 +1813,8 @@ static void process_command_flags(struct cardstate *cs)
1813 1813
1814 if (cs->at_state.pending_commands & PC_INIT) { 1814 if (cs->at_state.pending_commands & PC_INIT) {
1815 cs->at_state.pending_commands &= ~PC_INIT; 1815 cs->at_state.pending_commands &= ~PC_INIT;
1816 cs->dle = 0; //FIXME 1816 cs->dle = 0;
1817 cs->inbuf->inputstate = INS_command; 1817 cs->inbuf->inputstate = INS_command;
1818 //FIXME reset card state (or -> LOCK0)?
1819 schedule_sequence(cs, &cs->at_state, SEQ_INIT); 1818 schedule_sequence(cs, &cs->at_state, SEQ_INIT);
1820 return; 1819 return;
1821 } 1820 }
@@ -1855,7 +1854,7 @@ static void process_command_flags(struct cardstate *cs)
1855 switch (cs->mode) { 1854 switch (cs->mode) {
1856 case M_UNIMODEM: 1855 case M_UNIMODEM:
1857 cs->at_state.pending_commands |= PC_CIDMODE; 1856 cs->at_state.pending_commands |= PC_CIDMODE;
1858 gig_dbg(DEBUG_CMD, "Scheduling PC_CIDMODE"); 1857 gig_dbg(DEBUG_EVENT, "Scheduling PC_CIDMODE");
1859 cs->commands_pending = 1; 1858 cs->commands_pending = 1;
1860 return; 1859 return;
1861#ifdef GIG_MAYINITONDIAL 1860#ifdef GIG_MAYINITONDIAL
diff --git a/drivers/isdn/gigaset/gigaset.h b/drivers/isdn/gigaset/gigaset.h
index a2f6125739eb..05947f9c1849 100644
--- a/drivers/isdn/gigaset/gigaset.h
+++ b/drivers/isdn/gigaset/gigaset.h
@@ -20,11 +20,12 @@
20#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 20#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
21 21
22#include <linux/kernel.h> 22#include <linux/kernel.h>
23#include <linux/sched.h>
23#include <linux/compiler.h> 24#include <linux/compiler.h>
24#include <linux/types.h> 25#include <linux/types.h>
26#include <linux/ctype.h>
27#include <linux/slab.h>
25#include <linux/spinlock.h> 28#include <linux/spinlock.h>
26#include <linux/isdnif.h>
27#include <linux/usb.h>
28#include <linux/skbuff.h> 29#include <linux/skbuff.h>
29#include <linux/netdevice.h> 30#include <linux/netdevice.h>
30#include <linux/ppp_defs.h> 31#include <linux/ppp_defs.h>
@@ -35,12 +36,11 @@
35#include <linux/list.h> 36#include <linux/list.h>
36#include <asm/atomic.h> 37#include <asm/atomic.h>
37 38
38#define GIG_VERSION {0,5,0,0} 39#define GIG_VERSION {0, 5, 0, 0}
39#define GIG_COMPAT {0,4,0,0} 40#define GIG_COMPAT {0, 4, 0, 0}
40 41
41#define MAX_REC_PARAMS 10 /* Max. number of params in response string */ 42#define MAX_REC_PARAMS 10 /* Max. number of params in response string */
42#define MAX_RESP_SIZE 512 /* Max. size of a response string */ 43#define MAX_RESP_SIZE 511 /* Max. size of a response string */
43#define HW_HDR_LEN 2 /* Header size used to store ack info */
44 44
45#define MAX_EVENTS 64 /* size of event queue */ 45#define MAX_EVENTS 64 /* size of event queue */
46 46
@@ -80,9 +80,10 @@ enum debuglevel {
80 DEBUG_STREAM = 0x00040, /* application data stream I/O events */ 80 DEBUG_STREAM = 0x00040, /* application data stream I/O events */
81 DEBUG_STREAM_DUMP = 0x00080, /* application data stream content */ 81 DEBUG_STREAM_DUMP = 0x00080, /* application data stream content */
82 DEBUG_LLDATA = 0x00100, /* sent/received LL data */ 82 DEBUG_LLDATA = 0x00100, /* sent/received LL data */
83 DEBUG_EVENT = 0x00200, /* event processing */
83 DEBUG_DRIVER = 0x00400, /* driver structure */ 84 DEBUG_DRIVER = 0x00400, /* driver structure */
84 DEBUG_HDLC = 0x00800, /* M10x HDLC processing */ 85 DEBUG_HDLC = 0x00800, /* M10x HDLC processing */
85 DEBUG_WRITE = 0x01000, /* M105 data write */ 86 DEBUG_CHANNEL = 0x01000, /* channel allocation/deallocation */
86 DEBUG_TRANSCMD = 0x02000, /* AT-COMMANDS+RESPONSES */ 87 DEBUG_TRANSCMD = 0x02000, /* AT-COMMANDS+RESPONSES */
87 DEBUG_MCMD = 0x04000, /* COMMANDS THAT ARE SENT VERY OFTEN */ 88 DEBUG_MCMD = 0x04000, /* COMMANDS THAT ARE SENT VERY OFTEN */
88 DEBUG_INIT = 0x08000, /* (de)allocation+initialization of data 89 DEBUG_INIT = 0x08000, /* (de)allocation+initialization of data
@@ -135,35 +136,32 @@ void gigaset_dbg_buffer(enum debuglevel level, const unsigned char *msg,
135#define OUT_VENDOR_REQ (USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_ENDPOINT) 136#define OUT_VENDOR_REQ (USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_ENDPOINT)
136#define IN_VENDOR_REQ (USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_ENDPOINT) 137#define IN_VENDOR_REQ (USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_ENDPOINT)
137 138
138/* int-in-events 3070 */ 139/* interrupt pipe messages */
139#define HD_B1_FLOW_CONTROL 0x80 140#define HD_B1_FLOW_CONTROL 0x80
140#define HD_B2_FLOW_CONTROL 0x81 141#define HD_B2_FLOW_CONTROL 0x81
141#define HD_RECEIVEATDATA_ACK (0x35) // 3070 142#define HD_RECEIVEATDATA_ACK (0x35) /* 3070 */
142 // att: HD_RECEIVE>>AT<<DATA_ACK 143#define HD_READY_SEND_ATDATA (0x36) /* 3070 */
143#define HD_READY_SEND_ATDATA (0x36) // 3070 144#define HD_OPEN_ATCHANNEL_ACK (0x37) /* 3070 */
144#define HD_OPEN_ATCHANNEL_ACK (0x37) // 3070 145#define HD_CLOSE_ATCHANNEL_ACK (0x38) /* 3070 */
145#define HD_CLOSE_ATCHANNEL_ACK (0x38) // 3070 146#define HD_DEVICE_INIT_OK (0x11) /* ISurf USB + 3070 */
146#define HD_DEVICE_INIT_OK (0x11) // ISurf USB + 3070 147#define HD_OPEN_B1CHANNEL_ACK (0x51) /* ISurf USB + 3070 */
147#define HD_OPEN_B1CHANNEL_ACK (0x51) // ISurf USB + 3070 148#define HD_OPEN_B2CHANNEL_ACK (0x52) /* ISurf USB + 3070 */
148#define HD_OPEN_B2CHANNEL_ACK (0x52) // ISurf USB + 3070 149#define HD_CLOSE_B1CHANNEL_ACK (0x53) /* ISurf USB + 3070 */
149#define HD_CLOSE_B1CHANNEL_ACK (0x53) // ISurf USB + 3070 150#define HD_CLOSE_B2CHANNEL_ACK (0x54) /* ISurf USB + 3070 */
150#define HD_CLOSE_B2CHANNEL_ACK (0x54) // ISurf USB + 3070 151#define HD_SUSPEND_END (0x61) /* ISurf USB */
151// Powermangment 152#define HD_RESET_INTERRUPT_PIPE_ACK (0xFF) /* ISurf USB + 3070 */
152#define HD_SUSPEND_END (0x61) // ISurf USB 153
153// Configuration 154/* control requests */
154#define HD_RESET_INTERRUPT_PIPE_ACK (0xFF) // ISurf USB + 3070 155#define HD_OPEN_B1CHANNEL (0x23) /* ISurf USB + 3070 */
155 156#define HD_CLOSE_B1CHANNEL (0x24) /* ISurf USB + 3070 */
156/* control requests 3070 */ 157#define HD_OPEN_B2CHANNEL (0x25) /* ISurf USB + 3070 */
157#define HD_OPEN_B1CHANNEL (0x23) // ISurf USB + 3070 158#define HD_CLOSE_B2CHANNEL (0x26) /* ISurf USB + 3070 */
158#define HD_CLOSE_B1CHANNEL (0x24) // ISurf USB + 3070 159#define HD_RESET_INTERRUPT_PIPE (0x27) /* ISurf USB + 3070 */
159#define HD_OPEN_B2CHANNEL (0x25) // ISurf USB + 3070 160#define HD_DEVICE_INIT_ACK (0x34) /* ISurf USB + 3070 */
160#define HD_CLOSE_B2CHANNEL (0x26) // ISurf USB + 3070 161#define HD_WRITE_ATMESSAGE (0x12) /* 3070 */
161#define HD_RESET_INTERRUPT_PIPE (0x27) // ISurf USB + 3070 162#define HD_READ_ATMESSAGE (0x13) /* 3070 */
162#define HD_DEVICE_INIT_ACK (0x34) // ISurf USB + 3070 163#define HD_OPEN_ATCHANNEL (0x28) /* 3070 */
163#define HD_WRITE_ATMESSAGE (0x12) // 3070 164#define HD_CLOSE_ATCHANNEL (0x29) /* 3070 */
164#define HD_READ_ATMESSAGE (0x13) // 3070
165#define HD_OPEN_ATCHANNEL (0x28) // 3070
166#define HD_CLOSE_ATCHANNEL (0x29) // 3070
167 165
168/* number of B channels supported by base driver */ 166/* number of B channels supported by base driver */
169#define BAS_CHANNELS 2 167#define BAS_CHANNELS 2
@@ -193,7 +191,9 @@ void gigaset_dbg_buffer(enum debuglevel level, const unsigned char *msg,
193#define AT_PROTO 4 191#define AT_PROTO 4
194#define AT_TYPE 5 192#define AT_TYPE 5
195#define AT_HLC 6 193#define AT_HLC 6
196#define AT_NUM 7 194#define AT_CLIP 7
195/* total number */
196#define AT_NUM 8
197 197
198/* variables in struct at_state_t */ 198/* variables in struct at_state_t */
199#define VAR_ZSAU 0 199#define VAR_ZSAU 0
@@ -216,7 +216,6 @@ void gigaset_dbg_buffer(enum debuglevel level, const unsigned char *msg,
216#define EV_START -110 216#define EV_START -110
217#define EV_STOP -111 217#define EV_STOP -111
218#define EV_IF_LOCK -112 218#define EV_IF_LOCK -112
219#define EV_PROTO_L2 -113
220#define EV_ACCEPT -114 219#define EV_ACCEPT -114
221#define EV_DIAL -115 220#define EV_DIAL -115
222#define EV_HUP -116 221#define EV_HUP -116
@@ -224,12 +223,11 @@ void gigaset_dbg_buffer(enum debuglevel level, const unsigned char *msg,
224#define EV_BC_CLOSED -118 223#define EV_BC_CLOSED -118
225 224
226/* input state */ 225/* input state */
227#define INS_command 0x0001 226#define INS_command 0x0001 /* receiving messages (not payload data) */
228#define INS_DLE_char 0x0002 227#define INS_DLE_char 0x0002 /* DLE flag received (in DLE mode) */
229#define INS_byte_stuff 0x0004 228#define INS_byte_stuff 0x0004
230#define INS_have_data 0x0008 229#define INS_have_data 0x0008
231#define INS_skip_frame 0x0010 230#define INS_DLE_command 0x0020 /* DLE message start (<DLE> X) received */
232#define INS_DLE_command 0x0020
233#define INS_flag_hunt 0x0040 231#define INS_flag_hunt 0x0040
234 232
235/* channel state */ 233/* channel state */
@@ -259,6 +257,11 @@ void gigaset_dbg_buffer(enum debuglevel level, const unsigned char *msg,
259#define SM_LOCKED 0 257#define SM_LOCKED 0
260#define SM_ISDN 1 /* default */ 258#define SM_ISDN 1 /* default */
261 259
260/* layer 2 protocols (AT^SBPR=...) */
261#define L2_BITSYNC 0
262#define L2_HDLC 1
263#define L2_VOICE 2
264
262struct gigaset_ops; 265struct gigaset_ops;
263struct gigaset_driver; 266struct gigaset_driver;
264 267
@@ -286,8 +289,6 @@ extern struct reply_t gigaset_tab_cid[];
286extern struct reply_t gigaset_tab_nocid[]; 289extern struct reply_t gigaset_tab_nocid[];
287 290
288struct inbuf_t { 291struct inbuf_t {
289 unsigned char *rcvbuf; /* usb-gigaset receive buffer */
290 struct bc_state *bcs;
291 struct cardstate *cs; 292 struct cardstate *cs;
292 int inputstate; 293 int inputstate;
293 int head, tail; 294 int head, tail;
@@ -359,12 +360,6 @@ struct at_state_t {
359 struct bc_state *bcs; 360 struct bc_state *bcs;
360}; 361};
361 362
362struct resp_type_t {
363 unsigned char *response;
364 int resp_code; /* RSP_XXXX */
365 int type; /* RT_XXXX */
366};
367
368struct event_t { 363struct event_t {
369 int type; 364 int type;
370 void *ptr, *arg; 365 void *ptr, *arg;
@@ -395,7 +390,7 @@ struct bc_state {
395 390
396 unsigned chstate; /* bitmap (CHS_*) */ 391 unsigned chstate; /* bitmap (CHS_*) */
397 int ignore; 392 int ignore;
398 unsigned proto2; /* Layer 2 protocol (ISDN_PROTO_L2_*) */ 393 unsigned proto2; /* layer 2 protocol (L2_*) */
399 char *commands[AT_NUM]; /* see AT_XXXX */ 394 char *commands[AT_NUM]; /* see AT_XXXX */
400 395
401#ifdef CONFIG_GIGASET_DEBUG 396#ifdef CONFIG_GIGASET_DEBUG
@@ -410,6 +405,8 @@ struct bc_state {
410 struct usb_bc_state *usb; /* usb hardware driver (m105) */ 405 struct usb_bc_state *usb; /* usb hardware driver (m105) */
411 struct bas_bc_state *bas; /* usb hardware driver (base) */ 406 struct bas_bc_state *bas; /* usb hardware driver (base) */
412 } hw; 407 } hw;
408
409 void *ap; /* LL application structure */
413}; 410};
414 411
415struct cardstate { 412struct cardstate {
@@ -456,12 +453,13 @@ struct cardstate {
456 453
457 unsigned running; /* !=0 if events are handled */ 454 unsigned running; /* !=0 if events are handled */
458 unsigned connected; /* !=0 if hardware is connected */ 455 unsigned connected; /* !=0 if hardware is connected */
459 unsigned isdn_up; /* !=0 after ISDN_STAT_RUN */ 456 unsigned isdn_up; /* !=0 after gigaset_isdn_start() */
460 457
461 unsigned cidmode; 458 unsigned cidmode;
462 459
463 int myid; /* id for communication with LL */ 460 int myid; /* id for communication with LL */
464 isdn_if iif; 461 void *iif; /* LL interface structure */
462 unsigned short hw_hdr_len; /* headroom needed in data skbs */
465 463
466 struct reply_t *tabnocid; 464 struct reply_t *tabnocid;
467 struct reply_t *tabcid; 465 struct reply_t *tabcid;
@@ -476,8 +474,8 @@ struct cardstate {
476 474
477 struct timer_list timer; 475 struct timer_list timer;
478 int retry_count; 476 int retry_count;
479 int dle; /* !=0 if modem commands/responses are 477 int dle; /* !=0 if DLE mode is active
480 dle encoded */ 478 (ZDLE=1 received -- M10x only) */
481 int cur_at_seq; /* sequence of AT commands being 479 int cur_at_seq; /* sequence of AT commands being
482 processed */ 480 processed */
483 int curchannel; /* channel those commands are meant 481 int curchannel; /* channel those commands are meant
@@ -503,7 +501,7 @@ struct cardstate {
503 spinlock_t ev_lock; 501 spinlock_t ev_lock;
504 502
505 /* current modem response */ 503 /* current modem response */
506 unsigned char respdata[MAX_RESP_SIZE]; 504 unsigned char respdata[MAX_RESP_SIZE+1];
507 unsigned cbytes; 505 unsigned cbytes;
508 506
509 /* private data of hardware drivers */ 507 /* private data of hardware drivers */
@@ -616,7 +614,9 @@ struct gigaset_ops {
616 int (*baud_rate)(struct cardstate *cs, unsigned cflag); 614 int (*baud_rate)(struct cardstate *cs, unsigned cflag);
617 int (*set_line_ctrl)(struct cardstate *cs, unsigned cflag); 615 int (*set_line_ctrl)(struct cardstate *cs, unsigned cflag);
618 616
619 /* Called from i4l.c to put an skb into the send-queue. */ 617 /* Called from LL interface to put an skb into the send-queue.
618 * After sending is completed, gigaset_skb_sent() must be called
619 * with the skb's link layer header preserved. */
620 int (*send_skb)(struct bc_state *bcs, struct sk_buff *skb); 620 int (*send_skb)(struct bc_state *bcs, struct sk_buff *skb);
621 621
622 /* Called from ev-layer.c to process a block of data 622 /* Called from ev-layer.c to process a block of data
@@ -625,7 +625,8 @@ struct gigaset_ops {
625 625
626}; 626};
627 627
628/* = Common structures and definitions ======================================= */ 628/* = Common structures and definitions =======================================
629 */
629 630
630/* Parser states for DLE-Event: 631/* Parser states for DLE-Event:
631 * <DLE-EVENT>: <DLE_FLAG> "X" <EVENT> <DLE_FLAG> "." 632 * <DLE-EVENT>: <DLE_FLAG> "X" <EVENT> <DLE_FLAG> "."
@@ -638,8 +639,7 @@ struct gigaset_ops {
638 * Functions implemented in asyncdata.c 639 * Functions implemented in asyncdata.c
639 */ 640 */
640 641
641/* Called from i4l.c to put an skb into the send-queue. 642/* Called from LL interface to put an skb into the send queue. */
642 * After sending gigaset_skb_sent() should be called. */
643int gigaset_m10x_send_skb(struct bc_state *bcs, struct sk_buff *skb); 643int gigaset_m10x_send_skb(struct bc_state *bcs, struct sk_buff *skb);
644 644
645/* Called from ev-layer.c to process a block of data 645/* Called from ev-layer.c to process a block of data
@@ -650,8 +650,7 @@ void gigaset_m10x_input(struct inbuf_t *inbuf);
650 * Functions implemented in isocdata.c 650 * Functions implemented in isocdata.c
651 */ 651 */
652 652
653/* Called from i4l.c to put an skb into the send-queue. 653/* Called from LL interface to put an skb into the send queue. */
654 * After sending gigaset_skb_sent() should be called. */
655int gigaset_isoc_send_skb(struct bc_state *bcs, struct sk_buff *skb); 654int gigaset_isoc_send_skb(struct bc_state *bcs, struct sk_buff *skb);
656 655
657/* Called from ev-layer.c to process a block of data 656/* Called from ev-layer.c to process a block of data
@@ -674,36 +673,28 @@ void gigaset_isowbuf_init(struct isowbuf_t *iwb, unsigned char idle);
674int gigaset_isowbuf_getbytes(struct isowbuf_t *iwb, int size); 673int gigaset_isowbuf_getbytes(struct isowbuf_t *iwb, int size);
675 674
676/* =========================================================================== 675/* ===========================================================================
677 * Functions implemented in i4l.c/gigaset.h 676 * Functions implemented in LL interface
678 */ 677 */
679 678
680/* Called by gigaset_initcs() for setting up with the isdn4linux subsystem */ 679/* Called from common.c for setting up/shutting down with the ISDN subsystem */
681int gigaset_register_to_LL(struct cardstate *cs, const char *isdnid); 680void gigaset_isdn_regdrv(void);
681void gigaset_isdn_unregdrv(void);
682int gigaset_isdn_regdev(struct cardstate *cs, const char *isdnid);
683void gigaset_isdn_unregdev(struct cardstate *cs);
682 684
683/* Called from xxx-gigaset.c to indicate completion of sending an skb */ 685/* Called from hardware module to indicate completion of an skb */
684void gigaset_skb_sent(struct bc_state *bcs, struct sk_buff *skb); 686void gigaset_skb_sent(struct bc_state *bcs, struct sk_buff *skb);
687void gigaset_skb_rcvd(struct bc_state *bcs, struct sk_buff *skb);
688void gigaset_isdn_rcv_err(struct bc_state *bcs);
685 689
686/* Called from common.c/ev-layer.c to indicate events relevant to the LL */ 690/* Called from common.c/ev-layer.c to indicate events relevant to the LL */
691void gigaset_isdn_start(struct cardstate *cs);
692void gigaset_isdn_stop(struct cardstate *cs);
687int gigaset_isdn_icall(struct at_state_t *at_state); 693int gigaset_isdn_icall(struct at_state_t *at_state);
688int gigaset_isdn_setup_accept(struct at_state_t *at_state); 694void gigaset_isdn_connD(struct bc_state *bcs);
689int gigaset_isdn_setup_dial(struct at_state_t *at_state, void *data); 695void gigaset_isdn_hupD(struct bc_state *bcs);
690 696void gigaset_isdn_connB(struct bc_state *bcs);
691void gigaset_i4l_cmd(struct cardstate *cs, int cmd); 697void gigaset_isdn_hupB(struct bc_state *bcs);
692void gigaset_i4l_channel_cmd(struct bc_state *bcs, int cmd);
693
694
695static inline void gigaset_isdn_rcv_err(struct bc_state *bcs)
696{
697 isdn_ctrl response;
698
699 /* error -> LL */
700 gig_dbg(DEBUG_CMD, "sending L1ERR");
701 response.driver = bcs->cs->myid;
702 response.command = ISDN_STAT_L1ERR;
703 response.arg = bcs->channel;
704 response.parm.errcode = ISDN_STAT_L1ERR_RECV;
705 bcs->cs->iif.statcallb(&response);
706}
707 698
708/* =========================================================================== 699/* ===========================================================================
709 * Functions implemented in ev-layer.c 700 * Functions implemented in ev-layer.c
@@ -732,6 +723,7 @@ void gigaset_bcs_reinit(struct bc_state *bcs);
732void gigaset_at_init(struct at_state_t *at_state, struct bc_state *bcs, 723void gigaset_at_init(struct at_state_t *at_state, struct bc_state *bcs,
733 struct cardstate *cs, int cid); 724 struct cardstate *cs, int cid);
734int gigaset_get_channel(struct bc_state *bcs); 725int gigaset_get_channel(struct bc_state *bcs);
726struct bc_state *gigaset_get_free_channel(struct cardstate *cs);
735void gigaset_free_channel(struct bc_state *bcs); 727void gigaset_free_channel(struct bc_state *bcs);
736int gigaset_get_channels(struct cardstate *cs); 728int gigaset_get_channels(struct cardstate *cs);
737void gigaset_free_channels(struct cardstate *cs); 729void gigaset_free_channels(struct cardstate *cs);
@@ -781,7 +773,7 @@ struct event_t *gigaset_add_event(struct cardstate *cs,
781 void *ptr, int parameter, void *arg); 773 void *ptr, int parameter, void *arg);
782 774
783/* Called on CONFIG1 command from frontend. */ 775/* Called on CONFIG1 command from frontend. */
784int gigaset_enterconfigmode(struct cardstate *cs); //0: success <0: errorcode 776int gigaset_enterconfigmode(struct cardstate *cs);
785 777
786/* cs->lock must not be locked */ 778/* cs->lock must not be locked */
787static inline void gigaset_schedule_event(struct cardstate *cs) 779static inline void gigaset_schedule_event(struct cardstate *cs)
@@ -798,8 +790,6 @@ static inline void gigaset_schedule_event(struct cardstate *cs)
798static inline void gigaset_bchannel_down(struct bc_state *bcs) 790static inline void gigaset_bchannel_down(struct bc_state *bcs)
799{ 791{
800 gigaset_add_event(bcs->cs, &bcs->at_state, EV_BC_CLOSED, NULL, 0, NULL); 792 gigaset_add_event(bcs->cs, &bcs->at_state, EV_BC_CLOSED, NULL, 0, NULL);
801
802 gig_dbg(DEBUG_CMD, "scheduling BC_CLOSED");
803 gigaset_schedule_event(bcs->cs); 793 gigaset_schedule_event(bcs->cs);
804} 794}
805 795
@@ -808,43 +798,12 @@ static inline void gigaset_bchannel_down(struct bc_state *bcs)
808static inline void gigaset_bchannel_up(struct bc_state *bcs) 798static inline void gigaset_bchannel_up(struct bc_state *bcs)
809{ 799{
810 gigaset_add_event(bcs->cs, &bcs->at_state, EV_BC_OPEN, NULL, 0, NULL); 800 gigaset_add_event(bcs->cs, &bcs->at_state, EV_BC_OPEN, NULL, 0, NULL);
811
812 gig_dbg(DEBUG_CMD, "scheduling BC_OPEN");
813 gigaset_schedule_event(bcs->cs); 801 gigaset_schedule_event(bcs->cs);
814} 802}
815 803
816/* handling routines for sk_buff */ 804/* handling routines for sk_buff */
817/* ============================= */ 805/* ============================= */
818 806
819/* pass received skb to LL
820 * Warning: skb must not be accessed anymore!
821 */
822static inline void gigaset_rcv_skb(struct sk_buff *skb,
823 struct cardstate *cs,
824 struct bc_state *bcs)
825{
826 cs->iif.rcvcallb_skb(cs->myid, bcs->channel, skb);
827 bcs->trans_down++;
828}
829
830/* handle reception of corrupted skb
831 * Warning: skb must not be accessed anymore!
832 */
833static inline void gigaset_rcv_error(struct sk_buff *procskb,
834 struct cardstate *cs,
835 struct bc_state *bcs)
836{
837 if (procskb)
838 dev_kfree_skb(procskb);
839
840 if (bcs->ignore)
841 --bcs->ignore;
842 else {
843 ++bcs->corrupted;
844 gigaset_isdn_rcv_err(bcs);
845 }
846}
847
848/* append received bytes to inbuf */ 807/* append received bytes to inbuf */
849int gigaset_fill_inbuf(struct inbuf_t *inbuf, const unsigned char *src, 808int gigaset_fill_inbuf(struct inbuf_t *inbuf, const unsigned char *src,
850 unsigned numbytes); 809 unsigned numbytes);
diff --git a/drivers/isdn/gigaset/i4l.c b/drivers/isdn/gigaset/i4l.c
index 654489d836cd..c22e5ace8276 100644
--- a/drivers/isdn/gigaset/i4l.c
+++ b/drivers/isdn/gigaset/i4l.c
@@ -14,6 +14,9 @@
14 */ 14 */
15 15
16#include "gigaset.h" 16#include "gigaset.h"
17#include <linux/isdnif.h>
18
19#define HW_HDR_LEN 2 /* Header size used to store ack info */
17 20
18/* == Handling of I4L IO =====================================================*/ 21/* == Handling of I4L IO =====================================================*/
19 22
@@ -36,12 +39,12 @@
36static int writebuf_from_LL(int driverID, int channel, int ack, 39static int writebuf_from_LL(int driverID, int channel, int ack,
37 struct sk_buff *skb) 40 struct sk_buff *skb)
38{ 41{
39 struct cardstate *cs; 42 struct cardstate *cs = gigaset_get_cs_by_id(driverID);
40 struct bc_state *bcs; 43 struct bc_state *bcs;
44 unsigned char *ack_header;
41 unsigned len; 45 unsigned len;
42 unsigned skblen;
43 46
44 if (!(cs = gigaset_get_cs_by_id(driverID))) { 47 if (!cs) {
45 pr_err("%s: invalid driver ID (%d)\n", __func__, driverID); 48 pr_err("%s: invalid driver ID (%d)\n", __func__, driverID);
46 return -ENODEV; 49 return -ENODEV;
47 } 50 }
@@ -75,11 +78,23 @@ static int writebuf_from_LL(int driverID, int channel, int ack,
75 return -EINVAL; 78 return -EINVAL;
76 } 79 }
77 80
78 skblen = ack ? len : 0; 81 /* set up acknowledgement header */
79 skb->head[0] = skblen & 0xff; 82 if (skb_headroom(skb) < HW_HDR_LEN) {
80 skb->head[1] = skblen >> 8; 83 /* should never happen */
81 gig_dbg(DEBUG_MCMD, "skb: len=%u, skblen=%u: %02x %02x", 84 dev_err(cs->dev, "%s: insufficient skb headroom\n", __func__);
82 len, skblen, (unsigned) skb->head[0], (unsigned) skb->head[1]); 85 return -ENOMEM;
86 }
87 skb_set_mac_header(skb, -HW_HDR_LEN);
88 skb->mac_len = HW_HDR_LEN;
89 ack_header = skb_mac_header(skb);
90 if (ack) {
91 ack_header[0] = len & 0xff;
92 ack_header[1] = len >> 8;
93 } else {
94 ack_header[0] = ack_header[1] = 0;
95 }
96 gig_dbg(DEBUG_MCMD, "skb: len=%u, ack=%d: %02x %02x",
97 len, ack, ack_header[0], ack_header[1]);
83 98
84 /* pass to device-specific module */ 99 /* pass to device-specific module */
85 return cs->ops->send_skb(bcs, skb); 100 return cs->ops->send_skb(bcs, skb);
@@ -95,6 +110,8 @@ static int writebuf_from_LL(int driverID, int channel, int ack,
95 */ 110 */
96void gigaset_skb_sent(struct bc_state *bcs, struct sk_buff *skb) 111void gigaset_skb_sent(struct bc_state *bcs, struct sk_buff *skb)
97{ 112{
113 isdn_if *iif = bcs->cs->iif;
114 unsigned char *ack_header = skb_mac_header(skb);
98 unsigned len; 115 unsigned len;
99 isdn_ctrl response; 116 isdn_ctrl response;
100 117
@@ -104,8 +121,7 @@ void gigaset_skb_sent(struct bc_state *bcs, struct sk_buff *skb)
104 dev_warn(bcs->cs->dev, "%s: skb->len==%d\n", 121 dev_warn(bcs->cs->dev, "%s: skb->len==%d\n",
105 __func__, skb->len); 122 __func__, skb->len);
106 123
107 len = (unsigned char) skb->head[0] | 124 len = ack_header[0] + ((unsigned) ack_header[1] << 8);
108 (unsigned) (unsigned char) skb->head[1] << 8;
109 if (len) { 125 if (len) {
110 gig_dbg(DEBUG_MCMD, "ACKing to LL (id: %d, ch: %d, sz: %u)", 126 gig_dbg(DEBUG_MCMD, "ACKing to LL (id: %d, ch: %d, sz: %u)",
111 bcs->cs->myid, bcs->channel, len); 127 bcs->cs->myid, bcs->channel, len);
@@ -114,359 +130,297 @@ void gigaset_skb_sent(struct bc_state *bcs, struct sk_buff *skb)
114 response.command = ISDN_STAT_BSENT; 130 response.command = ISDN_STAT_BSENT;
115 response.arg = bcs->channel; 131 response.arg = bcs->channel;
116 response.parm.length = len; 132 response.parm.length = len;
117 bcs->cs->iif.statcallb(&response); 133 iif->statcallb(&response);
118 } 134 }
119} 135}
120EXPORT_SYMBOL_GPL(gigaset_skb_sent); 136EXPORT_SYMBOL_GPL(gigaset_skb_sent);
121 137
138/**
139 * gigaset_skb_rcvd() - pass received skb to LL
140 * @bcs: B channel descriptor structure.
141 * @skb: received data.
142 *
143 * Called by hardware module {bas,ser,usb}_gigaset when user data has
144 * been successfully received, for passing to the LL.
145 * Warning: skb must not be accessed anymore!
146 */
147void gigaset_skb_rcvd(struct bc_state *bcs, struct sk_buff *skb)
148{
149 isdn_if *iif = bcs->cs->iif;
150
151 iif->rcvcallb_skb(bcs->cs->myid, bcs->channel, skb);
152 bcs->trans_down++;
153}
154EXPORT_SYMBOL_GPL(gigaset_skb_rcvd);
155
156/**
157 * gigaset_isdn_rcv_err() - signal receive error
158 * @bcs: B channel descriptor structure.
159 *
160 * Called by hardware module {bas,ser,usb}_gigaset when a receive error
161 * has occurred, for signalling to the LL.
162 */
163void gigaset_isdn_rcv_err(struct bc_state *bcs)
164{
165 isdn_if *iif = bcs->cs->iif;
166 isdn_ctrl response;
167
168 /* if currently ignoring packets, just count down */
169 if (bcs->ignore) {
170 bcs->ignore--;
171 return;
172 }
173
174 /* update statistics */
175 bcs->corrupted++;
176
177 /* error -> LL */
178 gig_dbg(DEBUG_CMD, "sending L1ERR");
179 response.driver = bcs->cs->myid;
180 response.command = ISDN_STAT_L1ERR;
181 response.arg = bcs->channel;
182 response.parm.errcode = ISDN_STAT_L1ERR_RECV;
183 iif->statcallb(&response);
184}
185EXPORT_SYMBOL_GPL(gigaset_isdn_rcv_err);
186
122/* This function will be called by LL to send commands 187/* This function will be called by LL to send commands
123 * NOTE: LL ignores the returned value, for commands other than ISDN_CMD_IOCTL, 188 * NOTE: LL ignores the returned value, for commands other than ISDN_CMD_IOCTL,
124 * so don't put too much effort into it. 189 * so don't put too much effort into it.
125 */ 190 */
126static int command_from_LL(isdn_ctrl *cntrl) 191static int command_from_LL(isdn_ctrl *cntrl)
127{ 192{
128 struct cardstate *cs = gigaset_get_cs_by_id(cntrl->driver); 193 struct cardstate *cs;
129 struct bc_state *bcs; 194 struct bc_state *bcs;
130 int retval = 0; 195 int retval = 0;
131 struct setup_parm *sp; 196 char **commands;
197 int ch;
198 int i;
199 size_t l;
132 200
133 gigaset_debugdrivers(); 201 gigaset_debugdrivers();
134 202
135 if (!cs) { 203 gig_dbg(DEBUG_CMD, "driver: %d, command: %d, arg: 0x%lx",
204 cntrl->driver, cntrl->command, cntrl->arg);
205
206 cs = gigaset_get_cs_by_id(cntrl->driver);
207 if (cs == NULL) {
136 pr_err("%s: invalid driver ID (%d)\n", __func__, cntrl->driver); 208 pr_err("%s: invalid driver ID (%d)\n", __func__, cntrl->driver);
137 return -ENODEV; 209 return -ENODEV;
138 } 210 }
211 ch = cntrl->arg & 0xff;
139 212
140 switch (cntrl->command) { 213 switch (cntrl->command) {
141 case ISDN_CMD_IOCTL: 214 case ISDN_CMD_IOCTL:
142 gig_dbg(DEBUG_ANY, "ISDN_CMD_IOCTL (driver: %d, arg: %ld)",
143 cntrl->driver, cntrl->arg);
144
145 dev_warn(cs->dev, "ISDN_CMD_IOCTL not supported\n"); 215 dev_warn(cs->dev, "ISDN_CMD_IOCTL not supported\n");
146 return -EINVAL; 216 return -EINVAL;
147 217
148 case ISDN_CMD_DIAL: 218 case ISDN_CMD_DIAL:
149 gig_dbg(DEBUG_ANY, 219 gig_dbg(DEBUG_CMD,
150 "ISDN_CMD_DIAL (driver: %d, ch: %ld, " 220 "ISDN_CMD_DIAL (phone: %s, msn: %s, si1: %d, si2: %d)",
151 "phone: %s, ownmsn: %s, si1: %d, si2: %d)",
152 cntrl->driver, cntrl->arg,
153 cntrl->parm.setup.phone, cntrl->parm.setup.eazmsn, 221 cntrl->parm.setup.phone, cntrl->parm.setup.eazmsn,
154 cntrl->parm.setup.si1, cntrl->parm.setup.si2); 222 cntrl->parm.setup.si1, cntrl->parm.setup.si2);
155 223
156 if (cntrl->arg >= cs->channels) { 224 if (ch >= cs->channels) {
157 dev_err(cs->dev, 225 dev_err(cs->dev,
158 "ISDN_CMD_DIAL: invalid channel (%d)\n", 226 "ISDN_CMD_DIAL: invalid channel (%d)\n", ch);
159 (int) cntrl->arg);
160 return -EINVAL; 227 return -EINVAL;
161 } 228 }
162 229 bcs = cs->bcs + ch;
163 bcs = cs->bcs + cntrl->arg;
164
165 if (!gigaset_get_channel(bcs)) { 230 if (!gigaset_get_channel(bcs)) {
166 dev_err(cs->dev, "ISDN_CMD_DIAL: channel not free\n"); 231 dev_err(cs->dev, "ISDN_CMD_DIAL: channel not free\n");
167 return -EBUSY; 232 return -EBUSY;
168 } 233 }
169 234
170 sp = kmalloc(sizeof *sp, GFP_ATOMIC); 235 commands = kzalloc(AT_NUM*(sizeof *commands), GFP_ATOMIC);
171 if (!sp) { 236 if (!commands) {
172 gigaset_free_channel(bcs); 237 gigaset_free_channel(bcs);
173 dev_err(cs->dev, "ISDN_CMD_DIAL: out of memory\n"); 238 dev_err(cs->dev, "ISDN_CMD_DIAL: out of memory\n");
174 return -ENOMEM; 239 return -ENOMEM;
175 } 240 }
176 *sp = cntrl->parm.setup;
177 241
178 if (!gigaset_add_event(cs, &bcs->at_state, EV_DIAL, sp, 242 l = 3 + strlen(cntrl->parm.setup.phone);
243 commands[AT_DIAL] = kmalloc(l, GFP_ATOMIC);
244 if (!commands[AT_DIAL])
245 goto oom;
246 if (cntrl->parm.setup.phone[0] == '*' &&
247 cntrl->parm.setup.phone[1] == '*') {
248 /* internal call: translate ** prefix to CTP value */
249 commands[AT_TYPE] = kstrdup("^SCTP=0\r", GFP_ATOMIC);
250 if (!commands[AT_TYPE])
251 goto oom;
252 snprintf(commands[AT_DIAL], l,
253 "D%s\r", cntrl->parm.setup.phone+2);
254 } else {
255 commands[AT_TYPE] = kstrdup("^SCTP=1\r", GFP_ATOMIC);
256 if (!commands[AT_TYPE])
257 goto oom;
258 snprintf(commands[AT_DIAL], l,
259 "D%s\r", cntrl->parm.setup.phone);
260 }
261
262 l = strlen(cntrl->parm.setup.eazmsn);
263 if (l) {
264 l += 8;
265 commands[AT_MSN] = kmalloc(l, GFP_ATOMIC);
266 if (!commands[AT_MSN])
267 goto oom;
268 snprintf(commands[AT_MSN], l, "^SMSN=%s\r",
269 cntrl->parm.setup.eazmsn);
270 }
271
272 switch (cntrl->parm.setup.si1) {
273 case 1: /* audio */
274 /* BC = 9090A3: 3.1 kHz audio, A-law */
275 commands[AT_BC] = kstrdup("^SBC=9090A3\r", GFP_ATOMIC);
276 if (!commands[AT_BC])
277 goto oom;
278 break;
279 case 7: /* data */
280 default: /* hope the app knows what it is doing */
281 /* BC = 8890: unrestricted digital information */
282 commands[AT_BC] = kstrdup("^SBC=8890\r", GFP_ATOMIC);
283 if (!commands[AT_BC])
284 goto oom;
285 }
286 /* ToDo: other si1 values, inspect si2, set HLC/LLC */
287
288 commands[AT_PROTO] = kmalloc(9, GFP_ATOMIC);
289 if (!commands[AT_PROTO])
290 goto oom;
291 snprintf(commands[AT_PROTO], 9, "^SBPR=%u\r", bcs->proto2);
292
293 commands[AT_ISO] = kmalloc(9, GFP_ATOMIC);
294 if (!commands[AT_ISO])
295 goto oom;
296 snprintf(commands[AT_ISO], 9, "^SISO=%u\r",
297 (unsigned) bcs->channel + 1);
298
299 if (!gigaset_add_event(cs, &bcs->at_state, EV_DIAL, commands,
179 bcs->at_state.seq_index, NULL)) { 300 bcs->at_state.seq_index, NULL)) {
180 //FIXME what should we do? 301 for (i = 0; i < AT_NUM; ++i)
181 kfree(sp); 302 kfree(commands[i]);
303 kfree(commands);
182 gigaset_free_channel(bcs); 304 gigaset_free_channel(bcs);
183 return -ENOMEM; 305 return -ENOMEM;
184 } 306 }
185
186 gig_dbg(DEBUG_CMD, "scheduling DIAL");
187 gigaset_schedule_event(cs); 307 gigaset_schedule_event(cs);
188 break; 308 break;
189 case ISDN_CMD_ACCEPTD: //FIXME 309 case ISDN_CMD_ACCEPTD:
190 gig_dbg(DEBUG_ANY, "ISDN_CMD_ACCEPTD"); 310 gig_dbg(DEBUG_CMD, "ISDN_CMD_ACCEPTD");
191 311 if (ch >= cs->channels) {
192 if (cntrl->arg >= cs->channels) {
193 dev_err(cs->dev, 312 dev_err(cs->dev,
194 "ISDN_CMD_ACCEPTD: invalid channel (%d)\n", 313 "ISDN_CMD_ACCEPTD: invalid channel (%d)\n", ch);
195 (int) cntrl->arg);
196 return -EINVAL; 314 return -EINVAL;
197 } 315 }
198 316 bcs = cs->bcs + ch;
199 if (!gigaset_add_event(cs, &cs->bcs[cntrl->arg].at_state, 317 if (!gigaset_add_event(cs, &bcs->at_state,
200 EV_ACCEPT, NULL, 0, NULL)) { 318 EV_ACCEPT, NULL, 0, NULL))
201 //FIXME what should we do?
202 return -ENOMEM; 319 return -ENOMEM;
203 }
204
205 gig_dbg(DEBUG_CMD, "scheduling ACCEPT");
206 gigaset_schedule_event(cs); 320 gigaset_schedule_event(cs);
207 321
208 break; 322 break;
209 case ISDN_CMD_ACCEPTB:
210 gig_dbg(DEBUG_ANY, "ISDN_CMD_ACCEPTB");
211 break;
212 case ISDN_CMD_HANGUP: 323 case ISDN_CMD_HANGUP:
213 gig_dbg(DEBUG_ANY, "ISDN_CMD_HANGUP (ch: %d)", 324 gig_dbg(DEBUG_CMD, "ISDN_CMD_HANGUP");
214 (int) cntrl->arg); 325 if (ch >= cs->channels) {
215
216 if (cntrl->arg >= cs->channels) {
217 dev_err(cs->dev, 326 dev_err(cs->dev,
218 "ISDN_CMD_HANGUP: invalid channel (%d)\n", 327 "ISDN_CMD_HANGUP: invalid channel (%d)\n", ch);
219 (int) cntrl->arg);
220 return -EINVAL; 328 return -EINVAL;
221 } 329 }
222 330 bcs = cs->bcs + ch;
223 if (!gigaset_add_event(cs, &cs->bcs[cntrl->arg].at_state, 331 if (!gigaset_add_event(cs, &bcs->at_state,
224 EV_HUP, NULL, 0, NULL)) { 332 EV_HUP, NULL, 0, NULL))
225 //FIXME what should we do?
226 return -ENOMEM; 333 return -ENOMEM;
227 }
228
229 gig_dbg(DEBUG_CMD, "scheduling HUP");
230 gigaset_schedule_event(cs); 334 gigaset_schedule_event(cs);
231 335
232 break; 336 break;
233 case ISDN_CMD_CLREAZ: /* Do not signal incoming signals */ //FIXME 337 case ISDN_CMD_CLREAZ: /* Do not signal incoming signals */
234 gig_dbg(DEBUG_ANY, "ISDN_CMD_CLREAZ"); 338 dev_info(cs->dev, "ignoring ISDN_CMD_CLREAZ\n");
235 break; 339 break;
236 case ISDN_CMD_SETEAZ: /* Signal incoming calls for given MSN */ //FIXME 340 case ISDN_CMD_SETEAZ: /* Signal incoming calls for given MSN */
237 gig_dbg(DEBUG_ANY, 341 dev_info(cs->dev, "ignoring ISDN_CMD_SETEAZ (%s)\n",
238 "ISDN_CMD_SETEAZ (id: %d, ch: %ld, number: %s)", 342 cntrl->parm.num);
239 cntrl->driver, cntrl->arg, cntrl->parm.num);
240 break; 343 break;
241 case ISDN_CMD_SETL2: /* Set L2 to given protocol */ 344 case ISDN_CMD_SETL2: /* Set L2 to given protocol */
242 gig_dbg(DEBUG_ANY, "ISDN_CMD_SETL2 (ch: %ld, proto: %lx)", 345 if (ch >= cs->channels) {
243 cntrl->arg & 0xff, (cntrl->arg >> 8));
244
245 if ((cntrl->arg & 0xff) >= cs->channels) {
246 dev_err(cs->dev, 346 dev_err(cs->dev,
247 "ISDN_CMD_SETL2: invalid channel (%d)\n", 347 "ISDN_CMD_SETL2: invalid channel (%d)\n", ch);
248 (int) cntrl->arg & 0xff);
249 return -EINVAL; 348 return -EINVAL;
250 } 349 }
251 350 bcs = cs->bcs + ch;
252 if (!gigaset_add_event(cs, &cs->bcs[cntrl->arg & 0xff].at_state, 351 if (bcs->chstate & CHS_D_UP) {
253 EV_PROTO_L2, NULL, cntrl->arg >> 8, 352 dev_err(cs->dev,
254 NULL)) { 353 "ISDN_CMD_SETL2: channel active (%d)\n", ch);
255 //FIXME what should we do? 354 return -EINVAL;
256 return -ENOMEM; 355 }
356 switch (cntrl->arg >> 8) {
357 case ISDN_PROTO_L2_HDLC:
358 gig_dbg(DEBUG_CMD, "ISDN_CMD_SETL2: setting L2_HDLC");
359 bcs->proto2 = L2_HDLC;
360 break;
361 case ISDN_PROTO_L2_TRANS:
362 gig_dbg(DEBUG_CMD, "ISDN_CMD_SETL2: setting L2_VOICE");
363 bcs->proto2 = L2_VOICE;
364 break;
365 default:
366 dev_err(cs->dev,
367 "ISDN_CMD_SETL2: unsupported protocol (%lu)\n",
368 cntrl->arg >> 8);
369 return -EINVAL;
257 } 370 }
258
259 gig_dbg(DEBUG_CMD, "scheduling PROTO_L2");
260 gigaset_schedule_event(cs);
261 break; 371 break;
262 case ISDN_CMD_SETL3: /* Set L3 to given protocol */ 372 case ISDN_CMD_SETL3: /* Set L3 to given protocol */
263 gig_dbg(DEBUG_ANY, "ISDN_CMD_SETL3 (ch: %ld, proto: %lx)", 373 gig_dbg(DEBUG_CMD, "ISDN_CMD_SETL3");
264 cntrl->arg & 0xff, (cntrl->arg >> 8)); 374 if (ch >= cs->channels) {
265
266 if ((cntrl->arg & 0xff) >= cs->channels) {
267 dev_err(cs->dev, 375 dev_err(cs->dev,
268 "ISDN_CMD_SETL3: invalid channel (%d)\n", 376 "ISDN_CMD_SETL3: invalid channel (%d)\n", ch);
269 (int) cntrl->arg & 0xff);
270 return -EINVAL; 377 return -EINVAL;
271 } 378 }
272 379
273 if (cntrl->arg >> 8 != ISDN_PROTO_L3_TRANS) { 380 if (cntrl->arg >> 8 != ISDN_PROTO_L3_TRANS) {
274 dev_err(cs->dev, 381 dev_err(cs->dev,
275 "ISDN_CMD_SETL3: invalid protocol %lu\n", 382 "ISDN_CMD_SETL3: unsupported protocol (%lu)\n",
276 cntrl->arg >> 8); 383 cntrl->arg >> 8);
277 return -EINVAL; 384 return -EINVAL;
278 } 385 }
279 386
280 break; 387 break;
281 case ISDN_CMD_PROCEED: 388
282 gig_dbg(DEBUG_ANY, "ISDN_CMD_PROCEED"); //FIXME
283 break;
284 case ISDN_CMD_ALERT:
285 gig_dbg(DEBUG_ANY, "ISDN_CMD_ALERT"); //FIXME
286 if (cntrl->arg >= cs->channels) {
287 dev_err(cs->dev,
288 "ISDN_CMD_ALERT: invalid channel (%d)\n",
289 (int) cntrl->arg);
290 return -EINVAL;
291 }
292 //bcs = cs->bcs + cntrl->arg;
293 //bcs->proto2 = -1;
294 // FIXME
295 break;
296 case ISDN_CMD_REDIR:
297 gig_dbg(DEBUG_ANY, "ISDN_CMD_REDIR"); //FIXME
298 break;
299 case ISDN_CMD_PROT_IO:
300 gig_dbg(DEBUG_ANY, "ISDN_CMD_PROT_IO");
301 break;
302 case ISDN_CMD_FAXCMD:
303 gig_dbg(DEBUG_ANY, "ISDN_CMD_FAXCMD");
304 break;
305 case ISDN_CMD_GETL2:
306 gig_dbg(DEBUG_ANY, "ISDN_CMD_GETL2");
307 break;
308 case ISDN_CMD_GETL3:
309 gig_dbg(DEBUG_ANY, "ISDN_CMD_GETL3");
310 break;
311 case ISDN_CMD_GETEAZ:
312 gig_dbg(DEBUG_ANY, "ISDN_CMD_GETEAZ");
313 break;
314 case ISDN_CMD_SETSIL:
315 gig_dbg(DEBUG_ANY, "ISDN_CMD_SETSIL");
316 break;
317 case ISDN_CMD_GETSIL:
318 gig_dbg(DEBUG_ANY, "ISDN_CMD_GETSIL");
319 break;
320 default: 389 default:
321 dev_err(cs->dev, "unknown command %d from LL\n", 390 gig_dbg(DEBUG_CMD, "unknown command %d from LL",
322 cntrl->command); 391 cntrl->command);
323 return -EINVAL; 392 return -EINVAL;
324 } 393 }
325 394
326 return retval; 395 return retval;
396
397oom:
398 dev_err(bcs->cs->dev, "out of memory\n");
399 for (i = 0; i < AT_NUM; ++i)
400 kfree(commands[i]);
401 return -ENOMEM;
327} 402}
328 403
329void gigaset_i4l_cmd(struct cardstate *cs, int cmd) 404static void gigaset_i4l_cmd(struct cardstate *cs, int cmd)
330{ 405{
406 isdn_if *iif = cs->iif;
331 isdn_ctrl command; 407 isdn_ctrl command;
332 408
333 command.driver = cs->myid; 409 command.driver = cs->myid;
334 command.command = cmd; 410 command.command = cmd;
335 command.arg = 0; 411 command.arg = 0;
336 cs->iif.statcallb(&command); 412 iif->statcallb(&command);
337} 413}
338 414
339void gigaset_i4l_channel_cmd(struct bc_state *bcs, int cmd) 415static void gigaset_i4l_channel_cmd(struct bc_state *bcs, int cmd)
340{ 416{
417 isdn_if *iif = bcs->cs->iif;
341 isdn_ctrl command; 418 isdn_ctrl command;
342 419
343 command.driver = bcs->cs->myid; 420 command.driver = bcs->cs->myid;
344 command.command = cmd; 421 command.command = cmd;
345 command.arg = bcs->channel; 422 command.arg = bcs->channel;
346 bcs->cs->iif.statcallb(&command); 423 iif->statcallb(&command);
347}
348
349int gigaset_isdn_setup_dial(struct at_state_t *at_state, void *data)
350{
351 struct bc_state *bcs = at_state->bcs;
352 unsigned proto;
353 const char *bc;
354 size_t length[AT_NUM];
355 size_t l;
356 int i;
357 struct setup_parm *sp = data;
358
359 switch (bcs->proto2) {
360 case ISDN_PROTO_L2_HDLC:
361 proto = 1; /* 0: Bitsynchron, 1: HDLC, 2: voice */
362 break;
363 case ISDN_PROTO_L2_TRANS:
364 proto = 2; /* 0: Bitsynchron, 1: HDLC, 2: voice */
365 break;
366 default:
367 dev_err(bcs->cs->dev, "%s: invalid L2 protocol: %u\n",
368 __func__, bcs->proto2);
369 return -EINVAL;
370 }
371
372 switch (sp->si1) {
373 case 1: /* audio */
374 bc = "9090A3"; /* 3.1 kHz audio, A-law */
375 break;
376 case 7: /* data */
377 default: /* hope the app knows what it is doing */
378 bc = "8890"; /* unrestricted digital information */
379 }
380 //FIXME add missing si1 values from 1TR6, inspect si2, set HLC/LLC
381
382 length[AT_DIAL ] = 1 + strlen(sp->phone) + 1 + 1;
383 l = strlen(sp->eazmsn);
384 length[AT_MSN ] = l ? 6 + l + 1 + 1 : 0;
385 length[AT_BC ] = 5 + strlen(bc) + 1 + 1;
386 length[AT_PROTO] = 6 + 1 + 1 + 1; /* proto: 1 character */
387 length[AT_ISO ] = 6 + 1 + 1 + 1; /* channel: 1 character */
388 length[AT_TYPE ] = 6 + 1 + 1 + 1; /* call type: 1 character */
389 length[AT_HLC ] = 0;
390
391 for (i = 0; i < AT_NUM; ++i) {
392 kfree(bcs->commands[i]);
393 bcs->commands[i] = NULL;
394 if (length[i] &&
395 !(bcs->commands[i] = kmalloc(length[i], GFP_ATOMIC))) {
396 dev_err(bcs->cs->dev, "out of memory\n");
397 return -ENOMEM;
398 }
399 }
400
401 /* type = 1: extern, 0: intern, 2: recall, 3: door, 4: centrex */
402 if (sp->phone[0] == '*' && sp->phone[1] == '*') {
403 /* internal call: translate ** prefix to CTP value */
404 snprintf(bcs->commands[AT_DIAL], length[AT_DIAL],
405 "D%s\r", sp->phone+2);
406 strncpy(bcs->commands[AT_TYPE], "^SCTP=0\r", length[AT_TYPE]);
407 } else {
408 snprintf(bcs->commands[AT_DIAL], length[AT_DIAL],
409 "D%s\r", sp->phone);
410 strncpy(bcs->commands[AT_TYPE], "^SCTP=1\r", length[AT_TYPE]);
411 }
412
413 if (bcs->commands[AT_MSN])
414 snprintf(bcs->commands[AT_MSN], length[AT_MSN],
415 "^SMSN=%s\r", sp->eazmsn);
416 snprintf(bcs->commands[AT_BC ], length[AT_BC ],
417 "^SBC=%s\r", bc);
418 snprintf(bcs->commands[AT_PROTO], length[AT_PROTO],
419 "^SBPR=%u\r", proto);
420 snprintf(bcs->commands[AT_ISO ], length[AT_ISO ],
421 "^SISO=%u\r", (unsigned)bcs->channel + 1);
422
423 return 0;
424}
425
426int gigaset_isdn_setup_accept(struct at_state_t *at_state)
427{
428 unsigned proto;
429 size_t length[AT_NUM];
430 int i;
431 struct bc_state *bcs = at_state->bcs;
432
433 switch (bcs->proto2) {
434 case ISDN_PROTO_L2_HDLC:
435 proto = 1; /* 0: Bitsynchron, 1: HDLC, 2: voice */
436 break;
437 case ISDN_PROTO_L2_TRANS:
438 proto = 2; /* 0: Bitsynchron, 1: HDLC, 2: voice */
439 break;
440 default:
441 dev_err(at_state->cs->dev, "%s: invalid protocol: %u\n",
442 __func__, bcs->proto2);
443 return -EINVAL;
444 }
445
446 length[AT_DIAL ] = 0;
447 length[AT_MSN ] = 0;
448 length[AT_BC ] = 0;
449 length[AT_PROTO] = 6 + 1 + 1 + 1; /* proto: 1 character */
450 length[AT_ISO ] = 6 + 1 + 1 + 1; /* channel: 1 character */
451 length[AT_TYPE ] = 0;
452 length[AT_HLC ] = 0;
453
454 for (i = 0; i < AT_NUM; ++i) {
455 kfree(bcs->commands[i]);
456 bcs->commands[i] = NULL;
457 if (length[i] &&
458 !(bcs->commands[i] = kmalloc(length[i], GFP_ATOMIC))) {
459 dev_err(at_state->cs->dev, "out of memory\n");
460 return -ENOMEM;
461 }
462 }
463
464 snprintf(bcs->commands[AT_PROTO], length[AT_PROTO],
465 "^SBPR=%u\r", proto);
466 snprintf(bcs->commands[AT_ISO ], length[AT_ISO ],
467 "^SISO=%u\r", (unsigned) bcs->channel + 1);
468
469 return 0;
470} 424}
471 425
472/** 426/**
@@ -482,13 +436,14 @@ int gigaset_isdn_icall(struct at_state_t *at_state)
482{ 436{
483 struct cardstate *cs = at_state->cs; 437 struct cardstate *cs = at_state->cs;
484 struct bc_state *bcs = at_state->bcs; 438 struct bc_state *bcs = at_state->bcs;
439 isdn_if *iif = cs->iif;
485 isdn_ctrl response; 440 isdn_ctrl response;
486 int retval; 441 int retval;
487 442
488 /* fill ICALL structure */ 443 /* fill ICALL structure */
489 response.parm.setup.si1 = 0; /* default: unknown */ 444 response.parm.setup.si1 = 0; /* default: unknown */
490 response.parm.setup.si2 = 0; 445 response.parm.setup.si2 = 0;
491 response.parm.setup.screen = 0; //FIXME how to set these? 446 response.parm.setup.screen = 0;
492 response.parm.setup.plan = 0; 447 response.parm.setup.plan = 0;
493 if (!at_state->str_var[STR_ZBC]) { 448 if (!at_state->str_var[STR_ZBC]) {
494 /* no BC (internal call): assume speech, A-law */ 449 /* no BC (internal call): assume speech, A-law */
@@ -509,29 +464,27 @@ int gigaset_isdn_icall(struct at_state_t *at_state)
509 return ICALL_IGNORE; 464 return ICALL_IGNORE;
510 } 465 }
511 if (at_state->str_var[STR_NMBR]) { 466 if (at_state->str_var[STR_NMBR]) {
512 strncpy(response.parm.setup.phone, at_state->str_var[STR_NMBR], 467 strlcpy(response.parm.setup.phone, at_state->str_var[STR_NMBR],
513 sizeof response.parm.setup.phone - 1); 468 sizeof response.parm.setup.phone);
514 response.parm.setup.phone[sizeof response.parm.setup.phone - 1] = 0;
515 } else 469 } else
516 response.parm.setup.phone[0] = 0; 470 response.parm.setup.phone[0] = 0;
517 if (at_state->str_var[STR_ZCPN]) { 471 if (at_state->str_var[STR_ZCPN]) {
518 strncpy(response.parm.setup.eazmsn, at_state->str_var[STR_ZCPN], 472 strlcpy(response.parm.setup.eazmsn, at_state->str_var[STR_ZCPN],
519 sizeof response.parm.setup.eazmsn - 1); 473 sizeof response.parm.setup.eazmsn);
520 response.parm.setup.eazmsn[sizeof response.parm.setup.eazmsn - 1] = 0;
521 } else 474 } else
522 response.parm.setup.eazmsn[0] = 0; 475 response.parm.setup.eazmsn[0] = 0;
523 476
524 if (!bcs) { 477 if (!bcs) {
525 dev_notice(cs->dev, "no channel for incoming call\n"); 478 dev_notice(cs->dev, "no channel for incoming call\n");
526 response.command = ISDN_STAT_ICALLW; 479 response.command = ISDN_STAT_ICALLW;
527 response.arg = 0; //FIXME 480 response.arg = 0;
528 } else { 481 } else {
529 gig_dbg(DEBUG_CMD, "Sending ICALL"); 482 gig_dbg(DEBUG_CMD, "Sending ICALL");
530 response.command = ISDN_STAT_ICALL; 483 response.command = ISDN_STAT_ICALL;
531 response.arg = bcs->channel; //FIXME 484 response.arg = bcs->channel;
532 } 485 }
533 response.driver = cs->myid; 486 response.driver = cs->myid;
534 retval = cs->iif.statcallb(&response); 487 retval = iif->statcallb(&response);
535 gig_dbg(DEBUG_CMD, "Response: %d", retval); 488 gig_dbg(DEBUG_CMD, "Response: %d", retval);
536 switch (retval) { 489 switch (retval) {
537 case 0: /* no takers */ 490 case 0: /* no takers */
@@ -560,16 +513,107 @@ int gigaset_isdn_icall(struct at_state_t *at_state)
560 } 513 }
561} 514}
562 515
563/* Set Callback function pointer */ 516/**
564int gigaset_register_to_LL(struct cardstate *cs, const char *isdnid) 517 * gigaset_isdn_connD() - signal D channel connect
518 * @bcs: B channel descriptor structure.
519 *
520 * Called by main module to notify the LL that the D channel connection has
521 * been established.
522 */
523void gigaset_isdn_connD(struct bc_state *bcs)
524{
525 gig_dbg(DEBUG_CMD, "sending DCONN");
526 gigaset_i4l_channel_cmd(bcs, ISDN_STAT_DCONN);
527}
528
529/**
530 * gigaset_isdn_hupD() - signal D channel hangup
531 * @bcs: B channel descriptor structure.
532 *
533 * Called by main module to notify the LL that the D channel connection has
534 * been shut down.
535 */
536void gigaset_isdn_hupD(struct bc_state *bcs)
537{
538 gig_dbg(DEBUG_CMD, "sending DHUP");
539 gigaset_i4l_channel_cmd(bcs, ISDN_STAT_DHUP);
540}
541
542/**
543 * gigaset_isdn_connB() - signal B channel connect
544 * @bcs: B channel descriptor structure.
545 *
546 * Called by main module to notify the LL that the B channel connection has
547 * been established.
548 */
549void gigaset_isdn_connB(struct bc_state *bcs)
550{
551 gig_dbg(DEBUG_CMD, "sending BCONN");
552 gigaset_i4l_channel_cmd(bcs, ISDN_STAT_BCONN);
553}
554
555/**
556 * gigaset_isdn_hupB() - signal B channel hangup
557 * @bcs: B channel descriptor structure.
558 *
559 * Called by main module to notify the LL that the B channel connection has
560 * been shut down.
561 */
562void gigaset_isdn_hupB(struct bc_state *bcs)
565{ 563{
566 isdn_if *iif = &cs->iif; 564 gig_dbg(DEBUG_CMD, "sending BHUP");
565 gigaset_i4l_channel_cmd(bcs, ISDN_STAT_BHUP);
566}
567 567
568 gig_dbg(DEBUG_ANY, "Register driver capabilities to LL"); 568/**
569 * gigaset_isdn_start() - signal device availability
570 * @cs: device descriptor structure.
571 *
572 * Called by main module to notify the LL that the device is available for
573 * use.
574 */
575void gigaset_isdn_start(struct cardstate *cs)
576{
577 gig_dbg(DEBUG_CMD, "sending RUN");
578 gigaset_i4l_cmd(cs, ISDN_STAT_RUN);
579}
580
581/**
582 * gigaset_isdn_stop() - signal device unavailability
583 * @cs: device descriptor structure.
584 *
585 * Called by main module to notify the LL that the device is no longer
586 * available for use.
587 */
588void gigaset_isdn_stop(struct cardstate *cs)
589{
590 gig_dbg(DEBUG_CMD, "sending STOP");
591 gigaset_i4l_cmd(cs, ISDN_STAT_STOP);
592}
593
594/**
595 * gigaset_isdn_regdev() - register to LL
596 * @cs: device descriptor structure.
597 * @isdnid: device name.
598 *
599 * Return value: 1 for success, 0 for failure
600 */
601int gigaset_isdn_regdev(struct cardstate *cs, const char *isdnid)
602{
603 isdn_if *iif;
604
605 pr_info("ISDN4Linux interface\n");
606
607 iif = kmalloc(sizeof *iif, GFP_KERNEL);
608 if (!iif) {
609 pr_err("out of memory\n");
610 return 0;
611 }
569 612
570 if (snprintf(iif->id, sizeof iif->id, "%s_%u", isdnid, cs->minor_index) 613 if (snprintf(iif->id, sizeof iif->id, "%s_%u", isdnid, cs->minor_index)
571 >= sizeof iif->id) { 614 >= sizeof iif->id) {
572 pr_err("ID too long: %s\n", isdnid); 615 pr_err("ID too long: %s\n", isdnid);
616 kfree(iif);
573 return 0; 617 return 0;
574 } 618 }
575 619
@@ -593,9 +637,40 @@ int gigaset_register_to_LL(struct cardstate *cs, const char *isdnid)
593 637
594 if (!register_isdn(iif)) { 638 if (!register_isdn(iif)) {
595 pr_err("register_isdn failed\n"); 639 pr_err("register_isdn failed\n");
640 kfree(iif);
596 return 0; 641 return 0;
597 } 642 }
598 643
644 cs->iif = iif;
599 cs->myid = iif->channels; /* Set my device id */ 645 cs->myid = iif->channels; /* Set my device id */
646 cs->hw_hdr_len = HW_HDR_LEN;
600 return 1; 647 return 1;
601} 648}
649
650/**
651 * gigaset_isdn_unregdev() - unregister device from LL
652 * @cs: device descriptor structure.
653 */
654void gigaset_isdn_unregdev(struct cardstate *cs)
655{
656 gig_dbg(DEBUG_CMD, "sending UNLOAD");
657 gigaset_i4l_cmd(cs, ISDN_STAT_UNLOAD);
658 kfree(cs->iif);
659 cs->iif = NULL;
660}
661
662/**
663 * gigaset_isdn_regdrv() - register driver to LL
664 */
665void gigaset_isdn_regdrv(void)
666{
667 /* nothing to do */
668}
669
670/**
671 * gigaset_isdn_unregdrv() - unregister driver from LL
672 */
673void gigaset_isdn_unregdrv(void)
674{
675 /* nothing to do */
676}
diff --git a/drivers/isdn/gigaset/interface.c b/drivers/isdn/gigaset/interface.c
index 6a8e1384e7bd..c9f28dd40d5c 100644
--- a/drivers/isdn/gigaset/interface.c
+++ b/drivers/isdn/gigaset/interface.c
@@ -13,7 +13,6 @@
13 13
14#include "gigaset.h" 14#include "gigaset.h"
15#include <linux/gigaset_dev.h> 15#include <linux/gigaset_dev.h>
16#include <linux/tty.h>
17#include <linux/tty_flip.h> 16#include <linux/tty_flip.h>
18 17
19/*** our ioctls ***/ 18/*** our ioctls ***/
@@ -45,8 +44,6 @@ static int if_lock(struct cardstate *cs, int *arg)
45 cs->waiting = 0; 44 cs->waiting = 0;
46 return -ENOMEM; 45 return -ENOMEM;
47 } 46 }
48
49 gig_dbg(DEBUG_CMD, "scheduling IF_LOCK");
50 gigaset_schedule_event(cs); 47 gigaset_schedule_event(cs);
51 48
52 wait_event(cs->waitqueue, !cs->waiting); 49 wait_event(cs->waitqueue, !cs->waiting);
@@ -81,8 +78,6 @@ static int if_version(struct cardstate *cs, unsigned arg[4])
81 cs->waiting = 0; 78 cs->waiting = 0;
82 return -ENOMEM; 79 return -ENOMEM;
83 } 80 }
84
85 gig_dbg(DEBUG_CMD, "scheduling IF_VER");
86 gigaset_schedule_event(cs); 81 gigaset_schedule_event(cs);
87 82
88 wait_event(cs->waitqueue, !cs->waiting); 83 wait_event(cs->waitqueue, !cs->waiting);
@@ -162,7 +157,7 @@ static int if_open(struct tty_struct *tty, struct file *filp)
162 return -ENODEV; 157 return -ENODEV;
163 158
164 if (mutex_lock_interruptible(&cs->mutex)) 159 if (mutex_lock_interruptible(&cs->mutex))
165 return -ERESTARTSYS; // FIXME -EINTR? 160 return -ERESTARTSYS;
166 tty->driver_data = cs; 161 tty->driver_data = cs;
167 162
168 ++cs->open_count; 163 ++cs->open_count;
@@ -171,7 +166,7 @@ static int if_open(struct tty_struct *tty, struct file *filp)
171 spin_lock_irqsave(&cs->lock, flags); 166 spin_lock_irqsave(&cs->lock, flags);
172 cs->tty = tty; 167 cs->tty = tty;
173 spin_unlock_irqrestore(&cs->lock, flags); 168 spin_unlock_irqrestore(&cs->lock, flags);
174 tty->low_latency = 1; //FIXME test 169 tty->low_latency = 1;
175 } 170 }
176 171
177 mutex_unlock(&cs->mutex); 172 mutex_unlock(&cs->mutex);
@@ -228,7 +223,7 @@ static int if_ioctl(struct tty_struct *tty, struct file *file,
228 gig_dbg(DEBUG_IF, "%u: %s(0x%x)", cs->minor_index, __func__, cmd); 223 gig_dbg(DEBUG_IF, "%u: %s(0x%x)", cs->minor_index, __func__, cmd);
229 224
230 if (mutex_lock_interruptible(&cs->mutex)) 225 if (mutex_lock_interruptible(&cs->mutex))
231 return -ERESTARTSYS; // FIXME -EINTR? 226 return -ERESTARTSYS;
232 227
233 if (!cs->connected) { 228 if (!cs->connected) {
234 gig_dbg(DEBUG_IF, "not connected"); 229 gig_dbg(DEBUG_IF, "not connected");
@@ -274,7 +269,7 @@ static int if_ioctl(struct tty_struct *tty, struct file *file,
274 ? -EFAULT : 0; 269 ? -EFAULT : 0;
275 break; 270 break;
276 default: 271 default:
277 gig_dbg(DEBUG_ANY, "%s: arg not supported - 0x%04x", 272 gig_dbg(DEBUG_IF, "%s: arg not supported - 0x%04x",
278 __func__, cmd); 273 __func__, cmd);
279 retval = -ENOIOCTLCMD; 274 retval = -ENOIOCTLCMD;
280 } 275 }
@@ -299,9 +294,8 @@ static int if_tiocmget(struct tty_struct *tty, struct file *file)
299 gig_dbg(DEBUG_IF, "%u: %s()", cs->minor_index, __func__); 294 gig_dbg(DEBUG_IF, "%u: %s()", cs->minor_index, __func__);
300 295
301 if (mutex_lock_interruptible(&cs->mutex)) 296 if (mutex_lock_interruptible(&cs->mutex))
302 return -ERESTARTSYS; // FIXME -EINTR? 297 return -ERESTARTSYS;
303 298
304 // FIXME read from device?
305 retval = cs->control_state & (TIOCM_RTS|TIOCM_DTR); 299 retval = cs->control_state & (TIOCM_RTS|TIOCM_DTR);
306 300
307 mutex_unlock(&cs->mutex); 301 mutex_unlock(&cs->mutex);
@@ -326,7 +320,7 @@ static int if_tiocmset(struct tty_struct *tty, struct file *file,
326 cs->minor_index, __func__, set, clear); 320 cs->minor_index, __func__, set, clear);
327 321
328 if (mutex_lock_interruptible(&cs->mutex)) 322 if (mutex_lock_interruptible(&cs->mutex))
329 return -ERESTARTSYS; // FIXME -EINTR? 323 return -ERESTARTSYS;
330 324
331 if (!cs->connected) { 325 if (!cs->connected) {
332 gig_dbg(DEBUG_IF, "not connected"); 326 gig_dbg(DEBUG_IF, "not connected");
@@ -356,7 +350,7 @@ static int if_write(struct tty_struct *tty, const unsigned char *buf, int count)
356 gig_dbg(DEBUG_IF, "%u: %s()", cs->minor_index, __func__); 350 gig_dbg(DEBUG_IF, "%u: %s()", cs->minor_index, __func__);
357 351
358 if (mutex_lock_interruptible(&cs->mutex)) 352 if (mutex_lock_interruptible(&cs->mutex))
359 return -ERESTARTSYS; // FIXME -EINTR? 353 return -ERESTARTSYS;
360 354
361 if (!cs->connected) { 355 if (!cs->connected) {
362 gig_dbg(DEBUG_IF, "not connected"); 356 gig_dbg(DEBUG_IF, "not connected");
@@ -390,7 +384,7 @@ static int if_write_room(struct tty_struct *tty)
390 gig_dbg(DEBUG_IF, "%u: %s()", cs->minor_index, __func__); 384 gig_dbg(DEBUG_IF, "%u: %s()", cs->minor_index, __func__);
391 385
392 if (mutex_lock_interruptible(&cs->mutex)) 386 if (mutex_lock_interruptible(&cs->mutex))
393 return -ERESTARTSYS; // FIXME -EINTR? 387 return -ERESTARTSYS;
394 388
395 if (!cs->connected) { 389 if (!cs->connected) {
396 gig_dbg(DEBUG_IF, "not connected"); 390 gig_dbg(DEBUG_IF, "not connected");
@@ -455,9 +449,8 @@ static void if_throttle(struct tty_struct *tty)
455 gig_dbg(DEBUG_IF, "not connected"); /* nothing to do */ 449 gig_dbg(DEBUG_IF, "not connected"); /* nothing to do */
456 else if (!cs->open_count) 450 else if (!cs->open_count)
457 dev_warn(cs->dev, "%s: device not opened\n", __func__); 451 dev_warn(cs->dev, "%s: device not opened\n", __func__);
458 else { 452 else
459 //FIXME 453 gig_dbg(DEBUG_IF, "%s: not implemented\n", __func__);
460 }
461 454
462 mutex_unlock(&cs->mutex); 455 mutex_unlock(&cs->mutex);
463} 456}
@@ -480,9 +473,8 @@ static void if_unthrottle(struct tty_struct *tty)
480 gig_dbg(DEBUG_IF, "not connected"); /* nothing to do */ 473 gig_dbg(DEBUG_IF, "not connected"); /* nothing to do */
481 else if (!cs->open_count) 474 else if (!cs->open_count)
482 dev_warn(cs->dev, "%s: device not opened\n", __func__); 475 dev_warn(cs->dev, "%s: device not opened\n", __func__);
483 else { 476 else
484 //FIXME 477 gig_dbg(DEBUG_IF, "%s: not implemented\n", __func__);
485 }
486 478
487 mutex_unlock(&cs->mutex); 479 mutex_unlock(&cs->mutex);
488} 480}
@@ -515,10 +507,9 @@ static void if_set_termios(struct tty_struct *tty, struct ktermios *old)
515 goto out; 507 goto out;
516 } 508 }
517 509
518 // stolen from mct_u232.c
519 iflag = tty->termios->c_iflag; 510 iflag = tty->termios->c_iflag;
520 cflag = tty->termios->c_cflag; 511 cflag = tty->termios->c_cflag;
521 old_cflag = old ? old->c_cflag : cflag; //FIXME? 512 old_cflag = old ? old->c_cflag : cflag;
522 gig_dbg(DEBUG_IF, "%u: iflag %x cflag %x old %x", 513 gig_dbg(DEBUG_IF, "%u: iflag %x cflag %x old %x",
523 cs->minor_index, iflag, cflag, old_cflag); 514 cs->minor_index, iflag, cflag, old_cflag);
524 515
@@ -588,7 +579,7 @@ void gigaset_if_init(struct cardstate *cs)
588 if (!drv->have_tty) 579 if (!drv->have_tty)
589 return; 580 return;
590 581
591 tasklet_init(&cs->if_wake_tasklet, &if_wake, (unsigned long) cs); 582 tasklet_init(&cs->if_wake_tasklet, if_wake, (unsigned long) cs);
592 583
593 mutex_lock(&cs->mutex); 584 mutex_lock(&cs->mutex);
594 cs->tty_dev = tty_register_device(drv->tty, cs->minor_index, NULL); 585 cs->tty_dev = tty_register_device(drv->tty, cs->minor_index, NULL);
@@ -632,10 +623,10 @@ void gigaset_if_receive(struct cardstate *cs,
632 struct tty_struct *tty; 623 struct tty_struct *tty;
633 624
634 spin_lock_irqsave(&cs->lock, flags); 625 spin_lock_irqsave(&cs->lock, flags);
635 if ((tty = cs->tty) == NULL) 626 tty = cs->tty;
636 gig_dbg(DEBUG_ANY, "receive on closed device"); 627 if (tty == NULL)
628 gig_dbg(DEBUG_IF, "receive on closed device");
637 else { 629 else {
638 tty_buffer_request_room(tty, len);
639 tty_insert_flip_string(tty, buffer, len); 630 tty_insert_flip_string(tty, buffer, len);
640 tty_flip_buffer_push(tty); 631 tty_flip_buffer_push(tty);
641 } 632 }
@@ -659,9 +650,9 @@ void gigaset_if_initdriver(struct gigaset_driver *drv, const char *procname,
659 650
660 drv->have_tty = 0; 651 drv->have_tty = 0;
661 652
662 if ((drv->tty = alloc_tty_driver(minors)) == NULL) 653 drv->tty = tty = alloc_tty_driver(minors);
654 if (tty == NULL)
663 goto enomem; 655 goto enomem;
664 tty = drv->tty;
665 656
666 tty->magic = TTY_DRIVER_MAGIC, 657 tty->magic = TTY_DRIVER_MAGIC,
667 tty->major = GIG_MAJOR, 658 tty->major = GIG_MAJOR,
@@ -676,8 +667,8 @@ void gigaset_if_initdriver(struct gigaset_driver *drv, const char *procname,
676 667
677 tty->owner = THIS_MODULE; 668 tty->owner = THIS_MODULE;
678 669
679 tty->init_termios = tty_std_termios; //FIXME 670 tty->init_termios = tty_std_termios;
680 tty->init_termios.c_cflag = B9600 | CS8 | CREAD | HUPCL | CLOCAL; //FIXME 671 tty->init_termios.c_cflag = B9600 | CS8 | CREAD | HUPCL | CLOCAL;
681 tty_set_operations(tty, &if_ops); 672 tty_set_operations(tty, &if_ops);
682 673
683 ret = tty_register_driver(tty); 674 ret = tty_register_driver(tty);
diff --git a/drivers/isdn/gigaset/isocdata.c b/drivers/isdn/gigaset/isocdata.c
index 9f3ef7b4248c..16fd3bd48883 100644
--- a/drivers/isdn/gigaset/isocdata.c
+++ b/drivers/isdn/gigaset/isocdata.c
@@ -41,7 +41,8 @@ static inline int isowbuf_freebytes(struct isowbuf_t *iwb)
41 41
42 read = iwb->read; 42 read = iwb->read;
43 write = iwb->write; 43 write = iwb->write;
44 if ((freebytes = read - write) > 0) { 44 freebytes = read - write;
45 if (freebytes > 0) {
45 /* no wraparound: need padding space within regular area */ 46 /* no wraparound: need padding space within regular area */
46 return freebytes - BAS_OUTBUFPAD; 47 return freebytes - BAS_OUTBUFPAD;
47 } else if (read < BAS_OUTBUFPAD) { 48 } else if (read < BAS_OUTBUFPAD) {
@@ -53,29 +54,6 @@ static inline int isowbuf_freebytes(struct isowbuf_t *iwb)
53 } 54 }
54} 55}
55 56
56/* compare two offsets within the buffer
57 * The buffer is seen as circular, with the read position as start
58 * returns -1/0/1 if position a </=/> position b without crossing 'read'
59 */
60static inline int isowbuf_poscmp(struct isowbuf_t *iwb, int a, int b)
61{
62 int read;
63 if (a == b)
64 return 0;
65 read = iwb->read;
66 if (a < b) {
67 if (a < read && read <= b)
68 return +1;
69 else
70 return -1;
71 } else {
72 if (b < read && read <= a)
73 return -1;
74 else
75 return +1;
76 }
77}
78
79/* start writing 57/* start writing
80 * acquire the write semaphore 58 * acquire the write semaphore
81 * return true if acquired, false if busy 59 * return true if acquired, false if busy
@@ -271,7 +249,7 @@ static inline void dump_bytes(enum debuglevel level, const char *tag,
271 * bit 14..13 = number of bits added by stuffing 249 * bit 14..13 = number of bits added by stuffing
272 */ 250 */
273static const u16 stufftab[5 * 256] = { 251static const u16 stufftab[5 * 256] = {
274// previous 1s = 0: 252/* previous 1s = 0: */
275 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, 253 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f,
276 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, 0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x201f, 254 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, 0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x201f,
277 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, 255 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f,
@@ -289,7 +267,7 @@ static const u16 stufftab[5 * 256] = {
289 0x0ce0, 0x0ce1, 0x0ce2, 0x0ce3, 0x0ce4, 0x0ce5, 0x0ce6, 0x0ce7, 0x0ce8, 0x0ce9, 0x0cea, 0x0ceb, 0x0cec, 0x0ced, 0x0cee, 0x0cef, 267 0x0ce0, 0x0ce1, 0x0ce2, 0x0ce3, 0x0ce4, 0x0ce5, 0x0ce6, 0x0ce7, 0x0ce8, 0x0ce9, 0x0cea, 0x0ceb, 0x0cec, 0x0ced, 0x0cee, 0x0cef,
290 0x10f0, 0x10f1, 0x10f2, 0x10f3, 0x10f4, 0x10f5, 0x10f6, 0x10f7, 0x20f8, 0x20f9, 0x20fa, 0x20fb, 0x257c, 0x257d, 0x29be, 0x2ddf, 268 0x10f0, 0x10f1, 0x10f2, 0x10f3, 0x10f4, 0x10f5, 0x10f6, 0x10f7, 0x20f8, 0x20f9, 0x20fa, 0x20fb, 0x257c, 0x257d, 0x29be, 0x2ddf,
291 269
292// previous 1s = 1: 270/* previous 1s = 1: */
293 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x200f, 271 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x200f,
294 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, 0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x202f, 272 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, 0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x202f,
295 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x204f, 273 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x204f,
@@ -307,7 +285,7 @@ static const u16 stufftab[5 * 256] = {
307 0x0ce0, 0x0ce1, 0x0ce2, 0x0ce3, 0x0ce4, 0x0ce5, 0x0ce6, 0x0ce7, 0x0ce8, 0x0ce9, 0x0cea, 0x0ceb, 0x0cec, 0x0ced, 0x0cee, 0x2dcf, 285 0x0ce0, 0x0ce1, 0x0ce2, 0x0ce3, 0x0ce4, 0x0ce5, 0x0ce6, 0x0ce7, 0x0ce8, 0x0ce9, 0x0cea, 0x0ceb, 0x0cec, 0x0ced, 0x0cee, 0x2dcf,
308 0x10f0, 0x10f1, 0x10f2, 0x10f3, 0x10f4, 0x10f5, 0x10f6, 0x10f7, 0x20f8, 0x20f9, 0x20fa, 0x20fb, 0x257c, 0x257d, 0x29be, 0x31ef, 286 0x10f0, 0x10f1, 0x10f2, 0x10f3, 0x10f4, 0x10f5, 0x10f6, 0x10f7, 0x20f8, 0x20f9, 0x20fa, 0x20fb, 0x257c, 0x257d, 0x29be, 0x31ef,
309 287
310// previous 1s = 2: 288/* previous 1s = 2: */
311 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x2007, 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x2017, 289 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x2007, 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x2017,
312 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x2027, 0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x2037, 290 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x2027, 0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x2037,
313 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x2047, 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x2057, 291 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x2047, 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x2057,
@@ -325,7 +303,7 @@ static const u16 stufftab[5 * 256] = {
325 0x0ce0, 0x0ce1, 0x0ce2, 0x0ce3, 0x0ce4, 0x0ce5, 0x0ce6, 0x2dc7, 0x0ce8, 0x0ce9, 0x0cea, 0x0ceb, 0x0cec, 0x0ced, 0x0cee, 0x2dd7, 303 0x0ce0, 0x0ce1, 0x0ce2, 0x0ce3, 0x0ce4, 0x0ce5, 0x0ce6, 0x2dc7, 0x0ce8, 0x0ce9, 0x0cea, 0x0ceb, 0x0cec, 0x0ced, 0x0cee, 0x2dd7,
326 0x10f0, 0x10f1, 0x10f2, 0x10f3, 0x10f4, 0x10f5, 0x10f6, 0x31e7, 0x20f8, 0x20f9, 0x20fa, 0x20fb, 0x257c, 0x257d, 0x29be, 0x41f7, 304 0x10f0, 0x10f1, 0x10f2, 0x10f3, 0x10f4, 0x10f5, 0x10f6, 0x31e7, 0x20f8, 0x20f9, 0x20fa, 0x20fb, 0x257c, 0x257d, 0x29be, 0x41f7,
327 305
328// previous 1s = 3: 306/* previous 1s = 3: */
329 0x0000, 0x0001, 0x0002, 0x2003, 0x0004, 0x0005, 0x0006, 0x200b, 0x0008, 0x0009, 0x000a, 0x2013, 0x000c, 0x000d, 0x000e, 0x201b, 307 0x0000, 0x0001, 0x0002, 0x2003, 0x0004, 0x0005, 0x0006, 0x200b, 0x0008, 0x0009, 0x000a, 0x2013, 0x000c, 0x000d, 0x000e, 0x201b,
330 0x0010, 0x0011, 0x0012, 0x2023, 0x0014, 0x0015, 0x0016, 0x202b, 0x0018, 0x0019, 0x001a, 0x2033, 0x001c, 0x001d, 0x001e, 0x203b, 308 0x0010, 0x0011, 0x0012, 0x2023, 0x0014, 0x0015, 0x0016, 0x202b, 0x0018, 0x0019, 0x001a, 0x2033, 0x001c, 0x001d, 0x001e, 0x203b,
331 0x0020, 0x0021, 0x0022, 0x2043, 0x0024, 0x0025, 0x0026, 0x204b, 0x0028, 0x0029, 0x002a, 0x2053, 0x002c, 0x002d, 0x002e, 0x205b, 309 0x0020, 0x0021, 0x0022, 0x2043, 0x0024, 0x0025, 0x0026, 0x204b, 0x0028, 0x0029, 0x002a, 0x2053, 0x002c, 0x002d, 0x002e, 0x205b,
@@ -343,7 +321,7 @@ static const u16 stufftab[5 * 256] = {
343 0x0ce0, 0x0ce1, 0x0ce2, 0x2dc3, 0x0ce4, 0x0ce5, 0x0ce6, 0x2dcb, 0x0ce8, 0x0ce9, 0x0cea, 0x2dd3, 0x0cec, 0x0ced, 0x0cee, 0x2ddb, 321 0x0ce0, 0x0ce1, 0x0ce2, 0x2dc3, 0x0ce4, 0x0ce5, 0x0ce6, 0x2dcb, 0x0ce8, 0x0ce9, 0x0cea, 0x2dd3, 0x0cec, 0x0ced, 0x0cee, 0x2ddb,
344 0x10f0, 0x10f1, 0x10f2, 0x31e3, 0x10f4, 0x10f5, 0x10f6, 0x31eb, 0x20f8, 0x20f9, 0x20fa, 0x41f3, 0x257c, 0x257d, 0x29be, 0x46fb, 322 0x10f0, 0x10f1, 0x10f2, 0x31e3, 0x10f4, 0x10f5, 0x10f6, 0x31eb, 0x20f8, 0x20f9, 0x20fa, 0x41f3, 0x257c, 0x257d, 0x29be, 0x46fb,
345 323
346// previous 1s = 4: 324/* previous 1s = 4: */
347 0x0000, 0x2001, 0x0002, 0x2005, 0x0004, 0x2009, 0x0006, 0x200d, 0x0008, 0x2011, 0x000a, 0x2015, 0x000c, 0x2019, 0x000e, 0x201d, 325 0x0000, 0x2001, 0x0002, 0x2005, 0x0004, 0x2009, 0x0006, 0x200d, 0x0008, 0x2011, 0x000a, 0x2015, 0x000c, 0x2019, 0x000e, 0x201d,
348 0x0010, 0x2021, 0x0012, 0x2025, 0x0014, 0x2029, 0x0016, 0x202d, 0x0018, 0x2031, 0x001a, 0x2035, 0x001c, 0x2039, 0x001e, 0x203d, 326 0x0010, 0x2021, 0x0012, 0x2025, 0x0014, 0x2029, 0x0016, 0x202d, 0x0018, 0x2031, 0x001a, 0x2035, 0x001c, 0x2039, 0x001e, 0x203d,
349 0x0020, 0x2041, 0x0022, 0x2045, 0x0024, 0x2049, 0x0026, 0x204d, 0x0028, 0x2051, 0x002a, 0x2055, 0x002c, 0x2059, 0x002e, 0x205d, 327 0x0020, 0x2041, 0x0022, 0x2045, 0x0024, 0x2049, 0x0026, 0x204d, 0x0028, 0x2051, 0x002a, 0x2055, 0x002c, 0x2059, 0x002e, 0x205d,
@@ -367,7 +345,8 @@ static const u16 stufftab[5 * 256] = {
367 * parameters: 345 * parameters:
368 * cin input byte 346 * cin input byte
369 * ones number of trailing '1' bits in result before this step 347 * ones number of trailing '1' bits in result before this step
370 * iwb pointer to output buffer structure (write semaphore must be held) 348 * iwb pointer to output buffer structure
349 * (write semaphore must be held)
371 * return value: 350 * return value:
372 * number of trailing '1' bits in result after this step 351 * number of trailing '1' bits in result after this step
373 */ 352 */
@@ -408,7 +387,8 @@ static inline int hdlc_bitstuff_byte(struct isowbuf_t *iwb, unsigned char cin,
408 * parameters: 387 * parameters:
409 * in input buffer 388 * in input buffer
410 * count number of bytes in input buffer 389 * count number of bytes in input buffer
411 * iwb pointer to output buffer structure (write semaphore must be held) 390 * iwb pointer to output buffer structure
391 * (write semaphore must be held)
412 * return value: 392 * return value:
413 * position of end of packet in output buffer on success, 393 * position of end of packet in output buffer on success,
414 * -EAGAIN if write semaphore busy or buffer full 394 * -EAGAIN if write semaphore busy or buffer full
@@ -440,7 +420,8 @@ static inline int hdlc_buildframe(struct isowbuf_t *iwb,
440 fcs = crc_ccitt_byte(fcs, c); 420 fcs = crc_ccitt_byte(fcs, c);
441 } 421 }
442 422
443 /* bitstuff and append FCS (complemented, least significant byte first) */ 423 /* bitstuff and append FCS
424 * (complemented, least significant byte first) */
444 fcs ^= 0xffff; 425 fcs ^= 0xffff;
445 ones = hdlc_bitstuff_byte(iwb, fcs & 0x00ff, ones); 426 ones = hdlc_bitstuff_byte(iwb, fcs & 0x00ff, ones);
446 ones = hdlc_bitstuff_byte(iwb, (fcs >> 8) & 0x00ff, ones); 427 ones = hdlc_bitstuff_byte(iwb, (fcs >> 8) & 0x00ff, ones);
@@ -459,7 +440,8 @@ static inline int hdlc_buildframe(struct isowbuf_t *iwb,
459 * parameters: 440 * parameters:
460 * in input buffer 441 * in input buffer
461 * count number of bytes in input buffer 442 * count number of bytes in input buffer
462 * iwb pointer to output buffer structure (write semaphore must be held) 443 * iwb pointer to output buffer structure
444 * (write semaphore must be held)
463 * return value: 445 * return value:
464 * position of end of packet in output buffer on success, 446 * position of end of packet in output buffer on success,
465 * -EAGAIN if write semaphore busy or buffer full 447 * -EAGAIN if write semaphore busy or buffer full
@@ -500,7 +482,7 @@ int gigaset_isoc_buildframe(struct bc_state *bcs, unsigned char *in, int len)
500 int result; 482 int result;
501 483
502 switch (bcs->proto2) { 484 switch (bcs->proto2) {
503 case ISDN_PROTO_L2_HDLC: 485 case L2_HDLC:
504 result = hdlc_buildframe(bcs->hw.bas->isooutbuf, in, len); 486 result = hdlc_buildframe(bcs->hw.bas->isooutbuf, in, len);
505 gig_dbg(DEBUG_ISO, "%s: %d bytes HDLC -> %d", 487 gig_dbg(DEBUG_ISO, "%s: %d bytes HDLC -> %d",
506 __func__, len, result); 488 __func__, len, result);
@@ -542,8 +524,9 @@ static inline void hdlc_flush(struct bc_state *bcs)
542 if (likely(bcs->skb != NULL)) 524 if (likely(bcs->skb != NULL))
543 skb_trim(bcs->skb, 0); 525 skb_trim(bcs->skb, 0);
544 else if (!bcs->ignore) { 526 else if (!bcs->ignore) {
545 if ((bcs->skb = dev_alloc_skb(SBUFSIZE + HW_HDR_LEN)) != NULL) 527 bcs->skb = dev_alloc_skb(SBUFSIZE + bcs->cs->hw_hdr_len);
546 skb_reserve(bcs->skb, HW_HDR_LEN); 528 if (bcs->skb)
529 skb_reserve(bcs->skb, bcs->cs->hw_hdr_len);
547 else 530 else
548 dev_err(bcs->cs->dev, "could not allocate skb\n"); 531 dev_err(bcs->cs->dev, "could not allocate skb\n");
549 } 532 }
@@ -557,43 +540,46 @@ static inline void hdlc_flush(struct bc_state *bcs)
557 */ 540 */
558static inline void hdlc_done(struct bc_state *bcs) 541static inline void hdlc_done(struct bc_state *bcs)
559{ 542{
543 struct cardstate *cs = bcs->cs;
560 struct sk_buff *procskb; 544 struct sk_buff *procskb;
545 unsigned int len;
561 546
562 if (unlikely(bcs->ignore)) { 547 if (unlikely(bcs->ignore)) {
563 bcs->ignore--; 548 bcs->ignore--;
564 hdlc_flush(bcs); 549 hdlc_flush(bcs);
565 return; 550 return;
566 } 551 }
567 552 procskb = bcs->skb;
568 if ((procskb = bcs->skb) == NULL) { 553 if (procskb == NULL) {
569 /* previous error */ 554 /* previous error */
570 gig_dbg(DEBUG_ISO, "%s: skb=NULL", __func__); 555 gig_dbg(DEBUG_ISO, "%s: skb=NULL", __func__);
571 gigaset_rcv_error(NULL, bcs->cs, bcs); 556 gigaset_isdn_rcv_err(bcs);
572 } else if (procskb->len < 2) { 557 } else if (procskb->len < 2) {
573 dev_notice(bcs->cs->dev, "received short frame (%d octets)\n", 558 dev_notice(cs->dev, "received short frame (%d octets)\n",
574 procskb->len); 559 procskb->len);
575 bcs->hw.bas->runts++; 560 bcs->hw.bas->runts++;
576 gigaset_rcv_error(procskb, bcs->cs, bcs); 561 dev_kfree_skb_any(procskb);
562 gigaset_isdn_rcv_err(bcs);
577 } else if (bcs->fcs != PPP_GOODFCS) { 563 } else if (bcs->fcs != PPP_GOODFCS) {
578 dev_notice(bcs->cs->dev, "frame check error (0x%04x)\n", 564 dev_notice(cs->dev, "frame check error (0x%04x)\n", bcs->fcs);
579 bcs->fcs);
580 bcs->hw.bas->fcserrs++; 565 bcs->hw.bas->fcserrs++;
581 gigaset_rcv_error(procskb, bcs->cs, bcs); 566 dev_kfree_skb_any(procskb);
567 gigaset_isdn_rcv_err(bcs);
582 } else { 568 } else {
583 procskb->len -= 2; /* subtract FCS */ 569 len = procskb->len;
584 procskb->tail -= 2; 570 __skb_trim(procskb, len -= 2); /* subtract FCS */
585 gig_dbg(DEBUG_ISO, "%s: good frame (%d octets)", 571 gig_dbg(DEBUG_ISO, "%s: good frame (%d octets)", __func__, len);
586 __func__, procskb->len);
587 dump_bytes(DEBUG_STREAM_DUMP, 572 dump_bytes(DEBUG_STREAM_DUMP,
588 "rcv data", procskb->data, procskb->len); 573 "rcv data", procskb->data, len);
589 bcs->hw.bas->goodbytes += procskb->len; 574 bcs->hw.bas->goodbytes += len;
590 gigaset_rcv_skb(procskb, bcs->cs, bcs); 575 gigaset_skb_rcvd(bcs, procskb);
591 } 576 }
592 577
593 if ((bcs->skb = dev_alloc_skb(SBUFSIZE + HW_HDR_LEN)) != NULL) 578 bcs->skb = dev_alloc_skb(SBUFSIZE + cs->hw_hdr_len);
594 skb_reserve(bcs->skb, HW_HDR_LEN); 579 if (bcs->skb)
580 skb_reserve(bcs->skb, cs->hw_hdr_len);
595 else 581 else
596 dev_err(bcs->cs->dev, "could not allocate skb\n"); 582 dev_err(cs->dev, "could not allocate skb\n");
597 bcs->fcs = PPP_INITFCS; 583 bcs->fcs = PPP_INITFCS;
598} 584}
599 585
@@ -610,12 +596,8 @@ static inline void hdlc_frag(struct bc_state *bcs, unsigned inbits)
610 596
611 dev_notice(bcs->cs->dev, "received partial byte (%d bits)\n", inbits); 597 dev_notice(bcs->cs->dev, "received partial byte (%d bits)\n", inbits);
612 bcs->hw.bas->alignerrs++; 598 bcs->hw.bas->alignerrs++;
613 gigaset_rcv_error(bcs->skb, bcs->cs, bcs); 599 gigaset_isdn_rcv_err(bcs);
614 600 __skb_trim(bcs->skb, 0);
615 if ((bcs->skb = dev_alloc_skb(SBUFSIZE + HW_HDR_LEN)) != NULL)
616 skb_reserve(bcs->skb, HW_HDR_LEN);
617 else
618 dev_err(bcs->cs->dev, "could not allocate skb\n");
619 bcs->fcs = PPP_INITFCS; 601 bcs->fcs = PPP_INITFCS;
620} 602}
621 603
@@ -646,10 +628,10 @@ static const unsigned char bitcounts[256] = {
646}; 628};
647 629
648/* hdlc_unpack 630/* hdlc_unpack
649 * perform HDLC frame processing (bit unstuffing, flag detection, FCS calculation) 631 * perform HDLC frame processing (bit unstuffing, flag detection, FCS
650 * on a sequence of received data bytes (8 bits each, LSB first) 632 * calculation) on a sequence of received data bytes (8 bits each, LSB first)
651 * pass on successfully received, complete frames as SKBs via gigaset_rcv_skb 633 * pass on successfully received, complete frames as SKBs via gigaset_skb_rcvd
652 * notify of errors via gigaset_rcv_error 634 * notify of errors via gigaset_isdn_rcv_err
653 * tally frames, errors etc. in BC structure counters 635 * tally frames, errors etc. in BC structure counters
654 * parameters: 636 * parameters:
655 * src received data 637 * src received data
@@ -665,9 +647,12 @@ static inline void hdlc_unpack(unsigned char *src, unsigned count,
665 647
666 /* load previous state: 648 /* load previous state:
667 * inputstate = set of flag bits: 649 * inputstate = set of flag bits:
668 * - INS_flag_hunt: no complete opening flag received since connection setup or last abort 650 * - INS_flag_hunt: no complete opening flag received since connection
669 * - INS_have_data: at least one complete data byte received since last flag 651 * setup or last abort
670 * seqlen = number of consecutive '1' bits in last 7 input stream bits (0..7) 652 * - INS_have_data: at least one complete data byte received since last
653 * flag
654 * seqlen = number of consecutive '1' bits in last 7 input stream bits
655 * (0..7)
671 * inbyte = accumulated partial data byte (if !INS_flag_hunt) 656 * inbyte = accumulated partial data byte (if !INS_flag_hunt)
672 * inbits = number of valid bits in inbyte, starting at LSB (0..6) 657 * inbits = number of valid bits in inbyte, starting at LSB (0..6)
673 */ 658 */
@@ -701,9 +686,11 @@ static inline void hdlc_unpack(unsigned char *src, unsigned count,
701 inbyte = c >> (lead1 + 1); 686 inbyte = c >> (lead1 + 1);
702 inbits = 7 - lead1; 687 inbits = 7 - lead1;
703 if (trail1 >= 8) { 688 if (trail1 >= 8) {
704 /* interior stuffing: omitting the MSB handles most cases */ 689 /* interior stuffing:
690 * omitting the MSB handles most cases,
691 * correct the incorrectly handled
692 * cases individually */
705 inbits--; 693 inbits--;
706 /* correct the incorrectly handled cases individually */
707 switch (c) { 694 switch (c) {
708 case 0xbe: 695 case 0xbe:
709 inbyte = 0x3f; 696 inbyte = 0x3f;
@@ -729,13 +716,14 @@ static inline void hdlc_unpack(unsigned char *src, unsigned count,
729 hdlc_flush(bcs); 716 hdlc_flush(bcs);
730 inputstate |= INS_flag_hunt; 717 inputstate |= INS_flag_hunt;
731 } else if (seqlen == 6) { 718 } else if (seqlen == 6) {
732 /* closing flag, including (6 - lead1) '1's and one '0' from inbits */ 719 /* closing flag, including (6 - lead1) '1's
720 * and one '0' from inbits */
733 if (inbits > 7 - lead1) { 721 if (inbits > 7 - lead1) {
734 hdlc_frag(bcs, inbits + lead1 - 7); 722 hdlc_frag(bcs, inbits + lead1 - 7);
735 inputstate &= ~INS_have_data; 723 inputstate &= ~INS_have_data;
736 } else { 724 } else {
737 if (inbits < 7 - lead1) 725 if (inbits < 7 - lead1)
738 ubc->stolen0s ++; 726 ubc->stolen0s++;
739 if (inputstate & INS_have_data) { 727 if (inputstate & INS_have_data) {
740 hdlc_done(bcs); 728 hdlc_done(bcs);
741 inputstate &= ~INS_have_data; 729 inputstate &= ~INS_have_data;
@@ -744,7 +732,7 @@ static inline void hdlc_unpack(unsigned char *src, unsigned count,
744 732
745 if (c == PPP_FLAG) { 733 if (c == PPP_FLAG) {
746 /* complete flag, LSB overlaps preceding flag */ 734 /* complete flag, LSB overlaps preceding flag */
747 ubc->shared0s ++; 735 ubc->shared0s++;
748 inbits = 0; 736 inbits = 0;
749 inbyte = 0; 737 inbyte = 0;
750 } else if (trail1 != 7) { 738 } else if (trail1 != 7) {
@@ -752,9 +740,11 @@ static inline void hdlc_unpack(unsigned char *src, unsigned count,
752 inbyte = c >> (lead1 + 1); 740 inbyte = c >> (lead1 + 1);
753 inbits = 7 - lead1; 741 inbits = 7 - lead1;
754 if (trail1 >= 8) { 742 if (trail1 >= 8) {
755 /* interior stuffing: omitting the MSB handles most cases */ 743 /* interior stuffing:
744 * omitting the MSB handles most cases,
745 * correct the incorrectly handled
746 * cases individually */
756 inbits--; 747 inbits--;
757 /* correct the incorrectly handled cases individually */
758 switch (c) { 748 switch (c) {
759 case 0xbe: 749 case 0xbe:
760 inbyte = 0x3f; 750 inbyte = 0x3f;
@@ -762,7 +752,8 @@ static inline void hdlc_unpack(unsigned char *src, unsigned count,
762 } 752 }
763 } 753 }
764 } else { 754 } else {
765 /* abort sequence follows, skb already empty anyway */ 755 /* abort sequence follows,
756 * skb already empty anyway */
766 ubc->aborts++; 757 ubc->aborts++;
767 inputstate |= INS_flag_hunt; 758 inputstate |= INS_flag_hunt;
768 } 759 }
@@ -787,14 +778,17 @@ static inline void hdlc_unpack(unsigned char *src, unsigned count,
787 } else { 778 } else {
788 /* stuffed data */ 779 /* stuffed data */
789 if (trail1 < 7) { /* => seqlen == 5 */ 780 if (trail1 < 7) { /* => seqlen == 5 */
790 /* stuff bit at position lead1, no interior stuffing */ 781 /* stuff bit at position lead1,
782 * no interior stuffing */
791 unsigned char mask = (1 << lead1) - 1; 783 unsigned char mask = (1 << lead1) - 1;
792 c = (c & mask) | ((c & ~mask) >> 1); 784 c = (c & mask) | ((c & ~mask) >> 1);
793 inbyte |= c << inbits; 785 inbyte |= c << inbits;
794 inbits += 7; 786 inbits += 7;
795 } else if (seqlen < 5) { /* trail1 >= 8 */ 787 } else if (seqlen < 5) { /* trail1 >= 8 */
796 /* interior stuffing: omitting the MSB handles most cases */ 788 /* interior stuffing:
797 /* correct the incorrectly handled cases individually */ 789 * omitting the MSB handles most cases,
790 * correct the incorrectly handled
791 * cases individually */
798 switch (c) { 792 switch (c) {
799 case 0xbe: 793 case 0xbe:
800 c = 0x7e; 794 c = 0x7e;
@@ -804,8 +798,9 @@ static inline void hdlc_unpack(unsigned char *src, unsigned count,
804 inbits += 7; 798 inbits += 7;
805 } else { /* seqlen == 5 && trail1 >= 8 */ 799 } else { /* seqlen == 5 && trail1 >= 8 */
806 800
807 /* stuff bit at lead1 *and* interior stuffing */ 801 /* stuff bit at lead1 *and* interior
808 switch (c) { /* unstuff individually */ 802 * stuffing -- unstuff individually */
803 switch (c) {
809 case 0x7d: 804 case 0x7d:
810 c = 0x3f; 805 c = 0x3f;
811 break; 806 break;
@@ -841,7 +836,7 @@ static inline void hdlc_unpack(unsigned char *src, unsigned count,
841} 836}
842 837
843/* trans_receive 838/* trans_receive
844 * pass on received USB frame transparently as SKB via gigaset_rcv_skb 839 * pass on received USB frame transparently as SKB via gigaset_skb_rcvd
845 * invert bytes 840 * invert bytes
846 * tally frames, errors etc. in BC structure counters 841 * tally frames, errors etc. in BC structure counters
847 * parameters: 842 * parameters:
@@ -852,6 +847,7 @@ static inline void hdlc_unpack(unsigned char *src, unsigned count,
852static inline void trans_receive(unsigned char *src, unsigned count, 847static inline void trans_receive(unsigned char *src, unsigned count,
853 struct bc_state *bcs) 848 struct bc_state *bcs)
854{ 849{
850 struct cardstate *cs = bcs->cs;
855 struct sk_buff *skb; 851 struct sk_buff *skb;
856 int dobytes; 852 int dobytes;
857 unsigned char *dst; 853 unsigned char *dst;
@@ -861,13 +857,14 @@ static inline void trans_receive(unsigned char *src, unsigned count,
861 hdlc_flush(bcs); 857 hdlc_flush(bcs);
862 return; 858 return;
863 } 859 }
864 if (unlikely((skb = bcs->skb) == NULL)) { 860 skb = bcs->skb;
865 bcs->skb = skb = dev_alloc_skb(SBUFSIZE + HW_HDR_LEN); 861 if (unlikely(skb == NULL)) {
862 bcs->skb = skb = dev_alloc_skb(SBUFSIZE + cs->hw_hdr_len);
866 if (!skb) { 863 if (!skb) {
867 dev_err(bcs->cs->dev, "could not allocate skb\n"); 864 dev_err(cs->dev, "could not allocate skb\n");
868 return; 865 return;
869 } 866 }
870 skb_reserve(skb, HW_HDR_LEN); 867 skb_reserve(skb, cs->hw_hdr_len);
871 } 868 }
872 bcs->hw.bas->goodbytes += skb->len; 869 bcs->hw.bas->goodbytes += skb->len;
873 dobytes = TRANSBUFSIZE - skb->len; 870 dobytes = TRANSBUFSIZE - skb->len;
@@ -881,23 +878,24 @@ static inline void trans_receive(unsigned char *src, unsigned count,
881 if (dobytes == 0) { 878 if (dobytes == 0) {
882 dump_bytes(DEBUG_STREAM_DUMP, 879 dump_bytes(DEBUG_STREAM_DUMP,
883 "rcv data", skb->data, skb->len); 880 "rcv data", skb->data, skb->len);
884 gigaset_rcv_skb(skb, bcs->cs, bcs); 881 gigaset_skb_rcvd(bcs, skb);
885 bcs->skb = skb = dev_alloc_skb(SBUFSIZE + HW_HDR_LEN); 882 bcs->skb = skb =
883 dev_alloc_skb(SBUFSIZE + cs->hw_hdr_len);
886 if (!skb) { 884 if (!skb) {
887 dev_err(bcs->cs->dev, 885 dev_err(cs->dev, "could not allocate skb\n");
888 "could not allocate skb\n");
889 return; 886 return;
890 } 887 }
891 skb_reserve(bcs->skb, HW_HDR_LEN); 888 skb_reserve(skb, cs->hw_hdr_len);
892 dobytes = TRANSBUFSIZE; 889 dobytes = TRANSBUFSIZE;
893 } 890 }
894 } 891 }
895} 892}
896 893
897void gigaset_isoc_receive(unsigned char *src, unsigned count, struct bc_state *bcs) 894void gigaset_isoc_receive(unsigned char *src, unsigned count,
895 struct bc_state *bcs)
898{ 896{
899 switch (bcs->proto2) { 897 switch (bcs->proto2) {
900 case ISDN_PROTO_L2_HDLC: 898 case L2_HDLC:
901 hdlc_unpack(src, count, bcs); 899 hdlc_unpack(src, count, bcs);
902 break; 900 break;
903 default: /* assume transparent */ 901 default: /* assume transparent */
@@ -907,29 +905,49 @@ void gigaset_isoc_receive(unsigned char *src, unsigned count, struct bc_state *b
907 905
908/* == data input =========================================================== */ 906/* == data input =========================================================== */
909 907
908/* process a block of received bytes in command mode (mstate != MS_LOCKED)
909 * Append received bytes to the command response buffer and forward them
910 * line by line to the response handler.
911 * Note: Received lines may be terminated by CR, LF, or CR LF, which will be
912 * removed before passing the line to the response handler.
913 */
910static void cmd_loop(unsigned char *src, int numbytes, struct inbuf_t *inbuf) 914static void cmd_loop(unsigned char *src, int numbytes, struct inbuf_t *inbuf)
911{ 915{
912 struct cardstate *cs = inbuf->cs; 916 struct cardstate *cs = inbuf->cs;
913 unsigned cbytes = cs->cbytes; 917 unsigned cbytes = cs->cbytes;
918 unsigned char c;
914 919
915 while (numbytes--) { 920 while (numbytes--) {
916 /* copy next character, check for end of line */ 921 c = *src++;
917 switch (cs->respdata[cbytes] = *src++) { 922 switch (c) {
918 case '\r':
919 case '\n': 923 case '\n':
920 /* end of line */ 924 if (cbytes == 0 && cs->respdata[0] == '\r') {
921 gig_dbg(DEBUG_TRANSCMD, "%s: End of Command (%d Bytes)", 925 /* collapse LF with preceding CR */
922 __func__, cbytes); 926 cs->respdata[0] = 0;
923 if (cbytes >= MAX_RESP_SIZE - 1) 927 break;
924 dev_warn(cs->dev, "response too large\n"); 928 }
929 /* --v-- fall through --v-- */
930 case '\r':
931 /* end of message line, pass to response handler */
932 if (cbytes >= MAX_RESP_SIZE) {
933 dev_warn(cs->dev, "response too large (%d)\n",
934 cbytes);
935 cbytes = MAX_RESP_SIZE;
936 }
925 cs->cbytes = cbytes; 937 cs->cbytes = cbytes;
938 gigaset_dbg_buffer(DEBUG_TRANSCMD, "received response",
939 cbytes, cs->respdata);
926 gigaset_handle_modem_response(cs); 940 gigaset_handle_modem_response(cs);
927 cbytes = 0; 941 cbytes = 0;
942
943 /* store EOL byte for CRLF collapsing */
944 cs->respdata[0] = c;
928 break; 945 break;
929 default: 946 default:
930 /* advance in line buffer, checking for overflow */ 947 /* append to line buffer if possible */
931 if (cbytes < MAX_RESP_SIZE - 1) 948 if (cbytes < MAX_RESP_SIZE)
932 cbytes++; 949 cs->respdata[cbytes] = c;
950 cbytes++;
933 } 951 }
934 } 952 }
935 953
@@ -960,8 +978,6 @@ void gigaset_isoc_input(struct inbuf_t *inbuf)
960 numbytes, src); 978 numbytes, src);
961 gigaset_if_receive(inbuf->cs, src, numbytes); 979 gigaset_if_receive(inbuf->cs, src, numbytes);
962 } else { 980 } else {
963 gigaset_dbg_buffer(DEBUG_CMD, "received response",
964 numbytes, src);
965 cmd_loop(src, numbytes, inbuf); 981 cmd_loop(src, numbytes, inbuf);
966 } 982 }
967 983
@@ -981,8 +997,10 @@ void gigaset_isoc_input(struct inbuf_t *inbuf)
981 * @bcs: B channel descriptor structure. 997 * @bcs: B channel descriptor structure.
982 * @skb: data to send. 998 * @skb: data to send.
983 * 999 *
984 * Called by i4l.c to queue an skb for sending, and start transmission if 1000 * Called by LL to queue an skb for sending, and start transmission if
985 * necessary. 1001 * necessary.
1002 * Once the payload data has been transmitted completely, gigaset_skb_sent()
1003 * will be called with the skb's link layer header preserved.
986 * 1004 *
987 * Return value: 1005 * Return value:
988 * number of bytes accepted for sending (skb->len) if ok, 1006 * number of bytes accepted for sending (skb->len) if ok,
diff --git a/drivers/isdn/gigaset/proc.c b/drivers/isdn/gigaset/proc.c
index 9715aad9c3f0..b943efbff44d 100644
--- a/drivers/isdn/gigaset/proc.c
+++ b/drivers/isdn/gigaset/proc.c
@@ -14,7 +14,6 @@
14 */ 14 */
15 15
16#include "gigaset.h" 16#include "gigaset.h"
17#include <linux/ctype.h>
18 17
19static ssize_t show_cidmode(struct device *dev, 18static ssize_t show_cidmode(struct device *dev,
20 struct device_attribute *attr, char *buf) 19 struct device_attribute *attr, char *buf)
@@ -39,7 +38,7 @@ static ssize_t set_cidmode(struct device *dev, struct device_attribute *attr,
39 return -EINVAL; 38 return -EINVAL;
40 39
41 if (mutex_lock_interruptible(&cs->mutex)) 40 if (mutex_lock_interruptible(&cs->mutex))
42 return -ERESTARTSYS; // FIXME -EINTR? 41 return -ERESTARTSYS;
43 42
44 cs->waiting = 1; 43 cs->waiting = 1;
45 if (!gigaset_add_event(cs, &cs->at_state, EV_PROC_CIDMODE, 44 if (!gigaset_add_event(cs, &cs->at_state, EV_PROC_CIDMODE,
@@ -48,8 +47,6 @@ static ssize_t set_cidmode(struct device *dev, struct device_attribute *attr,
48 mutex_unlock(&cs->mutex); 47 mutex_unlock(&cs->mutex);
49 return -ENOMEM; 48 return -ENOMEM;
50 } 49 }
51
52 gig_dbg(DEBUG_CMD, "scheduling PROC_CIDMODE");
53 gigaset_schedule_event(cs); 50 gigaset_schedule_event(cs);
54 51
55 wait_event(cs->waitqueue, !cs->waiting); 52 wait_event(cs->waitqueue, !cs->waiting);
diff --git a/drivers/isdn/gigaset/ser-gigaset.c b/drivers/isdn/gigaset/ser-gigaset.c
index 3071a52467ed..e96c0586886c 100644
--- a/drivers/isdn/gigaset/ser-gigaset.c
+++ b/drivers/isdn/gigaset/ser-gigaset.c
@@ -11,11 +11,9 @@
11 */ 11 */
12 12
13#include "gigaset.h" 13#include "gigaset.h"
14
15#include <linux/module.h> 14#include <linux/module.h>
16#include <linux/moduleparam.h> 15#include <linux/moduleparam.h>
17#include <linux/platform_device.h> 16#include <linux/platform_device.h>
18#include <linux/tty.h>
19#include <linux/completion.h> 17#include <linux/completion.h>
20 18
21/* Version Information */ 19/* Version Information */
@@ -164,9 +162,15 @@ static void gigaset_modem_fill(unsigned long data)
164{ 162{
165 struct cardstate *cs = (struct cardstate *) data; 163 struct cardstate *cs = (struct cardstate *) data;
166 struct bc_state *bcs; 164 struct bc_state *bcs;
165 struct sk_buff *nextskb;
167 int sent = 0; 166 int sent = 0;
168 167
169 if (!cs || !(bcs = cs->bcs)) { 168 if (!cs) {
169 gig_dbg(DEBUG_OUTPUT, "%s: no cardstate", __func__);
170 return;
171 }
172 bcs = cs->bcs;
173 if (!bcs) {
170 gig_dbg(DEBUG_OUTPUT, "%s: no cardstate", __func__); 174 gig_dbg(DEBUG_OUTPUT, "%s: no cardstate", __func__);
171 return; 175 return;
172 } 176 }
@@ -179,9 +183,11 @@ static void gigaset_modem_fill(unsigned long data)
179 return; 183 return;
180 184
181 /* no command to send; get skb */ 185 /* no command to send; get skb */
182 if (!(bcs->tx_skb = skb_dequeue(&bcs->squeue))) 186 nextskb = skb_dequeue(&bcs->squeue);
187 if (!nextskb)
183 /* no skb either, nothing to do */ 188 /* no skb either, nothing to do */
184 return; 189 return;
190 bcs->tx_skb = nextskb;
185 191
186 gig_dbg(DEBUG_INTR, "Dequeued skb (Adr: %lx)", 192 gig_dbg(DEBUG_INTR, "Dequeued skb (Adr: %lx)",
187 (unsigned long) bcs->tx_skb); 193 (unsigned long) bcs->tx_skb);
@@ -236,19 +242,20 @@ static void flush_send_queue(struct cardstate *cs)
236 * number of bytes queued, or error code < 0 242 * number of bytes queued, or error code < 0
237 */ 243 */
238static int gigaset_write_cmd(struct cardstate *cs, const unsigned char *buf, 244static int gigaset_write_cmd(struct cardstate *cs, const unsigned char *buf,
239 int len, struct tasklet_struct *wake_tasklet) 245 int len, struct tasklet_struct *wake_tasklet)
240{ 246{
241 struct cmdbuf_t *cb; 247 struct cmdbuf_t *cb;
242 unsigned long flags; 248 unsigned long flags;
243 249
244 gigaset_dbg_buffer(cs->mstate != MS_LOCKED ? 250 gigaset_dbg_buffer(cs->mstate != MS_LOCKED ?
245 DEBUG_TRANSCMD : DEBUG_LOCKCMD, 251 DEBUG_TRANSCMD : DEBUG_LOCKCMD,
246 "CMD Transmit", len, buf); 252 "CMD Transmit", len, buf);
247 253
248 if (len <= 0) 254 if (len <= 0)
249 return 0; 255 return 0;
250 256
251 if (!(cb = kmalloc(sizeof(struct cmdbuf_t) + len, GFP_ATOMIC))) { 257 cb = kmalloc(sizeof(struct cmdbuf_t) + len, GFP_ATOMIC);
258 if (!cb) {
252 dev_err(cs->dev, "%s: out of memory!\n", __func__); 259 dev_err(cs->dev, "%s: out of memory!\n", __func__);
253 return -ENOMEM; 260 return -ENOMEM;
254 } 261 }
@@ -392,7 +399,6 @@ static void gigaset_device_release(struct device *dev)
392 struct platform_device *pdev = to_platform_device(dev); 399 struct platform_device *pdev = to_platform_device(dev);
393 400
394 /* adapted from platform_device_release() in drivers/base/platform.c */ 401 /* adapted from platform_device_release() in drivers/base/platform.c */
395 //FIXME is this actually necessary?
396 kfree(dev->platform_data); 402 kfree(dev->platform_data);
397 kfree(pdev->resource); 403 kfree(pdev->resource);
398} 404}
@@ -404,16 +410,20 @@ static void gigaset_device_release(struct device *dev)
404static int gigaset_initcshw(struct cardstate *cs) 410static int gigaset_initcshw(struct cardstate *cs)
405{ 411{
406 int rc; 412 int rc;
413 struct ser_cardstate *scs;
407 414
408 if (!(cs->hw.ser = kzalloc(sizeof(struct ser_cardstate), GFP_KERNEL))) { 415 scs = kzalloc(sizeof(struct ser_cardstate), GFP_KERNEL);
416 if (!scs) {
409 pr_err("out of memory\n"); 417 pr_err("out of memory\n");
410 return 0; 418 return 0;
411 } 419 }
420 cs->hw.ser = scs;
412 421
413 cs->hw.ser->dev.name = GIGASET_MODULENAME; 422 cs->hw.ser->dev.name = GIGASET_MODULENAME;
414 cs->hw.ser->dev.id = cs->minor_index; 423 cs->hw.ser->dev.id = cs->minor_index;
415 cs->hw.ser->dev.dev.release = gigaset_device_release; 424 cs->hw.ser->dev.dev.release = gigaset_device_release;
416 if ((rc = platform_device_register(&cs->hw.ser->dev)) != 0) { 425 rc = platform_device_register(&cs->hw.ser->dev);
426 if (rc != 0) {
417 pr_err("error %d registering platform device\n", rc); 427 pr_err("error %d registering platform device\n", rc);
418 kfree(cs->hw.ser); 428 kfree(cs->hw.ser);
419 cs->hw.ser = NULL; 429 cs->hw.ser = NULL;
@@ -422,7 +432,7 @@ static int gigaset_initcshw(struct cardstate *cs)
422 dev_set_drvdata(&cs->hw.ser->dev.dev, cs); 432 dev_set_drvdata(&cs->hw.ser->dev.dev, cs);
423 433
424 tasklet_init(&cs->write_tasklet, 434 tasklet_init(&cs->write_tasklet,
425 &gigaset_modem_fill, (unsigned long) cs); 435 gigaset_modem_fill, (unsigned long) cs);
426 return 1; 436 return 1;
427} 437}
428 438
@@ -434,7 +444,8 @@ static int gigaset_initcshw(struct cardstate *cs)
434 * Called by "gigaset_start" and "gigaset_enterconfigmode" in common.c 444 * Called by "gigaset_start" and "gigaset_enterconfigmode" in common.c
435 * and by "if_lock" and "if_termios" in interface.c 445 * and by "if_lock" and "if_termios" in interface.c
436 */ 446 */
437static int gigaset_set_modem_ctrl(struct cardstate *cs, unsigned old_state, unsigned new_state) 447static int gigaset_set_modem_ctrl(struct cardstate *cs, unsigned old_state,
448 unsigned new_state)
438{ 449{
439 struct tty_struct *tty = cs->hw.ser->tty; 450 struct tty_struct *tty = cs->hw.ser->tty;
440 unsigned int set, clear; 451 unsigned int set, clear;
@@ -520,8 +531,8 @@ gigaset_tty_open(struct tty_struct *tty)
520 } 531 }
521 532
522 /* allocate memory for our device state and intialize it */ 533 /* allocate memory for our device state and intialize it */
523 if (!(cs = gigaset_initcs(driver, 1, 1, 0, cidmode, 534 cs = gigaset_initcs(driver, 1, 1, 0, cidmode, GIGASET_MODULENAME);
524 GIGASET_MODULENAME))) 535 if (!cs)
525 goto error; 536 goto error;
526 537
527 cs->dev = &cs->hw.ser->dev.dev; 538 cs->dev = &cs->hw.ser->dev.dev;
@@ -690,7 +701,8 @@ gigaset_tty_receive(struct tty_struct *tty, const unsigned char *buf,
690 701
691 if (!cs) 702 if (!cs)
692 return; 703 return;
693 if (!(inbuf = cs->inbuf)) { 704 inbuf = cs->inbuf;
705 if (!inbuf) {
694 dev_err(cs->dev, "%s: no inbuf\n", __func__); 706 dev_err(cs->dev, "%s: no inbuf\n", __func__);
695 cs_put(cs); 707 cs_put(cs);
696 return; 708 return;
@@ -770,18 +782,21 @@ static int __init ser_gigaset_init(void)
770 int rc; 782 int rc;
771 783
772 gig_dbg(DEBUG_INIT, "%s", __func__); 784 gig_dbg(DEBUG_INIT, "%s", __func__);
773 if ((rc = platform_driver_register(&device_driver)) != 0) { 785 rc = platform_driver_register(&device_driver);
786 if (rc != 0) {
774 pr_err("error %d registering platform driver\n", rc); 787 pr_err("error %d registering platform driver\n", rc);
775 return rc; 788 return rc;
776 } 789 }
777 790
778 /* allocate memory for our driver state and intialize it */ 791 /* allocate memory for our driver state and intialize it */
779 if (!(driver = gigaset_initdriver(GIGASET_MINOR, GIGASET_MINORS, 792 driver = gigaset_initdriver(GIGASET_MINOR, GIGASET_MINORS,
780 GIGASET_MODULENAME, GIGASET_DEVNAME, 793 GIGASET_MODULENAME, GIGASET_DEVNAME,
781 &ops, THIS_MODULE))) 794 &ops, THIS_MODULE);
795 if (!driver)
782 goto error; 796 goto error;
783 797
784 if ((rc = tty_register_ldisc(N_GIGASET_M101, &gigaset_ldisc)) != 0) { 798 rc = tty_register_ldisc(N_GIGASET_M101, &gigaset_ldisc);
799 if (rc != 0) {
785 pr_err("error %d registering line discipline\n", rc); 800 pr_err("error %d registering line discipline\n", rc);
786 goto error; 801 goto error;
787 } 802 }
@@ -808,7 +823,8 @@ static void __exit ser_gigaset_exit(void)
808 driver = NULL; 823 driver = NULL;
809 } 824 }
810 825
811 if ((rc = tty_unregister_ldisc(N_GIGASET_M101)) != 0) 826 rc = tty_unregister_ldisc(N_GIGASET_M101);
827 if (rc != 0)
812 pr_err("error %d unregistering line discipline\n", rc); 828 pr_err("error %d unregistering line discipline\n", rc);
813 829
814 platform_driver_unregister(&device_driver); 830 platform_driver_unregister(&device_driver);
diff --git a/drivers/isdn/gigaset/usb-gigaset.c b/drivers/isdn/gigaset/usb-gigaset.c
index 4deb1ab0dbf8..76dbb20f3065 100644
--- a/drivers/isdn/gigaset/usb-gigaset.c
+++ b/drivers/isdn/gigaset/usb-gigaset.c
@@ -16,10 +16,6 @@
16 */ 16 */
17 17
18#include "gigaset.h" 18#include "gigaset.h"
19
20#include <linux/errno.h>
21#include <linux/init.h>
22#include <linux/slab.h>
23#include <linux/usb.h> 19#include <linux/usb.h>
24#include <linux/module.h> 20#include <linux/module.h>
25#include <linux/moduleparam.h> 21#include <linux/moduleparam.h>
@@ -43,14 +39,14 @@ MODULE_PARM_DESC(cidmode, "Call-ID mode");
43#define GIGASET_MODULENAME "usb_gigaset" 39#define GIGASET_MODULENAME "usb_gigaset"
44#define GIGASET_DEVNAME "ttyGU" 40#define GIGASET_DEVNAME "ttyGU"
45 41
46#define IF_WRITEBUF 2000 //FIXME // WAKEUP_CHARS: 256 42#define IF_WRITEBUF 2000 /* arbitrary limit */
47 43
48/* Values for the Gigaset M105 Data */ 44/* Values for the Gigaset M105 Data */
49#define USB_M105_VENDOR_ID 0x0681 45#define USB_M105_VENDOR_ID 0x0681
50#define USB_M105_PRODUCT_ID 0x0009 46#define USB_M105_PRODUCT_ID 0x0009
51 47
52/* table of devices that work with this driver */ 48/* table of devices that work with this driver */
53static const struct usb_device_id gigaset_table [] = { 49static const struct usb_device_id gigaset_table[] = {
54 { USB_DEVICE(USB_M105_VENDOR_ID, USB_M105_PRODUCT_ID) }, 50 { USB_DEVICE(USB_M105_VENDOR_ID, USB_M105_PRODUCT_ID) },
55 { } /* Terminating entry */ 51 { } /* Terminating entry */
56}; 52};
@@ -97,8 +93,8 @@ MODULE_DEVICE_TABLE(usb, gigaset_table);
97 * 41 19 -- -- -- -- 06 00 00 00 00 xx 11 13 93 * 41 19 -- -- -- -- 06 00 00 00 00 xx 11 13
98 * Used after every "configuration sequence" (RQ 12, RQs 01/03/13). 94 * Used after every "configuration sequence" (RQ 12, RQs 01/03/13).
99 * xx is usually 0x00 but was 0x7e before starting data transfer 95 * xx is usually 0x00 but was 0x7e before starting data transfer
100 * in unimodem mode. So, this might be an array of characters that need 96 * in unimodem mode. So, this might be an array of characters that
101 * special treatment ("commit all bufferd data"?), 11=^Q, 13=^S. 97 * need special treatment ("commit all bufferd data"?), 11=^Q, 13=^S.
102 * 98 *
103 * Unimodem mode: use "modprobe ppp_async flag_time=0" as the device _needs_ two 99 * Unimodem mode: use "modprobe ppp_async flag_time=0" as the device _needs_ two
104 * flags per packet. 100 * flags per packet.
@@ -114,7 +110,7 @@ static int gigaset_suspend(struct usb_interface *intf, pm_message_t message);
114static int gigaset_resume(struct usb_interface *intf); 110static int gigaset_resume(struct usb_interface *intf);
115static int gigaset_pre_reset(struct usb_interface *intf); 111static int gigaset_pre_reset(struct usb_interface *intf);
116 112
117static struct gigaset_driver *driver = NULL; 113static struct gigaset_driver *driver;
118 114
119/* usb specific object needed to register this driver with the usb subsystem */ 115/* usb specific object needed to register this driver with the usb subsystem */
120static struct usb_driver gigaset_usb_driver = { 116static struct usb_driver gigaset_usb_driver = {
@@ -141,6 +137,7 @@ struct usb_cardstate {
141 struct urb *bulk_out_urb; 137 struct urb *bulk_out_urb;
142 138
143 /* Input buffer */ 139 /* Input buffer */
140 unsigned char *rcvbuf;
144 int rcvbuf_size; 141 int rcvbuf_size;
145 struct urb *read_urb; 142 struct urb *read_urb;
146 __u8 int_in_endpointAddr; 143 __u8 int_in_endpointAddr;
@@ -164,13 +161,11 @@ static int gigaset_set_modem_ctrl(struct cardstate *cs, unsigned old_state,
164 val = tiocm_to_gigaset(new_state); 161 val = tiocm_to_gigaset(new_state);
165 162
166 gig_dbg(DEBUG_USBREQ, "set flags 0x%02x with mask 0x%02x", val, mask); 163 gig_dbg(DEBUG_USBREQ, "set flags 0x%02x with mask 0x%02x", val, mask);
167 // don't use this in an interrupt/BH
168 r = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 7, 0x41, 164 r = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 7, 0x41,
169 (val & 0xff) | ((mask & 0xff) << 8), 0, 165 (val & 0xff) | ((mask & 0xff) << 8), 0,
170 NULL, 0, 2000 /* timeout? */); 166 NULL, 0, 2000 /* timeout? */);
171 if (r < 0) 167 if (r < 0)
172 return r; 168 return r;
173 //..
174 return 0; 169 return 0;
175} 170}
176 171
@@ -220,7 +215,6 @@ static int gigaset_baud_rate(struct cardstate *cs, unsigned cflag)
220 cflag &= CBAUD; 215 cflag &= CBAUD;
221 216
222 switch (cflag) { 217 switch (cflag) {
223 //FIXME more values?
224 case B300: rate = 300; break; 218 case B300: rate = 300; break;
225 case B600: rate = 600; break; 219 case B600: rate = 600; break;
226 case B1200: rate = 1200; break; 220 case B1200: rate = 1200; break;
@@ -273,7 +267,7 @@ static int gigaset_set_line_ctrl(struct cardstate *cs, unsigned cflag)
273 /* set the number of stop bits */ 267 /* set the number of stop bits */
274 if (cflag & CSTOPB) { 268 if (cflag & CSTOPB) {
275 if ((cflag & CSIZE) == CS5) 269 if ((cflag & CSIZE) == CS5)
276 val |= 1; /* 1.5 stop bits */ //FIXME is this okay? 270 val |= 1; /* 1.5 stop bits */
277 else 271 else
278 val |= 2; /* 2 stop bits */ 272 val |= 2; /* 2 stop bits */
279 } 273 }
@@ -282,7 +276,7 @@ static int gigaset_set_line_ctrl(struct cardstate *cs, unsigned cflag)
282} 276}
283 277
284 278
285 /*================================================================================================================*/ 279/*============================================================================*/
286static int gigaset_init_bchannel(struct bc_state *bcs) 280static int gigaset_init_bchannel(struct bc_state *bcs)
287{ 281{
288 /* nothing to do for M10x */ 282 /* nothing to do for M10x */
@@ -344,7 +338,6 @@ static void gigaset_modem_fill(unsigned long data)
344 if (write_modem(cs) < 0) { 338 if (write_modem(cs) < 0) {
345 gig_dbg(DEBUG_OUTPUT, 339 gig_dbg(DEBUG_OUTPUT,
346 "modem_fill: write_modem failed"); 340 "modem_fill: write_modem failed");
347 // FIXME should we tell the LL?
348 again = 1; /* no callback will be called! */ 341 again = 1; /* no callback will be called! */
349 } 342 }
350 } 343 }
@@ -356,8 +349,8 @@ static void gigaset_modem_fill(unsigned long data)
356 */ 349 */
357static void gigaset_read_int_callback(struct urb *urb) 350static void gigaset_read_int_callback(struct urb *urb)
358{ 351{
359 struct inbuf_t *inbuf = urb->context; 352 struct cardstate *cs = urb->context;
360 struct cardstate *cs = inbuf->cs; 353 struct inbuf_t *inbuf = cs->inbuf;
361 int status = urb->status; 354 int status = urb->status;
362 int r; 355 int r;
363 unsigned numbytes; 356 unsigned numbytes;
@@ -368,7 +361,7 @@ static void gigaset_read_int_callback(struct urb *urb)
368 numbytes = urb->actual_length; 361 numbytes = urb->actual_length;
369 362
370 if (numbytes) { 363 if (numbytes) {
371 src = inbuf->rcvbuf; 364 src = cs->hw.usb->rcvbuf;
372 if (unlikely(*src)) 365 if (unlikely(*src))
373 dev_warn(cs->dev, 366 dev_warn(cs->dev,
374 "%s: There was no leading 0, but 0x%02x!\n", 367 "%s: There was no leading 0, but 0x%02x!\n",
@@ -440,7 +433,7 @@ static int send_cb(struct cardstate *cs, struct cmdbuf_t *cb)
440 struct cmdbuf_t *tcb; 433 struct cmdbuf_t *tcb;
441 unsigned long flags; 434 unsigned long flags;
442 int count; 435 int count;
443 int status = -ENOENT; // FIXME 436 int status = -ENOENT;
444 struct usb_cardstate *ucs = cs->hw.usb; 437 struct usb_cardstate *ucs = cs->hw.usb;
445 438
446 do { 439 do {
@@ -480,7 +473,9 @@ static int send_cb(struct cardstate *cs, struct cmdbuf_t *cb)
480 ucs->busy = 1; 473 ucs->busy = 1;
481 474
482 spin_lock_irqsave(&cs->lock, flags); 475 spin_lock_irqsave(&cs->lock, flags);
483 status = cs->connected ? usb_submit_urb(ucs->bulk_out_urb, GFP_ATOMIC) : -ENODEV; 476 status = cs->connected ?
477 usb_submit_urb(ucs->bulk_out_urb, GFP_ATOMIC) :
478 -ENODEV;
484 spin_unlock_irqrestore(&cs->lock, flags); 479 spin_unlock_irqrestore(&cs->lock, flags);
485 480
486 if (status) { 481 if (status) {
@@ -510,8 +505,8 @@ static int gigaset_write_cmd(struct cardstate *cs, const unsigned char *buf,
510 505
511 if (len <= 0) 506 if (len <= 0)
512 return 0; 507 return 0;
513 508 cb = kmalloc(sizeof(struct cmdbuf_t) + len, GFP_ATOMIC);
514 if (!(cb = kmalloc(sizeof(struct cmdbuf_t) + len, GFP_ATOMIC))) { 509 if (!cb) {
515 dev_err(cs->dev, "%s: out of memory\n", __func__); 510 dev_err(cs->dev, "%s: out of memory\n", __func__);
516 return -ENOMEM; 511 return -ENOMEM;
517 } 512 }
@@ -615,7 +610,7 @@ static int gigaset_initcshw(struct cardstate *cs)
615 ucs->bulk_out_urb = NULL; 610 ucs->bulk_out_urb = NULL;
616 ucs->read_urb = NULL; 611 ucs->read_urb = NULL;
617 tasklet_init(&cs->write_tasklet, 612 tasklet_init(&cs->write_tasklet,
618 &gigaset_modem_fill, (unsigned long) cs); 613 gigaset_modem_fill, (unsigned long) cs);
619 614
620 return 1; 615 return 1;
621} 616}
@@ -629,7 +624,7 @@ static int write_modem(struct cardstate *cs)
629 struct usb_cardstate *ucs = cs->hw.usb; 624 struct usb_cardstate *ucs = cs->hw.usb;
630 unsigned long flags; 625 unsigned long flags;
631 626
632 gig_dbg(DEBUG_WRITE, "len: %d...", bcs->tx_skb->len); 627 gig_dbg(DEBUG_OUTPUT, "len: %d...", bcs->tx_skb->len);
633 628
634 if (!bcs->tx_skb->len) { 629 if (!bcs->tx_skb->len) {
635 dev_kfree_skb_any(bcs->tx_skb); 630 dev_kfree_skb_any(bcs->tx_skb);
@@ -637,9 +632,7 @@ static int write_modem(struct cardstate *cs)
637 return -EINVAL; 632 return -EINVAL;
638 } 633 }
639 634
640 /* Copy data to bulk out buffer and // FIXME copying not necessary 635 /* Copy data to bulk out buffer and transmit data */
641 * transmit data
642 */
643 count = min(bcs->tx_skb->len, (unsigned) ucs->bulk_out_size); 636 count = min(bcs->tx_skb->len, (unsigned) ucs->bulk_out_size);
644 skb_copy_from_linear_data(bcs->tx_skb, ucs->bulk_out_buffer, count); 637 skb_copy_from_linear_data(bcs->tx_skb, ucs->bulk_out_buffer, count);
645 skb_pull(bcs->tx_skb, count); 638 skb_pull(bcs->tx_skb, count);
@@ -650,7 +643,8 @@ static int write_modem(struct cardstate *cs)
650 if (cs->connected) { 643 if (cs->connected) {
651 usb_fill_bulk_urb(ucs->bulk_out_urb, ucs->udev, 644 usb_fill_bulk_urb(ucs->bulk_out_urb, ucs->udev,
652 usb_sndbulkpipe(ucs->udev, 645 usb_sndbulkpipe(ucs->udev,
653 ucs->bulk_out_endpointAddr & 0x0f), 646 ucs->bulk_out_endpointAddr &
647 0x0f),
654 ucs->bulk_out_buffer, count, 648 ucs->bulk_out_buffer, count,
655 gigaset_write_bulk_callback, cs); 649 gigaset_write_bulk_callback, cs);
656 ret = usb_submit_urb(ucs->bulk_out_urb, GFP_ATOMIC); 650 ret = usb_submit_urb(ucs->bulk_out_urb, GFP_ATOMIC);
@@ -666,7 +660,7 @@ static int write_modem(struct cardstate *cs)
666 660
667 if (!bcs->tx_skb->len) { 661 if (!bcs->tx_skb->len) {
668 /* skb sent completely */ 662 /* skb sent completely */
669 gigaset_skb_sent(bcs, bcs->tx_skb); //FIXME also, when ret<0? 663 gigaset_skb_sent(bcs, bcs->tx_skb);
670 664
671 gig_dbg(DEBUG_INTR, "kfree skb (Adr: %lx)!", 665 gig_dbg(DEBUG_INTR, "kfree skb (Adr: %lx)!",
672 (unsigned long) bcs->tx_skb); 666 (unsigned long) bcs->tx_skb);
@@ -763,8 +757,8 @@ static int gigaset_probe(struct usb_interface *interface,
763 buffer_size = le16_to_cpu(endpoint->wMaxPacketSize); 757 buffer_size = le16_to_cpu(endpoint->wMaxPacketSize);
764 ucs->rcvbuf_size = buffer_size; 758 ucs->rcvbuf_size = buffer_size;
765 ucs->int_in_endpointAddr = endpoint->bEndpointAddress; 759 ucs->int_in_endpointAddr = endpoint->bEndpointAddress;
766 cs->inbuf[0].rcvbuf = kmalloc(buffer_size, GFP_KERNEL); 760 ucs->rcvbuf = kmalloc(buffer_size, GFP_KERNEL);
767 if (!cs->inbuf[0].rcvbuf) { 761 if (!ucs->rcvbuf) {
768 dev_err(cs->dev, "Couldn't allocate rcvbuf\n"); 762 dev_err(cs->dev, "Couldn't allocate rcvbuf\n");
769 retval = -ENOMEM; 763 retval = -ENOMEM;
770 goto error; 764 goto error;
@@ -773,9 +767,9 @@ static int gigaset_probe(struct usb_interface *interface,
773 usb_fill_int_urb(ucs->read_urb, udev, 767 usb_fill_int_urb(ucs->read_urb, udev,
774 usb_rcvintpipe(udev, 768 usb_rcvintpipe(udev,
775 endpoint->bEndpointAddress & 0x0f), 769 endpoint->bEndpointAddress & 0x0f),
776 cs->inbuf[0].rcvbuf, buffer_size, 770 ucs->rcvbuf, buffer_size,
777 gigaset_read_int_callback, 771 gigaset_read_int_callback,
778 cs->inbuf + 0, endpoint->bInterval); 772 cs, endpoint->bInterval);
779 773
780 retval = usb_submit_urb(ucs->read_urb, GFP_KERNEL); 774 retval = usb_submit_urb(ucs->read_urb, GFP_KERNEL);
781 if (retval) { 775 if (retval) {
@@ -789,7 +783,7 @@ static int gigaset_probe(struct usb_interface *interface,
789 783
790 if (!gigaset_start(cs)) { 784 if (!gigaset_start(cs)) {
791 tasklet_kill(&cs->write_tasklet); 785 tasklet_kill(&cs->write_tasklet);
792 retval = -ENODEV; //FIXME 786 retval = -ENODEV;
793 goto error; 787 goto error;
794 } 788 }
795 return 0; 789 return 0;
@@ -798,11 +792,11 @@ error:
798 usb_kill_urb(ucs->read_urb); 792 usb_kill_urb(ucs->read_urb);
799 kfree(ucs->bulk_out_buffer); 793 kfree(ucs->bulk_out_buffer);
800 usb_free_urb(ucs->bulk_out_urb); 794 usb_free_urb(ucs->bulk_out_urb);
801 kfree(cs->inbuf[0].rcvbuf); 795 kfree(ucs->rcvbuf);
802 usb_free_urb(ucs->read_urb); 796 usb_free_urb(ucs->read_urb);
803 usb_set_intfdata(interface, NULL); 797 usb_set_intfdata(interface, NULL);
804 ucs->read_urb = ucs->bulk_out_urb = NULL; 798 ucs->read_urb = ucs->bulk_out_urb = NULL;
805 cs->inbuf[0].rcvbuf = ucs->bulk_out_buffer = NULL; 799 ucs->rcvbuf = ucs->bulk_out_buffer = NULL;
806 usb_put_dev(ucs->udev); 800 usb_put_dev(ucs->udev);
807 ucs->udev = NULL; 801 ucs->udev = NULL;
808 ucs->interface = NULL; 802 ucs->interface = NULL;
@@ -831,10 +825,10 @@ static void gigaset_disconnect(struct usb_interface *interface)
831 825
832 kfree(ucs->bulk_out_buffer); 826 kfree(ucs->bulk_out_buffer);
833 usb_free_urb(ucs->bulk_out_urb); 827 usb_free_urb(ucs->bulk_out_urb);
834 kfree(cs->inbuf[0].rcvbuf); 828 kfree(ucs->rcvbuf);
835 usb_free_urb(ucs->read_urb); 829 usb_free_urb(ucs->read_urb);
836 ucs->read_urb = ucs->bulk_out_urb = NULL; 830 ucs->read_urb = ucs->bulk_out_urb = NULL;
837 cs->inbuf[0].rcvbuf = ucs->bulk_out_buffer = NULL; 831 ucs->rcvbuf = ucs->bulk_out_buffer = NULL;
838 832
839 usb_put_dev(ucs->udev); 833 usb_put_dev(ucs->udev);
840 ucs->interface = NULL; 834 ucs->interface = NULL;
@@ -916,9 +910,10 @@ static int __init usb_gigaset_init(void)
916 int result; 910 int result;
917 911
918 /* allocate memory for our driver state and intialize it */ 912 /* allocate memory for our driver state and intialize it */
919 if ((driver = gigaset_initdriver(GIGASET_MINOR, GIGASET_MINORS, 913 driver = gigaset_initdriver(GIGASET_MINOR, GIGASET_MINORS,
920 GIGASET_MODULENAME, GIGASET_DEVNAME, 914 GIGASET_MODULENAME, GIGASET_DEVNAME,
921 &ops, THIS_MODULE)) == NULL) 915 &ops, THIS_MODULE);
916 if (driver == NULL)
922 goto error; 917 goto error;
923 918
924 /* register this driver with the USB subsystem */ 919 /* register this driver with the USB subsystem */
diff --git a/drivers/isdn/hardware/avm/avm_cs.c b/drivers/isdn/hardware/avm/avm_cs.c
index c72565520e41..94b796d84053 100644
--- a/drivers/isdn/hardware/avm/avm_cs.c
+++ b/drivers/isdn/hardware/avm/avm_cs.c
@@ -108,10 +108,7 @@ static int avmcs_probe(struct pcmcia_device *p_dev)
108 p_dev->io.NumPorts2 = 0; 108 p_dev->io.NumPorts2 = 0;
109 109
110 /* Interrupt setup */ 110 /* Interrupt setup */
111 p_dev->irq.Attributes = IRQ_TYPE_EXCLUSIVE; 111 p_dev->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
112 p_dev->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING|IRQ_FIRST_SHARED;
113
114 p_dev->irq.IRQInfo1 = IRQ_LEVEL_ID;
115 112
116 /* General socket configuration */ 113 /* General socket configuration */
117 p_dev->conf.Attributes = CONF_ENABLE_IRQ; 114 p_dev->conf.Attributes = CONF_ENABLE_IRQ;
@@ -198,7 +195,6 @@ static int avmcs_config(struct pcmcia_device *link)
198 */ 195 */
199 i = pcmcia_request_irq(link, &link->irq); 196 i = pcmcia_request_irq(link, &link->irq);
200 if (i != 0) { 197 if (i != 0) {
201 cs_error(link, RequestIRQ, i);
202 /* undo */ 198 /* undo */
203 pcmcia_disable_device(link); 199 pcmcia_disable_device(link);
204 break; 200 break;
@@ -209,7 +205,6 @@ static int avmcs_config(struct pcmcia_device *link)
209 */ 205 */
210 i = pcmcia_request_configuration(link, &link->conf); 206 i = pcmcia_request_configuration(link, &link->conf);
211 if (i != 0) { 207 if (i != 0) {
212 cs_error(link, RequestConfiguration, i);
213 pcmcia_disable_device(link); 208 pcmcia_disable_device(link);
214 break; 209 break;
215 } 210 }
diff --git a/drivers/isdn/hardware/avm/avmcard.h b/drivers/isdn/hardware/avm/avmcard.h
index d964f07e4a56..a70e8854461d 100644
--- a/drivers/isdn/hardware/avm/avmcard.h
+++ b/drivers/isdn/hardware/avm/avmcard.h
@@ -556,8 +556,7 @@ u16 b1_send_message(struct capi_ctr *ctrl, struct sk_buff *skb);
556void b1_parse_version(avmctrl_info *card); 556void b1_parse_version(avmctrl_info *card);
557irqreturn_t b1_interrupt(int interrupt, void *devptr); 557irqreturn_t b1_interrupt(int interrupt, void *devptr);
558 558
559int b1ctl_read_proc(char *page, char **start, off_t off, 559extern const struct file_operations b1ctl_proc_fops;
560 int count, int *eof, struct capi_ctr *ctrl);
561 560
562avmcard_dmainfo *avmcard_dma_alloc(char *name, struct pci_dev *, 561avmcard_dmainfo *avmcard_dma_alloc(char *name, struct pci_dev *,
563 long rsize, long ssize); 562 long rsize, long ssize);
@@ -577,7 +576,6 @@ void b1dma_register_appl(struct capi_ctr *ctrl,
577 capi_register_params *rp); 576 capi_register_params *rp);
578void b1dma_release_appl(struct capi_ctr *ctrl, u16 appl); 577void b1dma_release_appl(struct capi_ctr *ctrl, u16 appl);
579u16 b1dma_send_message(struct capi_ctr *ctrl, struct sk_buff *skb); 578u16 b1dma_send_message(struct capi_ctr *ctrl, struct sk_buff *skb);
580int b1dmactl_read_proc(char *page, char **start, off_t off, 579extern const struct file_operations b1dmactl_proc_fops;
581 int count, int *eof, struct capi_ctr *ctrl);
582 580
583#endif /* _AVMCARD_H_ */ 581#endif /* _AVMCARD_H_ */
diff --git a/drivers/isdn/hardware/avm/b1.c b/drivers/isdn/hardware/avm/b1.c
index a7c0083e78a7..2a57da590d79 100644
--- a/drivers/isdn/hardware/avm/b1.c
+++ b/drivers/isdn/hardware/avm/b1.c
@@ -12,6 +12,8 @@
12#include <linux/module.h> 12#include <linux/module.h>
13#include <linux/kernel.h> 13#include <linux/kernel.h>
14#include <linux/pci.h> 14#include <linux/pci.h>
15#include <linux/proc_fs.h>
16#include <linux/seq_file.h>
15#include <linux/skbuff.h> 17#include <linux/skbuff.h>
16#include <linux/delay.h> 18#include <linux/delay.h>
17#include <linux/mm.h> 19#include <linux/mm.h>
@@ -19,6 +21,7 @@
19#include <linux/ioport.h> 21#include <linux/ioport.h>
20#include <linux/capi.h> 22#include <linux/capi.h>
21#include <linux/kernelcapi.h> 23#include <linux/kernelcapi.h>
24#include <linux/slab.h>
22#include <asm/io.h> 25#include <asm/io.h>
23#include <linux/init.h> 26#include <linux/init.h>
24#include <asm/uaccess.h> 27#include <asm/uaccess.h>
@@ -634,18 +637,17 @@ irqreturn_t b1_interrupt(int interrupt, void *devptr)
634} 637}
635 638
636/* ------------------------------------------------------------- */ 639/* ------------------------------------------------------------- */
637int b1ctl_read_proc(char *page, char **start, off_t off, 640static int b1ctl_proc_show(struct seq_file *m, void *v)
638 int count, int *eof, struct capi_ctr *ctrl)
639{ 641{
642 struct capi_ctr *ctrl = m->private;
640 avmctrl_info *cinfo = (avmctrl_info *)(ctrl->driverdata); 643 avmctrl_info *cinfo = (avmctrl_info *)(ctrl->driverdata);
641 avmcard *card = cinfo->card; 644 avmcard *card = cinfo->card;
642 u8 flag; 645 u8 flag;
643 int len = 0;
644 char *s; 646 char *s;
645 647
646 len += sprintf(page+len, "%-16s %s\n", "name", card->name); 648 seq_printf(m, "%-16s %s\n", "name", card->name);
647 len += sprintf(page+len, "%-16s 0x%x\n", "io", card->port); 649 seq_printf(m, "%-16s 0x%x\n", "io", card->port);
648 len += sprintf(page+len, "%-16s %d\n", "irq", card->irq); 650 seq_printf(m, "%-16s %d\n", "irq", card->irq);
649 switch (card->cardtype) { 651 switch (card->cardtype) {
650 case avm_b1isa: s = "B1 ISA"; break; 652 case avm_b1isa: s = "B1 ISA"; break;
651 case avm_b1pci: s = "B1 PCI"; break; 653 case avm_b1pci: s = "B1 PCI"; break;
@@ -658,20 +660,20 @@ int b1ctl_read_proc(char *page, char **start, off_t off,
658 case avm_c2: s = "C2"; break; 660 case avm_c2: s = "C2"; break;
659 default: s = "???"; break; 661 default: s = "???"; break;
660 } 662 }
661 len += sprintf(page+len, "%-16s %s\n", "type", s); 663 seq_printf(m, "%-16s %s\n", "type", s);
662 if (card->cardtype == avm_t1isa) 664 if (card->cardtype == avm_t1isa)
663 len += sprintf(page+len, "%-16s %d\n", "cardnr", card->cardnr); 665 seq_printf(m, "%-16s %d\n", "cardnr", card->cardnr);
664 if ((s = cinfo->version[VER_DRIVER]) != NULL) 666 if ((s = cinfo->version[VER_DRIVER]) != NULL)
665 len += sprintf(page+len, "%-16s %s\n", "ver_driver", s); 667 seq_printf(m, "%-16s %s\n", "ver_driver", s);
666 if ((s = cinfo->version[VER_CARDTYPE]) != NULL) 668 if ((s = cinfo->version[VER_CARDTYPE]) != NULL)
667 len += sprintf(page+len, "%-16s %s\n", "ver_cardtype", s); 669 seq_printf(m, "%-16s %s\n", "ver_cardtype", s);
668 if ((s = cinfo->version[VER_SERIAL]) != NULL) 670 if ((s = cinfo->version[VER_SERIAL]) != NULL)
669 len += sprintf(page+len, "%-16s %s\n", "ver_serial", s); 671 seq_printf(m, "%-16s %s\n", "ver_serial", s);
670 672
671 if (card->cardtype != avm_m1) { 673 if (card->cardtype != avm_m1) {
672 flag = ((u8 *)(ctrl->profile.manu))[3]; 674 flag = ((u8 *)(ctrl->profile.manu))[3];
673 if (flag) 675 if (flag)
674 len += sprintf(page+len, "%-16s%s%s%s%s%s%s%s\n", 676 seq_printf(m, "%-16s%s%s%s%s%s%s%s\n",
675 "protocol", 677 "protocol",
676 (flag & 0x01) ? " DSS1" : "", 678 (flag & 0x01) ? " DSS1" : "",
677 (flag & 0x02) ? " CT1" : "", 679 (flag & 0x02) ? " CT1" : "",
@@ -685,7 +687,7 @@ int b1ctl_read_proc(char *page, char **start, off_t off,
685 if (card->cardtype != avm_m1) { 687 if (card->cardtype != avm_m1) {
686 flag = ((u8 *)(ctrl->profile.manu))[5]; 688 flag = ((u8 *)(ctrl->profile.manu))[5];
687 if (flag) 689 if (flag)
688 len += sprintf(page+len, "%-16s%s%s%s%s\n", 690 seq_printf(m, "%-16s%s%s%s%s\n",
689 "linetype", 691 "linetype",
690 (flag & 0x01) ? " point to point" : "", 692 (flag & 0x01) ? " point to point" : "",
691 (flag & 0x02) ? " point to multipoint" : "", 693 (flag & 0x02) ? " point to multipoint" : "",
@@ -693,16 +695,25 @@ int b1ctl_read_proc(char *page, char **start, off_t off,
693 (flag & 0x04) ? " leased line with D-channel" : "" 695 (flag & 0x04) ? " leased line with D-channel" : ""
694 ); 696 );
695 } 697 }
696 len += sprintf(page+len, "%-16s %s\n", "cardname", cinfo->cardname); 698 seq_printf(m, "%-16s %s\n", "cardname", cinfo->cardname);
697 699
698 if (off+count >= len) 700 return 0;
699 *eof = 1; 701}
700 if (len < off) 702
701 return 0; 703static int b1ctl_proc_open(struct inode *inode, struct file *file)
702 *start = page + off; 704{
703 return ((count < len-off) ? count : len-off); 705 return single_open(file, b1ctl_proc_show, PDE(inode)->data);
704} 706}
705 707
708const struct file_operations b1ctl_proc_fops = {
709 .owner = THIS_MODULE,
710 .open = b1ctl_proc_open,
711 .read = seq_read,
712 .llseek = seq_lseek,
713 .release = single_release,
714};
715EXPORT_SYMBOL(b1ctl_proc_fops);
716
706/* ------------------------------------------------------------- */ 717/* ------------------------------------------------------------- */
707 718
708#ifdef CONFIG_PCI 719#ifdef CONFIG_PCI
@@ -781,8 +792,6 @@ EXPORT_SYMBOL(b1_send_message);
781EXPORT_SYMBOL(b1_parse_version); 792EXPORT_SYMBOL(b1_parse_version);
782EXPORT_SYMBOL(b1_interrupt); 793EXPORT_SYMBOL(b1_interrupt);
783 794
784EXPORT_SYMBOL(b1ctl_read_proc);
785
786static int __init b1_init(void) 795static int __init b1_init(void)
787{ 796{
788 char *p; 797 char *p;
diff --git a/drivers/isdn/hardware/avm/b1dma.c b/drivers/isdn/hardware/avm/b1dma.c
index 0e84aaae43fd..9c8d7aa053c5 100644
--- a/drivers/isdn/hardware/avm/b1dma.c
+++ b/drivers/isdn/hardware/avm/b1dma.c
@@ -11,6 +11,8 @@
11 11
12#include <linux/module.h> 12#include <linux/module.h>
13#include <linux/kernel.h> 13#include <linux/kernel.h>
14#include <linux/proc_fs.h>
15#include <linux/seq_file.h>
14#include <linux/skbuff.h> 16#include <linux/skbuff.h>
15#include <linux/delay.h> 17#include <linux/delay.h>
16#include <linux/mm.h> 18#include <linux/mm.h>
@@ -18,6 +20,7 @@
18#include <linux/ioport.h> 20#include <linux/ioport.h>
19#include <linux/capi.h> 21#include <linux/capi.h>
20#include <linux/kernelcapi.h> 22#include <linux/kernelcapi.h>
23#include <linux/gfp.h>
21#include <asm/io.h> 24#include <asm/io.h>
22#include <linux/init.h> 25#include <linux/init.h>
23#include <asm/uaccess.h> 26#include <asm/uaccess.h>
@@ -855,21 +858,20 @@ u16 b1dma_send_message(struct capi_ctr *ctrl, struct sk_buff *skb)
855 858
856/* ------------------------------------------------------------- */ 859/* ------------------------------------------------------------- */
857 860
858int b1dmactl_read_proc(char *page, char **start, off_t off, 861static int b1dmactl_proc_show(struct seq_file *m, void *v)
859 int count, int *eof, struct capi_ctr *ctrl)
860{ 862{
863 struct capi_ctr *ctrl = m->private;
861 avmctrl_info *cinfo = (avmctrl_info *)(ctrl->driverdata); 864 avmctrl_info *cinfo = (avmctrl_info *)(ctrl->driverdata);
862 avmcard *card = cinfo->card; 865 avmcard *card = cinfo->card;
863 u8 flag; 866 u8 flag;
864 int len = 0;
865 char *s; 867 char *s;
866 u32 txoff, txlen, rxoff, rxlen, csr; 868 u32 txoff, txlen, rxoff, rxlen, csr;
867 unsigned long flags; 869 unsigned long flags;
868 870
869 len += sprintf(page+len, "%-16s %s\n", "name", card->name); 871 seq_printf(m, "%-16s %s\n", "name", card->name);
870 len += sprintf(page+len, "%-16s 0x%x\n", "io", card->port); 872 seq_printf(m, "%-16s 0x%x\n", "io", card->port);
871 len += sprintf(page+len, "%-16s %d\n", "irq", card->irq); 873 seq_printf(m, "%-16s %d\n", "irq", card->irq);
872 len += sprintf(page+len, "%-16s 0x%lx\n", "membase", card->membase); 874 seq_printf(m, "%-16s 0x%lx\n", "membase", card->membase);
873 switch (card->cardtype) { 875 switch (card->cardtype) {
874 case avm_b1isa: s = "B1 ISA"; break; 876 case avm_b1isa: s = "B1 ISA"; break;
875 case avm_b1pci: s = "B1 PCI"; break; 877 case avm_b1pci: s = "B1 PCI"; break;
@@ -882,18 +884,18 @@ int b1dmactl_read_proc(char *page, char **start, off_t off,
882 case avm_c2: s = "C2"; break; 884 case avm_c2: s = "C2"; break;
883 default: s = "???"; break; 885 default: s = "???"; break;
884 } 886 }
885 len += sprintf(page+len, "%-16s %s\n", "type", s); 887 seq_printf(m, "%-16s %s\n", "type", s);
886 if ((s = cinfo->version[VER_DRIVER]) != NULL) 888 if ((s = cinfo->version[VER_DRIVER]) != NULL)
887 len += sprintf(page+len, "%-16s %s\n", "ver_driver", s); 889 seq_printf(m, "%-16s %s\n", "ver_driver", s);
888 if ((s = cinfo->version[VER_CARDTYPE]) != NULL) 890 if ((s = cinfo->version[VER_CARDTYPE]) != NULL)
889 len += sprintf(page+len, "%-16s %s\n", "ver_cardtype", s); 891 seq_printf(m, "%-16s %s\n", "ver_cardtype", s);
890 if ((s = cinfo->version[VER_SERIAL]) != NULL) 892 if ((s = cinfo->version[VER_SERIAL]) != NULL)
891 len += sprintf(page+len, "%-16s %s\n", "ver_serial", s); 893 seq_printf(m, "%-16s %s\n", "ver_serial", s);
892 894
893 if (card->cardtype != avm_m1) { 895 if (card->cardtype != avm_m1) {
894 flag = ((u8 *)(ctrl->profile.manu))[3]; 896 flag = ((u8 *)(ctrl->profile.manu))[3];
895 if (flag) 897 if (flag)
896 len += sprintf(page+len, "%-16s%s%s%s%s%s%s%s\n", 898 seq_printf(m, "%-16s%s%s%s%s%s%s%s\n",
897 "protocol", 899 "protocol",
898 (flag & 0x01) ? " DSS1" : "", 900 (flag & 0x01) ? " DSS1" : "",
899 (flag & 0x02) ? " CT1" : "", 901 (flag & 0x02) ? " CT1" : "",
@@ -907,7 +909,7 @@ int b1dmactl_read_proc(char *page, char **start, off_t off,
907 if (card->cardtype != avm_m1) { 909 if (card->cardtype != avm_m1) {
908 flag = ((u8 *)(ctrl->profile.manu))[5]; 910 flag = ((u8 *)(ctrl->profile.manu))[5];
909 if (flag) 911 if (flag)
910 len += sprintf(page+len, "%-16s%s%s%s%s\n", 912 seq_printf(m, "%-16s%s%s%s%s\n",
911 "linetype", 913 "linetype",
912 (flag & 0x01) ? " point to point" : "", 914 (flag & 0x01) ? " point to point" : "",
913 (flag & 0x02) ? " point to multipoint" : "", 915 (flag & 0x02) ? " point to multipoint" : "",
@@ -915,7 +917,7 @@ int b1dmactl_read_proc(char *page, char **start, off_t off,
915 (flag & 0x04) ? " leased line with D-channel" : "" 917 (flag & 0x04) ? " leased line with D-channel" : ""
916 ); 918 );
917 } 919 }
918 len += sprintf(page+len, "%-16s %s\n", "cardname", cinfo->cardname); 920 seq_printf(m, "%-16s %s\n", "cardname", cinfo->cardname);
919 921
920 922
921 spin_lock_irqsave(&card->lock, flags); 923 spin_lock_irqsave(&card->lock, flags);
@@ -930,27 +932,30 @@ int b1dmactl_read_proc(char *page, char **start, off_t off,
930 932
931 spin_unlock_irqrestore(&card->lock, flags); 933 spin_unlock_irqrestore(&card->lock, flags);
932 934
933 len += sprintf(page+len, "%-16s 0x%lx\n", 935 seq_printf(m, "%-16s 0x%lx\n", "csr (cached)", (unsigned long)card->csr);
934 "csr (cached)", (unsigned long)card->csr); 936 seq_printf(m, "%-16s 0x%lx\n", "csr", (unsigned long)csr);
935 len += sprintf(page+len, "%-16s 0x%lx\n", 937 seq_printf(m, "%-16s %lu\n", "txoff", (unsigned long)txoff);
936 "csr", (unsigned long)csr); 938 seq_printf(m, "%-16s %lu\n", "txlen", (unsigned long)txlen);
937 len += sprintf(page+len, "%-16s %lu\n", 939 seq_printf(m, "%-16s %lu\n", "rxoff", (unsigned long)rxoff);
938 "txoff", (unsigned long)txoff); 940 seq_printf(m, "%-16s %lu\n", "rxlen", (unsigned long)rxlen);
939 len += sprintf(page+len, "%-16s %lu\n", 941
940 "txlen", (unsigned long)txlen); 942 return 0;
941 len += sprintf(page+len, "%-16s %lu\n", 943}
942 "rxoff", (unsigned long)rxoff); 944
943 len += sprintf(page+len, "%-16s %lu\n", 945static int b1dmactl_proc_open(struct inode *inode, struct file *file)
944 "rxlen", (unsigned long)rxlen); 946{
945 947 return single_open(file, b1dmactl_proc_show, PDE(inode)->data);
946 if (off+count >= len)
947 *eof = 1;
948 if (len < off)
949 return 0;
950 *start = page + off;
951 return ((count < len-off) ? count : len-off);
952} 948}
953 949
950const struct file_operations b1dmactl_proc_fops = {
951 .owner = THIS_MODULE,
952 .open = b1dmactl_proc_open,
953 .read = seq_read,
954 .llseek = seq_lseek,
955 .release = single_release,
956};
957EXPORT_SYMBOL(b1dmactl_proc_fops);
958
954/* ------------------------------------------------------------- */ 959/* ------------------------------------------------------------- */
955 960
956EXPORT_SYMBOL(b1dma_reset); 961EXPORT_SYMBOL(b1dma_reset);
@@ -963,7 +968,6 @@ EXPORT_SYMBOL(b1dma_reset_ctr);
963EXPORT_SYMBOL(b1dma_register_appl); 968EXPORT_SYMBOL(b1dma_register_appl);
964EXPORT_SYMBOL(b1dma_release_appl); 969EXPORT_SYMBOL(b1dma_release_appl);
965EXPORT_SYMBOL(b1dma_send_message); 970EXPORT_SYMBOL(b1dma_send_message);
966EXPORT_SYMBOL(b1dmactl_read_proc);
967 971
968static int __init b1dma_init(void) 972static int __init b1dma_init(void)
969{ 973{
diff --git a/drivers/isdn/hardware/avm/b1isa.c b/drivers/isdn/hardware/avm/b1isa.c
index 6461a32bc838..ff5390546f92 100644
--- a/drivers/isdn/hardware/avm/b1isa.c
+++ b/drivers/isdn/hardware/avm/b1isa.c
@@ -121,7 +121,7 @@ static int b1isa_probe(struct pci_dev *pdev)
121 cinfo->capi_ctrl.load_firmware = b1_load_firmware; 121 cinfo->capi_ctrl.load_firmware = b1_load_firmware;
122 cinfo->capi_ctrl.reset_ctr = b1_reset_ctr; 122 cinfo->capi_ctrl.reset_ctr = b1_reset_ctr;
123 cinfo->capi_ctrl.procinfo = b1isa_procinfo; 123 cinfo->capi_ctrl.procinfo = b1isa_procinfo;
124 cinfo->capi_ctrl.ctr_read_proc = b1ctl_read_proc; 124 cinfo->capi_ctrl.proc_fops = &b1ctl_proc_fops;
125 strcpy(cinfo->capi_ctrl.name, card->name); 125 strcpy(cinfo->capi_ctrl.name, card->name);
126 126
127 retval = attach_capi_ctr(&cinfo->capi_ctrl); 127 retval = attach_capi_ctr(&cinfo->capi_ctrl);
diff --git a/drivers/isdn/hardware/avm/b1pci.c b/drivers/isdn/hardware/avm/b1pci.c
index 5b314a2c4049..c97e4315079d 100644
--- a/drivers/isdn/hardware/avm/b1pci.c
+++ b/drivers/isdn/hardware/avm/b1pci.c
@@ -112,7 +112,7 @@ static int b1pci_probe(struct capicardparams *p, struct pci_dev *pdev)
112 cinfo->capi_ctrl.load_firmware = b1_load_firmware; 112 cinfo->capi_ctrl.load_firmware = b1_load_firmware;
113 cinfo->capi_ctrl.reset_ctr = b1_reset_ctr; 113 cinfo->capi_ctrl.reset_ctr = b1_reset_ctr;
114 cinfo->capi_ctrl.procinfo = b1pci_procinfo; 114 cinfo->capi_ctrl.procinfo = b1pci_procinfo;
115 cinfo->capi_ctrl.ctr_read_proc = b1ctl_read_proc; 115 cinfo->capi_ctrl.proc_fops = &b1ctl_proc_fops;
116 strcpy(cinfo->capi_ctrl.name, card->name); 116 strcpy(cinfo->capi_ctrl.name, card->name);
117 cinfo->capi_ctrl.owner = THIS_MODULE; 117 cinfo->capi_ctrl.owner = THIS_MODULE;
118 118
@@ -251,7 +251,7 @@ static int b1pciv4_probe(struct capicardparams *p, struct pci_dev *pdev)
251 cinfo->capi_ctrl.load_firmware = b1dma_load_firmware; 251 cinfo->capi_ctrl.load_firmware = b1dma_load_firmware;
252 cinfo->capi_ctrl.reset_ctr = b1dma_reset_ctr; 252 cinfo->capi_ctrl.reset_ctr = b1dma_reset_ctr;
253 cinfo->capi_ctrl.procinfo = b1pciv4_procinfo; 253 cinfo->capi_ctrl.procinfo = b1pciv4_procinfo;
254 cinfo->capi_ctrl.ctr_read_proc = b1dmactl_read_proc; 254 cinfo->capi_ctrl.proc_fops = &b1dmactl_proc_fops;
255 strcpy(cinfo->capi_ctrl.name, card->name); 255 strcpy(cinfo->capi_ctrl.name, card->name);
256 256
257 retval = attach_capi_ctr(&cinfo->capi_ctrl); 257 retval = attach_capi_ctr(&cinfo->capi_ctrl);
diff --git a/drivers/isdn/hardware/avm/b1pcmcia.c b/drivers/isdn/hardware/avm/b1pcmcia.c
index 7740403b40e1..d6391e0afeea 100644
--- a/drivers/isdn/hardware/avm/b1pcmcia.c
+++ b/drivers/isdn/hardware/avm/b1pcmcia.c
@@ -108,7 +108,7 @@ static int b1pcmcia_add_card(unsigned int port, unsigned irq,
108 cinfo->capi_ctrl.load_firmware = b1_load_firmware; 108 cinfo->capi_ctrl.load_firmware = b1_load_firmware;
109 cinfo->capi_ctrl.reset_ctr = b1_reset_ctr; 109 cinfo->capi_ctrl.reset_ctr = b1_reset_ctr;
110 cinfo->capi_ctrl.procinfo = b1pcmcia_procinfo; 110 cinfo->capi_ctrl.procinfo = b1pcmcia_procinfo;
111 cinfo->capi_ctrl.ctr_read_proc = b1ctl_read_proc; 111 cinfo->capi_ctrl.proc_fops = &b1ctl_proc_fops;
112 strcpy(cinfo->capi_ctrl.name, card->name); 112 strcpy(cinfo->capi_ctrl.name, card->name);
113 113
114 retval = attach_capi_ctr(&cinfo->capi_ctrl); 114 retval = attach_capi_ctr(&cinfo->capi_ctrl);
diff --git a/drivers/isdn/hardware/avm/c4.c b/drivers/isdn/hardware/avm/c4.c
index 6833301a45fc..7715d3242ec8 100644
--- a/drivers/isdn/hardware/avm/c4.c
+++ b/drivers/isdn/hardware/avm/c4.c
@@ -11,6 +11,8 @@
11 11
12#include <linux/module.h> 12#include <linux/module.h>
13#include <linux/kernel.h> 13#include <linux/kernel.h>
14#include <linux/proc_fs.h>
15#include <linux/seq_file.h>
14#include <linux/skbuff.h> 16#include <linux/skbuff.h>
15#include <linux/delay.h> 17#include <linux/delay.h>
16#include <linux/mm.h> 18#include <linux/mm.h>
@@ -20,6 +22,7 @@
20#include <linux/capi.h> 22#include <linux/capi.h>
21#include <linux/kernelcapi.h> 23#include <linux/kernelcapi.h>
22#include <linux/init.h> 24#include <linux/init.h>
25#include <linux/gfp.h>
23#include <asm/io.h> 26#include <asm/io.h>
24#include <asm/uaccess.h> 27#include <asm/uaccess.h>
25#include <linux/netdevice.h> 28#include <linux/netdevice.h>
@@ -1062,19 +1065,18 @@ static char *c4_procinfo(struct capi_ctr *ctrl)
1062 return cinfo->infobuf; 1065 return cinfo->infobuf;
1063} 1066}
1064 1067
1065static int c4_read_proc(char *page, char **start, off_t off, 1068static int c4_proc_show(struct seq_file *m, void *v)
1066 int count, int *eof, struct capi_ctr *ctrl)
1067{ 1069{
1070 struct capi_ctr *ctrl = m->private;
1068 avmctrl_info *cinfo = (avmctrl_info *)(ctrl->driverdata); 1071 avmctrl_info *cinfo = (avmctrl_info *)(ctrl->driverdata);
1069 avmcard *card = cinfo->card; 1072 avmcard *card = cinfo->card;
1070 u8 flag; 1073 u8 flag;
1071 int len = 0;
1072 char *s; 1074 char *s;
1073 1075
1074 len += sprintf(page+len, "%-16s %s\n", "name", card->name); 1076 seq_printf(m, "%-16s %s\n", "name", card->name);
1075 len += sprintf(page+len, "%-16s 0x%x\n", "io", card->port); 1077 seq_printf(m, "%-16s 0x%x\n", "io", card->port);
1076 len += sprintf(page+len, "%-16s %d\n", "irq", card->irq); 1078 seq_printf(m, "%-16s %d\n", "irq", card->irq);
1077 len += sprintf(page+len, "%-16s 0x%lx\n", "membase", card->membase); 1079 seq_printf(m, "%-16s 0x%lx\n", "membase", card->membase);
1078 switch (card->cardtype) { 1080 switch (card->cardtype) {
1079 case avm_b1isa: s = "B1 ISA"; break; 1081 case avm_b1isa: s = "B1 ISA"; break;
1080 case avm_b1pci: s = "B1 PCI"; break; 1082 case avm_b1pci: s = "B1 PCI"; break;
@@ -1087,18 +1089,18 @@ static int c4_read_proc(char *page, char **start, off_t off,
1087 case avm_c2: s = "C2"; break; 1089 case avm_c2: s = "C2"; break;
1088 default: s = "???"; break; 1090 default: s = "???"; break;
1089 } 1091 }
1090 len += sprintf(page+len, "%-16s %s\n", "type", s); 1092 seq_printf(m, "%-16s %s\n", "type", s);
1091 if ((s = cinfo->version[VER_DRIVER]) != NULL) 1093 if ((s = cinfo->version[VER_DRIVER]) != NULL)
1092 len += sprintf(page+len, "%-16s %s\n", "ver_driver", s); 1094 seq_printf(m, "%-16s %s\n", "ver_driver", s);
1093 if ((s = cinfo->version[VER_CARDTYPE]) != NULL) 1095 if ((s = cinfo->version[VER_CARDTYPE]) != NULL)
1094 len += sprintf(page+len, "%-16s %s\n", "ver_cardtype", s); 1096 seq_printf(m, "%-16s %s\n", "ver_cardtype", s);
1095 if ((s = cinfo->version[VER_SERIAL]) != NULL) 1097 if ((s = cinfo->version[VER_SERIAL]) != NULL)
1096 len += sprintf(page+len, "%-16s %s\n", "ver_serial", s); 1098 seq_printf(m, "%-16s %s\n", "ver_serial", s);
1097 1099
1098 if (card->cardtype != avm_m1) { 1100 if (card->cardtype != avm_m1) {
1099 flag = ((u8 *)(ctrl->profile.manu))[3]; 1101 flag = ((u8 *)(ctrl->profile.manu))[3];
1100 if (flag) 1102 if (flag)
1101 len += sprintf(page+len, "%-16s%s%s%s%s%s%s%s\n", 1103 seq_printf(m, "%-16s%s%s%s%s%s%s%s\n",
1102 "protocol", 1104 "protocol",
1103 (flag & 0x01) ? " DSS1" : "", 1105 (flag & 0x01) ? " DSS1" : "",
1104 (flag & 0x02) ? " CT1" : "", 1106 (flag & 0x02) ? " CT1" : "",
@@ -1112,7 +1114,7 @@ static int c4_read_proc(char *page, char **start, off_t off,
1112 if (card->cardtype != avm_m1) { 1114 if (card->cardtype != avm_m1) {
1113 flag = ((u8 *)(ctrl->profile.manu))[5]; 1115 flag = ((u8 *)(ctrl->profile.manu))[5];
1114 if (flag) 1116 if (flag)
1115 len += sprintf(page+len, "%-16s%s%s%s%s\n", 1117 seq_printf(m, "%-16s%s%s%s%s\n",
1116 "linetype", 1118 "linetype",
1117 (flag & 0x01) ? " point to point" : "", 1119 (flag & 0x01) ? " point to point" : "",
1118 (flag & 0x02) ? " point to multipoint" : "", 1120 (flag & 0x02) ? " point to multipoint" : "",
@@ -1120,16 +1122,24 @@ static int c4_read_proc(char *page, char **start, off_t off,
1120 (flag & 0x04) ? " leased line with D-channel" : "" 1122 (flag & 0x04) ? " leased line with D-channel" : ""
1121 ); 1123 );
1122 } 1124 }
1123 len += sprintf(page+len, "%-16s %s\n", "cardname", cinfo->cardname); 1125 seq_printf(m, "%-16s %s\n", "cardname", cinfo->cardname);
1124 1126
1125 if (off+count >= len) 1127 return 0;
1126 *eof = 1;
1127 if (len < off)
1128 return 0;
1129 *start = page + off;
1130 return ((count < len-off) ? count : len-off);
1131} 1128}
1132 1129
1130static int c4_proc_open(struct inode *inode, struct file *file)
1131{
1132 return single_open(file, c4_proc_show, PDE(inode)->data);
1133}
1134
1135static const struct file_operations c4_proc_fops = {
1136 .owner = THIS_MODULE,
1137 .open = c4_proc_open,
1138 .read = seq_read,
1139 .llseek = seq_lseek,
1140 .release = single_release,
1141};
1142
1133/* ------------------------------------------------------------- */ 1143/* ------------------------------------------------------------- */
1134 1144
1135static int c4_add_card(struct capicardparams *p, struct pci_dev *dev, 1145static int c4_add_card(struct capicardparams *p, struct pci_dev *dev,
@@ -1201,7 +1211,7 @@ static int c4_add_card(struct capicardparams *p, struct pci_dev *dev,
1201 cinfo->capi_ctrl.load_firmware = c4_load_firmware; 1211 cinfo->capi_ctrl.load_firmware = c4_load_firmware;
1202 cinfo->capi_ctrl.reset_ctr = c4_reset_ctr; 1212 cinfo->capi_ctrl.reset_ctr = c4_reset_ctr;
1203 cinfo->capi_ctrl.procinfo = c4_procinfo; 1213 cinfo->capi_ctrl.procinfo = c4_procinfo;
1204 cinfo->capi_ctrl.ctr_read_proc = c4_read_proc; 1214 cinfo->capi_ctrl.proc_fops = &c4_proc_fops;
1205 strcpy(cinfo->capi_ctrl.name, card->name); 1215 strcpy(cinfo->capi_ctrl.name, card->name);
1206 1216
1207 retval = attach_capi_ctr(&cinfo->capi_ctrl); 1217 retval = attach_capi_ctr(&cinfo->capi_ctrl);
diff --git a/drivers/isdn/hardware/avm/t1isa.c b/drivers/isdn/hardware/avm/t1isa.c
index 1c53fd49adb6..08216b14be13 100644
--- a/drivers/isdn/hardware/avm/t1isa.c
+++ b/drivers/isdn/hardware/avm/t1isa.c
@@ -21,6 +21,7 @@
21#include <linux/kernelcapi.h> 21#include <linux/kernelcapi.h>
22#include <linux/init.h> 22#include <linux/init.h>
23#include <linux/pci.h> 23#include <linux/pci.h>
24#include <linux/gfp.h>
24#include <asm/io.h> 25#include <asm/io.h>
25#include <linux/isdn/capicmd.h> 26#include <linux/isdn/capicmd.h>
26#include <linux/isdn/capiutil.h> 27#include <linux/isdn/capiutil.h>
@@ -429,7 +430,7 @@ static int t1isa_probe(struct pci_dev *pdev, int cardnr)
429 cinfo->capi_ctrl.load_firmware = t1isa_load_firmware; 430 cinfo->capi_ctrl.load_firmware = t1isa_load_firmware;
430 cinfo->capi_ctrl.reset_ctr = t1isa_reset_ctr; 431 cinfo->capi_ctrl.reset_ctr = t1isa_reset_ctr;
431 cinfo->capi_ctrl.procinfo = t1isa_procinfo; 432 cinfo->capi_ctrl.procinfo = t1isa_procinfo;
432 cinfo->capi_ctrl.ctr_read_proc = b1ctl_read_proc; 433 cinfo->capi_ctrl.proc_fops = &b1ctl_proc_fops;
433 strcpy(cinfo->capi_ctrl.name, card->name); 434 strcpy(cinfo->capi_ctrl.name, card->name);
434 435
435 retval = attach_capi_ctr(&cinfo->capi_ctrl); 436 retval = attach_capi_ctr(&cinfo->capi_ctrl);
diff --git a/drivers/isdn/hardware/avm/t1pci.c b/drivers/isdn/hardware/avm/t1pci.c
index e6d298d75146..5a3f83098018 100644
--- a/drivers/isdn/hardware/avm/t1pci.c
+++ b/drivers/isdn/hardware/avm/t1pci.c
@@ -119,7 +119,7 @@ static int t1pci_add_card(struct capicardparams *p, struct pci_dev *pdev)
119 cinfo->capi_ctrl.load_firmware = b1dma_load_firmware; 119 cinfo->capi_ctrl.load_firmware = b1dma_load_firmware;
120 cinfo->capi_ctrl.reset_ctr = b1dma_reset_ctr; 120 cinfo->capi_ctrl.reset_ctr = b1dma_reset_ctr;
121 cinfo->capi_ctrl.procinfo = t1pci_procinfo; 121 cinfo->capi_ctrl.procinfo = t1pci_procinfo;
122 cinfo->capi_ctrl.ctr_read_proc = b1dmactl_read_proc; 122 cinfo->capi_ctrl.proc_fops = &b1dmactl_proc_fops;
123 strcpy(cinfo->capi_ctrl.name, card->name); 123 strcpy(cinfo->capi_ctrl.name, card->name);
124 124
125 retval = attach_capi_ctr(&cinfo->capi_ctrl); 125 retval = attach_capi_ctr(&cinfo->capi_ctrl);
diff --git a/drivers/isdn/hardware/eicon/capimain.c b/drivers/isdn/hardware/eicon/capimain.c
index 98fcdfc7ca55..97a20964cfc7 100644
--- a/drivers/isdn/hardware/eicon/capimain.c
+++ b/drivers/isdn/hardware/eicon/capimain.c
@@ -11,8 +11,10 @@
11 */ 11 */
12 12
13#include <linux/module.h> 13#include <linux/module.h>
14#include <linux/slab.h>
14#include <linux/init.h> 15#include <linux/init.h>
15#include <asm/uaccess.h> 16#include <asm/uaccess.h>
17#include <linux/seq_file.h>
16#include <linux/skbuff.h> 18#include <linux/skbuff.h>
17 19
18#include "os_capi.h" 20#include "os_capi.h"
@@ -75,25 +77,32 @@ void diva_os_free_message_buffer(diva_os_message_buffer_s * dmb)
75/* 77/*
76 * proc function for controller info 78 * proc function for controller info
77 */ 79 */
78static int diva_ctl_read_proc(char *page, char **start, off_t off, 80static int diva_ctl_proc_show(struct seq_file *m, void *v)
79 int count, int *eof, struct capi_ctr *ctrl)
80{ 81{
82 struct capi_ctr *ctrl = m->private;
81 diva_card *card = (diva_card *) ctrl->driverdata; 83 diva_card *card = (diva_card *) ctrl->driverdata;
82 int len = 0; 84
83 85 seq_printf(m, "%s\n", ctrl->name);
84 len += sprintf(page + len, "%s\n", ctrl->name); 86 seq_printf(m, "Serial No. : %s\n", ctrl->serial);
85 len += sprintf(page + len, "Serial No. : %s\n", ctrl->serial); 87 seq_printf(m, "Id : %d\n", card->Id);
86 len += sprintf(page + len, "Id : %d\n", card->Id); 88 seq_printf(m, "Channels : %d\n", card->d.channels);
87 len += sprintf(page + len, "Channels : %d\n", card->d.channels); 89
88 90 return 0;
89 if (off + count >= len) 91}
90 *eof = 1; 92
91 if (len < off) 93static int diva_ctl_proc_open(struct inode *inode, struct file *file)
92 return 0; 94{
93 *start = page + off; 95 return single_open(file, diva_ctl_proc_show, NULL);
94 return ((count < len - off) ? count : len - off);
95} 96}
96 97
98static const struct file_operations diva_ctl_proc_fops = {
99 .owner = THIS_MODULE,
100 .open = diva_ctl_proc_open,
101 .read = seq_read,
102 .llseek = seq_lseek,
103 .release = single_release,
104};
105
97/* 106/*
98 * set additional os settings in capi_ctr struct 107 * set additional os settings in capi_ctr struct
99 */ 108 */
@@ -102,7 +111,7 @@ void diva_os_set_controller_struct(struct capi_ctr *ctrl)
102 ctrl->driver_name = DRIVERLNAME; 111 ctrl->driver_name = DRIVERLNAME;
103 ctrl->load_firmware = NULL; 112 ctrl->load_firmware = NULL;
104 ctrl->reset_ctr = NULL; 113 ctrl->reset_ctr = NULL;
105 ctrl->ctr_read_proc = diva_ctl_read_proc; 114 ctrl->proc_fops = &diva_ctl_proc_fops;
106 ctrl->owner = THIS_MODULE; 115 ctrl->owner = THIS_MODULE;
107} 116}
108 117
diff --git a/drivers/isdn/hardware/eicon/di.c b/drivers/isdn/hardware/eicon/di.c
index b029d130eb21..cb14ae3e7154 100644
--- a/drivers/isdn/hardware/eicon/di.c
+++ b/drivers/isdn/hardware/eicon/di.c
@@ -806,7 +806,7 @@ static void xdi_xlog_request (byte Adapter, byte Id,
806 DELIVERY - indication entered isdn_rc function 806 DELIVERY - indication entered isdn_rc function
807 RNR=... - application had returned RNR=... after the 807 RNR=... - application had returned RNR=... after the
808 look ahead callback 808 look ahead callback
809 RNum=0 - aplication had not returned any buffer to copy 809 RNum=0 - application had not returned any buffer to copy
810 this indication and will copy it self 810 this indication and will copy it self
811 COMPLETE - XDI had copied the data to the buffers provided 811 COMPLETE - XDI had copied the data to the buffers provided
812 bu the application and is about to issue the 812 bu the application and is about to issue the
diff --git a/drivers/isdn/hardware/eicon/diva_didd.c b/drivers/isdn/hardware/eicon/diva_didd.c
index 993b14cf1778..5d06a7437824 100644
--- a/drivers/isdn/hardware/eicon/diva_didd.c
+++ b/drivers/isdn/hardware/eicon/diva_didd.c
@@ -15,6 +15,7 @@
15#include <linux/init.h> 15#include <linux/init.h>
16#include <linux/kernel.h> 16#include <linux/kernel.h>
17#include <linux/proc_fs.h> 17#include <linux/proc_fs.h>
18#include <linux/seq_file.h>
18#include <net/net_namespace.h> 19#include <net/net_namespace.h>
19 20
20#include "platform.h" 21#include "platform.h"
@@ -62,39 +63,41 @@ static char *getrev(const char *revision)
62 return rev; 63 return rev;
63} 64}
64 65
65static int 66static int divadidd_proc_show(struct seq_file *m, void *v)
66proc_read(char *page, char **start, off_t off, int count, int *eof,
67 void *data)
68{ 67{
69 int len = 0;
70 char tmprev[32]; 68 char tmprev[32];
71 69
72 strcpy(tmprev, main_revision); 70 strcpy(tmprev, main_revision);
73 len += sprintf(page + len, "%s\n", DRIVERNAME); 71 seq_printf(m, "%s\n", DRIVERNAME);
74 len += sprintf(page + len, "name : %s\n", DRIVERLNAME); 72 seq_printf(m, "name : %s\n", DRIVERLNAME);
75 len += sprintf(page + len, "release : %s\n", DRIVERRELEASE_DIDD); 73 seq_printf(m, "release : %s\n", DRIVERRELEASE_DIDD);
76 len += sprintf(page + len, "build : %s(%s)\n", 74 seq_printf(m, "build : %s(%s)\n",
77 diva_didd_common_code_build, DIVA_BUILD); 75 diva_didd_common_code_build, DIVA_BUILD);
78 len += sprintf(page + len, "revision : %s\n", getrev(tmprev)); 76 seq_printf(m, "revision : %s\n", getrev(tmprev));
79 77
80 if (off + count >= len) 78 return 0;
81 *eof = 1;
82 if (len < off)
83 return 0;
84 *start = page + off;
85 return ((count < len - off) ? count : len - off);
86} 79}
87 80
81static int divadidd_proc_open(struct inode *inode, struct file *file)
82{
83 return single_open(file, divadidd_proc_show, NULL);
84}
85
86static const struct file_operations divadidd_proc_fops = {
87 .owner = THIS_MODULE,
88 .open = divadidd_proc_open,
89 .read = seq_read,
90 .llseek = seq_lseek,
91 .release = single_release,
92};
93
88static int DIVA_INIT_FUNCTION create_proc(void) 94static int DIVA_INIT_FUNCTION create_proc(void)
89{ 95{
90 proc_net_eicon = proc_mkdir("eicon", init_net.proc_net); 96 proc_net_eicon = proc_mkdir("eicon", init_net.proc_net);
91 97
92 if (proc_net_eicon) { 98 if (proc_net_eicon) {
93 if ((proc_didd = 99 proc_didd = proc_create(DRIVERLNAME, S_IRUGO, proc_net_eicon,
94 create_proc_entry(DRIVERLNAME, S_IFREG | S_IRUGO, 100 &divadidd_proc_fops);
95 proc_net_eicon))) {
96 proc_didd->read_proc = proc_read;
97 }
98 return (1); 101 return (1);
99 } 102 }
100 return (0); 103 return (0);
diff --git a/drivers/isdn/hardware/eicon/divasi.c b/drivers/isdn/hardware/eicon/divasi.c
index 69e71ebe7841..f577719ab3fa 100644
--- a/drivers/isdn/hardware/eicon/divasi.c
+++ b/drivers/isdn/hardware/eicon/divasi.c
@@ -17,6 +17,7 @@
17#include <linux/poll.h> 17#include <linux/poll.h>
18#include <linux/proc_fs.h> 18#include <linux/proc_fs.h>
19#include <linux/skbuff.h> 19#include <linux/skbuff.h>
20#include <linux/seq_file.h>
20#include <linux/smp_lock.h> 21#include <linux/smp_lock.h>
21#include <asm/uaccess.h> 22#include <asm/uaccess.h>
22 23
@@ -86,39 +87,40 @@ static void diva_um_timer_function(unsigned long data);
86extern struct proc_dir_entry *proc_net_eicon; 87extern struct proc_dir_entry *proc_net_eicon;
87static struct proc_dir_entry *um_idi_proc_entry = NULL; 88static struct proc_dir_entry *um_idi_proc_entry = NULL;
88 89
89static int 90static int um_idi_proc_show(struct seq_file *m, void *v)
90um_idi_proc_read(char *page, char **start, off_t off, int count, int *eof,
91 void *data)
92{ 91{
93 int len = 0;
94 char tmprev[32]; 92 char tmprev[32];
95 93
96 len += sprintf(page + len, "%s\n", DRIVERNAME); 94 seq_printf(m, "%s\n", DRIVERNAME);
97 len += sprintf(page + len, "name : %s\n", DRIVERLNAME); 95 seq_printf(m, "name : %s\n", DRIVERLNAME);
98 len += sprintf(page + len, "release : %s\n", DRIVERRELEASE_IDI); 96 seq_printf(m, "release : %s\n", DRIVERRELEASE_IDI);
99 strcpy(tmprev, main_revision); 97 strcpy(tmprev, main_revision);
100 len += sprintf(page + len, "revision : %s\n", getrev(tmprev)); 98 seq_printf(m, "revision : %s\n", getrev(tmprev));
101 len += sprintf(page + len, "build : %s\n", DIVA_BUILD); 99 seq_printf(m, "build : %s\n", DIVA_BUILD);
102 len += sprintf(page + len, "major : %d\n", major); 100 seq_printf(m, "major : %d\n", major);
103 101
104 if (off + count >= len) 102 return 0;
105 *eof = 1; 103}
106 if (len < off) 104
107 return 0; 105static int um_idi_proc_open(struct inode *inode, struct file *file)
108 *start = page + off; 106{
109 return ((count < len - off) ? count : len - off); 107 return single_open(file, um_idi_proc_show, NULL);
110} 108}
111 109
110static const struct file_operations um_idi_proc_fops = {
111 .owner = THIS_MODULE,
112 .open = um_idi_proc_open,
113 .read = seq_read,
114 .llseek = seq_lseek,
115 .release = single_release,
116};
117
112static int DIVA_INIT_FUNCTION create_um_idi_proc(void) 118static int DIVA_INIT_FUNCTION create_um_idi_proc(void)
113{ 119{
114 um_idi_proc_entry = create_proc_entry(DRIVERLNAME, 120 um_idi_proc_entry = proc_create(DRIVERLNAME, S_IRUGO, proc_net_eicon,
115 S_IFREG | S_IRUGO | S_IWUSR, 121 &um_idi_proc_fops);
116 proc_net_eicon);
117 if (!um_idi_proc_entry) 122 if (!um_idi_proc_entry)
118 return (0); 123 return (0);
119
120 um_idi_proc_entry->read_proc = um_idi_proc_read;
121
122 return (1); 124 return (1);
123} 125}
124 126
diff --git a/drivers/isdn/hardware/eicon/divasproc.c b/drivers/isdn/hardware/eicon/divasproc.c
index 040827288ec9..46d44a942624 100644
--- a/drivers/isdn/hardware/eicon/divasproc.c
+++ b/drivers/isdn/hardware/eicon/divasproc.c
@@ -14,6 +14,7 @@
14#include <linux/kernel.h> 14#include <linux/kernel.h>
15#include <linux/poll.h> 15#include <linux/poll.h>
16#include <linux/proc_fs.h> 16#include <linux/proc_fs.h>
17#include <linux/seq_file.h>
17#include <linux/list.h> 18#include <linux/list.h>
18#include <asm/uaccess.h> 19#include <asm/uaccess.h>
19 20
@@ -141,14 +142,10 @@ void remove_divas_proc(void)
141 } 142 }
142} 143}
143 144
144/* 145static ssize_t grp_opt_proc_write(struct file *file, const char __user *buffer,
145** write group_optimization 146 size_t count, loff_t *pos)
146*/
147static int
148write_grp_opt(struct file *file, const char __user *buffer, unsigned long count,
149 void *data)
150{ 147{
151 diva_os_xdi_adapter_t *a = (diva_os_xdi_adapter_t *) data; 148 diva_os_xdi_adapter_t *a = PDE(file->f_path.dentry->d_inode)->data;
152 PISDN_ADAPTER IoAdapter = IoAdapters[a->controller - 1]; 149 PISDN_ADAPTER IoAdapter = IoAdapters[a->controller - 1];
153 150
154 if ((count == 1) || (count == 2)) { 151 if ((count == 1) || (count == 2)) {
@@ -172,14 +169,10 @@ write_grp_opt(struct file *file, const char __user *buffer, unsigned long count,
172 return (-EINVAL); 169 return (-EINVAL);
173} 170}
174 171
175/* 172static ssize_t d_l1_down_proc_write(struct file *file, const char __user *buffer,
176** write dynamic_l1_down 173 size_t count, loff_t *pos)
177*/
178static int
179write_d_l1_down(struct file *file, const char __user *buffer, unsigned long count,
180 void *data)
181{ 174{
182 diva_os_xdi_adapter_t *a = (diva_os_xdi_adapter_t *) data; 175 diva_os_xdi_adapter_t *a = PDE(file->f_path.dentry->d_inode)->data;
183 PISDN_ADAPTER IoAdapter = IoAdapters[a->controller - 1]; 176 PISDN_ADAPTER IoAdapter = IoAdapters[a->controller - 1];
184 177
185 if ((count == 1) || (count == 2)) { 178 if ((count == 1) || (count == 2)) {
@@ -203,63 +196,62 @@ write_d_l1_down(struct file *file, const char __user *buffer, unsigned long coun
203 return (-EINVAL); 196 return (-EINVAL);
204} 197}
205 198
206 199static int d_l1_down_proc_show(struct seq_file *m, void *v)
207/*
208** read dynamic_l1_down
209*/
210static int
211read_d_l1_down(char *page, char **start, off_t off, int count, int *eof,
212 void *data)
213{ 200{
214 int len = 0; 201 diva_os_xdi_adapter_t *a = m->private;
215 diva_os_xdi_adapter_t *a = (diva_os_xdi_adapter_t *) data;
216 PISDN_ADAPTER IoAdapter = IoAdapters[a->controller - 1]; 202 PISDN_ADAPTER IoAdapter = IoAdapters[a->controller - 1];
217 203
218 len += sprintf(page + len, "%s\n", 204 seq_printf(m, "%s\n",
219 (IoAdapter->capi_cfg. 205 (IoAdapter->capi_cfg.
220 cfg_1 & DIVA_XDI_CAPI_CFG_1_DYNAMIC_L1_ON) ? "1" : 206 cfg_1 & DIVA_XDI_CAPI_CFG_1_DYNAMIC_L1_ON) ? "1" :
221 "0"); 207 "0");
208 return 0;
209}
222 210
223 if (off + count >= len) 211static int d_l1_down_proc_open(struct inode *inode, struct file *file)
224 *eof = 1; 212{
225 if (len < off) 213 return single_open(file, d_l1_down_proc_show, PDE(inode)->data);
226 return 0;
227 *start = page + off;
228 return ((count < len - off) ? count : len - off);
229} 214}
230 215
231/* 216static const struct file_operations d_l1_down_proc_fops = {
232** read group_optimization 217 .owner = THIS_MODULE,
233*/ 218 .open = d_l1_down_proc_open,
234static int 219 .read = seq_read,
235read_grp_opt(char *page, char **start, off_t off, int count, int *eof, 220 .llseek = seq_lseek,
236 void *data) 221 .release = single_release,
222 .write = d_l1_down_proc_write,
223};
224
225static int grp_opt_proc_show(struct seq_file *m, void *v)
237{ 226{
238 int len = 0; 227 diva_os_xdi_adapter_t *a = m->private;
239 diva_os_xdi_adapter_t *a = (diva_os_xdi_adapter_t *) data;
240 PISDN_ADAPTER IoAdapter = IoAdapters[a->controller - 1]; 228 PISDN_ADAPTER IoAdapter = IoAdapters[a->controller - 1];
241 229
242 len += sprintf(page + len, "%s\n", 230 seq_printf(m, "%s\n",
243 (IoAdapter->capi_cfg. 231 (IoAdapter->capi_cfg.
244 cfg_1 & DIVA_XDI_CAPI_CFG_1_GROUP_POPTIMIZATION_ON) 232 cfg_1 & DIVA_XDI_CAPI_CFG_1_GROUP_POPTIMIZATION_ON)
245 ? "1" : "0"); 233 ? "1" : "0");
234 return 0;
235}
246 236
247 if (off + count >= len) 237static int grp_opt_proc_open(struct inode *inode, struct file *file)
248 *eof = 1; 238{
249 if (len < off) 239 return single_open(file, grp_opt_proc_show, PDE(inode)->data);
250 return 0;
251 *start = page + off;
252 return ((count < len - off) ? count : len - off);
253} 240}
254 241
255/* 242static const struct file_operations grp_opt_proc_fops = {
256** info write 243 .owner = THIS_MODULE,
257*/ 244 .open = grp_opt_proc_open,
258static int 245 .read = seq_read,
259info_write(struct file *file, const char __user *buffer, unsigned long count, 246 .llseek = seq_lseek,
260 void *data) 247 .release = single_release,
248 .write = grp_opt_proc_write,
249};
250
251static ssize_t info_proc_write(struct file *file, const char __user *buffer,
252 size_t count, loff_t *pos)
261{ 253{
262 diva_os_xdi_adapter_t *a = (diva_os_xdi_adapter_t *) data; 254 diva_os_xdi_adapter_t *a = PDE(file->f_path.dentry->d_inode)->data;
263 PISDN_ADAPTER IoAdapter = IoAdapters[a->controller - 1]; 255 PISDN_ADAPTER IoAdapter = IoAdapters[a->controller - 1];
264 char c[4]; 256 char c[4];
265 257
@@ -277,63 +269,46 @@ info_write(struct file *file, const char __user *buffer, unsigned long count,
277 return (-EINVAL); 269 return (-EINVAL);
278} 270}
279 271
280/* 272static int info_proc_show(struct seq_file *m, void *v)
281** info read
282*/
283static int
284info_read(char *page, char **start, off_t off, int count, int *eof,
285 void *data)
286{ 273{
287 int i = 0; 274 int i = 0;
288 int len = 0;
289 char *p; 275 char *p;
290 char tmpser[16]; 276 char tmpser[16];
291 diva_os_xdi_adapter_t *a = (diva_os_xdi_adapter_t *) data; 277 diva_os_xdi_adapter_t *a = m->private;
292 PISDN_ADAPTER IoAdapter = IoAdapters[a->controller - 1]; 278 PISDN_ADAPTER IoAdapter = IoAdapters[a->controller - 1];
293 279
294 len += 280 seq_printf(m, "Name : %s\n", IoAdapter->Properties.Name);
295 sprintf(page + len, "Name : %s\n", 281 seq_printf(m, "DSP state : %08x\n", a->dsp_mask);
296 IoAdapter->Properties.Name); 282 seq_printf(m, "Channels : %02d\n", IoAdapter->Properties.Channels);
297 len += sprintf(page + len, "DSP state : %08x\n", a->dsp_mask); 283 seq_printf(m, "E. max/used : %03d/%03d\n",
298 len += sprintf(page + len, "Channels : %02d\n",
299 IoAdapter->Properties.Channels);
300 len += sprintf(page + len, "E. max/used : %03d/%03d\n",
301 IoAdapter->e_max, IoAdapter->e_count); 284 IoAdapter->e_max, IoAdapter->e_count);
302 diva_get_vserial_number(IoAdapter, tmpser); 285 diva_get_vserial_number(IoAdapter, tmpser);
303 len += sprintf(page + len, "Serial : %s\n", tmpser); 286 seq_printf(m, "Serial : %s\n", tmpser);
304 len += 287 seq_printf(m, "IRQ : %d\n", IoAdapter->irq_info.irq_nr);
305 sprintf(page + len, "IRQ : %d\n", 288 seq_printf(m, "CardIndex : %d\n", a->CardIndex);
306 IoAdapter->irq_info.irq_nr); 289 seq_printf(m, "CardOrdinal : %d\n", a->CardOrdinal);
307 len += sprintf(page + len, "CardIndex : %d\n", a->CardIndex); 290 seq_printf(m, "Controller : %d\n", a->controller);
308 len += sprintf(page + len, "CardOrdinal : %d\n", a->CardOrdinal); 291 seq_printf(m, "Bus-Type : %s\n",
309 len += sprintf(page + len, "Controller : %d\n", a->controller);
310 len += sprintf(page + len, "Bus-Type : %s\n",
311 (a->Bus == 292 (a->Bus ==
312 DIVAS_XDI_ADAPTER_BUS_ISA) ? "ISA" : "PCI"); 293 DIVAS_XDI_ADAPTER_BUS_ISA) ? "ISA" : "PCI");
313 len += sprintf(page + len, "Port-Name : %s\n", a->port_name); 294 seq_printf(m, "Port-Name : %s\n", a->port_name);
314 if (a->Bus == DIVAS_XDI_ADAPTER_BUS_PCI) { 295 if (a->Bus == DIVAS_XDI_ADAPTER_BUS_PCI) {
315 len += 296 seq_printf(m, "PCI-bus : %d\n", a->resources.pci.bus);
316 sprintf(page + len, "PCI-bus : %d\n", 297 seq_printf(m, "PCI-func : %d\n", a->resources.pci.func);
317 a->resources.pci.bus);
318 len +=
319 sprintf(page + len, "PCI-func : %d\n",
320 a->resources.pci.func);
321 for (i = 0; i < 8; i++) { 298 for (i = 0; i < 8; i++) {
322 if (a->resources.pci.bar[i]) { 299 if (a->resources.pci.bar[i]) {
323 len += 300 seq_printf(m,
324 sprintf(page + len,
325 "Mem / I/O %d : 0x%x / mapped : 0x%lx", 301 "Mem / I/O %d : 0x%x / mapped : 0x%lx",
326 i, a->resources.pci.bar[i], 302 i, a->resources.pci.bar[i],
327 (unsigned long) a->resources. 303 (unsigned long) a->resources.
328 pci.addr[i]); 304 pci.addr[i]);
329 if (a->resources.pci.length[i]) { 305 if (a->resources.pci.length[i]) {
330 len += 306 seq_printf(m,
331 sprintf(page + len,
332 " / length : %d", 307 " / length : %d",
333 a->resources.pci. 308 a->resources.pci.
334 length[i]); 309 length[i]);
335 } 310 }
336 len += sprintf(page + len, "\n"); 311 seq_putc(m, '\n');
337 } 312 }
338 } 313 }
339 } 314 }
@@ -353,16 +328,25 @@ info_read(char *page, char **start, off_t off, int count, int *eof,
353 } else { 328 } else {
354 p = "ready"; 329 p = "ready";
355 } 330 }
356 len += sprintf(page + len, "State : %s\n", p); 331 seq_printf(m, "State : %s\n", p);
357 332
358 if (off + count >= len) 333 return 0;
359 *eof = 1; 334}
360 if (len < off) 335
361 return 0; 336static int info_proc_open(struct inode *inode, struct file *file)
362 *start = page + off; 337{
363 return ((count < len - off) ? count : len - off); 338 return single_open(file, info_proc_show, PDE(inode)->data);
364} 339}
365 340
341static const struct file_operations info_proc_fops = {
342 .owner = THIS_MODULE,
343 .open = info_proc_open,
344 .read = seq_read,
345 .llseek = seq_lseek,
346 .release = single_release,
347 .write = info_proc_write,
348};
349
366/* 350/*
367** adapter proc init/de-init 351** adapter proc init/de-init
368*/ 352*/
@@ -380,28 +364,20 @@ int create_adapter_proc(diva_os_xdi_adapter_t * a)
380 return (0); 364 return (0);
381 a->proc_adapter_dir = (void *) de; 365 a->proc_adapter_dir = (void *) de;
382 366
383 if (!(pe = 367 pe = proc_create_data(info_proc_name, S_IRUGO | S_IWUSR, de,
384 create_proc_entry(info_proc_name, S_IFREG | S_IRUGO | S_IWUSR, de))) 368 &info_proc_fops, a);
369 if (!pe)
385 return (0); 370 return (0);
386 a->proc_info = (void *) pe; 371 a->proc_info = (void *) pe;
387 pe->write_proc = info_write;
388 pe->read_proc = info_read;
389 pe->data = a;
390 372
391 if ((pe = create_proc_entry(grp_opt_proc_name, 373 pe = proc_create_data(grp_opt_proc_name, S_IRUGO | S_IWUSR, de,
392 S_IFREG | S_IRUGO | S_IWUSR, de))) { 374 &grp_opt_proc_fops, a);
375 if (pe)
393 a->proc_grp_opt = (void *) pe; 376 a->proc_grp_opt = (void *) pe;
394 pe->write_proc = write_grp_opt; 377 pe = proc_create_data(d_l1_down_proc_name, S_IRUGO | S_IWUSR, de,
395 pe->read_proc = read_grp_opt; 378 &d_l1_down_proc_fops, a);
396 pe->data = a; 379 if (pe)
397 }
398 if ((pe = create_proc_entry(d_l1_down_proc_name,
399 S_IFREG | S_IRUGO | S_IWUSR, de))) {
400 a->proc_d_l1_down = (void *) pe; 380 a->proc_d_l1_down = (void *) pe;
401 pe->write_proc = write_d_l1_down;
402 pe->read_proc = read_d_l1_down;
403 pe->data = a;
404 }
405 381
406 DBG_TRC(("proc entry %s created", tmp)); 382 DBG_TRC(("proc entry %s created", tmp));
407 383
diff --git a/drivers/isdn/hardware/eicon/maintidi.c b/drivers/isdn/hardware/eicon/maintidi.c
index 41c26e756452..534978bdf382 100644
--- a/drivers/isdn/hardware/eicon/maintidi.c
+++ b/drivers/isdn/hardware/eicon/maintidi.c
@@ -385,7 +385,7 @@ static int SuperTraceMessageInput (void* hLib) {
385 } 385 }
386 break; 386 break;
387 default: 387 default:
388 diva_mnt_internal_dprintf (0, DLI_ERR, "Unknon IDI Ind (DMA mode): %02x", Ind); 388 diva_mnt_internal_dprintf (0, DLI_ERR, "Unknown IDI Ind (DMA mode): %02x", Ind);
389 } 389 }
390 p += (this_ind_length+1); 390 p += (this_ind_length+1);
391 total_length -= (4 + this_ind_length); 391 total_length -= (4 + this_ind_length);
@@ -420,7 +420,7 @@ static int SuperTraceMessageInput (void* hLib) {
420 } 420 }
421 break; 421 break;
422 default: 422 default:
423 diva_mnt_internal_dprintf (0, DLI_ERR, "Unknon IDI Ind: %02x", Ind); 423 diva_mnt_internal_dprintf (0, DLI_ERR, "Unknown IDI Ind: %02x", Ind);
424 } 424 }
425 } 425 }
426 } 426 }
diff --git a/drivers/isdn/hardware/eicon/message.c b/drivers/isdn/hardware/eicon/message.c
index ae89fb89da64..341ef17c22ac 100644
--- a/drivers/isdn/hardware/eicon/message.c
+++ b/drivers/isdn/hardware/eicon/message.c
@@ -2754,7 +2754,7 @@ static byte connect_b3_req(dword Id, word Number, DIVA_CAPI_ADAPTER *a,
2754 for (i = 0; i < w; i++) 2754 for (i = 0; i < w; i++)
2755 ((T30_INFO *)(plci->fax_connect_info_buffer))->station_id[i] = fax_parms[4].info[1+i]; 2755 ((T30_INFO *)(plci->fax_connect_info_buffer))->station_id[i] = fax_parms[4].info[1+i];
2756 ((T30_INFO *)(plci->fax_connect_info_buffer))->head_line_len = 0; 2756 ((T30_INFO *)(plci->fax_connect_info_buffer))->head_line_len = 0;
2757 len = offsetof(T30_INFO, station_id) + 20; 2757 len = offsetof(T30_INFO, station_id) + T30_MAX_STATION_ID_LENGTH;
2758 w = fax_parms[5].length; 2758 w = fax_parms[5].length;
2759 if (w > 20) 2759 if (w > 20)
2760 w = 20; 2760 w = 20;
@@ -2892,7 +2892,7 @@ static byte connect_b3_res(dword Id, word Number, DIVA_CAPI_ADAPTER *a,
2892 && (plci->nsf_control_bits & T30_NSF_CONTROL_BIT_ENABLE_NSF) 2892 && (plci->nsf_control_bits & T30_NSF_CONTROL_BIT_ENABLE_NSF)
2893 && (plci->nsf_control_bits & T30_NSF_CONTROL_BIT_NEGOTIATE_RESP)) 2893 && (plci->nsf_control_bits & T30_NSF_CONTROL_BIT_NEGOTIATE_RESP))
2894 { 2894 {
2895 len = offsetof(T30_INFO, station_id) + 20; 2895 len = offsetof(T30_INFO, station_id) + T30_MAX_STATION_ID_LENGTH;
2896 if (plci->fax_connect_info_length < len) 2896 if (plci->fax_connect_info_length < len)
2897 { 2897 {
2898 ((T30_INFO *)(plci->fax_connect_info_buffer))->station_id_len = 0; 2898 ((T30_INFO *)(plci->fax_connect_info_buffer))->station_id_len = 0;
@@ -3802,7 +3802,7 @@ static byte manufacturer_res(dword Id, word Number, DIVA_CAPI_ADAPTER *a,
3802 break; 3802 break;
3803 } 3803 }
3804 ncpi = &m_parms[1]; 3804 ncpi = &m_parms[1];
3805 len = offsetof(T30_INFO, station_id) + 20; 3805 len = offsetof(T30_INFO, station_id) + T30_MAX_STATION_ID_LENGTH;
3806 if (plci->fax_connect_info_length < len) 3806 if (plci->fax_connect_info_length < len)
3807 { 3807 {
3808 ((T30_INFO *)(plci->fax_connect_info_buffer))->station_id_len = 0; 3808 ((T30_INFO *)(plci->fax_connect_info_buffer))->station_id_len = 0;
@@ -6830,7 +6830,7 @@ static void nl_ind(PLCI *plci)
6830 if(((T30_INFO *)plci->NL.RBuffer->P)->station_id_len) 6830 if(((T30_INFO *)plci->NL.RBuffer->P)->station_id_len)
6831 { 6831 {
6832 plci->ncpi_buffer[len] = 20; 6832 plci->ncpi_buffer[len] = 20;
6833 for (i = 0; i < 20; i++) 6833 for (i = 0; i < T30_MAX_STATION_ID_LENGTH; i++)
6834 plci->ncpi_buffer[++len] = ((T30_INFO *)plci->NL.RBuffer->P)->station_id[i]; 6834 plci->ncpi_buffer[++len] = ((T30_INFO *)plci->NL.RBuffer->P)->station_id[i];
6835 } 6835 }
6836 if (((plci->NL.Ind & 0x0f) == N_DISC) || ((plci->NL.Ind & 0x0f) == N_DISC_ACK)) 6836 if (((plci->NL.Ind & 0x0f) == N_DISC) || ((plci->NL.Ind & 0x0f) == N_DISC_ACK))
@@ -6844,7 +6844,7 @@ static void nl_ind(PLCI *plci)
6844 if ((plci->requested_options_conn | plci->requested_options | a->requested_options_table[plci->appl->Id-1]) 6844 if ((plci->requested_options_conn | plci->requested_options | a->requested_options_table[plci->appl->Id-1])
6845 & ((1L << PRIVATE_FAX_SUB_SEP_PWD) | (1L << PRIVATE_FAX_NONSTANDARD))) 6845 & ((1L << PRIVATE_FAX_SUB_SEP_PWD) | (1L << PRIVATE_FAX_NONSTANDARD)))
6846 { 6846 {
6847 i = offsetof(T30_INFO, station_id) + 20 + ((T30_INFO *)plci->NL.RBuffer->P)->head_line_len; 6847 i = offsetof(T30_INFO, station_id) + T30_MAX_STATION_ID_LENGTH + ((T30_INFO *)plci->NL.RBuffer->P)->head_line_len;
6848 while (i < plci->NL.RBuffer->length) 6848 while (i < plci->NL.RBuffer->length)
6849 plci->ncpi_buffer[++len] = plci->NL.RBuffer->P[i++]; 6849 plci->ncpi_buffer[++len] = plci->NL.RBuffer->P[i++];
6850 } 6850 }
@@ -8400,7 +8400,7 @@ static word add_b23(PLCI *plci, API_PARSE *bp)
8400 } 8400 }
8401 } 8401 }
8402 /* copy station id to NLC */ 8402 /* copy station id to NLC */
8403 for(i=0; i<20; i++) 8403 for(i=0; i < T30_MAX_STATION_ID_LENGTH; i++)
8404 { 8404 {
8405 if(i<b3_config_parms[2].length) 8405 if(i<b3_config_parms[2].length)
8406 { 8406 {
@@ -8411,29 +8411,29 @@ static word add_b23(PLCI *plci, API_PARSE *bp)
8411 ((T30_INFO *)&nlc[1])->station_id[i] = ' '; 8411 ((T30_INFO *)&nlc[1])->station_id[i] = ' ';
8412 } 8412 }
8413 } 8413 }
8414 ((T30_INFO *)&nlc[1])->station_id_len = 20; 8414 ((T30_INFO *)&nlc[1])->station_id_len = T30_MAX_STATION_ID_LENGTH;
8415 /* copy head line to NLC */ 8415 /* copy head line to NLC */
8416 if(b3_config_parms[3].length) 8416 if(b3_config_parms[3].length)
8417 { 8417 {
8418 8418
8419 pos = (byte)(fax_head_line_time (&(((T30_INFO *)&nlc[1])->station_id[20]))); 8419 pos = (byte)(fax_head_line_time (&(((T30_INFO *)&nlc[1])->station_id[T30_MAX_STATION_ID_LENGTH])));
8420 if (pos != 0) 8420 if (pos != 0)
8421 { 8421 {
8422 if (CAPI_MAX_DATE_TIME_LENGTH + 2 + b3_config_parms[3].length > CAPI_MAX_HEAD_LINE_SPACE) 8422 if (CAPI_MAX_DATE_TIME_LENGTH + 2 + b3_config_parms[3].length > CAPI_MAX_HEAD_LINE_SPACE)
8423 pos = 0; 8423 pos = 0;
8424 else 8424 else
8425 { 8425 {
8426 ((T30_INFO *)&nlc[1])->station_id[20 + pos++] = ' '; 8426 nlc[1 + offsetof(T30_INFO, station_id) + T30_MAX_STATION_ID_LENGTH + pos++] = ' ';
8427 ((T30_INFO *)&nlc[1])->station_id[20 + pos++] = ' '; 8427 nlc[1 + offsetof(T30_INFO, station_id) + T30_MAX_STATION_ID_LENGTH + pos++] = ' ';
8428 len = (byte)b3_config_parms[2].length; 8428 len = (byte)b3_config_parms[2].length;
8429 if (len > 20) 8429 if (len > 20)
8430 len = 20; 8430 len = 20;
8431 if (CAPI_MAX_DATE_TIME_LENGTH + 2 + len + 2 + b3_config_parms[3].length <= CAPI_MAX_HEAD_LINE_SPACE) 8431 if (CAPI_MAX_DATE_TIME_LENGTH + 2 + len + 2 + b3_config_parms[3].length <= CAPI_MAX_HEAD_LINE_SPACE)
8432 { 8432 {
8433 for (i = 0; i < len; i++) 8433 for (i = 0; i < len; i++)
8434 ((T30_INFO *)&nlc[1])->station_id[20 + pos++] = ((byte *)b3_config_parms[2].info)[1+i]; 8434 nlc[1 + offsetof(T30_INFO, station_id) + T30_MAX_STATION_ID_LENGTH + pos++] = ((byte *)b3_config_parms[2].info)[1+i];
8435 ((T30_INFO *)&nlc[1])->station_id[20 + pos++] = ' '; 8435 nlc[1 + offsetof(T30_INFO, station_id) + T30_MAX_STATION_ID_LENGTH + pos++] = ' ';
8436 ((T30_INFO *)&nlc[1])->station_id[20 + pos++] = ' '; 8436 nlc[1 + offsetof(T30_INFO, station_id) + T30_MAX_STATION_ID_LENGTH + pos++] = ' ';
8437 } 8437 }
8438 } 8438 }
8439 } 8439 }
@@ -8444,9 +8444,8 @@ static word add_b23(PLCI *plci, API_PARSE *bp)
8444 ((T30_INFO *)&nlc[1])->head_line_len = (byte)(pos + len); 8444 ((T30_INFO *)&nlc[1])->head_line_len = (byte)(pos + len);
8445 nlc[0] += (byte)(pos + len); 8445 nlc[0] += (byte)(pos + len);
8446 for (i = 0; i < len; i++) 8446 for (i = 0; i < len; i++)
8447 ((T30_INFO *)&nlc[1])->station_id[20 + pos++] = ((byte *)b3_config_parms[3].info)[1+i]; 8447 nlc[1 + offsetof(T30_INFO, station_id) + T30_MAX_STATION_ID_LENGTH + pos++] = ((byte *)b3_config_parms[3].info)[1+i];
8448 } 8448 } else
8449 else
8450 ((T30_INFO *)&nlc[1])->head_line_len = 0; 8449 ((T30_INFO *)&nlc[1])->head_line_len = 0;
8451 8450
8452 plci->nsf_control_bits = 0; 8451 plci->nsf_control_bits = 0;
@@ -8473,7 +8472,7 @@ static word add_b23(PLCI *plci, API_PARSE *bp)
8473 fax_control_bits |= T30_CONTROL_BIT_ACCEPT_SEL_POLLING; 8472 fax_control_bits |= T30_CONTROL_BIT_ACCEPT_SEL_POLLING;
8474 } 8473 }
8475 len = nlc[0]; 8474 len = nlc[0];
8476 pos = offsetof(T30_INFO, station_id) + 20; 8475 pos = offsetof(T30_INFO, station_id) + T30_MAX_STATION_ID_LENGTH;
8477 if (pos < plci->fax_connect_info_length) 8476 if (pos < plci->fax_connect_info_length)
8478 { 8477 {
8479 for (i = 1 + plci->fax_connect_info_buffer[pos]; i != 0; i--) 8478 for (i = 1 + plci->fax_connect_info_buffer[pos]; i != 0; i--)
@@ -8525,7 +8524,7 @@ static word add_b23(PLCI *plci, API_PARSE *bp)
8525 } 8524 }
8526 8525
8527 PUT_WORD(&(((T30_INFO *)&nlc[1])->control_bits_low), fax_control_bits); 8526 PUT_WORD(&(((T30_INFO *)&nlc[1])->control_bits_low), fax_control_bits);
8528 len = offsetof(T30_INFO, station_id) + 20; 8527 len = offsetof(T30_INFO, station_id) + T30_MAX_STATION_ID_LENGTH;
8529 for (i = 0; i < len; i++) 8528 for (i = 0; i < len; i++)
8530 plci->fax_connect_info_buffer[i] = nlc[1+i]; 8529 plci->fax_connect_info_buffer[i] = nlc[1+i];
8531 ((T30_INFO *) plci->fax_connect_info_buffer)->head_line_len = 0; 8530 ((T30_INFO *) plci->fax_connect_info_buffer)->head_line_len = 0;
diff --git a/drivers/isdn/hardware/mISDN/avmfritz.c b/drivers/isdn/hardware/mISDN/avmfritz.c
index 81ac541d40d9..d4215369bb59 100644
--- a/drivers/isdn/hardware/mISDN/avmfritz.c
+++ b/drivers/isdn/hardware/mISDN/avmfritz.c
@@ -24,6 +24,7 @@
24#include <linux/pci.h> 24#include <linux/pci.h>
25#include <linux/delay.h> 25#include <linux/delay.h>
26#include <linux/mISDNhw.h> 26#include <linux/mISDNhw.h>
27#include <linux/slab.h>
27#include <asm/unaligned.h> 28#include <asm/unaligned.h>
28#include "ipac.h" 29#include "ipac.h"
29 30
diff --git a/drivers/isdn/hardware/mISDN/hfcmulti.c b/drivers/isdn/hardware/mISDN/hfcmulti.c
index a6624ad252c5..75e71b5d9215 100644
--- a/drivers/isdn/hardware/mISDN/hfcmulti.c
+++ b/drivers/isdn/hardware/mISDN/hfcmulti.c
@@ -153,6 +153,7 @@
153#define HFC_MULTI_VERSION "2.03" 153#define HFC_MULTI_VERSION "2.03"
154 154
155#include <linux/module.h> 155#include <linux/module.h>
156#include <linux/slab.h>
156#include <linux/pci.h> 157#include <linux/pci.h>
157#include <linux/delay.h> 158#include <linux/delay.h>
158#include <linux/mISDNhw.h> 159#include <linux/mISDNhw.h>
@@ -2846,7 +2847,7 @@ mode_hfcmulti(struct hfc_multi *hc, int ch, int protocol, int slot_tx,
2846 int conf; 2847 int conf;
2847 2848
2848 if (ch < 0 || ch > 31) 2849 if (ch < 0 || ch > 31)
2849 return EINVAL; 2850 return -EINVAL;
2850 oslot_tx = hc->chan[ch].slot_tx; 2851 oslot_tx = hc->chan[ch].slot_tx;
2851 oslot_rx = hc->chan[ch].slot_rx; 2852 oslot_rx = hc->chan[ch].slot_rx;
2852 conf = hc->chan[ch].conf; 2853 conf = hc->chan[ch].conf;
@@ -3152,7 +3153,7 @@ static void
3152hfcmulti_pcm(struct hfc_multi *hc, int ch, int slot_tx, int bank_tx, 3153hfcmulti_pcm(struct hfc_multi *hc, int ch, int slot_tx, int bank_tx,
3153 int slot_rx, int bank_rx) 3154 int slot_rx, int bank_rx)
3154{ 3155{
3155 if (slot_rx < 0 || slot_rx < 0 || bank_tx < 0 || bank_rx < 0) { 3156 if (slot_tx < 0 || slot_rx < 0 || bank_tx < 0 || bank_rx < 0) {
3156 /* disable PCM */ 3157 /* disable PCM */
3157 mode_hfcmulti(hc, ch, hc->chan[ch].protocol, -1, 0, -1, 0); 3158 mode_hfcmulti(hc, ch, hc->chan[ch].protocol, -1, 0, -1, 0);
3158 return; 3159 return;
@@ -5265,6 +5266,8 @@ static const struct hm_map hfcm_map[] = {
5265/*31*/ {VENDOR_CCD, "XHFC-4S Speech Design", 5, 4, 0, 0, 0, 0, 5266/*31*/ {VENDOR_CCD, "XHFC-4S Speech Design", 5, 4, 0, 0, 0, 0,
5266 HFC_IO_MODE_EMBSD, XHFC_IRQ}, 5267 HFC_IO_MODE_EMBSD, XHFC_IRQ},
5267/*32*/ {VENDOR_JH, "HFC-8S (junghanns)", 8, 8, 1, 0, 0, 0, 0, 0}, 5268/*32*/ {VENDOR_JH, "HFC-8S (junghanns)", 8, 8, 1, 0, 0, 0, 0, 0},
5269/*33*/ {VENDOR_BN, "HFC-2S Beronet Card PCIe", 4, 2, 1, 3, 0, DIP_4S, 0, 0},
5270/*34*/ {VENDOR_BN, "HFC-4S Beronet Card PCIe", 4, 4, 1, 2, 0, DIP_4S, 0, 0},
5268}; 5271};
5269 5272
5270#undef H 5273#undef H
@@ -5300,6 +5303,10 @@ static struct pci_device_id hfmultipci_ids[] __devinitdata = {
5300 PCI_SUBDEVICE_ID_CCD_OV4S, 0, 0, H(28)}, /* OpenVox 4 */ 5303 PCI_SUBDEVICE_ID_CCD_OV4S, 0, 0, H(28)}, /* OpenVox 4 */
5301 { PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_HFC4S, PCI_VENDOR_ID_CCD, 5304 { PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_HFC4S, PCI_VENDOR_ID_CCD,
5302 PCI_SUBDEVICE_ID_CCD_OV2S, 0, 0, H(29)}, /* OpenVox 2 */ 5305 PCI_SUBDEVICE_ID_CCD_OV2S, 0, 0, H(29)}, /* OpenVox 2 */
5306 { PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_HFC4S, PCI_VENDOR_ID_CCD,
5307 0xb761, 0, 0, H(33)}, /* BN2S PCIe */
5308 { PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_HFC4S, PCI_VENDOR_ID_CCD,
5309 0xb762, 0, 0, H(34)}, /* BN4S PCIe */
5303 5310
5304 /* Cards with HFC-8S Chip */ 5311 /* Cards with HFC-8S Chip */
5305 { PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_HFC8S, PCI_VENDOR_ID_CCD, 5312 { PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_HFC8S, PCI_VENDOR_ID_CCD,
diff --git a/drivers/isdn/hardware/mISDN/hfcpci.c b/drivers/isdn/hardware/mISDN/hfcpci.c
index 70e6b0e01121..5940a2c12074 100644
--- a/drivers/isdn/hardware/mISDN/hfcpci.c
+++ b/drivers/isdn/hardware/mISDN/hfcpci.c
@@ -48,6 +48,7 @@
48#include <linux/pci.h> 48#include <linux/pci.h>
49#include <linux/delay.h> 49#include <linux/delay.h>
50#include <linux/mISDNhw.h> 50#include <linux/mISDNhw.h>
51#include <linux/slab.h>
51 52
52#include "hfc_pci.h" 53#include "hfc_pci.h"
53 54
diff --git a/drivers/isdn/hardware/mISDN/hfcsusb.c b/drivers/isdn/hardware/mISDN/hfcsusb.c
index fc46a26cb14f..b3b7e2879bac 100644
--- a/drivers/isdn/hardware/mISDN/hfcsusb.c
+++ b/drivers/isdn/hardware/mISDN/hfcsusb.c
@@ -33,6 +33,7 @@
33#include <linux/delay.h> 33#include <linux/delay.h>
34#include <linux/usb.h> 34#include <linux/usb.h>
35#include <linux/mISDNhw.h> 35#include <linux/mISDNhw.h>
36#include <linux/slab.h>
36#include "hfcsusb.h" 37#include "hfcsusb.h"
37 38
38static const char *hfcsusb_rev = "Revision: 0.3.3 (socket), 2008-11-05"; 39static const char *hfcsusb_rev = "Revision: 0.3.3 (socket), 2008-11-05";
@@ -721,7 +722,7 @@ hfcsusb_setup_bch(struct bchannel *bch, int protocol)
721 switch (protocol) { 722 switch (protocol) {
722 case (-1): /* used for init */ 723 case (-1): /* used for init */
723 bch->state = -1; 724 bch->state = -1;
724 /* fall trough */ 725 /* fall through */
725 case (ISDN_P_NONE): 726 case (ISDN_P_NONE):
726 if (bch->state == ISDN_P_NONE) 727 if (bch->state == ISDN_P_NONE)
727 return 0; /* already in idle state */ 728 return 0; /* already in idle state */
diff --git a/drivers/isdn/hardware/mISDN/hfcsusb.h b/drivers/isdn/hardware/mISDN/hfcsusb.h
index 43efe7358fa3..369196adae03 100644
--- a/drivers/isdn/hardware/mISDN/hfcsusb.h
+++ b/drivers/isdn/hardware/mISDN/hfcsusb.h
@@ -150,7 +150,7 @@ symbolic(struct hfcusb_symbolic_list list[], const int num)
150 for (i = 0; list[i].name != NULL; i++) 150 for (i = 0; list[i].name != NULL; i++)
151 if (list[i].num == num) 151 if (list[i].num == num)
152 return list[i].name; 152 return list[i].name;
153 return "<unkown USB Error>"; 153 return "<unknown USB Error>";
154} 154}
155 155
156/* USB descriptor need to contain one of the following EndPoint combination: */ 156/* USB descriptor need to contain one of the following EndPoint combination: */
diff --git a/drivers/isdn/hardware/mISDN/mISDNinfineon.c b/drivers/isdn/hardware/mISDN/mISDNinfineon.c
index 62441ba53b95..f5b3d2b26a08 100644
--- a/drivers/isdn/hardware/mISDN/mISDNinfineon.c
+++ b/drivers/isdn/hardware/mISDN/mISDNinfineon.c
@@ -42,6 +42,7 @@
42#include <linux/pci.h> 42#include <linux/pci.h>
43#include <linux/delay.h> 43#include <linux/delay.h>
44#include <linux/mISDNhw.h> 44#include <linux/mISDNhw.h>
45#include <linux/slab.h>
45#include "ipac.h" 46#include "ipac.h"
46 47
47#define INFINEON_REV "1.0" 48#define INFINEON_REV "1.0"
@@ -1133,6 +1134,7 @@ inf_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
1133 if (err) { 1134 if (err) {
1134 kfree(sc); 1135 kfree(sc);
1135 release_card(card); 1136 release_card(card);
1137 break;
1136 } else 1138 } else
1137 card->sc[i - 1] = sc; 1139 card->sc[i - 1] = sc;
1138 } 1140 }
diff --git a/drivers/isdn/hardware/mISDN/mISDNipac.c b/drivers/isdn/hardware/mISDN/mISDNipac.c
index 613ba0435372..64ecc6f5ffaf 100644
--- a/drivers/isdn/hardware/mISDN/mISDNipac.c
+++ b/drivers/isdn/hardware/mISDN/mISDNipac.c
@@ -20,6 +20,7 @@
20 * 20 *
21 */ 21 */
22 22
23#include <linux/slab.h>
23#include <linux/module.h> 24#include <linux/module.h>
24#include <linux/mISDNhw.h> 25#include <linux/mISDNhw.h>
25#include "ipac.h" 26#include "ipac.h"
diff --git a/drivers/isdn/hardware/mISDN/mISDNisar.c b/drivers/isdn/hardware/mISDN/mISDNisar.c
index de352a17673a..38eb31439a73 100644
--- a/drivers/isdn/hardware/mISDN/mISDNisar.c
+++ b/drivers/isdn/hardware/mISDN/mISDNisar.c
@@ -25,6 +25,7 @@
25 */ 25 */
26/* #define DEBUG */ 26/* #define DEBUG */
27 27
28#include <linux/gfp.h>
28#include <linux/delay.h> 29#include <linux/delay.h>
29#include <linux/vmalloc.h> 30#include <linux/vmalloc.h>
30#include <linux/mISDNhw.h> 31#include <linux/mISDNhw.h>
@@ -860,7 +861,7 @@ isar_pump_statev_modem(struct isar_ch *ch, u8 devt) {
860 pr_debug("%s: pump stev GSTN CLEAR\n", ch->is->name); 861 pr_debug("%s: pump stev GSTN CLEAR\n", ch->is->name);
861 break; 862 break;
862 default: 863 default:
863 pr_info("u%s: nknown pump stev %x\n", ch->is->name, devt); 864 pr_info("u%s: unknown pump stev %x\n", ch->is->name, devt);
864 break; 865 break;
865 } 866 }
866} 867}
@@ -1712,13 +1713,13 @@ mISDNisar_init(struct isar_hw *isar, void *hw)
1712} 1713}
1713EXPORT_SYMBOL(mISDNisar_init); 1714EXPORT_SYMBOL(mISDNisar_init);
1714 1715
1715static int isar_mod_init(void) 1716static int __init isar_mod_init(void)
1716{ 1717{
1717 pr_notice("mISDN: ISAR driver Rev. %s\n", ISAR_REV); 1718 pr_notice("mISDN: ISAR driver Rev. %s\n", ISAR_REV);
1718 return 0; 1719 return 0;
1719} 1720}
1720 1721
1721static void isar_mod_cleanup(void) 1722static void __exit isar_mod_cleanup(void)
1722{ 1723{
1723 pr_notice("mISDN: ISAR module unloaded\n"); 1724 pr_notice("mISDN: ISAR module unloaded\n");
1724} 1725}
diff --git a/drivers/isdn/hardware/mISDN/netjet.c b/drivers/isdn/hardware/mISDN/netjet.c
index 6c1b164937a9..0a3553df065f 100644
--- a/drivers/isdn/hardware/mISDN/netjet.c
+++ b/drivers/isdn/hardware/mISDN/netjet.c
@@ -24,6 +24,7 @@
24#include <linux/pci.h> 24#include <linux/pci.h>
25#include <linux/delay.h> 25#include <linux/delay.h>
26#include <linux/mISDNhw.h> 26#include <linux/mISDNhw.h>
27#include <linux/slab.h>
27#include "ipac.h" 28#include "ipac.h"
28#include "iohelper.h" 29#include "iohelper.h"
29#include "netjet.h" 30#include "netjet.h"
diff --git a/drivers/isdn/hardware/mISDN/speedfax.c b/drivers/isdn/hardware/mISDN/speedfax.c
index ff3a4e290da3..d097a4e40e2b 100644
--- a/drivers/isdn/hardware/mISDN/speedfax.c
+++ b/drivers/isdn/hardware/mISDN/speedfax.c
@@ -23,6 +23,7 @@
23 */ 23 */
24 24
25#include <linux/module.h> 25#include <linux/module.h>
26#include <linux/slab.h>
26#include <linux/pci.h> 27#include <linux/pci.h>
27#include <linux/delay.h> 28#include <linux/delay.h>
28#include <linux/mISDNhw.h> 29#include <linux/mISDNhw.h>
@@ -110,6 +111,7 @@ set_debug(const char *val, struct kernel_param *kp)
110MODULE_AUTHOR("Karsten Keil"); 111MODULE_AUTHOR("Karsten Keil");
111MODULE_LICENSE("GPL v2"); 112MODULE_LICENSE("GPL v2");
112MODULE_VERSION(SPEEDFAX_REV); 113MODULE_VERSION(SPEEDFAX_REV);
114MODULE_FIRMWARE("isdn/ISAR.BIN");
113module_param_call(debug, set_debug, param_get_uint, &debug, S_IRUGO | S_IWUSR); 115module_param_call(debug, set_debug, param_get_uint, &debug, S_IRUGO | S_IWUSR);
114MODULE_PARM_DESC(debug, "Speedfax debug mask"); 116MODULE_PARM_DESC(debug, "Speedfax debug mask");
115module_param(irqloops, uint, S_IRUGO | S_IWUSR); 117module_param(irqloops, uint, S_IRUGO | S_IWUSR);
diff --git a/drivers/isdn/hardware/mISDN/w6692.c b/drivers/isdn/hardware/mISDN/w6692.c
index d3f1077b709b..31f9d71fb22f 100644
--- a/drivers/isdn/hardware/mISDN/w6692.c
+++ b/drivers/isdn/hardware/mISDN/w6692.c
@@ -25,6 +25,7 @@
25#include <linux/pci.h> 25#include <linux/pci.h>
26#include <linux/delay.h> 26#include <linux/delay.h>
27#include <linux/mISDNhw.h> 27#include <linux/mISDNhw.h>
28#include <linux/slab.h>
28#include "w6692.h" 29#include "w6692.h"
29 30
30#define W6692_REV "2.0" 31#define W6692_REV "2.0"
@@ -529,6 +530,7 @@ W6692_fill_Bfifo(struct w6692_ch *wch)
529 } 530 }
530} 531}
531 532
533#if 0
532static int 534static int
533setvolume(struct w6692_ch *wch, int mic, struct sk_buff *skb) 535setvolume(struct w6692_ch *wch, int mic, struct sk_buff *skb)
534{ 536{
@@ -571,6 +573,7 @@ enable_pots(struct w6692_ch *wch)
571 WriteW6692(card, W_PCTL, card->pctl); 573 WriteW6692(card, W_PCTL, card->pctl);
572 return 0; 574 return 0;
573} 575}
576#endif
574 577
575static int 578static int
576disable_pots(struct w6692_ch *wch) 579disable_pots(struct w6692_ch *wch)
diff --git a/drivers/isdn/hisax/Kconfig b/drivers/isdn/hisax/Kconfig
index 3464ebc4cdbc..452fde9edf86 100644
--- a/drivers/isdn/hisax/Kconfig
+++ b/drivers/isdn/hisax/Kconfig
@@ -109,7 +109,7 @@ config HISAX_16_3
109 109
110config HISAX_TELESPCI 110config HISAX_TELESPCI
111 bool "Teles PCI" 111 bool "Teles PCI"
112 depends on PCI && PCI_LEGACY && (BROKEN || !(SPARC || PPC || PARISC || M68K || (MIPS && !CPU_LITTLE_ENDIAN) || FRV)) 112 depends on PCI && (BROKEN || !(SPARC || PPC || PARISC || M68K || (MIPS && !CPU_LITTLE_ENDIAN) || FRV))
113 help 113 help
114 This enables HiSax support for the Teles PCI. 114 This enables HiSax support for the Teles PCI.
115 See <file:Documentation/isdn/README.HiSax> on how to configure it. 115 See <file:Documentation/isdn/README.HiSax> on how to configure it.
@@ -237,7 +237,7 @@ config HISAX_MIC
237 237
238config HISAX_NETJET 238config HISAX_NETJET
239 bool "NETjet card" 239 bool "NETjet card"
240 depends on PCI && PCI_LEGACY && (BROKEN || !(SPARC || PPC || PARISC || M68K || (MIPS && !CPU_LITTLE_ENDIAN) || FRV)) 240 depends on PCI && (BROKEN || !(SPARC || PPC || PARISC || M68K || (MIPS && !CPU_LITTLE_ENDIAN) || FRV))
241 help 241 help
242 This enables HiSax support for the NetJet from Traverse 242 This enables HiSax support for the NetJet from Traverse
243 Technologies. 243 Technologies.
@@ -248,7 +248,7 @@ config HISAX_NETJET
248 248
249config HISAX_NETJET_U 249config HISAX_NETJET_U
250 bool "NETspider U card" 250 bool "NETspider U card"
251 depends on PCI && PCI_LEGACY && (BROKEN || !(SPARC || PPC || PARISC || M68K || (MIPS && !CPU_LITTLE_ENDIAN) || FRV)) 251 depends on PCI && (BROKEN || !(SPARC || PPC || PARISC || M68K || (MIPS && !CPU_LITTLE_ENDIAN) || FRV))
252 help 252 help
253 This enables HiSax support for the Netspider U interface ISDN card 253 This enables HiSax support for the Netspider U interface ISDN card
254 from Traverse Technologies. 254 from Traverse Technologies.
@@ -287,7 +287,7 @@ config HISAX_HSTSAPHIR
287 287
288config HISAX_BKM_A4T 288config HISAX_BKM_A4T
289 bool "Telekom A4T card" 289 bool "Telekom A4T card"
290 depends on PCI && PCI_LEGACY 290 depends on PCI
291 help 291 help
292 This enables HiSax support for the Telekom A4T card. 292 This enables HiSax support for the Telekom A4T card.
293 293
@@ -297,7 +297,7 @@ config HISAX_BKM_A4T
297 297
298config HISAX_SCT_QUADRO 298config HISAX_SCT_QUADRO
299 bool "Scitel Quadro card" 299 bool "Scitel Quadro card"
300 depends on PCI && PCI_LEGACY 300 depends on PCI
301 help 301 help
302 This enables HiSax support for the Scitel Quadro card. 302 This enables HiSax support for the Scitel Quadro card.
303 303
@@ -316,7 +316,7 @@ config HISAX_GAZEL
316 316
317config HISAX_HFC_PCI 317config HISAX_HFC_PCI
318 bool "HFC PCI-Bus cards" 318 bool "HFC PCI-Bus cards"
319 depends on PCI && PCI_LEGACY && (BROKEN || !(SPARC || PPC || PARISC || M68K || (MIPS && !CPU_LITTLE_ENDIAN) || FRV)) 319 depends on PCI && (BROKEN || !(SPARC || PPC || PARISC || M68K || (MIPS && !CPU_LITTLE_ENDIAN) || FRV))
320 help 320 help
321 This enables HiSax support for the HFC-S PCI 2BDS0 based cards. 321 This enables HiSax support for the HFC-S PCI 2BDS0 based cards.
322 322
@@ -325,7 +325,7 @@ config HISAX_HFC_PCI
325 325
326config HISAX_W6692 326config HISAX_W6692
327 bool "Winbond W6692 based cards" 327 bool "Winbond W6692 based cards"
328 depends on PCI && PCI_LEGACY 328 depends on PCI
329 help 329 help
330 This enables HiSax support for Winbond W6692 based PCI ISDN cards. 330 This enables HiSax support for Winbond W6692 based PCI ISDN cards.
331 331
@@ -341,7 +341,7 @@ config HISAX_HFC_SX
341 341
342config HISAX_ENTERNOW_PCI 342config HISAX_ENTERNOW_PCI
343 bool "Formula-n enter:now PCI card" 343 bool "Formula-n enter:now PCI card"
344 depends on HISAX_NETJET && PCI && PCI_LEGACY && (BROKEN || !(SPARC || PPC || PARISC || M68K || (MIPS && !CPU_LITTLE_ENDIAN) || FRV)) 344 depends on HISAX_NETJET && PCI && (BROKEN || !(SPARC || PPC || PARISC || M68K || (MIPS && !CPU_LITTLE_ENDIAN) || FRV))
345 help 345 help
346 This enables HiSax support for the Formula-n enter:now PCI 346 This enables HiSax support for the Formula-n enter:now PCI
347 ISDN card. 347 ISDN card.
@@ -412,7 +412,7 @@ config HISAX_HFC4S8S
412 412
413config HISAX_FRITZ_PCIPNP 413config HISAX_FRITZ_PCIPNP
414 tristate "AVM Fritz!Card PCI/PCIv2/PnP support (EXPERIMENTAL)" 414 tristate "AVM Fritz!Card PCI/PCIv2/PnP support (EXPERIMENTAL)"
415 depends on PCI && PCI_LEGACY && EXPERIMENTAL 415 depends on PCI && EXPERIMENTAL
416 help 416 help
417 This enables the driver for the AVM Fritz!Card PCI, 417 This enables the driver for the AVM Fritz!Card PCI,
418 Fritz!Card PCI v2 and Fritz!Card PnP. 418 Fritz!Card PCI v2 and Fritz!Card PnP.
diff --git a/drivers/isdn/hisax/amd7930_fn.c b/drivers/isdn/hisax/amd7930_fn.c
index d6fdf1f66754..5d7278397878 100644
--- a/drivers/isdn/hisax/amd7930_fn.c
+++ b/drivers/isdn/hisax/amd7930_fn.c
@@ -59,6 +59,7 @@
59#include "amd7930_fn.h" 59#include "amd7930_fn.h"
60#include <linux/interrupt.h> 60#include <linux/interrupt.h>
61#include <linux/init.h> 61#include <linux/init.h>
62#include <linux/gfp.h>
62 63
63static void Amd7930_new_ph(struct IsdnCardState *cs); 64static void Amd7930_new_ph(struct IsdnCardState *cs);
64 65
diff --git a/drivers/isdn/hisax/avm_pci.c b/drivers/isdn/hisax/avm_pci.c
index 7cabc5a19492..fcf4ed1cb4b9 100644
--- a/drivers/isdn/hisax/avm_pci.c
+++ b/drivers/isdn/hisax/avm_pci.c
@@ -17,6 +17,7 @@
17#include "isac.h" 17#include "isac.h"
18#include "isdnl1.h" 18#include "isdnl1.h"
19#include <linux/pci.h> 19#include <linux/pci.h>
20#include <linux/slab.h>
20#include <linux/isapnp.h> 21#include <linux/isapnp.h>
21#include <linux/interrupt.h> 22#include <linux/interrupt.h>
22 23
@@ -822,7 +823,7 @@ static int __devinit avm_pnp_setup(struct IsdnCardState *cs)
822 823
823#endif /* __ISAPNP__ */ 824#endif /* __ISAPNP__ */
824 825
825#ifndef CONFIG_PCI_LEGACY 826#ifndef CONFIG_PCI
826 827
827static int __devinit avm_pci_setup(struct IsdnCardState *cs) 828static int __devinit avm_pci_setup(struct IsdnCardState *cs)
828{ 829{
@@ -835,7 +836,7 @@ static struct pci_dev *dev_avm __devinitdata = NULL;
835 836
836static int __devinit avm_pci_setup(struct IsdnCardState *cs) 837static int __devinit avm_pci_setup(struct IsdnCardState *cs)
837{ 838{
838 if ((dev_avm = pci_find_device(PCI_VENDOR_ID_AVM, 839 if ((dev_avm = hisax_find_pci_device(PCI_VENDOR_ID_AVM,
839 PCI_DEVICE_ID_AVM_A1, dev_avm))) { 840 PCI_DEVICE_ID_AVM_A1, dev_avm))) {
840 841
841 if (pci_enable_device(dev_avm)) 842 if (pci_enable_device(dev_avm))
@@ -864,7 +865,7 @@ static int __devinit avm_pci_setup(struct IsdnCardState *cs)
864 return (1); 865 return (1);
865} 866}
866 867
867#endif /* CONFIG_PCI_LEGACY */ 868#endif /* CONFIG_PCI */
868 869
869int __devinit 870int __devinit
870setup_avm_pcipnp(struct IsdnCard *card) 871setup_avm_pcipnp(struct IsdnCard *card)
diff --git a/drivers/isdn/hisax/avma1_cs.c b/drivers/isdn/hisax/avma1_cs.c
index 23560c897ec3..8d1d63a02b34 100644
--- a/drivers/isdn/hisax/avma1_cs.c
+++ b/drivers/isdn/hisax/avma1_cs.c
@@ -30,22 +30,6 @@ MODULE_DESCRIPTION("ISDN4Linux: PCMCIA client driver for AVM A1/Fritz!PCMCIA car
30MODULE_AUTHOR("Carsten Paeth"); 30MODULE_AUTHOR("Carsten Paeth");
31MODULE_LICENSE("GPL"); 31MODULE_LICENSE("GPL");
32 32
33/*
34 All the PCMCIA modules use PCMCIA_DEBUG to control debugging. If
35 you do not define PCMCIA_DEBUG at all, all the debug code will be
36 left out. If you compile with PCMCIA_DEBUG=0, the debug code will
37 be present but disabled -- but it can then be enabled for specific
38 modules at load time with a 'pc_debug=#' option to insmod.
39*/
40#ifdef PCMCIA_DEBUG
41static int pc_debug = PCMCIA_DEBUG;
42module_param(pc_debug, int, 0);
43#define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args);
44static char *version =
45"avma1_cs.c 1.00 1998/01/23 10:00:00 (Carsten Paeth)";
46#else
47#define DEBUG(n, args...)
48#endif
49 33
50/*====================================================================*/ 34/*====================================================================*/
51 35
@@ -66,7 +50,7 @@ module_param(isdnprot, int, 0);
66 handler. 50 handler.
67*/ 51*/
68 52
69static int avma1cs_config(struct pcmcia_device *link); 53static int avma1cs_config(struct pcmcia_device *link) __devinit ;
70static void avma1cs_release(struct pcmcia_device *link); 54static void avma1cs_release(struct pcmcia_device *link);
71 55
72/* 56/*
@@ -75,7 +59,7 @@ static void avma1cs_release(struct pcmcia_device *link);
75 needed to manage one actual PCMCIA card. 59 needed to manage one actual PCMCIA card.
76*/ 60*/
77 61
78static void avma1cs_detach(struct pcmcia_device *p_dev); 62static void avma1cs_detach(struct pcmcia_device *p_dev) __devexit ;
79 63
80 64
81/* 65/*
@@ -115,11 +99,11 @@ typedef struct local_info_t {
115 99
116======================================================================*/ 100======================================================================*/
117 101
118static int avma1cs_probe(struct pcmcia_device *p_dev) 102static int __devinit avma1cs_probe(struct pcmcia_device *p_dev)
119{ 103{
120 local_info_t *local; 104 local_info_t *local;
121 105
122 DEBUG(0, "avma1cs_attach()\n"); 106 dev_dbg(&p_dev->dev, "avma1cs_attach()\n");
123 107
124 /* Allocate space for private device-specific data */ 108 /* Allocate space for private device-specific data */
125 local = kzalloc(sizeof(local_info_t), GFP_KERNEL); 109 local = kzalloc(sizeof(local_info_t), GFP_KERNEL);
@@ -136,10 +120,7 @@ static int avma1cs_probe(struct pcmcia_device *p_dev)
136 p_dev->io.IOAddrLines = 5; 120 p_dev->io.IOAddrLines = 5;
137 121
138 /* Interrupt setup */ 122 /* Interrupt setup */
139 p_dev->irq.Attributes = IRQ_TYPE_EXCLUSIVE; 123 p_dev->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
140 p_dev->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING|IRQ_FIRST_SHARED;
141
142 p_dev->irq.IRQInfo1 = IRQ_LEVEL_ID;
143 124
144 /* General socket configuration */ 125 /* General socket configuration */
145 p_dev->conf.Attributes = CONF_ENABLE_IRQ; 126 p_dev->conf.Attributes = CONF_ENABLE_IRQ;
@@ -159,9 +140,9 @@ static int avma1cs_probe(struct pcmcia_device *p_dev)
159 140
160======================================================================*/ 141======================================================================*/
161 142
162static void avma1cs_detach(struct pcmcia_device *link) 143static void __devexit avma1cs_detach(struct pcmcia_device *link)
163{ 144{
164 DEBUG(0, "avma1cs_detach(0x%p)\n", link); 145 dev_dbg(&link->dev, "avma1cs_detach(0x%p)\n", link);
165 avma1cs_release(link); 146 avma1cs_release(link);
166 kfree(link->priv); 147 kfree(link->priv);
167} /* avma1cs_detach */ 148} /* avma1cs_detach */
@@ -193,7 +174,7 @@ static int avma1cs_configcheck(struct pcmcia_device *p_dev,
193} 174}
194 175
195 176
196static int avma1cs_config(struct pcmcia_device *link) 177static int __devinit avma1cs_config(struct pcmcia_device *link)
197{ 178{
198 local_info_t *dev; 179 local_info_t *dev;
199 int i; 180 int i;
@@ -203,7 +184,7 @@ static int avma1cs_config(struct pcmcia_device *link)
203 184
204 dev = link->priv; 185 dev = link->priv;
205 186
206 DEBUG(0, "avma1cs_config(0x%p)\n", link); 187 dev_dbg(&link->dev, "avma1cs_config(0x%p)\n", link);
207 188
208 devname[0] = 0; 189 devname[0] = 0;
209 if (link->prod_id[1]) 190 if (link->prod_id[1])
@@ -218,7 +199,6 @@ static int avma1cs_config(struct pcmcia_device *link)
218 */ 199 */
219 i = pcmcia_request_irq(link, &link->irq); 200 i = pcmcia_request_irq(link, &link->irq);
220 if (i != 0) { 201 if (i != 0) {
221 cs_error(link, RequestIRQ, i);
222 /* undo */ 202 /* undo */
223 pcmcia_disable_device(link); 203 pcmcia_disable_device(link);
224 break; 204 break;
@@ -229,7 +209,6 @@ static int avma1cs_config(struct pcmcia_device *link)
229 */ 209 */
230 i = pcmcia_request_configuration(link, &link->conf); 210 i = pcmcia_request_configuration(link, &link->conf);
231 if (i != 0) { 211 if (i != 0) {
232 cs_error(link, RequestConfiguration, i);
233 pcmcia_disable_device(link); 212 pcmcia_disable_device(link);
234 break; 213 break;
235 } 214 }
@@ -281,7 +260,7 @@ static void avma1cs_release(struct pcmcia_device *link)
281{ 260{
282 local_info_t *local = link->priv; 261 local_info_t *local = link->priv;
283 262
284 DEBUG(0, "avma1cs_release(0x%p)\n", link); 263 dev_dbg(&link->dev, "avma1cs_release(0x%p)\n", link);
285 264
286 /* now unregister function with hisax */ 265 /* now unregister function with hisax */
287 HiSax_closecard(local->node.minor); 266 HiSax_closecard(local->node.minor);
@@ -303,7 +282,7 @@ static struct pcmcia_driver avma1cs_driver = {
303 .name = "avma1_cs", 282 .name = "avma1_cs",
304 }, 283 },
305 .probe = avma1cs_probe, 284 .probe = avma1cs_probe,
306 .remove = avma1cs_detach, 285 .remove = __devexit_p(avma1cs_detach),
307 .id_table = avma1cs_ids, 286 .id_table = avma1cs_ids,
308}; 287};
309 288
diff --git a/drivers/isdn/hisax/bkm_a4t.c b/drivers/isdn/hisax/bkm_a4t.c
index 9ca2ee54cc94..9f2009c0b69c 100644
--- a/drivers/isdn/hisax/bkm_a4t.c
+++ b/drivers/isdn/hisax/bkm_a4t.c
@@ -340,7 +340,7 @@ setup_bkm_a4t(struct IsdnCard *card)
340 } else 340 } else
341 return (0); 341 return (0);
342 342
343 while ((dev_a4t = pci_find_device(PCI_VENDOR_ID_ZORAN, 343 while ((dev_a4t = hisax_find_pci_device(PCI_VENDOR_ID_ZORAN,
344 PCI_DEVICE_ID_ZORAN_36120, dev_a4t))) { 344 PCI_DEVICE_ID_ZORAN_36120, dev_a4t))) {
345 ret = a4t_pci_probe(dev_a4t, cs, &found, &pci_memaddr); 345 ret = a4t_pci_probe(dev_a4t, cs, &found, &pci_memaddr);
346 if (!ret) 346 if (!ret)
diff --git a/drivers/isdn/hisax/bkm_a8.c b/drivers/isdn/hisax/bkm_a8.c
index e1ff4717a8a6..e775706c60e3 100644
--- a/drivers/isdn/hisax/bkm_a8.c
+++ b/drivers/isdn/hisax/bkm_a8.c
@@ -301,7 +301,7 @@ setup_sct_quadro(struct IsdnCard *card)
301 (sub_vendor_id != PCI_VENDOR_ID_BERKOM))) 301 (sub_vendor_id != PCI_VENDOR_ID_BERKOM)))
302 return (0); 302 return (0);
303 if (cs->subtyp == SCT_1) { 303 if (cs->subtyp == SCT_1) {
304 while ((dev_a8 = pci_find_device(PCI_VENDOR_ID_PLX, 304 while ((dev_a8 = hisax_find_pci_device(PCI_VENDOR_ID_PLX,
305 PCI_DEVICE_ID_PLX_9050, dev_a8))) { 305 PCI_DEVICE_ID_PLX_9050, dev_a8))) {
306 306
307 sub_vendor_id = dev_a8->subsystem_vendor; 307 sub_vendor_id = dev_a8->subsystem_vendor;
diff --git a/drivers/isdn/hisax/callc.c b/drivers/isdn/hisax/callc.c
index 475b1a020003..f58ded8f403f 100644
--- a/drivers/isdn/hisax/callc.c
+++ b/drivers/isdn/hisax/callc.c
@@ -17,6 +17,7 @@
17 */ 17 */
18 18
19#include <linux/module.h> 19#include <linux/module.h>
20#include <linux/slab.h>
20#include <linux/init.h> 21#include <linux/init.h>
21#include "hisax.h" 22#include "hisax.h"
22#include <linux/isdn/capicmd.h> 23#include <linux/isdn/capicmd.h>
diff --git a/drivers/isdn/hisax/config.c b/drivers/isdn/hisax/config.c
index 4fab18d4d02f..544cf4b1cce3 100644
--- a/drivers/isdn/hisax/config.c
+++ b/drivers/isdn/hisax/config.c
@@ -23,6 +23,7 @@
23#include <linux/kernel_stat.h> 23#include <linux/kernel_stat.h>
24#include <linux/workqueue.h> 24#include <linux/workqueue.h>
25#include <linux/interrupt.h> 25#include <linux/interrupt.h>
26#include <linux/slab.h>
26#define HISAX_STATUS_BUFSIZE 4096 27#define HISAX_STATUS_BUFSIZE 4096
27 28
28/* 29/*
diff --git a/drivers/isdn/hisax/diva.c b/drivers/isdn/hisax/diva.c
index 0b0c2e5d806b..780da9bda915 100644
--- a/drivers/isdn/hisax/diva.c
+++ b/drivers/isdn/hisax/diva.c
@@ -1148,7 +1148,7 @@ static int __devinit setup_diva_isapnp(struct IsdnCard *card)
1148 1148
1149#endif /* ISAPNP */ 1149#endif /* ISAPNP */
1150 1150
1151#ifdef CONFIG_PCI_LEGACY 1151#ifdef CONFIG_PCI
1152static struct pci_dev *dev_diva __devinitdata = NULL; 1152static struct pci_dev *dev_diva __devinitdata = NULL;
1153static struct pci_dev *dev_diva_u __devinitdata = NULL; 1153static struct pci_dev *dev_diva_u __devinitdata = NULL;
1154static struct pci_dev *dev_diva201 __devinitdata = NULL; 1154static struct pci_dev *dev_diva201 __devinitdata = NULL;
@@ -1159,21 +1159,21 @@ static int __devinit setup_diva_pci(struct IsdnCard *card)
1159 struct IsdnCardState *cs = card->cs; 1159 struct IsdnCardState *cs = card->cs;
1160 1160
1161 cs->subtyp = 0; 1161 cs->subtyp = 0;
1162 if ((dev_diva = pci_find_device(PCI_VENDOR_ID_EICON, 1162 if ((dev_diva = hisax_find_pci_device(PCI_VENDOR_ID_EICON,
1163 PCI_DEVICE_ID_EICON_DIVA20, dev_diva))) { 1163 PCI_DEVICE_ID_EICON_DIVA20, dev_diva))) {
1164 if (pci_enable_device(dev_diva)) 1164 if (pci_enable_device(dev_diva))
1165 return(0); 1165 return(0);
1166 cs->subtyp = DIVA_PCI; 1166 cs->subtyp = DIVA_PCI;
1167 cs->irq = dev_diva->irq; 1167 cs->irq = dev_diva->irq;
1168 cs->hw.diva.cfg_reg = pci_resource_start(dev_diva, 2); 1168 cs->hw.diva.cfg_reg = pci_resource_start(dev_diva, 2);
1169 } else if ((dev_diva_u = pci_find_device(PCI_VENDOR_ID_EICON, 1169 } else if ((dev_diva_u = hisax_find_pci_device(PCI_VENDOR_ID_EICON,
1170 PCI_DEVICE_ID_EICON_DIVA20_U, dev_diva_u))) { 1170 PCI_DEVICE_ID_EICON_DIVA20_U, dev_diva_u))) {
1171 if (pci_enable_device(dev_diva_u)) 1171 if (pci_enable_device(dev_diva_u))
1172 return(0); 1172 return(0);
1173 cs->subtyp = DIVA_PCI; 1173 cs->subtyp = DIVA_PCI;
1174 cs->irq = dev_diva_u->irq; 1174 cs->irq = dev_diva_u->irq;
1175 cs->hw.diva.cfg_reg = pci_resource_start(dev_diva_u, 2); 1175 cs->hw.diva.cfg_reg = pci_resource_start(dev_diva_u, 2);
1176 } else if ((dev_diva201 = pci_find_device(PCI_VENDOR_ID_EICON, 1176 } else if ((dev_diva201 = hisax_find_pci_device(PCI_VENDOR_ID_EICON,
1177 PCI_DEVICE_ID_EICON_DIVA201, dev_diva201))) { 1177 PCI_DEVICE_ID_EICON_DIVA201, dev_diva201))) {
1178 if (pci_enable_device(dev_diva201)) 1178 if (pci_enable_device(dev_diva201))
1179 return(0); 1179 return(0);
@@ -1183,7 +1183,7 @@ static int __devinit setup_diva_pci(struct IsdnCard *card)
1183 (ulong) ioremap(pci_resource_start(dev_diva201, 0), 4096); 1183 (ulong) ioremap(pci_resource_start(dev_diva201, 0), 4096);
1184 cs->hw.diva.cfg_reg = 1184 cs->hw.diva.cfg_reg =
1185 (ulong) ioremap(pci_resource_start(dev_diva201, 1), 4096); 1185 (ulong) ioremap(pci_resource_start(dev_diva201, 1), 4096);
1186 } else if ((dev_diva202 = pci_find_device(PCI_VENDOR_ID_EICON, 1186 } else if ((dev_diva202 = hisax_find_pci_device(PCI_VENDOR_ID_EICON,
1187 PCI_DEVICE_ID_EICON_DIVA202, dev_diva202))) { 1187 PCI_DEVICE_ID_EICON_DIVA202, dev_diva202))) {
1188 if (pci_enable_device(dev_diva202)) 1188 if (pci_enable_device(dev_diva202))
1189 return(0); 1189 return(0);
@@ -1229,14 +1229,14 @@ static int __devinit setup_diva_pci(struct IsdnCard *card)
1229 return (1); /* card found */ 1229 return (1); /* card found */
1230} 1230}
1231 1231
1232#else /* if !CONFIG_PCI_LEGACY */ 1232#else /* if !CONFIG_PCI */
1233 1233
1234static int __devinit setup_diva_pci(struct IsdnCard *card) 1234static int __devinit setup_diva_pci(struct IsdnCard *card)
1235{ 1235{
1236 return (-1); /* card not found; continue search */ 1236 return (-1); /* card not found; continue search */
1237} 1237}
1238 1238
1239#endif /* CONFIG_PCI_LEGACY */ 1239#endif /* CONFIG_PCI */
1240 1240
1241int __devinit 1241int __devinit
1242setup_diva(struct IsdnCard *card) 1242setup_diva(struct IsdnCard *card)
diff --git a/drivers/isdn/hisax/elsa.c b/drivers/isdn/hisax/elsa.c
index aa29d1cf16af..5d9d338814aa 100644
--- a/drivers/isdn/hisax/elsa.c
+++ b/drivers/isdn/hisax/elsa.c
@@ -19,6 +19,7 @@
19 */ 19 */
20 20
21#include <linux/init.h> 21#include <linux/init.h>
22#include <linux/slab.h>
22#include "hisax.h" 23#include "hisax.h"
23#include "arcofi.h" 24#include "arcofi.h"
24#include "isac.h" 25#include "isac.h"
@@ -1025,7 +1026,7 @@ setup_elsa_pcmcia(struct IsdnCard *card)
1025 cs->irq); 1026 cs->irq);
1026} 1027}
1027 1028
1028#ifdef CONFIG_PCI_LEGACY 1029#ifdef CONFIG_PCI
1029static struct pci_dev *dev_qs1000 __devinitdata = NULL; 1030static struct pci_dev *dev_qs1000 __devinitdata = NULL;
1030static struct pci_dev *dev_qs3000 __devinitdata = NULL; 1031static struct pci_dev *dev_qs3000 __devinitdata = NULL;
1031 1032
@@ -1035,7 +1036,7 @@ setup_elsa_pci(struct IsdnCard *card)
1035 struct IsdnCardState *cs = card->cs; 1036 struct IsdnCardState *cs = card->cs;
1036 1037
1037 cs->subtyp = 0; 1038 cs->subtyp = 0;
1038 if ((dev_qs1000 = pci_find_device(PCI_VENDOR_ID_ELSA, 1039 if ((dev_qs1000 = hisax_find_pci_device(PCI_VENDOR_ID_ELSA,
1039 PCI_DEVICE_ID_ELSA_MICROLINK, dev_qs1000))) { 1040 PCI_DEVICE_ID_ELSA_MICROLINK, dev_qs1000))) {
1040 if (pci_enable_device(dev_qs1000)) 1041 if (pci_enable_device(dev_qs1000))
1041 return(0); 1042 return(0);
@@ -1043,7 +1044,7 @@ setup_elsa_pci(struct IsdnCard *card)
1043 cs->irq = dev_qs1000->irq; 1044 cs->irq = dev_qs1000->irq;
1044 cs->hw.elsa.cfg = pci_resource_start(dev_qs1000, 1); 1045 cs->hw.elsa.cfg = pci_resource_start(dev_qs1000, 1);
1045 cs->hw.elsa.base = pci_resource_start(dev_qs1000, 3); 1046 cs->hw.elsa.base = pci_resource_start(dev_qs1000, 3);
1046 } else if ((dev_qs3000 = pci_find_device(PCI_VENDOR_ID_ELSA, 1047 } else if ((dev_qs3000 = hisax_find_pci_device(PCI_VENDOR_ID_ELSA,
1047 PCI_DEVICE_ID_ELSA_QS3000, dev_qs3000))) { 1048 PCI_DEVICE_ID_ELSA_QS3000, dev_qs3000))) {
1048 if (pci_enable_device(dev_qs3000)) 1049 if (pci_enable_device(dev_qs3000))
1049 return(0); 1050 return(0);
@@ -1093,7 +1094,7 @@ setup_elsa_pci(struct IsdnCard *card)
1093{ 1094{
1094 return (1); 1095 return (1);
1095} 1096}
1096#endif /* CONFIG_PCI_LEGACY */ 1097#endif /* CONFIG_PCI */
1097 1098
1098static int __devinit 1099static int __devinit
1099setup_elsa_common(struct IsdnCard *card) 1100setup_elsa_common(struct IsdnCard *card)
diff --git a/drivers/isdn/hisax/elsa_cs.c b/drivers/isdn/hisax/elsa_cs.c
index f4d0fe29bcf8..c9f2279e21f5 100644
--- a/drivers/isdn/hisax/elsa_cs.c
+++ b/drivers/isdn/hisax/elsa_cs.c
@@ -57,23 +57,6 @@ MODULE_DESCRIPTION("ISDN4Linux: PCMCIA client driver for Elsa PCM cards");
57MODULE_AUTHOR("Klaus Lichtenwalder"); 57MODULE_AUTHOR("Klaus Lichtenwalder");
58MODULE_LICENSE("Dual MPL/GPL"); 58MODULE_LICENSE("Dual MPL/GPL");
59 59
60/*
61 All the PCMCIA modules use PCMCIA_DEBUG to control debugging. If
62 you do not define PCMCIA_DEBUG at all, all the debug code will be
63 left out. If you compile with PCMCIA_DEBUG=0, the debug code will
64 be present but disabled -- but it can then be enabled for specific
65 modules at load time with a 'pc_debug=#' option to insmod.
66*/
67
68#ifdef PCMCIA_DEBUG
69static int pc_debug = PCMCIA_DEBUG;
70module_param(pc_debug, int, 0);
71#define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args);
72static char *version =
73"elsa_cs.c $Revision: 1.2.2.4 $ $Date: 2004/01/25 15:07:06 $ (K.Lichtenwalder)";
74#else
75#define DEBUG(n, args...)
76#endif
77 60
78/*====================================================================*/ 61/*====================================================================*/
79 62
@@ -93,7 +76,7 @@ module_param(protocol, int, 0);
93 handler. 76 handler.
94*/ 77*/
95 78
96static int elsa_cs_config(struct pcmcia_device *link); 79static int elsa_cs_config(struct pcmcia_device *link) __devinit ;
97static void elsa_cs_release(struct pcmcia_device *link); 80static void elsa_cs_release(struct pcmcia_device *link);
98 81
99/* 82/*
@@ -102,7 +85,7 @@ static void elsa_cs_release(struct pcmcia_device *link);
102 needed to manage one actual PCMCIA card. 85 needed to manage one actual PCMCIA card.
103*/ 86*/
104 87
105static void elsa_cs_detach(struct pcmcia_device *p_dev); 88static void elsa_cs_detach(struct pcmcia_device *p_dev) __devexit;
106 89
107/* 90/*
108 A driver needs to provide a dev_node_t structure for each device 91 A driver needs to provide a dev_node_t structure for each device
@@ -138,11 +121,11 @@ typedef struct local_info_t {
138 121
139======================================================================*/ 122======================================================================*/
140 123
141static int elsa_cs_probe(struct pcmcia_device *link) 124static int __devinit elsa_cs_probe(struct pcmcia_device *link)
142{ 125{
143 local_info_t *local; 126 local_info_t *local;
144 127
145 DEBUG(0, "elsa_cs_attach()\n"); 128 dev_dbg(&link->dev, "elsa_cs_attach()\n");
146 129
147 /* Allocate space for private device-specific data */ 130 /* Allocate space for private device-specific data */
148 local = kzalloc(sizeof(local_info_t), GFP_KERNEL); 131 local = kzalloc(sizeof(local_info_t), GFP_KERNEL);
@@ -154,8 +137,7 @@ static int elsa_cs_probe(struct pcmcia_device *link)
154 local->cardnr = -1; 137 local->cardnr = -1;
155 138
156 /* Interrupt setup */ 139 /* Interrupt setup */
157 link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING|IRQ_FIRST_SHARED; 140 link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
158 link->irq.IRQInfo1 = IRQ_LEVEL_ID|IRQ_SHARE_ID;
159 link->irq.Handler = NULL; 141 link->irq.Handler = NULL;
160 142
161 /* 143 /*
@@ -184,11 +166,11 @@ static int elsa_cs_probe(struct pcmcia_device *link)
184 166
185======================================================================*/ 167======================================================================*/
186 168
187static void elsa_cs_detach(struct pcmcia_device *link) 169static void __devexit elsa_cs_detach(struct pcmcia_device *link)
188{ 170{
189 local_info_t *info = link->priv; 171 local_info_t *info = link->priv;
190 172
191 DEBUG(0, "elsa_cs_detach(0x%p)\n", link); 173 dev_dbg(&link->dev, "elsa_cs_detach(0x%p)\n", link);
192 174
193 info->busy = 1; 175 info->busy = 1;
194 elsa_cs_release(link); 176 elsa_cs_release(link);
@@ -228,33 +210,28 @@ static int elsa_cs_configcheck(struct pcmcia_device *p_dev,
228 return -ENODEV; 210 return -ENODEV;
229} 211}
230 212
231static int elsa_cs_config(struct pcmcia_device *link) 213static int __devinit elsa_cs_config(struct pcmcia_device *link)
232{ 214{
233 local_info_t *dev; 215 local_info_t *dev;
234 int i, last_fn; 216 int i;
235 IsdnCard_t icard; 217 IsdnCard_t icard;
236 218
237 DEBUG(0, "elsa_config(0x%p)\n", link); 219 dev_dbg(&link->dev, "elsa_config(0x%p)\n", link);
238 dev = link->priv; 220 dev = link->priv;
239 221
240 i = pcmcia_loop_config(link, elsa_cs_configcheck, NULL); 222 i = pcmcia_loop_config(link, elsa_cs_configcheck, NULL);
241 if (i != 0) { 223 if (i != 0)
242 last_fn = RequestIO; 224 goto failed;
243 goto cs_failed;
244 }
245 225
246 i = pcmcia_request_irq(link, &link->irq); 226 i = pcmcia_request_irq(link, &link->irq);
247 if (i != 0) { 227 if (i != 0) {
248 link->irq.AssignedIRQ = 0; 228 link->irq.AssignedIRQ = 0;
249 last_fn = RequestIRQ; 229 goto failed;
250 goto cs_failed;
251 } 230 }
252 231
253 i = pcmcia_request_configuration(link, &link->conf); 232 i = pcmcia_request_configuration(link, &link->conf);
254 if (i != 0) { 233 if (i != 0)
255 last_fn = RequestConfiguration; 234 goto failed;
256 goto cs_failed;
257 }
258 235
259 /* At this point, the dev_node_t structure(s) should be 236 /* At this point, the dev_node_t structure(s) should be
260 initialized and arranged in a linked list at link->dev. *//* */ 237 initialized and arranged in a linked list at link->dev. *//* */
@@ -290,8 +267,7 @@ static int elsa_cs_config(struct pcmcia_device *link)
290 ((local_info_t*)link->priv)->cardnr = i; 267 ((local_info_t*)link->priv)->cardnr = i;
291 268
292 return 0; 269 return 0;
293cs_failed: 270failed:
294 cs_error(link, last_fn, i);
295 elsa_cs_release(link); 271 elsa_cs_release(link);
296 return -ENODEV; 272 return -ENODEV;
297} /* elsa_cs_config */ 273} /* elsa_cs_config */
@@ -308,7 +284,7 @@ static void elsa_cs_release(struct pcmcia_device *link)
308{ 284{
309 local_info_t *local = link->priv; 285 local_info_t *local = link->priv;
310 286
311 DEBUG(0, "elsa_cs_release(0x%p)\n", link); 287 dev_dbg(&link->dev, "elsa_cs_release(0x%p)\n", link);
312 288
313 if (local) { 289 if (local) {
314 if (local->cardnr >= 0) { 290 if (local->cardnr >= 0) {
@@ -351,7 +327,7 @@ static struct pcmcia_driver elsa_cs_driver = {
351 .name = "elsa_cs", 327 .name = "elsa_cs",
352 }, 328 },
353 .probe = elsa_cs_probe, 329 .probe = elsa_cs_probe,
354 .remove = elsa_cs_detach, 330 .remove = __devexit_p(elsa_cs_detach),
355 .id_table = elsa_ids, 331 .id_table = elsa_ids,
356 .suspend = elsa_suspend, 332 .suspend = elsa_suspend,
357 .resume = elsa_resume, 333 .resume = elsa_resume,
diff --git a/drivers/isdn/hisax/elsa_ser.c b/drivers/isdn/hisax/elsa_ser.c
index 1657bba7879e..cbda3790a10d 100644
--- a/drivers/isdn/hisax/elsa_ser.c
+++ b/drivers/isdn/hisax/elsa_ser.c
@@ -9,6 +9,7 @@
9 9
10#include <linux/serial.h> 10#include <linux/serial.h>
11#include <linux/serial_reg.h> 11#include <linux/serial_reg.h>
12#include <linux/slab.h>
12 13
13#define MAX_MODEM_BUF 256 14#define MAX_MODEM_BUF 256
14#define WAKEUP_CHARS (MAX_MODEM_BUF/2) 15#define WAKEUP_CHARS (MAX_MODEM_BUF/2)
diff --git a/drivers/isdn/hisax/enternow_pci.c b/drivers/isdn/hisax/enternow_pci.c
index 39f421ed8de8..26264abf1f58 100644
--- a/drivers/isdn/hisax/enternow_pci.c
+++ b/drivers/isdn/hisax/enternow_pci.c
@@ -406,7 +406,7 @@ setup_enternow_pci(struct IsdnCard *card)
406 406
407 for ( ;; ) 407 for ( ;; )
408 { 408 {
409 if ((dev_netjet = pci_find_device(PCI_VENDOR_ID_TIGERJET, 409 if ((dev_netjet = hisax_find_pci_device(PCI_VENDOR_ID_TIGERJET,
410 PCI_DEVICE_ID_TIGERJET_300, dev_netjet))) { 410 PCI_DEVICE_ID_TIGERJET_300, dev_netjet))) {
411 ret = en_pci_probe(dev_netjet, cs); 411 ret = en_pci_probe(dev_netjet, cs);
412 if (!ret) 412 if (!ret)
diff --git a/drivers/isdn/hisax/fsm.c b/drivers/isdn/hisax/fsm.c
index 34fade96a581..732ea633758c 100644
--- a/drivers/isdn/hisax/fsm.c
+++ b/drivers/isdn/hisax/fsm.c
@@ -15,6 +15,7 @@
15 */ 15 */
16 16
17#include <linux/module.h> 17#include <linux/module.h>
18#include <linux/slab.h>
18#include <linux/init.h> 19#include <linux/init.h>
19#include "hisax.h" 20#include "hisax.h"
20 21
diff --git a/drivers/isdn/hisax/gazel.c b/drivers/isdn/hisax/gazel.c
index 0ea3b4607680..353982fc1436 100644
--- a/drivers/isdn/hisax/gazel.c
+++ b/drivers/isdn/hisax/gazel.c
@@ -531,7 +531,7 @@ setup_gazelisa(struct IsdnCard *card, struct IsdnCardState *cs)
531 return (0); 531 return (0);
532} 532}
533 533
534#ifdef CONFIG_PCI_LEGACY 534#ifdef CONFIG_PCI
535static struct pci_dev *dev_tel __devinitdata = NULL; 535static struct pci_dev *dev_tel __devinitdata = NULL;
536 536
537static int __devinit 537static int __devinit
@@ -546,7 +546,7 @@ setup_gazelpci(struct IsdnCardState *cs)
546 found = 0; 546 found = 0;
547 seekcard = PCI_DEVICE_ID_PLX_R685; 547 seekcard = PCI_DEVICE_ID_PLX_R685;
548 for (nbseek = 0; nbseek < 4; nbseek++) { 548 for (nbseek = 0; nbseek < 4; nbseek++) {
549 if ((dev_tel = pci_find_device(PCI_VENDOR_ID_PLX, 549 if ((dev_tel = hisax_find_pci_device(PCI_VENDOR_ID_PLX,
550 seekcard, dev_tel))) { 550 seekcard, dev_tel))) {
551 if (pci_enable_device(dev_tel)) 551 if (pci_enable_device(dev_tel))
552 return 1; 552 return 1;
@@ -620,7 +620,7 @@ setup_gazelpci(struct IsdnCardState *cs)
620 620
621 return (0); 621 return (0);
622} 622}
623#endif /* CONFIG_PCI_LEGACY */ 623#endif /* CONFIG_PCI */
624 624
625int __devinit 625int __devinit
626setup_gazel(struct IsdnCard *card) 626setup_gazel(struct IsdnCard *card)
@@ -640,7 +640,7 @@ setup_gazel(struct IsdnCard *card)
640 return (0); 640 return (0);
641 } else { 641 } else {
642 642
643#ifdef CONFIG_PCI_LEGACY 643#ifdef CONFIG_PCI
644 if (setup_gazelpci(cs)) 644 if (setup_gazelpci(cs))
645 return (0); 645 return (0);
646#else 646#else
diff --git a/drivers/isdn/hisax/hfc4s8s_l1.c b/drivers/isdn/hisax/hfc4s8s_l1.c
index ab98e135bcbb..051b44e2556c 100644
--- a/drivers/isdn/hisax/hfc4s8s_l1.c
+++ b/drivers/isdn/hisax/hfc4s8s_l1.c
@@ -25,6 +25,7 @@
25#include <linux/pci.h> 25#include <linux/pci.h>
26#include <linux/interrupt.h> 26#include <linux/interrupt.h>
27#include <linux/delay.h> 27#include <linux/delay.h>
28#include <linux/slab.h>
28#include <linux/timer.h> 29#include <linux/timer.h>
29#include <linux/skbuff.h> 30#include <linux/skbuff.h>
30#include <linux/wait.h> 31#include <linux/wait.h>
diff --git a/drivers/isdn/hisax/hfc_2bds0.c b/drivers/isdn/hisax/hfc_2bds0.c
index 8d22f50760eb..7250f56a5246 100644
--- a/drivers/isdn/hisax/hfc_2bds0.c
+++ b/drivers/isdn/hisax/hfc_2bds0.c
@@ -12,6 +12,7 @@
12 12
13#include <linux/init.h> 13#include <linux/init.h>
14#include <linux/sched.h> 14#include <linux/sched.h>
15#include <linux/slab.h>
15#include "hisax.h" 16#include "hisax.h"
16#include "hfc_2bds0.h" 17#include "hfc_2bds0.h"
17#include "isdnl1.h" 18#include "isdnl1.h"
diff --git a/drivers/isdn/hisax/hfc_2bs0.c b/drivers/isdn/hisax/hfc_2bs0.c
index d0520ad30677..b1f6481e1193 100644
--- a/drivers/isdn/hisax/hfc_2bs0.c
+++ b/drivers/isdn/hisax/hfc_2bs0.c
@@ -16,6 +16,7 @@
16#include "isac.h" 16#include "isac.h"
17#include "isdnl1.h" 17#include "isdnl1.h"
18#include <linux/interrupt.h> 18#include <linux/interrupt.h>
19#include <linux/slab.h>
19 20
20static inline int 21static inline int
21WaitForBusy(struct IsdnCardState *cs) 22WaitForBusy(struct IsdnCardState *cs)
diff --git a/drivers/isdn/hisax/hfc_pci.c b/drivers/isdn/hisax/hfc_pci.c
index 10914731b304..917cc84065bd 100644
--- a/drivers/isdn/hisax/hfc_pci.c
+++ b/drivers/isdn/hisax/hfc_pci.c
@@ -1658,7 +1658,7 @@ setup_hfcpci(struct IsdnCard *card)
1658 1658
1659 i = 0; 1659 i = 0;
1660 while (id_list[i].vendor_id) { 1660 while (id_list[i].vendor_id) {
1661 tmp_hfcpci = pci_find_device(id_list[i].vendor_id, 1661 tmp_hfcpci = hisax_find_pci_device(id_list[i].vendor_id,
1662 id_list[i].device_id, 1662 id_list[i].device_id,
1663 dev_hfcpci); 1663 dev_hfcpci);
1664 i++; 1664 i++;
diff --git a/drivers/isdn/hisax/hfc_sx.c b/drivers/isdn/hisax/hfc_sx.c
index 419f87cad8cb..be5faf4aa868 100644
--- a/drivers/isdn/hisax/hfc_sx.c
+++ b/drivers/isdn/hisax/hfc_sx.c
@@ -17,6 +17,7 @@
17#include "isdnl1.h" 17#include "isdnl1.h"
18#include <linux/interrupt.h> 18#include <linux/interrupt.h>
19#include <linux/isapnp.h> 19#include <linux/isapnp.h>
20#include <linux/slab.h>
20 21
21static const char *hfcsx_revision = "$Revision: 1.12.2.5 $"; 22static const char *hfcsx_revision = "$Revision: 1.12.2.5 $";
22 23
diff --git a/drivers/isdn/hisax/hfc_usb.c b/drivers/isdn/hisax/hfc_usb.c
index a420b64472e3..ed9527aa5f2c 100644
--- a/drivers/isdn/hisax/hfc_usb.c
+++ b/drivers/isdn/hisax/hfc_usb.c
@@ -39,6 +39,7 @@
39#include <linux/kernel.h> 39#include <linux/kernel.h>
40#include <linux/sched.h> 40#include <linux/sched.h>
41#include <linux/moduleparam.h> 41#include <linux/moduleparam.h>
42#include <linux/slab.h>
42#include "hisax.h" 43#include "hisax.h"
43#include "hisax_if.h" 44#include "hisax_if.h"
44#include "hfc_usb.h" 45#include "hfc_usb.h"
@@ -1086,7 +1087,7 @@ hfc_usb_l2l1(struct hisax_if *my_hisax_if, int pr, void *arg)
1086 break; 1087 break;
1087 default: 1088 default:
1088 DBG(HFCUSB_DBG_STATES, 1089 DBG(HFCUSB_DBG_STATES,
1089 "HFC_USB: hfc_usb_d_l2l1: unkown state : %#x", pr); 1090 "HFC_USB: hfc_usb_d_l2l1: unknown state : %#x", pr);
1090 break; 1091 break;
1091 } 1092 }
1092} 1093}
diff --git a/drivers/isdn/hisax/hisax.h b/drivers/isdn/hisax/hisax.h
index 0685c1946969..832a87855ffb 100644
--- a/drivers/isdn/hisax/hisax.h
+++ b/drivers/isdn/hisax/hisax.h
@@ -1323,3 +1323,26 @@ void release_tei(struct IsdnCardState *cs);
1323char *HiSax_getrev(const char *revision); 1323char *HiSax_getrev(const char *revision);
1324int TeiNew(void); 1324int TeiNew(void);
1325void TeiFree(void); 1325void TeiFree(void);
1326
1327#ifdef CONFIG_PCI
1328
1329#include <linux/pci.h>
1330
1331/* adaptation wrapper for old usage
1332 * WARNING! This is unfit for use in a PCI hotplug environment,
1333 * as the returned PCI device can disappear at any moment in time.
1334 * Callers should be converted to use pci_get_device() instead.
1335 */
1336static inline struct pci_dev *hisax_find_pci_device(unsigned int vendor,
1337 unsigned int device,
1338 struct pci_dev *from)
1339{
1340 struct pci_dev *pdev;
1341
1342 pci_dev_get(from);
1343 pdev = pci_get_subsys(vendor, device, PCI_ANY_ID, PCI_ANY_ID, from);
1344 pci_dev_put(pdev);
1345 return pdev;
1346}
1347
1348#endif
diff --git a/drivers/isdn/hisax/hisax_isac.c b/drivers/isdn/hisax/hisax_isac.c
index d0fefcf999cb..a8447fa2f470 100644
--- a/drivers/isdn/hisax/hisax_isac.c
+++ b/drivers/isdn/hisax/hisax_isac.c
@@ -21,6 +21,7 @@
21 */ 21 */
22 22
23#include <linux/module.h> 23#include <linux/module.h>
24#include <linux/gfp.h>
24#include <linux/init.h> 25#include <linux/init.h>
25#include <linux/netdevice.h> 26#include <linux/netdevice.h>
26#include "hisax_isac.h" 27#include "hisax_isac.h"
diff --git a/drivers/isdn/hisax/hscx.c b/drivers/isdn/hisax/hscx.c
index c8f9951f7914..904b9100df95 100644
--- a/drivers/isdn/hisax/hscx.c
+++ b/drivers/isdn/hisax/hscx.c
@@ -16,6 +16,7 @@
16#include "isac.h" 16#include "isac.h"
17#include "isdnl1.h" 17#include "isdnl1.h"
18#include <linux/interrupt.h> 18#include <linux/interrupt.h>
19#include <linux/slab.h>
19 20
20static char *HSCXVer[] = 21static char *HSCXVer[] =
21{"A1", "?1", "A2", "?3", "A3", "V2.1", "?6", "?7", 22{"A1", "?1", "A2", "?3", "A3", "V2.1", "?6", "?7",
diff --git a/drivers/isdn/hisax/icc.c b/drivers/isdn/hisax/icc.c
index c80cbb8a2ef9..63057268cc3d 100644
--- a/drivers/isdn/hisax/icc.c
+++ b/drivers/isdn/hisax/icc.c
@@ -20,6 +20,7 @@
20// #include "arcofi.h" 20// #include "arcofi.h"
21#include "isdnl1.h" 21#include "isdnl1.h"
22#include <linux/interrupt.h> 22#include <linux/interrupt.h>
23#include <linux/slab.h>
23 24
24#define DBUSY_TIMER_VALUE 80 25#define DBUSY_TIMER_VALUE 80
25#define ARCOFI_USE 0 26#define ARCOFI_USE 0
diff --git a/drivers/isdn/hisax/ipacx.c b/drivers/isdn/hisax/ipacx.c
index 00afd5538909..751b25f2ff58 100644
--- a/drivers/isdn/hisax/ipacx.c
+++ b/drivers/isdn/hisax/ipacx.c
@@ -10,6 +10,7 @@
10 * 10 *
11 */ 11 */
12#include <linux/kernel.h> 12#include <linux/kernel.h>
13#include <linux/slab.h>
13#include <linux/init.h> 14#include <linux/init.h>
14#include "hisax_if.h" 15#include "hisax_if.h"
15#include "hisax.h" 16#include "hisax.h"
diff --git a/drivers/isdn/hisax/isac.c b/drivers/isdn/hisax/isac.c
index a19354d94343..2b66728136d5 100644
--- a/drivers/isdn/hisax/isac.c
+++ b/drivers/isdn/hisax/isac.c
@@ -18,6 +18,7 @@
18#include "arcofi.h" 18#include "arcofi.h"
19#include "isdnl1.h" 19#include "isdnl1.h"
20#include <linux/interrupt.h> 20#include <linux/interrupt.h>
21#include <linux/slab.h>
21#include <linux/init.h> 22#include <linux/init.h>
22 23
23#define DBUSY_TIMER_VALUE 80 24#define DBUSY_TIMER_VALUE 80
diff --git a/drivers/isdn/hisax/isar.c b/drivers/isdn/hisax/isar.c
index bfeb9b6aa043..40b914bded8c 100644
--- a/drivers/isdn/hisax/isar.c
+++ b/drivers/isdn/hisax/isar.c
@@ -13,6 +13,7 @@
13#include "isar.h" 13#include "isar.h"
14#include "isdnl1.h" 14#include "isdnl1.h"
15#include <linux/interrupt.h> 15#include <linux/interrupt.h>
16#include <linux/slab.h>
16 17
17#define DBG_LOADFIRM 0 18#define DBG_LOADFIRM 0
18#define DUMP_MBOXFRAME 2 19#define DUMP_MBOXFRAME 2
@@ -138,7 +139,7 @@ waitrecmsg(struct IsdnCardState *cs, u_char *len,
138 while((!(cs->BC_Read_Reg(cs, 0, ISAR_IRQBIT) & ISAR_IRQSTA)) && 139 while((!(cs->BC_Read_Reg(cs, 0, ISAR_IRQBIT) & ISAR_IRQSTA)) &&
139 (timeout++ < maxdelay)) 140 (timeout++ < maxdelay))
140 udelay(1); 141 udelay(1);
141 if (timeout >= maxdelay) { 142 if (timeout > maxdelay) {
142 printk(KERN_WARNING"isar recmsg IRQSTA timeout\n"); 143 printk(KERN_WARNING"isar recmsg IRQSTA timeout\n");
143 return(0); 144 return(0);
144 } 145 }
diff --git a/drivers/isdn/hisax/isdnl1.c b/drivers/isdn/hisax/isdnl1.c
index 9ce6abe05b1a..d5eeacf565d6 100644
--- a/drivers/isdn/hisax/isdnl1.c
+++ b/drivers/isdn/hisax/isdnl1.c
@@ -19,6 +19,7 @@
19 */ 19 */
20 20
21#include <linux/init.h> 21#include <linux/init.h>
22#include <linux/gfp.h>
22#include "hisax.h" 23#include "hisax.h"
23#include "isdnl1.h" 24#include "isdnl1.h"
24 25
diff --git a/drivers/isdn/hisax/isdnl2.c b/drivers/isdn/hisax/isdnl2.c
index 7b9496a63b5f..0858791978d8 100644
--- a/drivers/isdn/hisax/isdnl2.c
+++ b/drivers/isdn/hisax/isdnl2.c
@@ -16,6 +16,7 @@
16 */ 16 */
17 17
18#include <linux/init.h> 18#include <linux/init.h>
19#include <linux/gfp.h>
19#include "hisax.h" 20#include "hisax.h"
20#include "isdnl2.h" 21#include "isdnl2.h"
21 22
diff --git a/drivers/isdn/hisax/isdnl3.c b/drivers/isdn/hisax/isdnl3.c
index 06766022d3ae..fd0b643ab740 100644
--- a/drivers/isdn/hisax/isdnl3.c
+++ b/drivers/isdn/hisax/isdnl3.c
@@ -16,6 +16,7 @@
16 */ 16 */
17 17
18#include <linux/init.h> 18#include <linux/init.h>
19#include <linux/slab.h>
19#include "hisax.h" 20#include "hisax.h"
20#include "isdnl3.h" 21#include "isdnl3.h"
21 22
diff --git a/drivers/isdn/hisax/jade.c b/drivers/isdn/hisax/jade.c
index 70840a710acf..ea8f840871d0 100644
--- a/drivers/isdn/hisax/jade.c
+++ b/drivers/isdn/hisax/jade.c
@@ -17,6 +17,7 @@
17#include "jade.h" 17#include "jade.h"
18#include "isdnl1.h" 18#include "isdnl1.h"
19#include <linux/interrupt.h> 19#include <linux/interrupt.h>
20#include <linux/slab.h>
20 21
21 22
22int 23int
diff --git a/drivers/isdn/hisax/l3dss1.c b/drivers/isdn/hisax/l3dss1.c
index a12fa4d34903..cc6ee2d39880 100644
--- a/drivers/isdn/hisax/l3dss1.c
+++ b/drivers/isdn/hisax/l3dss1.c
@@ -23,6 +23,7 @@
23#include "isdnl3.h" 23#include "isdnl3.h"
24#include "l3dss1.h" 24#include "l3dss1.h"
25#include <linux/ctype.h> 25#include <linux/ctype.h>
26#include <linux/slab.h>
26 27
27extern char *HiSax_getrev(const char *revision); 28extern char *HiSax_getrev(const char *revision);
28static const char *dss1_revision = "$Revision: 2.32.2.3 $"; 29static const char *dss1_revision = "$Revision: 2.32.2.3 $";
diff --git a/drivers/isdn/hisax/l3ni1.c b/drivers/isdn/hisax/l3ni1.c
index 4622d43c7e10..f9584491fe8e 100644
--- a/drivers/isdn/hisax/l3ni1.c
+++ b/drivers/isdn/hisax/l3ni1.c
@@ -22,6 +22,7 @@
22#include "isdnl3.h" 22#include "isdnl3.h"
23#include "l3ni1.h" 23#include "l3ni1.h"
24#include <linux/ctype.h> 24#include <linux/ctype.h>
25#include <linux/slab.h>
25 26
26extern char *HiSax_getrev(const char *revision); 27extern char *HiSax_getrev(const char *revision);
27static const char *ni1_revision = "$Revision: 2.8.2.3 $"; 28static const char *ni1_revision = "$Revision: 2.8.2.3 $";
diff --git a/drivers/isdn/hisax/netjet.c b/drivers/isdn/hisax/netjet.c
index 02c6fbaeccf8..5d7f0f2ff9b9 100644
--- a/drivers/isdn/hisax/netjet.c
+++ b/drivers/isdn/hisax/netjet.c
@@ -21,6 +21,7 @@
21#include "isdnl1.h" 21#include "isdnl1.h"
22#include <linux/interrupt.h> 22#include <linux/interrupt.h>
23#include <linux/ppp_defs.h> 23#include <linux/ppp_defs.h>
24#include <linux/slab.h>
24#include <asm/io.h> 25#include <asm/io.h>
25#include "netjet.h" 26#include "netjet.h"
26 27
diff --git a/drivers/isdn/hisax/niccy.c b/drivers/isdn/hisax/niccy.c
index ef00633e1d2a..ccaa6e13310f 100644
--- a/drivers/isdn/hisax/niccy.c
+++ b/drivers/isdn/hisax/niccy.c
@@ -297,12 +297,12 @@ int __devinit setup_niccy(struct IsdnCard *card)
297 return 0; 297 return 0;
298 } 298 }
299 } else { 299 } else {
300#ifdef CONFIG_PCI_LEGACY 300#ifdef CONFIG_PCI
301 static struct pci_dev *niccy_dev __devinitdata; 301 static struct pci_dev *niccy_dev __devinitdata;
302 302
303 u_int pci_ioaddr; 303 u_int pci_ioaddr;
304 cs->subtyp = 0; 304 cs->subtyp = 0;
305 if ((niccy_dev = pci_find_device(PCI_VENDOR_ID_SATSAGEM, 305 if ((niccy_dev = hisax_find_pci_device(PCI_VENDOR_ID_SATSAGEM,
306 PCI_DEVICE_ID_SATSAGEM_NICCY, 306 PCI_DEVICE_ID_SATSAGEM_NICCY,
307 niccy_dev))) { 307 niccy_dev))) {
308 if (pci_enable_device(niccy_dev)) 308 if (pci_enable_device(niccy_dev))
@@ -354,7 +354,7 @@ int __devinit setup_niccy(struct IsdnCard *card)
354 printk(KERN_WARNING "Niccy: io0 0 and NO_PCI_BIOS\n"); 354 printk(KERN_WARNING "Niccy: io0 0 and NO_PCI_BIOS\n");
355 printk(KERN_WARNING "Niccy: unable to config NICCY PCI\n"); 355 printk(KERN_WARNING "Niccy: unable to config NICCY PCI\n");
356 return 0; 356 return 0;
357#endif /* CONFIG_PCI_LEGACY */ 357#endif /* CONFIG_PCI */
358 } 358 }
359 printk(KERN_INFO "HiSax: NICCY %s config irq:%d data:0x%X ale:0x%X\n", 359 printk(KERN_INFO "HiSax: NICCY %s config irq:%d data:0x%X ale:0x%X\n",
360 (cs->subtyp == 1) ? "PnP" : "PCI", 360 (cs->subtyp == 1) ? "PnP" : "PCI",
diff --git a/drivers/isdn/hisax/nj_s.c b/drivers/isdn/hisax/nj_s.c
index 8d36ccc87d81..2344e7b33448 100644
--- a/drivers/isdn/hisax/nj_s.c
+++ b/drivers/isdn/hisax/nj_s.c
@@ -276,7 +276,7 @@ setup_netjet_s(struct IsdnCard *card)
276 276
277 for ( ;; ) 277 for ( ;; )
278 { 278 {
279 if ((dev_netjet = pci_find_device(PCI_VENDOR_ID_TIGERJET, 279 if ((dev_netjet = hisax_find_pci_device(PCI_VENDOR_ID_TIGERJET,
280 PCI_DEVICE_ID_TIGERJET_300, dev_netjet))) { 280 PCI_DEVICE_ID_TIGERJET_300, dev_netjet))) {
281 ret = njs_pci_probe(dev_netjet, cs); 281 ret = njs_pci_probe(dev_netjet, cs);
282 if (!ret) 282 if (!ret)
diff --git a/drivers/isdn/hisax/nj_u.c b/drivers/isdn/hisax/nj_u.c
index d306c946ffba..095e974aed80 100644
--- a/drivers/isdn/hisax/nj_u.c
+++ b/drivers/isdn/hisax/nj_u.c
@@ -240,7 +240,7 @@ setup_netjet_u(struct IsdnCard *card)
240 240
241 for ( ;; ) 241 for ( ;; )
242 { 242 {
243 if ((dev_netjet = pci_find_device(PCI_VENDOR_ID_TIGERJET, 243 if ((dev_netjet = hisax_find_pci_device(PCI_VENDOR_ID_TIGERJET,
244 PCI_DEVICE_ID_TIGERJET_300, dev_netjet))) { 244 PCI_DEVICE_ID_TIGERJET_300, dev_netjet))) {
245 ret = nju_pci_probe(dev_netjet, cs); 245 ret = nju_pci_probe(dev_netjet, cs);
246 if (!ret) 246 if (!ret)
diff --git a/drivers/isdn/hisax/sedlbauer.c b/drivers/isdn/hisax/sedlbauer.c
index 5569a522e2a1..69dfc8d29017 100644
--- a/drivers/isdn/hisax/sedlbauer.c
+++ b/drivers/isdn/hisax/sedlbauer.c
@@ -598,7 +598,7 @@ setup_sedlbauer_isapnp(struct IsdnCard *card, int *bytecnt)
598} 598}
599#endif /* __ISAPNP__ */ 599#endif /* __ISAPNP__ */
600 600
601#ifdef CONFIG_PCI_LEGACY 601#ifdef CONFIG_PCI
602static struct pci_dev *dev_sedl __devinitdata = NULL; 602static struct pci_dev *dev_sedl __devinitdata = NULL;
603 603
604static int __devinit 604static int __devinit
@@ -607,7 +607,7 @@ setup_sedlbauer_pci(struct IsdnCard *card)
607 struct IsdnCardState *cs = card->cs; 607 struct IsdnCardState *cs = card->cs;
608 u16 sub_vendor_id, sub_id; 608 u16 sub_vendor_id, sub_id;
609 609
610 if ((dev_sedl = pci_find_device(PCI_VENDOR_ID_TIGERJET, 610 if ((dev_sedl = hisax_find_pci_device(PCI_VENDOR_ID_TIGERJET,
611 PCI_DEVICE_ID_TIGERJET_100, dev_sedl))) { 611 PCI_DEVICE_ID_TIGERJET_100, dev_sedl))) {
612 if (pci_enable_device(dev_sedl)) 612 if (pci_enable_device(dev_sedl))
613 return(0); 613 return(0);
@@ -673,7 +673,7 @@ setup_sedlbauer_pci(struct IsdnCard *card)
673 return (1); 673 return (1);
674} 674}
675 675
676#endif /* CONFIG_PCI_LEGACY */ 676#endif /* CONFIG_PCI */
677 677
678int __devinit 678int __devinit
679setup_sedlbauer(struct IsdnCard *card) 679setup_sedlbauer(struct IsdnCard *card)
diff --git a/drivers/isdn/hisax/sedlbauer_cs.c b/drivers/isdn/hisax/sedlbauer_cs.c
index 9a3c9f5e4fe8..71b3ddef03bb 100644
--- a/drivers/isdn/hisax/sedlbauer_cs.c
+++ b/drivers/isdn/hisax/sedlbauer_cs.c
@@ -57,24 +57,6 @@ MODULE_DESCRIPTION("ISDN4Linux: PCMCIA client driver for Sedlbauer cards");
57MODULE_AUTHOR("Marcus Niemann"); 57MODULE_AUTHOR("Marcus Niemann");
58MODULE_LICENSE("Dual MPL/GPL"); 58MODULE_LICENSE("Dual MPL/GPL");
59 59
60/*
61 All the PCMCIA modules use PCMCIA_DEBUG to control debugging. If
62 you do not define PCMCIA_DEBUG at all, all the debug code will be
63 left out. If you compile with PCMCIA_DEBUG=0, the debug code will
64 be present but disabled -- but it can then be enabled for specific
65 modules at load time with a 'pc_debug=#' option to insmod.
66*/
67
68#ifdef PCMCIA_DEBUG
69static int pc_debug = PCMCIA_DEBUG;
70module_param(pc_debug, int, 0);
71#define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args);
72static char *version =
73"sedlbauer_cs.c 1.1a 2001/01/28 15:04:04 (M.Niemann)";
74#else
75#define DEBUG(n, args...)
76#endif
77
78 60
79/*====================================================================*/ 61/*====================================================================*/
80 62
@@ -94,7 +76,7 @@ module_param(protocol, int, 0);
94 event handler. 76 event handler.
95*/ 77*/
96 78
97static int sedlbauer_config(struct pcmcia_device *link); 79static int sedlbauer_config(struct pcmcia_device *link) __devinit ;
98static void sedlbauer_release(struct pcmcia_device *link); 80static void sedlbauer_release(struct pcmcia_device *link);
99 81
100/* 82/*
@@ -103,7 +85,7 @@ static void sedlbauer_release(struct pcmcia_device *link);
103 needed to manage one actual PCMCIA card. 85 needed to manage one actual PCMCIA card.
104*/ 86*/
105 87
106static void sedlbauer_detach(struct pcmcia_device *p_dev); 88static void sedlbauer_detach(struct pcmcia_device *p_dev) __devexit;
107 89
108/* 90/*
109 You'll also need to prototype all the functions that will actually 91 You'll also need to prototype all the functions that will actually
@@ -147,11 +129,11 @@ typedef struct local_info_t {
147 129
148======================================================================*/ 130======================================================================*/
149 131
150static int sedlbauer_probe(struct pcmcia_device *link) 132static int __devinit sedlbauer_probe(struct pcmcia_device *link)
151{ 133{
152 local_info_t *local; 134 local_info_t *local;
153 135
154 DEBUG(0, "sedlbauer_attach()\n"); 136 dev_dbg(&link->dev, "sedlbauer_attach()\n");
155 137
156 /* Allocate space for private device-specific data */ 138 /* Allocate space for private device-specific data */
157 local = kzalloc(sizeof(local_info_t), GFP_KERNEL); 139 local = kzalloc(sizeof(local_info_t), GFP_KERNEL);
@@ -162,8 +144,7 @@ static int sedlbauer_probe(struct pcmcia_device *link)
162 link->priv = local; 144 link->priv = local;
163 145
164 /* Interrupt setup */ 146 /* Interrupt setup */
165 link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING|IRQ_FIRST_SHARED; 147 link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
166 link->irq.IRQInfo1 = IRQ_LEVEL_ID;
167 link->irq.Handler = NULL; 148 link->irq.Handler = NULL;
168 149
169 /* 150 /*
@@ -196,9 +177,9 @@ static int sedlbauer_probe(struct pcmcia_device *link)
196 177
197======================================================================*/ 178======================================================================*/
198 179
199static void sedlbauer_detach(struct pcmcia_device *link) 180static void __devexit sedlbauer_detach(struct pcmcia_device *link)
200{ 181{
201 DEBUG(0, "sedlbauer_detach(0x%p)\n", link); 182 dev_dbg(&link->dev, "sedlbauer_detach(0x%p)\n", link);
202 183
203 ((local_info_t *)link->priv)->stop = 1; 184 ((local_info_t *)link->priv)->stop = 1;
204 sedlbauer_release(link); 185 sedlbauer_release(link);
@@ -214,9 +195,6 @@ static void sedlbauer_detach(struct pcmcia_device *link)
214 device available to the system. 195 device available to the system.
215 196
216======================================================================*/ 197======================================================================*/
217#define CS_CHECK(fn, ret) \
218do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
219
220static int sedlbauer_config_check(struct pcmcia_device *p_dev, 198static int sedlbauer_config_check(struct pcmcia_device *p_dev,
221 cistpl_cftable_entry_t *cfg, 199 cistpl_cftable_entry_t *cfg,
222 cistpl_cftable_entry_t *dflt, 200 cistpl_cftable_entry_t *dflt,
@@ -293,11 +271,11 @@ static int sedlbauer_config_check(struct pcmcia_device *p_dev,
293 req->Base = mem->win[0].host_addr; 271 req->Base = mem->win[0].host_addr;
294 req->Size = mem->win[0].len; 272 req->Size = mem->win[0].len;
295 req->AccessSpeed = 0; 273 req->AccessSpeed = 0;
296 if (pcmcia_request_window(&p_dev, req, &p_dev->win) != 0) 274 if (pcmcia_request_window(p_dev, req, &p_dev->win) != 0)
297 return -ENODEV; 275 return -ENODEV;
298 map.Page = 0; 276 map.Page = 0;
299 map.CardOffset = mem->win[0].card_addr; 277 map.CardOffset = mem->win[0].card_addr;
300 if (pcmcia_map_mem_page(p_dev->win, &map) != 0) 278 if (pcmcia_map_mem_page(p_dev, p_dev->win, &map) != 0)
301 return -ENODEV; 279 return -ENODEV;
302 } 280 }
303 return 0; 281 return 0;
@@ -305,14 +283,14 @@ static int sedlbauer_config_check(struct pcmcia_device *p_dev,
305 283
306 284
307 285
308static int sedlbauer_config(struct pcmcia_device *link) 286static int __devinit sedlbauer_config(struct pcmcia_device *link)
309{ 287{
310 local_info_t *dev = link->priv; 288 local_info_t *dev = link->priv;
311 win_req_t *req; 289 win_req_t *req;
312 int last_fn, last_ret; 290 int ret;
313 IsdnCard_t icard; 291 IsdnCard_t icard;
314 292
315 DEBUG(0, "sedlbauer_config(0x%p)\n", link); 293 dev_dbg(&link->dev, "sedlbauer_config(0x%p)\n", link);
316 294
317 req = kzalloc(sizeof(win_req_t), GFP_KERNEL); 295 req = kzalloc(sizeof(win_req_t), GFP_KERNEL);
318 if (!req) 296 if (!req)
@@ -330,8 +308,8 @@ static int sedlbauer_config(struct pcmcia_device *link)
330 these things without consulting the CIS, and most client drivers 308 these things without consulting the CIS, and most client drivers
331 will only use the CIS to fill in implementation-defined details. 309 will only use the CIS to fill in implementation-defined details.
332 */ 310 */
333 last_ret = pcmcia_loop_config(link, sedlbauer_config_check, req); 311 ret = pcmcia_loop_config(link, sedlbauer_config_check, req);
334 if (last_ret) 312 if (ret)
335 goto failed; 313 goto failed;
336 314
337 /* 315 /*
@@ -339,15 +317,20 @@ static int sedlbauer_config(struct pcmcia_device *link)
339 handler to the interrupt, unless the 'Handler' member of the 317 handler to the interrupt, unless the 'Handler' member of the
340 irq structure is initialized. 318 irq structure is initialized.
341 */ 319 */
342 if (link->conf.Attributes & CONF_ENABLE_IRQ) 320 if (link->conf.Attributes & CONF_ENABLE_IRQ) {
343 CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq)); 321 ret = pcmcia_request_irq(link, &link->irq);
322 if (ret)
323 goto failed;
324 }
344 325
345 /* 326 /*
346 This actually configures the PCMCIA socket -- setting up 327 This actually configures the PCMCIA socket -- setting up
347 the I/O windows and the interrupt mapping, and putting the 328 the I/O windows and the interrupt mapping, and putting the
348 card and host interface into "Memory and IO" mode. 329 card and host interface into "Memory and IO" mode.
349 */ 330 */
350 CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link, &link->conf)); 331 ret = pcmcia_request_configuration(link, &link->conf);
332 if (ret)
333 goto failed;
351 334
352 /* 335 /*
353 At this point, the dev_node_t structure(s) need to be 336 At this point, the dev_node_t structure(s) need to be
@@ -380,19 +363,18 @@ static int sedlbauer_config(struct pcmcia_device *link)
380 icard.protocol = protocol; 363 icard.protocol = protocol;
381 icard.typ = ISDN_CTYPE_SEDLBAUER_PCMCIA; 364 icard.typ = ISDN_CTYPE_SEDLBAUER_PCMCIA;
382 365
383 last_ret = hisax_init_pcmcia(link, &(((local_info_t*)link->priv)->stop), &icard); 366 ret = hisax_init_pcmcia(link,
384 if (last_ret < 0) { 367 &(((local_info_t *)link->priv)->stop), &icard);
385 printk(KERN_ERR "sedlbauer_cs: failed to initialize SEDLBAUER PCMCIA %d at i/o %#x\n", 368 if (ret < 0) {
386 last_ret, link->io.BasePort1); 369 printk(KERN_ERR "sedlbauer_cs: failed to initialize SEDLBAUER PCMCIA %d at i/o %#x\n",
370 ret, link->io.BasePort1);
387 sedlbauer_release(link); 371 sedlbauer_release(link);
388 return -ENODEV; 372 return -ENODEV;
389 } else 373 } else
390 ((local_info_t*)link->priv)->cardnr = last_ret; 374 ((local_info_t *)link->priv)->cardnr = ret;
391 375
392 return 0; 376 return 0;
393 377
394cs_failed:
395 cs_error(link, last_fn, last_ret);
396failed: 378failed:
397 sedlbauer_release(link); 379 sedlbauer_release(link);
398 return -ENODEV; 380 return -ENODEV;
@@ -410,7 +392,7 @@ failed:
410static void sedlbauer_release(struct pcmcia_device *link) 392static void sedlbauer_release(struct pcmcia_device *link)
411{ 393{
412 local_info_t *local = link->priv; 394 local_info_t *local = link->priv;
413 DEBUG(0, "sedlbauer_release(0x%p)\n", link); 395 dev_dbg(&link->dev, "sedlbauer_release(0x%p)\n", link);
414 396
415 if (local) { 397 if (local) {
416 if (local->cardnr >= 0) { 398 if (local->cardnr >= 0) {
@@ -459,7 +441,7 @@ static struct pcmcia_driver sedlbauer_driver = {
459 .name = "sedlbauer_cs", 441 .name = "sedlbauer_cs",
460 }, 442 },
461 .probe = sedlbauer_probe, 443 .probe = sedlbauer_probe,
462 .remove = sedlbauer_detach, 444 .remove = __devexit_p(sedlbauer_detach),
463 .id_table = sedlbauer_ids, 445 .id_table = sedlbauer_ids,
464 .suspend = sedlbauer_suspend, 446 .suspend = sedlbauer_suspend,
465 .resume = sedlbauer_resume, 447 .resume = sedlbauer_resume,
diff --git a/drivers/isdn/hisax/st5481_b.c b/drivers/isdn/hisax/st5481_b.c
index 95b1cdd97958..e56e5af889b6 100644
--- a/drivers/isdn/hisax/st5481_b.c
+++ b/drivers/isdn/hisax/st5481_b.c
@@ -11,8 +11,8 @@
11 */ 11 */
12 12
13#include <linux/init.h> 13#include <linux/init.h>
14#include <linux/gfp.h>
14#include <linux/usb.h> 15#include <linux/usb.h>
15#include <linux/slab.h>
16#include <linux/netdevice.h> 16#include <linux/netdevice.h>
17#include <linux/bitrev.h> 17#include <linux/bitrev.h>
18#include "st5481.h" 18#include "st5481.h"
diff --git a/drivers/isdn/hisax/st5481_d.c b/drivers/isdn/hisax/st5481_d.c
index 39e8e49cfd2d..b7876b19fe73 100644
--- a/drivers/isdn/hisax/st5481_d.c
+++ b/drivers/isdn/hisax/st5481_d.c
@@ -11,8 +11,8 @@
11 */ 11 */
12 12
13#include <linux/init.h> 13#include <linux/init.h>
14#include <linux/gfp.h>
14#include <linux/usb.h> 15#include <linux/usb.h>
15#include <linux/slab.h>
16#include <linux/netdevice.h> 16#include <linux/netdevice.h>
17#include "st5481.h" 17#include "st5481.h"
18 18
diff --git a/drivers/isdn/hisax/tei.c b/drivers/isdn/hisax/tei.c
index 6e65424f1f04..f4cb178b0666 100644
--- a/drivers/isdn/hisax/tei.c
+++ b/drivers/isdn/hisax/tei.c
@@ -17,6 +17,7 @@
17 17
18#include "hisax.h" 18#include "hisax.h"
19#include "isdnl2.h" 19#include "isdnl2.h"
20#include <linux/gfp.h>
20#include <linux/init.h> 21#include <linux/init.h>
21#include <linux/random.h> 22#include <linux/random.h>
22 23
diff --git a/drivers/isdn/hisax/teles_cs.c b/drivers/isdn/hisax/teles_cs.c
index 623d111544d4..d010a0da8e19 100644
--- a/drivers/isdn/hisax/teles_cs.c
+++ b/drivers/isdn/hisax/teles_cs.c
@@ -38,23 +38,6 @@ MODULE_DESCRIPTION("ISDN4Linux: PCMCIA client driver for Teles PCMCIA cards");
38MODULE_AUTHOR("Christof Petig, christof.petig@wtal.de, Karsten Keil, kkeil@suse.de"); 38MODULE_AUTHOR("Christof Petig, christof.petig@wtal.de, Karsten Keil, kkeil@suse.de");
39MODULE_LICENSE("GPL"); 39MODULE_LICENSE("GPL");
40 40
41/*
42 All the PCMCIA modules use PCMCIA_DEBUG to control debugging. If
43 you do not define PCMCIA_DEBUG at all, all the debug code will be
44 left out. If you compile with PCMCIA_DEBUG=0, the debug code will
45 be present but disabled -- but it can then be enabled for specific
46 modules at load time with a 'pc_debug=#' option to insmod.
47*/
48
49#ifdef PCMCIA_DEBUG
50static int pc_debug = PCMCIA_DEBUG;
51module_param(pc_debug, int, 0);
52#define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args);
53static char *version =
54"teles_cs.c 2.10 2002/07/30 22:23:34 kkeil";
55#else
56#define DEBUG(n, args...)
57#endif
58 41
59/*====================================================================*/ 42/*====================================================================*/
60 43
@@ -74,7 +57,7 @@ module_param(protocol, int, 0);
74 handler. 57 handler.
75*/ 58*/
76 59
77static int teles_cs_config(struct pcmcia_device *link); 60static int teles_cs_config(struct pcmcia_device *link) __devinit ;
78static void teles_cs_release(struct pcmcia_device *link); 61static void teles_cs_release(struct pcmcia_device *link);
79 62
80/* 63/*
@@ -83,7 +66,7 @@ static void teles_cs_release(struct pcmcia_device *link);
83 needed to manage one actual PCMCIA card. 66 needed to manage one actual PCMCIA card.
84*/ 67*/
85 68
86static void teles_detach(struct pcmcia_device *p_dev); 69static void teles_detach(struct pcmcia_device *p_dev) __devexit ;
87 70
88/* 71/*
89 A linked list of "instances" of the teles_cs device. Each actual 72 A linked list of "instances" of the teles_cs device. Each actual
@@ -129,11 +112,11 @@ typedef struct local_info_t {
129 112
130======================================================================*/ 113======================================================================*/
131 114
132static int teles_probe(struct pcmcia_device *link) 115static int __devinit teles_probe(struct pcmcia_device *link)
133{ 116{
134 local_info_t *local; 117 local_info_t *local;
135 118
136 DEBUG(0, "teles_attach()\n"); 119 dev_dbg(&link->dev, "teles_attach()\n");
137 120
138 /* Allocate space for private device-specific data */ 121 /* Allocate space for private device-specific data */
139 local = kzalloc(sizeof(local_info_t), GFP_KERNEL); 122 local = kzalloc(sizeof(local_info_t), GFP_KERNEL);
@@ -144,8 +127,7 @@ static int teles_probe(struct pcmcia_device *link)
144 link->priv = local; 127 link->priv = local;
145 128
146 /* Interrupt setup */ 129 /* Interrupt setup */
147 link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING|IRQ_FIRST_SHARED; 130 link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
148 link->irq.IRQInfo1 = IRQ_LEVEL_ID|IRQ_SHARE_ID;
149 link->irq.Handler = NULL; 131 link->irq.Handler = NULL;
150 132
151 /* 133 /*
@@ -174,11 +156,11 @@ static int teles_probe(struct pcmcia_device *link)
174 156
175======================================================================*/ 157======================================================================*/
176 158
177static void teles_detach(struct pcmcia_device *link) 159static void __devexit teles_detach(struct pcmcia_device *link)
178{ 160{
179 local_info_t *info = link->priv; 161 local_info_t *info = link->priv;
180 162
181 DEBUG(0, "teles_detach(0x%p)\n", link); 163 dev_dbg(&link->dev, "teles_detach(0x%p)\n", link);
182 164
183 info->busy = 1; 165 info->busy = 1;
184 teles_cs_release(link); 166 teles_cs_release(link);
@@ -218,33 +200,28 @@ static int teles_cs_configcheck(struct pcmcia_device *p_dev,
218 return -ENODEV; 200 return -ENODEV;
219} 201}
220 202
221static int teles_cs_config(struct pcmcia_device *link) 203static int __devinit teles_cs_config(struct pcmcia_device *link)
222{ 204{
223 local_info_t *dev; 205 local_info_t *dev;
224 int i, last_fn; 206 int i;
225 IsdnCard_t icard; 207 IsdnCard_t icard;
226 208
227 DEBUG(0, "teles_config(0x%p)\n", link); 209 dev_dbg(&link->dev, "teles_config(0x%p)\n", link);
228 dev = link->priv; 210 dev = link->priv;
229 211
230 i = pcmcia_loop_config(link, teles_cs_configcheck, NULL); 212 i = pcmcia_loop_config(link, teles_cs_configcheck, NULL);
231 if (i != 0) { 213 if (i != 0)
232 last_fn = RequestIO;
233 goto cs_failed; 214 goto cs_failed;
234 }
235 215
236 i = pcmcia_request_irq(link, &link->irq); 216 i = pcmcia_request_irq(link, &link->irq);
237 if (i != 0) { 217 if (i != 0) {
238 link->irq.AssignedIRQ = 0; 218 link->irq.AssignedIRQ = 0;
239 last_fn = RequestIRQ;
240 goto cs_failed; 219 goto cs_failed;
241 } 220 }
242 221
243 i = pcmcia_request_configuration(link, &link->conf); 222 i = pcmcia_request_configuration(link, &link->conf);
244 if (i != 0) { 223 if (i != 0)
245 last_fn = RequestConfiguration;
246 goto cs_failed; 224 goto cs_failed;
247 }
248 225
249 /* At this point, the dev_node_t structure(s) should be 226 /* At this point, the dev_node_t structure(s) should be
250 initialized and arranged in a linked list at link->dev. *//* */ 227 initialized and arranged in a linked list at link->dev. *//* */
@@ -283,7 +260,6 @@ static int teles_cs_config(struct pcmcia_device *link)
283 return 0; 260 return 0;
284 261
285cs_failed: 262cs_failed:
286 cs_error(link, last_fn, i);
287 teles_cs_release(link); 263 teles_cs_release(link);
288 return -ENODEV; 264 return -ENODEV;
289} /* teles_cs_config */ 265} /* teles_cs_config */
@@ -300,7 +276,7 @@ static void teles_cs_release(struct pcmcia_device *link)
300{ 276{
301 local_info_t *local = link->priv; 277 local_info_t *local = link->priv;
302 278
303 DEBUG(0, "teles_cs_release(0x%p)\n", link); 279 dev_dbg(&link->dev, "teles_cs_release(0x%p)\n", link);
304 280
305 if (local) { 281 if (local) {
306 if (local->cardnr >= 0) { 282 if (local->cardnr >= 0) {
@@ -343,7 +319,7 @@ static struct pcmcia_driver teles_cs_driver = {
343 .name = "teles_cs", 319 .name = "teles_cs",
344 }, 320 },
345 .probe = teles_probe, 321 .probe = teles_probe,
346 .remove = teles_detach, 322 .remove = __devexit_p(teles_detach),
347 .id_table = teles_ids, 323 .id_table = teles_ids,
348 .suspend = teles_suspend, 324 .suspend = teles_suspend,
349 .resume = teles_resume, 325 .resume = teles_resume,
diff --git a/drivers/isdn/hisax/telespci.c b/drivers/isdn/hisax/telespci.c
index 28b08de4673d..b85ceb3746ce 100644
--- a/drivers/isdn/hisax/telespci.c
+++ b/drivers/isdn/hisax/telespci.c
@@ -300,7 +300,7 @@ setup_telespci(struct IsdnCard *card)
300 if (cs->typ != ISDN_CTYPE_TELESPCI) 300 if (cs->typ != ISDN_CTYPE_TELESPCI)
301 return (0); 301 return (0);
302 302
303 if ((dev_tel = pci_find_device (PCI_VENDOR_ID_ZORAN, PCI_DEVICE_ID_ZORAN_36120, dev_tel))) { 303 if ((dev_tel = hisax_find_pci_device (PCI_VENDOR_ID_ZORAN, PCI_DEVICE_ID_ZORAN_36120, dev_tel))) {
304 if (pci_enable_device(dev_tel)) 304 if (pci_enable_device(dev_tel))
305 return(0); 305 return(0);
306 cs->irq = dev_tel->irq; 306 cs->irq = dev_tel->irq;
diff --git a/drivers/isdn/hisax/w6692.c b/drivers/isdn/hisax/w6692.c
index c4d862c11a60..e2cfb6f5aa42 100644
--- a/drivers/isdn/hisax/w6692.c
+++ b/drivers/isdn/hisax/w6692.c
@@ -16,6 +16,7 @@
16#include "isdnl1.h" 16#include "isdnl1.h"
17#include <linux/interrupt.h> 17#include <linux/interrupt.h>
18#include <linux/pci.h> 18#include <linux/pci.h>
19#include <linux/slab.h>
19 20
20/* table entry in the PCI devices list */ 21/* table entry in the PCI devices list */
21typedef struct { 22typedef struct {
@@ -1007,7 +1008,7 @@ setup_w6692(struct IsdnCard *card)
1007 return (0); 1008 return (0);
1008 1009
1009 while (id_list[id_idx].vendor_id) { 1010 while (id_list[id_idx].vendor_id) {
1010 dev_w6692 = pci_find_device(id_list[id_idx].vendor_id, 1011 dev_w6692 = hisax_find_pci_device(id_list[id_idx].vendor_id,
1011 id_list[id_idx].device_id, 1012 id_list[id_idx].device_id,
1012 dev_w6692); 1013 dev_w6692);
1013 if (dev_w6692) { 1014 if (dev_w6692) {
diff --git a/drivers/isdn/hysdn/Kconfig b/drivers/isdn/hysdn/Kconfig
index c9e4231968ef..e86bc6583d71 100644
--- a/drivers/isdn/hysdn/Kconfig
+++ b/drivers/isdn/hysdn/Kconfig
@@ -1,6 +1,3 @@
1#
2# Config.in for HYSDN ISDN driver
3#
4config HYSDN 1config HYSDN
5 tristate "Hypercope HYSDN cards (Champ, Ergo, Metro) support (module only)" 2 tristate "Hypercope HYSDN cards (Champ, Ergo, Metro) support (module only)"
6 depends on m && PROC_FS && PCI 3 depends on m && PROC_FS && PCI
@@ -15,4 +12,3 @@ config HYSDN_CAPI
15 depends on HYSDN && ISDN_CAPI 12 depends on HYSDN && ISDN_CAPI
16 help 13 help
17 Say Y here if you like to use Hypercope's CAPI 2.0 interface. 14 Say Y here if you like to use Hypercope's CAPI 2.0 interface.
18
diff --git a/drivers/isdn/hysdn/hycapi.c b/drivers/isdn/hysdn/hycapi.c
index 4ffaa14b9fc4..6299b06ae009 100644
--- a/drivers/isdn/hysdn/hycapi.c
+++ b/drivers/isdn/hysdn/hycapi.c
@@ -11,10 +11,13 @@
11 */ 11 */
12 12
13#include <linux/module.h> 13#include <linux/module.h>
14#include <linux/proc_fs.h>
15#include <linux/seq_file.h>
14#include <linux/signal.h> 16#include <linux/signal.h>
15#include <linux/kernel.h> 17#include <linux/kernel.h>
16#include <linux/skbuff.h> 18#include <linux/skbuff.h>
17#include <linux/netdevice.h> 19#include <linux/netdevice.h>
20#include <linux/slab.h>
18 21
19#define VER_DRIVER 0 22#define VER_DRIVER 0
20#define VER_CARDTYPE 1 23#define VER_CARDTYPE 1
@@ -432,26 +435,16 @@ static u16 hycapi_send_message(struct capi_ctr *ctrl, struct sk_buff *skb)
432 return retval; 435 return retval;
433} 436}
434 437
435/********************************************************************* 438static int hycapi_proc_show(struct seq_file *m, void *v)
436hycapi_read_proc
437
438Informations provided in the /proc/capi-entries.
439
440*********************************************************************/
441
442static int hycapi_read_proc(char *page, char **start, off_t off,
443 int count, int *eof, struct capi_ctr *ctrl)
444{ 439{
440 struct capi_ctr *ctrl = m->private;
445 hycapictrl_info *cinfo = (hycapictrl_info *)(ctrl->driverdata); 441 hycapictrl_info *cinfo = (hycapictrl_info *)(ctrl->driverdata);
446 hysdn_card *card = cinfo->card; 442 hysdn_card *card = cinfo->card;
447 int len = 0;
448 char *s; 443 char *s;
449#ifdef HYCAPI_PRINTFNAMES 444
450 printk(KERN_NOTICE "hycapi_read_proc\n"); 445 seq_printf(m, "%-16s %s\n", "name", cinfo->cardname);
451#endif 446 seq_printf(m, "%-16s 0x%x\n", "io", card->iobase);
452 len += sprintf(page+len, "%-16s %s\n", "name", cinfo->cardname); 447 seq_printf(m, "%-16s %d\n", "irq", card->irq);
453 len += sprintf(page+len, "%-16s 0x%x\n", "io", card->iobase);
454 len += sprintf(page+len, "%-16s %d\n", "irq", card->irq);
455 448
456 switch (card->brdtype) { 449 switch (card->brdtype) {
457 case BD_PCCARD: s = "HYSDN Hycard"; break; 450 case BD_PCCARD: s = "HYSDN Hycard"; break;
@@ -461,24 +454,32 @@ static int hycapi_read_proc(char *page, char **start, off_t off,
461 case BD_PLEXUS: s = "HYSDN Plexus30"; break; 454 case BD_PLEXUS: s = "HYSDN Plexus30"; break;
462 default: s = "???"; break; 455 default: s = "???"; break;
463 } 456 }
464 len += sprintf(page+len, "%-16s %s\n", "type", s); 457 seq_printf(m, "%-16s %s\n", "type", s);
465 if ((s = cinfo->version[VER_DRIVER]) != NULL) 458 if ((s = cinfo->version[VER_DRIVER]) != NULL)
466 len += sprintf(page+len, "%-16s %s\n", "ver_driver", s); 459 seq_printf(m, "%-16s %s\n", "ver_driver", s);
467 if ((s = cinfo->version[VER_CARDTYPE]) != NULL) 460 if ((s = cinfo->version[VER_CARDTYPE]) != NULL)
468 len += sprintf(page+len, "%-16s %s\n", "ver_cardtype", s); 461 seq_printf(m, "%-16s %s\n", "ver_cardtype", s);
469 if ((s = cinfo->version[VER_SERIAL]) != NULL) 462 if ((s = cinfo->version[VER_SERIAL]) != NULL)
470 len += sprintf(page+len, "%-16s %s\n", "ver_serial", s); 463 seq_printf(m, "%-16s %s\n", "ver_serial", s);
471 464
472 len += sprintf(page+len, "%-16s %s\n", "cardname", cinfo->cardname); 465 seq_printf(m, "%-16s %s\n", "cardname", cinfo->cardname);
473 466
474 if (off+count >= len) 467 return 0;
475 *eof = 1; 468}
476 if (len < off) 469
477 return 0; 470static int hycapi_proc_open(struct inode *inode, struct file *file)
478 *start = page + off; 471{
479 return ((count < len-off) ? count : len-off); 472 return single_open(file, hycapi_proc_show, PDE(inode)->data);
480} 473}
481 474
475static const struct file_operations hycapi_proc_fops = {
476 .owner = THIS_MODULE,
477 .open = hycapi_proc_open,
478 .read = seq_read,
479 .llseek = seq_lseek,
480 .release = single_release,
481};
482
482/************************************************************** 483/**************************************************************
483hycapi_load_firmware 484hycapi_load_firmware
484 485
@@ -774,7 +775,7 @@ hycapi_capi_create(hysdn_card *card)
774 ctrl->load_firmware = hycapi_load_firmware; 775 ctrl->load_firmware = hycapi_load_firmware;
775 ctrl->reset_ctr = hycapi_reset_ctr; 776 ctrl->reset_ctr = hycapi_reset_ctr;
776 ctrl->procinfo = hycapi_procinfo; 777 ctrl->procinfo = hycapi_procinfo;
777 ctrl->ctr_read_proc = hycapi_read_proc; 778 ctrl->proc_fops = &hycapi_proc_fops;
778 strcpy(ctrl->name, cinfo->cardname); 779 strcpy(ctrl->name, cinfo->cardname);
779 ctrl->owner = THIS_MODULE; 780 ctrl->owner = THIS_MODULE;
780 781
diff --git a/drivers/isdn/hysdn/hysdn_boot.c b/drivers/isdn/hysdn/hysdn_boot.c
index be787e16bb79..4f541ef14f9e 100644
--- a/drivers/isdn/hysdn/hysdn_boot.c
+++ b/drivers/isdn/hysdn/hysdn_boot.c
@@ -143,7 +143,7 @@ pof_handle_data(hysdn_card * card, int datlen)
143 (boot->pof_recid == TAG_CABSDATA) ? "CABSDATA" : "ABSDATA", 143 (boot->pof_recid == TAG_CABSDATA) ? "CABSDATA" : "ABSDATA",
144 datlen, boot->pof_recoffset); 144 datlen, boot->pof_recoffset);
145 145
146 if ((boot->last_error = card->writebootseq(card, boot->buf.BootBuf, datlen) < 0)) 146 if ((boot->last_error = card->writebootseq(card, boot->buf.BootBuf, datlen)) < 0)
147 return (boot->last_error); /* error writing data */ 147 return (boot->last_error); /* error writing data */
148 148
149 if (boot->pof_recoffset + datlen >= boot->pof_reclen) 149 if (boot->pof_recoffset + datlen >= boot->pof_reclen)
diff --git a/drivers/isdn/hysdn/hysdn_procconf.c b/drivers/isdn/hysdn/hysdn_procconf.c
index 90b35e1a4b7e..80966462d6dc 100644
--- a/drivers/isdn/hysdn/hysdn_procconf.c
+++ b/drivers/isdn/hysdn/hysdn_procconf.c
@@ -16,6 +16,7 @@
16#include <linux/poll.h> 16#include <linux/poll.h>
17#include <linux/proc_fs.h> 17#include <linux/proc_fs.h>
18#include <linux/pci.h> 18#include <linux/pci.h>
19#include <linux/slab.h>
19#include <linux/smp_lock.h> 20#include <linux/smp_lock.h>
20#include <net/net_namespace.h> 21#include <net/net_namespace.h>
21 22
diff --git a/drivers/isdn/hysdn/hysdn_proclog.c b/drivers/isdn/hysdn/hysdn_proclog.c
index 8bcae28c4409..e83f6fda32fe 100644
--- a/drivers/isdn/hysdn/hysdn_proclog.c
+++ b/drivers/isdn/hysdn/hysdn_proclog.c
@@ -14,6 +14,7 @@
14#include <linux/poll.h> 14#include <linux/poll.h>
15#include <linux/proc_fs.h> 15#include <linux/proc_fs.h>
16#include <linux/sched.h> 16#include <linux/sched.h>
17#include <linux/slab.h>
17#include <linux/smp_lock.h> 18#include <linux/smp_lock.h>
18 19
19#include "hysdn_defs.h" 20#include "hysdn_defs.h"
diff --git a/drivers/isdn/i4l/Kconfig b/drivers/isdn/i4l/Kconfig
index 07c4e49f9e77..9c6650ea848e 100644
--- a/drivers/isdn/i4l/Kconfig
+++ b/drivers/isdn/i4l/Kconfig
@@ -134,14 +134,7 @@ source "drivers/isdn/sc/Kconfig"
134 134
135source "drivers/isdn/act2000/Kconfig" 135source "drivers/isdn/act2000/Kconfig"
136 136
137source "drivers/isdn/hysdn/Kconfig"
138
139endmenu 137endmenu
140# end ISDN_I4L 138# end ISDN_I4L
141endif 139endif
142 140
143config ISDN_HDLC
144 tristate
145 select CRC_CCITT
146 select BITREVERSE
147
diff --git a/drivers/isdn/i4l/isdn_audio.c b/drivers/isdn/i4l/isdn_audio.c
index fb350c567c6b..861bdf3421f2 100644
--- a/drivers/isdn/i4l/isdn_audio.c
+++ b/drivers/isdn/i4l/isdn_audio.c
@@ -12,6 +12,7 @@
12 */ 12 */
13 13
14#include <linux/isdn.h> 14#include <linux/isdn.h>
15#include <linux/slab.h>
15#include "isdn_audio.h" 16#include "isdn_audio.h"
16#include "isdn_common.h" 17#include "isdn_common.h"
17 18
diff --git a/drivers/isdn/i4l/isdn_common.c b/drivers/isdn/i4l/isdn_common.c
index adb1e8c36b46..70044ee4b228 100644
--- a/drivers/isdn/i4l/isdn_common.c
+++ b/drivers/isdn/i4l/isdn_common.c
@@ -14,6 +14,7 @@
14#include <linux/module.h> 14#include <linux/module.h>
15#include <linux/init.h> 15#include <linux/init.h>
16#include <linux/poll.h> 16#include <linux/poll.h>
17#include <linux/slab.h>
17#include <linux/vmalloc.h> 18#include <linux/vmalloc.h>
18#include <linux/isdn.h> 19#include <linux/isdn.h>
19#include <linux/smp_lock.h> 20#include <linux/smp_lock.h>
@@ -1347,7 +1348,7 @@ isdn_ioctl(struct inode *inode, struct file *file, uint cmd, ulong arg)
1347/* 1348/*
1348 * isdn net devices manage lots of configuration variables as linked lists. 1349 * isdn net devices manage lots of configuration variables as linked lists.
1349 * Those lists must only be manipulated from user space. Some of the ioctl's 1350 * Those lists must only be manipulated from user space. Some of the ioctl's
1350 * service routines access user space and are not atomic. Therefor, ioctl's 1351 * service routines access user space and are not atomic. Therefore, ioctl's
1351 * manipulating the lists and ioctl's sleeping while accessing the lists 1352 * manipulating the lists and ioctl's sleeping while accessing the lists
1352 * are serialized by means of a semaphore. 1353 * are serialized by means of a semaphore.
1353 */ 1354 */
diff --git a/drivers/isdn/i4l/isdn_net.c b/drivers/isdn/i4l/isdn_net.c
index 90b56ed8651f..8c85d1e88cc6 100644
--- a/drivers/isdn/i4l/isdn_net.c
+++ b/drivers/isdn/i4l/isdn_net.c
@@ -23,6 +23,7 @@
23 */ 23 */
24 24
25#include <linux/isdn.h> 25#include <linux/isdn.h>
26#include <linux/slab.h>
26#include <net/arp.h> 27#include <net/arp.h>
27#include <net/dst.h> 28#include <net/dst.h>
28#include <net/pkt_sched.h> 29#include <net/pkt_sched.h>
@@ -1563,7 +1564,7 @@ isdn_net_ciscohdlck_slarp_send_keepalive(unsigned long data)
1563 *(__be32 *)(p + 4) = cpu_to_be32(CISCO_SLARP_KEEPALIVE); 1564 *(__be32 *)(p + 4) = cpu_to_be32(CISCO_SLARP_KEEPALIVE);
1564 *(__be32 *)(p + 8) = cpu_to_be32(lp->cisco_myseq); 1565 *(__be32 *)(p + 8) = cpu_to_be32(lp->cisco_myseq);
1565 *(__be32 *)(p + 12) = cpu_to_be32(lp->cisco_yourseq); 1566 *(__be32 *)(p + 12) = cpu_to_be32(lp->cisco_yourseq);
1566 *(__be16 *)(p + 16) = cpu_to_be16(0xffff); // reliablity, always 0xffff 1567 *(__be16 *)(p + 16) = cpu_to_be16(0xffff); // reliability, always 0xffff
1567 p += 18; 1568 p += 18;
1568 1569
1569 isdn_net_write_super(lp, skb); 1570 isdn_net_write_super(lp, skb);
diff --git a/drivers/isdn/i4l/isdn_ppp.c b/drivers/isdn/i4l/isdn_ppp.c
index 642d5aaf53ce..f37b8f68d0aa 100644
--- a/drivers/isdn/i4l/isdn_ppp.c
+++ b/drivers/isdn/i4l/isdn_ppp.c
@@ -12,6 +12,7 @@
12#include <linux/isdn.h> 12#include <linux/isdn.h>
13#include <linux/poll.h> 13#include <linux/poll.h>
14#include <linux/ppp-comp.h> 14#include <linux/ppp-comp.h>
15#include <linux/slab.h>
15#ifdef CONFIG_IPPP_FILTER 16#ifdef CONFIG_IPPP_FILTER
16#include <linux/filter.h> 17#include <linux/filter.h>
17#endif 18#endif
@@ -836,7 +837,7 @@ isdn_ppp_write(int min, struct file *file, const char __user *buf, int count)
836 unsigned short hl; 837 unsigned short hl;
837 struct sk_buff *skb; 838 struct sk_buff *skb;
838 /* 839 /*
839 * we need to reserve enought space in front of 840 * we need to reserve enough space in front of
840 * sk_buff. old call to dev_alloc_skb only reserved 841 * sk_buff. old call to dev_alloc_skb only reserved
841 * 16 bytes, now we are looking what the driver want 842 * 16 bytes, now we are looking what the driver want
842 */ 843 */
@@ -1326,7 +1327,7 @@ isdn_ppp_xmit(struct sk_buff *skb, struct net_device *netdev)
1326 struct sk_buff *new_skb; 1327 struct sk_buff *new_skb;
1327 unsigned short hl; 1328 unsigned short hl;
1328 /* 1329 /*
1329 * we need to reserve enought space in front of 1330 * we need to reserve enough space in front of
1330 * sk_buff. old call to dev_alloc_skb only reserved 1331 * sk_buff. old call to dev_alloc_skb only reserved
1331 * 16 bytes, now we are looking what the driver want. 1332 * 16 bytes, now we are looking what the driver want.
1332 */ 1333 */
@@ -1674,7 +1675,7 @@ static void isdn_ppp_mp_receive(isdn_net_dev * net_dev, isdn_net_local * lp,
1674 * - insert new fragment into the proper sequence slot (once that's done 1675 * - insert new fragment into the proper sequence slot (once that's done
1675 * newfrag will be set to NULL) 1676 * newfrag will be set to NULL)
1676 * - reassemble any complete fragment sequence (non-null 'start' 1677 * - reassemble any complete fragment sequence (non-null 'start'
1677 * indicates there is a continguous sequence present) 1678 * indicates there is a contiguous sequence present)
1678 * - discard any incomplete sequences that are below minseq -- due 1679 * - discard any incomplete sequences that are below minseq -- due
1679 * to the fact that sender always increment sequence number, if there 1680 * to the fact that sender always increment sequence number, if there
1680 * is an incomplete sequence below minseq, no new fragments would 1681 * is an incomplete sequence below minseq, no new fragments would
diff --git a/drivers/isdn/i4l/isdn_tty.c b/drivers/isdn/i4l/isdn_tty.c
index 2881a66c1aa9..fc8454d2eea5 100644
--- a/drivers/isdn/i4l/isdn_tty.c
+++ b/drivers/isdn/i4l/isdn_tty.c
@@ -12,6 +12,7 @@
12#undef ISDN_TTY_STAT_DEBUG 12#undef ISDN_TTY_STAT_DEBUG
13 13
14#include <linux/isdn.h> 14#include <linux/isdn.h>
15#include <linux/slab.h>
15#include <linux/delay.h> 16#include <linux/delay.h>
16#include <linux/smp_lock.h> 17#include <linux/smp_lock.h>
17#include "isdn_common.h" 18#include "isdn_common.h"
diff --git a/drivers/isdn/i4l/isdn_ttyfax.c b/drivers/isdn/i4l/isdn_ttyfax.c
index 78f7660c1d0e..4c41f191d4e2 100644
--- a/drivers/isdn/i4l/isdn_ttyfax.c
+++ b/drivers/isdn/i4l/isdn_ttyfax.c
@@ -470,7 +470,7 @@ isdn_tty_cmd_FCLASS2(char **p, modem_info * info)
470 } 470 }
471 return 0; 471 return 0;
472 } 472 }
473 /* BADMUL=value - dummy 0=disable errorchk disabled (treshold multiplier) */ 473 /* BADMUL=value - dummy 0=disable errorchk disabled (threshold multiplier) */
474 if (!strncmp(p[0], "BADMUL", 6)) { 474 if (!strncmp(p[0], "BADMUL", 6)) {
475 p[0] += 6; 475 p[0] += 6;
476 switch (*p[0]) { 476 switch (*p[0]) {
diff --git a/drivers/isdn/i4l/isdn_x25iface.c b/drivers/isdn/i4l/isdn_x25iface.c
index 8b3efc243161..efcf1f9327e5 100644
--- a/drivers/isdn/i4l/isdn_x25iface.c
+++ b/drivers/isdn/i4l/isdn_x25iface.c
@@ -20,6 +20,7 @@
20/* #include <linux/isdn.h> */ 20/* #include <linux/isdn.h> */
21#include <linux/netdevice.h> 21#include <linux/netdevice.h>
22#include <linux/concap.h> 22#include <linux/concap.h>
23#include <linux/slab.h>
23#include <linux/wanrouter.h> 24#include <linux/wanrouter.h>
24#include <net/x25device.h> 25#include <net/x25device.h>
25#include "isdn_x25iface.h" 26#include "isdn_x25iface.h"
diff --git a/drivers/isdn/icn/Kconfig b/drivers/isdn/icn/Kconfig
index 89d15eed765e..4534f21a1852 100644
--- a/drivers/isdn/icn/Kconfig
+++ b/drivers/isdn/icn/Kconfig
@@ -1,6 +1,3 @@
1#
2# Config.in for ICN ISDN driver
3#
4config ISDN_DRV_ICN 1config ISDN_DRV_ICN
5 tristate "ICN 2B and 4B support" 2 tristate "ICN 2B and 4B support"
6 depends on ISA 3 depends on ISA
@@ -13,4 +10,3 @@ config ISDN_DRV_ICN
13 separately. See <file:Documentation/isdn/README> and 10 separately. See <file:Documentation/isdn/README> and
14 <file:Documentation/isdn/README.icn> for more 11 <file:Documentation/isdn/README.icn> for more
15 information. 12 information.
16
diff --git a/drivers/isdn/icn/icn.c b/drivers/isdn/icn/icn.c
index bf7997abc4ac..2e847a90bad0 100644
--- a/drivers/isdn/icn/icn.c
+++ b/drivers/isdn/icn/icn.c
@@ -12,6 +12,7 @@
12#include "icn.h" 12#include "icn.h"
13#include <linux/module.h> 13#include <linux/module.h>
14#include <linux/init.h> 14#include <linux/init.h>
15#include <linux/slab.h>
15#include <linux/sched.h> 16#include <linux/sched.h>
16 17
17static int portbase = ICN_BASEADDR; 18static int portbase = ICN_BASEADDR;
diff --git a/drivers/isdn/isdnloop/isdnloop.c b/drivers/isdn/isdnloop/isdnloop.c
index a335c85a736e..b8a1098b66ed 100644
--- a/drivers/isdn/isdnloop/isdnloop.c
+++ b/drivers/isdn/isdnloop/isdnloop.c
@@ -11,6 +11,7 @@
11 11
12#include <linux/module.h> 12#include <linux/module.h>
13#include <linux/interrupt.h> 13#include <linux/interrupt.h>
14#include <linux/slab.h>
14#include <linux/init.h> 15#include <linux/init.h>
15#include <linux/sched.h> 16#include <linux/sched.h>
16#include "isdnloop.h" 17#include "isdnloop.h"
diff --git a/drivers/isdn/mISDN/clock.c b/drivers/isdn/mISDN/clock.c
index f1bbc88763b2..1fa629b3b940 100644
--- a/drivers/isdn/mISDN/clock.c
+++ b/drivers/isdn/mISDN/clock.c
@@ -33,6 +33,7 @@
33 * 33 *
34 */ 34 */
35 35
36#include <linux/slab.h>
36#include <linux/types.h> 37#include <linux/types.h>
37#include <linux/stddef.h> 38#include <linux/stddef.h>
38#include <linux/spinlock.h> 39#include <linux/spinlock.h>
diff --git a/drivers/isdn/mISDN/core.c b/drivers/isdn/mISDN/core.c
index 21d34be5af6a..afeebb00fe0b 100644
--- a/drivers/isdn/mISDN/core.c
+++ b/drivers/isdn/mISDN/core.c
@@ -12,6 +12,7 @@
12 * 12 *
13 */ 13 */
14 14
15#include <linux/slab.h>
15#include <linux/types.h> 16#include <linux/types.h>
16#include <linux/stddef.h> 17#include <linux/stddef.h>
17#include <linux/module.h> 18#include <linux/module.h>
diff --git a/drivers/isdn/mISDN/dsp_cmx.c b/drivers/isdn/mISDN/dsp_cmx.c
index 9c7c0d1ba55f..713ef2b805a2 100644
--- a/drivers/isdn/mISDN/dsp_cmx.c
+++ b/drivers/isdn/mISDN/dsp_cmx.c
@@ -124,6 +124,7 @@
124 124
125/* delay.h is required for hw_lock.h */ 125/* delay.h is required for hw_lock.h */
126 126
127#include <linux/slab.h>
127#include <linux/delay.h> 128#include <linux/delay.h>
128#include <linux/mISDNif.h> 129#include <linux/mISDNif.h>
129#include <linux/mISDNdsp.h> 130#include <linux/mISDNdsp.h>
diff --git a/drivers/isdn/mISDN/dsp_core.c b/drivers/isdn/mISDN/dsp_core.c
index 77ee2867c8b4..6f5b54864283 100644
--- a/drivers/isdn/mISDN/dsp_core.c
+++ b/drivers/isdn/mISDN/dsp_core.c
@@ -110,7 +110,7 @@
110 * crossconnections and conferences via software if not possible through 110 * crossconnections and conferences via software if not possible through
111 * hardware. If hardware capability is available, hardware is used. 111 * hardware. If hardware capability is available, hardware is used.
112 * 112 *
113 * Echo: Is generated by CMX and is used to check performane of hard and 113 * Echo: Is generated by CMX and is used to check performance of hard and
114 * software CMX. 114 * software CMX.
115 * 115 *
116 * The CMX has special functions for conferences with one, two and more 116 * The CMX has special functions for conferences with one, two and more
@@ -154,6 +154,7 @@
154 */ 154 */
155 155
156#include <linux/delay.h> 156#include <linux/delay.h>
157#include <linux/gfp.h>
157#include <linux/mISDNif.h> 158#include <linux/mISDNif.h>
158#include <linux/mISDNdsp.h> 159#include <linux/mISDNdsp.h>
159#include <linux/module.h> 160#include <linux/module.h>
@@ -1114,7 +1115,7 @@ static struct Bprotocol DSP = {
1114 .create = dspcreate 1115 .create = dspcreate
1115}; 1116};
1116 1117
1117static int dsp_init(void) 1118static int __init dsp_init(void)
1118{ 1119{
1119 int err; 1120 int err;
1120 int tics; 1121 int tics;
@@ -1212,7 +1213,7 @@ static int dsp_init(void)
1212} 1213}
1213 1214
1214 1215
1215static void dsp_cleanup(void) 1216static void __exit dsp_cleanup(void)
1216{ 1217{
1217 mISDN_unregister_Bprotocol(&DSP); 1218 mISDN_unregister_Bprotocol(&DSP);
1218 1219
diff --git a/drivers/isdn/mISDN/dsp_pipeline.c b/drivers/isdn/mISDN/dsp_pipeline.c
index e9941678edfa..621f31007095 100644
--- a/drivers/isdn/mISDN/dsp_pipeline.c
+++ b/drivers/isdn/mISDN/dsp_pipeline.c
@@ -25,6 +25,7 @@
25 */ 25 */
26 26
27#include <linux/kernel.h> 27#include <linux/kernel.h>
28#include <linux/slab.h>
28#include <linux/list.h> 29#include <linux/list.h>
29#include <linux/string.h> 30#include <linux/string.h>
30#include <linux/mISDNif.h> 31#include <linux/mISDNif.h>
diff --git a/drivers/isdn/mISDN/dsp_tones.c b/drivers/isdn/mISDN/dsp_tones.c
index 1debf53670de..7dbe54ed1deb 100644
--- a/drivers/isdn/mISDN/dsp_tones.c
+++ b/drivers/isdn/mISDN/dsp_tones.c
@@ -8,6 +8,7 @@
8 * 8 *
9 */ 9 */
10 10
11#include <linux/gfp.h>
11#include <linux/mISDNif.h> 12#include <linux/mISDNif.h>
12#include <linux/mISDNdsp.h> 13#include <linux/mISDNdsp.h>
13#include "core.h" 14#include "core.h"
diff --git a/drivers/isdn/mISDN/hwchannel.c b/drivers/isdn/mISDN/hwchannel.c
index e8049be552aa..307bd6e8988b 100644
--- a/drivers/isdn/mISDN/hwchannel.c
+++ b/drivers/isdn/mISDN/hwchannel.c
@@ -15,6 +15,7 @@
15 * 15 *
16 */ 16 */
17 17
18#include <linux/gfp.h>
18#include <linux/module.h> 19#include <linux/module.h>
19#include <linux/mISDNhw.h> 20#include <linux/mISDNhw.h>
20 21
diff --git a/drivers/isdn/mISDN/l1oip_core.c b/drivers/isdn/mISDN/l1oip_core.c
index 7e5f30dbc0a0..22f38e48ac4e 100644
--- a/drivers/isdn/mISDN/l1oip_core.c
+++ b/drivers/isdn/mISDN/l1oip_core.c
@@ -233,6 +233,7 @@ socket process and create a new one.
233#include <linux/inet.h> 233#include <linux/inet.h>
234#include <linux/workqueue.h> 234#include <linux/workqueue.h>
235#include <linux/kthread.h> 235#include <linux/kthread.h>
236#include <linux/slab.h>
236#include <net/sock.h> 237#include <net/sock.h>
237#include "core.h" 238#include "core.h"
238#include "l1oip.h" 239#include "l1oip.h"
@@ -477,7 +478,7 @@ l1oip_socket_parse(struct l1oip *hc, struct sockaddr_in *sin, u8 *buf, int len)
477 printk(KERN_DEBUG "%s: received frame, parsing... (%d)\n", 478 printk(KERN_DEBUG "%s: received frame, parsing... (%d)\n",
478 __func__, len); 479 __func__, len);
479 480
480 /* check lenght */ 481 /* check length */
481 if (len < 1+1+2) { 482 if (len < 1+1+2) {
482 printk(KERN_WARNING "%s: packet error - length %d below " 483 printk(KERN_WARNING "%s: packet error - length %d below "
483 "4 bytes\n", __func__, len); 484 "4 bytes\n", __func__, len);
@@ -661,7 +662,7 @@ l1oip_socket_thread(void *data)
661 size_t recvbuf_size = 1500; 662 size_t recvbuf_size = 1500;
662 int recvlen; 663 int recvlen;
663 struct socket *socket = NULL; 664 struct socket *socket = NULL;
664 DECLARE_COMPLETION(wait); 665 DECLARE_COMPLETION_ONSTACK(wait);
665 666
666 /* allocate buffer memory */ 667 /* allocate buffer memory */
667 recvbuf = kmalloc(recvbuf_size, GFP_KERNEL); 668 recvbuf = kmalloc(recvbuf_size, GFP_KERNEL);
@@ -1509,7 +1510,7 @@ l1oip_init(void)
1509 printk(KERN_DEBUG "%s: interface %d is %s with %s.\n", 1510 printk(KERN_DEBUG "%s: interface %d is %s with %s.\n",
1510 __func__, l1oip_cnt, pri ? "PRI" : "BRI", 1511 __func__, l1oip_cnt, pri ? "PRI" : "BRI",
1511 bundle ? "bundled IP packet for all B-channels" : 1512 bundle ? "bundled IP packet for all B-channels" :
1512 "seperate IP packets for every B-channel"); 1513 "separate IP packets for every B-channel");
1513 1514
1514 hc = kzalloc(sizeof(struct l1oip), GFP_ATOMIC); 1515 hc = kzalloc(sizeof(struct l1oip), GFP_ATOMIC);
1515 if (!hc) { 1516 if (!hc) {
diff --git a/drivers/isdn/mISDN/layer1.c b/drivers/isdn/mISDN/layer1.c
index e826eeb1ecec..ac4aa18c632b 100644
--- a/drivers/isdn/mISDN/layer1.c
+++ b/drivers/isdn/mISDN/layer1.c
@@ -16,6 +16,7 @@
16 */ 16 */
17 17
18 18
19#include <linux/slab.h>
19#include <linux/module.h> 20#include <linux/module.h>
20#include <linux/mISDNhw.h> 21#include <linux/mISDNhw.h>
21#include "core.h" 22#include "core.h"
diff --git a/drivers/isdn/mISDN/layer2.c b/drivers/isdn/mISDN/layer2.c
index e17f0044e0b6..c97371788764 100644
--- a/drivers/isdn/mISDN/layer2.c
+++ b/drivers/isdn/mISDN/layer2.c
@@ -16,6 +16,7 @@
16 */ 16 */
17 17
18#include <linux/mISDNif.h> 18#include <linux/mISDNif.h>
19#include <linux/slab.h>
19#include "core.h" 20#include "core.h"
20#include "fsm.h" 21#include "fsm.h"
21#include "layer2.h" 22#include "layer2.h"
diff --git a/drivers/isdn/mISDN/socket.c b/drivers/isdn/mISDN/socket.c
index feb0fa45b664..3232206406b1 100644
--- a/drivers/isdn/mISDN/socket.c
+++ b/drivers/isdn/mISDN/socket.c
@@ -16,6 +16,7 @@
16 */ 16 */
17 17
18#include <linux/mISDNif.h> 18#include <linux/mISDNif.h>
19#include <linux/slab.h>
19#include "core.h" 20#include "core.h"
20 21
21static u_int *debug; 22static u_int *debug;
@@ -779,7 +780,7 @@ base_sock_create(struct net *net, struct socket *sock, int protocol)
779} 780}
780 781
781static int 782static int
782mISDN_sock_create(struct net *net, struct socket *sock, int proto) 783mISDN_sock_create(struct net *net, struct socket *sock, int proto, int kern)
783{ 784{
784 int err = -EPROTONOSUPPORT; 785 int err = -EPROTONOSUPPORT;
785 786
@@ -808,8 +809,7 @@ mISDN_sock_create(struct net *net, struct socket *sock, int proto)
808 return err; 809 return err;
809} 810}
810 811
811static struct 812static const struct net_proto_family mISDN_sock_family_ops = {
812net_proto_family mISDN_sock_family_ops = {
813 .owner = THIS_MODULE, 813 .owner = THIS_MODULE,
814 .family = PF_ISDN, 814 .family = PF_ISDN,
815 .create = mISDN_sock_create, 815 .create = mISDN_sock_create,
diff --git a/drivers/isdn/mISDN/stack.c b/drivers/isdn/mISDN/stack.c
index 0d05ec43012c..b159bd59e64e 100644
--- a/drivers/isdn/mISDN/stack.c
+++ b/drivers/isdn/mISDN/stack.c
@@ -15,6 +15,7 @@
15 * 15 *
16 */ 16 */
17 17
18#include <linux/slab.h>
18#include <linux/mISDNif.h> 19#include <linux/mISDNif.h>
19#include <linux/kthread.h> 20#include <linux/kthread.h>
20#include <linux/smp_lock.h> 21#include <linux/smp_lock.h>
diff --git a/drivers/isdn/mISDN/tei.c b/drivers/isdn/mISDN/tei.c
index e04bad6c5baf..34e898fe2f4f 100644
--- a/drivers/isdn/mISDN/tei.c
+++ b/drivers/isdn/mISDN/tei.c
@@ -16,6 +16,7 @@
16 */ 16 */
17#include "layer2.h" 17#include "layer2.h"
18#include <linux/random.h> 18#include <linux/random.h>
19#include <linux/slab.h>
19#include "core.h" 20#include "core.h"
20 21
21#define ID_REQUEST 1 22#define ID_REQUEST 1
@@ -725,7 +726,7 @@ tei_id_ver_tout_net(struct FsmInst *fi, int event, void *arg)
725 if (tm->rcnt == 1) { 726 if (tm->rcnt == 1) {
726 if (*debug & DEBUG_L2_TEI) 727 if (*debug & DEBUG_L2_TEI)
727 tm->tei_m.printdebug(fi, 728 tm->tei_m.printdebug(fi,
728 "check req for tei %d sucessful\n", tm->l2->tei); 729 "check req for tei %d successful\n", tm->l2->tei);
729 mISDN_FsmChangeState(fi, ST_TEI_NOP); 730 mISDN_FsmChangeState(fi, ST_TEI_NOP);
730 } else if (tm->rcnt > 1) { 731 } else if (tm->rcnt > 1) {
731 /* duplicate assignment; remove */ 732 /* duplicate assignment; remove */
diff --git a/drivers/isdn/mISDN/timerdev.c b/drivers/isdn/mISDN/timerdev.c
index 5b7e9bf514f1..8785004e85e0 100644
--- a/drivers/isdn/mISDN/timerdev.c
+++ b/drivers/isdn/mISDN/timerdev.c
@@ -19,6 +19,7 @@
19 19
20#include <linux/poll.h> 20#include <linux/poll.h>
21#include <linux/vmalloc.h> 21#include <linux/vmalloc.h>
22#include <linux/slab.h>
22#include <linux/timer.h> 23#include <linux/timer.h>
23#include <linux/miscdevice.h> 24#include <linux/miscdevice.h>
24#include <linux/module.h> 25#include <linux/module.h>
diff --git a/drivers/isdn/pcbit/Kconfig b/drivers/isdn/pcbit/Kconfig
index ffba6eca1244..e9b2dd85d410 100644
--- a/drivers/isdn/pcbit/Kconfig
+++ b/drivers/isdn/pcbit/Kconfig
@@ -1,6 +1,3 @@
1#
2# Config.in for PCBIT ISDN driver
3#
4config ISDN_DRV_PCBIT 1config ISDN_DRV_PCBIT
5 tristate "PCBIT-D support" 2 tristate "PCBIT-D support"
6 depends on ISA && (BROKEN || X86) 3 depends on ISA && (BROKEN || X86)
@@ -11,4 +8,3 @@ config ISDN_DRV_PCBIT
11 the card using a utility which is distributed separately. See 8 the card using a utility which is distributed separately. See
12 <file:Documentation/isdn/README> and 9 <file:Documentation/isdn/README> and
13 <file:Documentation/isdn/README.pcbit> for more information. 10 <file:Documentation/isdn/README.pcbit> for more information.
14
diff --git a/drivers/isdn/pcbit/callbacks.c b/drivers/isdn/pcbit/callbacks.c
index 43ecd0f54235..976143b2346d 100644
--- a/drivers/isdn/pcbit/callbacks.c
+++ b/drivers/isdn/pcbit/callbacks.c
@@ -19,7 +19,6 @@
19#include <linux/kernel.h> 19#include <linux/kernel.h>
20 20
21#include <linux/types.h> 21#include <linux/types.h>
22#include <linux/slab.h>
23#include <linux/mm.h> 22#include <linux/mm.h>
24#include <linux/skbuff.h> 23#include <linux/skbuff.h>
25 24
diff --git a/drivers/isdn/pcbit/edss1.c b/drivers/isdn/pcbit/edss1.c
index 37e9626cebf6..d5920ae22d73 100644
--- a/drivers/isdn/pcbit/edss1.c
+++ b/drivers/isdn/pcbit/edss1.c
@@ -19,7 +19,6 @@
19#include <linux/kernel.h> 19#include <linux/kernel.h>
20 20
21#include <linux/types.h> 21#include <linux/types.h>
22#include <linux/slab.h>
23#include <linux/mm.h> 22#include <linux/mm.h>
24#include <linux/skbuff.h> 23#include <linux/skbuff.h>
25 24
diff --git a/drivers/isdn/sc/Kconfig b/drivers/isdn/sc/Kconfig
index e6510ca7bf43..7469863a7925 100644
--- a/drivers/isdn/sc/Kconfig
+++ b/drivers/isdn/sc/Kconfig
@@ -1,6 +1,3 @@
1#
2# Config.in for Spellcaster ISDN driver
3#
4config ISDN_DRV_SC 1config ISDN_DRV_SC
5 tristate "Spellcaster support" 2 tristate "Spellcaster support"
6 depends on ISA 3 depends on ISA
@@ -9,4 +6,3 @@ config ISDN_DRV_SC
9 driver currently builds only in a modularized version. 6 driver currently builds only in a modularized version.
10 To build it, choose M here: the module will be called sc. 7 To build it, choose M here: the module will be called sc.
11 See <file:Documentation/isdn/README.sc> for more information. 8 See <file:Documentation/isdn/README.sc> for more information.
12
diff --git a/drivers/isdn/sc/hardware.h b/drivers/isdn/sc/hardware.h
index 9e6d5302bf8e..627324856ead 100644
--- a/drivers/isdn/sc/hardware.h
+++ b/drivers/isdn/sc/hardware.h
@@ -87,7 +87,7 @@
87#define BRI_CHANNELS 2 /* Number of B channels */ 87#define BRI_CHANNELS 2 /* Number of B channels */
88#define BRI_BASEPG_VAL 0x98 88#define BRI_BASEPG_VAL 0x98
89#define BRI_MAGIC 0x60000 /* Magic Number */ 89#define BRI_MAGIC 0x60000 /* Magic Number */
90#define BRI_MEMSIZE 0x10000 /* Ammount of RAM (64K) */ 90#define BRI_MEMSIZE 0x10000 /* Amount of RAM (64K) */
91#define BRI_PARTNO "72-029" 91#define BRI_PARTNO "72-029"
92#define BRI_FEATURES ISDN_FEATURE_L2_HDLC | ISDN_FEATURE_L3_TRANS; 92#define BRI_FEATURES ISDN_FEATURE_L2_HDLC | ISDN_FEATURE_L3_TRANS;
93/* 93/*
diff --git a/drivers/isdn/sc/init.c b/drivers/isdn/sc/init.c
index 5a0774880d56..ca710ab278ec 100644
--- a/drivers/isdn/sc/init.c
+++ b/drivers/isdn/sc/init.c
@@ -9,6 +9,7 @@
9#include <linux/interrupt.h> 9#include <linux/interrupt.h>
10#include <linux/delay.h> 10#include <linux/delay.h>
11#include <linux/sched.h> 11#include <linux/sched.h>
12#include <linux/slab.h>
12#include "includes.h" 13#include "includes.h"
13#include "hardware.h" 14#include "hardware.h"
14#include "card.h" 15#include "card.h"