aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/isdn
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/isdn')
-rw-r--r--drivers/isdn/Kconfig43
-rw-r--r--drivers/isdn/capi/Kconfig16
-rw-r--r--drivers/isdn/capi/capi.c1203
-rw-r--r--drivers/isdn/capi/capidrv.c103
-rw-r--r--drivers/isdn/capi/capifs.c126
-rw-r--r--drivers/isdn/capi/capifs.h21
-rw-r--r--drivers/isdn/capi/kcapi.c817
-rw-r--r--drivers/isdn/capi/kcapi.h13
-rw-r--r--drivers/isdn/capi/kcapi_proc.c41
-rw-r--r--drivers/isdn/gigaset/asyncdata.c6
-rw-r--r--drivers/isdn/gigaset/bas-gigaset.c18
-rw-r--r--drivers/isdn/gigaset/capi.c106
-rw-r--r--drivers/isdn/gigaset/common.c49
-rw-r--r--drivers/isdn/gigaset/ev-layer.c63
-rw-r--r--drivers/isdn/gigaset/gigaset.h11
-rw-r--r--drivers/isdn/gigaset/i4l.c52
-rw-r--r--drivers/isdn/gigaset/interface.c12
-rw-r--r--drivers/isdn/gigaset/isocdata.c44
-rw-r--r--drivers/isdn/gigaset/proc.c2
-rw-r--r--drivers/isdn/gigaset/usb-gigaset.c2
-rw-r--r--drivers/isdn/hardware/avm/avmcard.h6
-rw-r--r--drivers/isdn/hardware/avm/b1.c54
-rw-r--r--drivers/isdn/hardware/avm/b1dma.c71
-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.c53
-rw-r--r--drivers/isdn/hardware/avm/t1isa.c2
-rw-r--r--drivers/isdn/hardware/avm/t1pci.c2
-rw-r--r--drivers/isdn/hardware/eicon/capimain.c40
-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/mISDN/hfcmulti.c2
-rw-r--r--drivers/isdn/hardware/mISDN/mISDNinfineon.c1
-rw-r--r--drivers/isdn/hardware/mISDN/w6692.c2
-rw-r--r--drivers/isdn/hisax/Kconfig18
-rw-r--r--drivers/isdn/hisax/avm_pci.c6
-rw-r--r--drivers/isdn/hisax/bkm_a4t.c2
-rw-r--r--drivers/isdn/hisax/bkm_a8.c2
-rw-r--r--drivers/isdn/hisax/diva.c14
-rw-r--r--drivers/isdn/hisax/elsa.c8
-rw-r--r--drivers/isdn/hisax/enternow_pci.c2
-rw-r--r--drivers/isdn/hisax/gazel.c8
-rw-r--r--drivers/isdn/hisax/hfc_pci.c2
-rw-r--r--drivers/isdn/hisax/hisax.h23
-rw-r--r--drivers/isdn/hisax/isar.c2
-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/telespci.c2
-rw-r--r--drivers/isdn/hisax/w6692.c2
-rw-r--r--drivers/isdn/hysdn/hycapi.c56
-rw-r--r--drivers/isdn/i4l/Kconfig7
55 files changed, 1727 insertions, 1723 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/capi/Kconfig b/drivers/isdn/capi/Kconfig
index b2a04755c96a..a168e8a891be 100644
--- a/drivers/isdn/capi/Kconfig
+++ b/drivers/isdn/capi/Kconfig
@@ -17,8 +17,7 @@ config CAPI_TRACE
17 If unsure, say Y. 17 If unsure, say Y.
18 18
19config ISDN_CAPI_MIDDLEWARE 19config ISDN_CAPI_MIDDLEWARE
20 bool "CAPI2.0 Middleware support (EXPERIMENTAL)" 20 bool "CAPI2.0 Middleware support"
21 depends on EXPERIMENTAL
22 help 21 help
23 This option will enhance the capabilities of the /dev/capi20 22 This option will enhance the capabilities of the /dev/capi20
24 interface. It will provide a means of moving a data connection, 23 interface. It will provide a means of moving a data connection,
@@ -35,18 +34,19 @@ config ISDN_CAPI_CAPI20
35 Y/M here. 34 Y/M here.
36 35
37config ISDN_CAPI_CAPIFS_BOOL 36config ISDN_CAPI_CAPIFS_BOOL
38 bool "CAPI2.0 filesystem support" 37 bool "CAPI2.0 filesystem support (DEPRECATED)"
39 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.
40 45
41config ISDN_CAPI_CAPIFS 46config ISDN_CAPI_CAPIFS
42 tristate 47 tristate
43 depends on ISDN_CAPI_CAPIFS_BOOL 48 depends on ISDN_CAPI_CAPIFS_BOOL
44 default ISDN_CAPI_CAPI20 49 default ISDN_CAPI_CAPI20
45 help
46 This option provides a special file system, similar to /dev/pts with
47 device nodes for the special ttys established by using the
48 middleware extension above. If you want to use pppd with
49 pppdcapiplugin to dial up to your ISP, say Y here.
50 50
51config ISDN_CAPI_CAPIDRV 51config ISDN_CAPI_CAPIDRV
52 tristate "CAPI2.0 capidrv interface support" 52 tristate "CAPI2.0 capidrv interface support"
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 66b7d7a86474..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");
@@ -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..8596bd1a4d26 100644
--- a/drivers/isdn/capi/capifs.c
+++ b/drivers/isdn/capi/capifs.c
@@ -25,14 +25,10 @@ MODULE_LICENSE("GPL");
25 25
26/* ------------------------------------------------------------------ */ 26/* ------------------------------------------------------------------ */
27 27
28static char *revision = "$Revision: 1.1.2.3 $";
29
30/* ------------------------------------------------------------------ */
31
32#define CAPIFS_SUPER_MAGIC (('C'<<8)|'N') 28#define CAPIFS_SUPER_MAGIC (('C'<<8)|'N')
33 29
34static struct vfsmount *capifs_mnt; 30static struct vfsmount *capifs_mnt;
35static struct dentry *capifs_root; 31static int capifs_mnt_count;
36 32
37static struct { 33static struct {
38 int setuid; 34 int setuid;
@@ -118,7 +114,7 @@ capifs_fill_super(struct super_block *s, void *data, int silent)
118 inode->i_fop = &simple_dir_operations; 114 inode->i_fop = &simple_dir_operations;
119 inode->i_nlink = 2; 115 inode->i_nlink = 2;
120 116
121 capifs_root = s->s_root = d_alloc_root(inode); 117 s->s_root = d_alloc_root(inode);
122 if (s->s_root) 118 if (s->s_root)
123 return 0; 119 return 0;
124 120
@@ -141,82 +137,98 @@ static struct file_system_type capifs_fs_type = {
141 .kill_sb = kill_anon_super, 137 .kill_sb = kill_anon_super,
142}; 138};
143 139
144static struct dentry *get_node(int num) 140static struct dentry *new_ncci(unsigned int number, dev_t device)
145{ 141{
146 char s[10]; 142 struct super_block *s = capifs_mnt->mnt_sb;
147 struct dentry *root = capifs_root; 143 struct dentry *root = s->s_root;
144 struct dentry *dentry;
145 struct inode *inode;
146 char name[10];
147 int namelen;
148
148 mutex_lock(&root->d_inode->i_mutex); 149 mutex_lock(&root->d_inode->i_mutex);
149 return lookup_one_len(s, root, sprintf(s, "%d", num));
150}
151 150
152void capifs_new_ncci(unsigned int number, dev_t device) 151 namelen = sprintf(name, "%d", number);
153{ 152 dentry = lookup_one_len(name, root, namelen);
154 struct dentry *dentry; 153 if (IS_ERR(dentry)) {
155 struct inode *inode = new_inode(capifs_mnt->mnt_sb); 154 dentry = NULL;
156 if (!inode) 155 goto unlock_out;
157 return; 156 }
158 inode->i_ino = number+2;
159 157
160 dentry = get_node(number); 158 if (dentry->d_inode) {
159 dput(dentry);
160 dentry = NULL;
161 goto unlock_out;
162 }
163
164 inode = new_inode(s);
165 if (!inode) {
166 dput(dentry);
167 dentry = NULL;
168 goto unlock_out;
169 }
161 170
162 /* config contents is protected by root's i_mutex */ 171 /* config contents is protected by root's i_mutex */
163 inode->i_uid = config.setuid ? config.uid : current_fsuid(); 172 inode->i_uid = config.setuid ? config.uid : current_fsuid();
164 inode->i_gid = config.setgid ? config.gid : current_fsgid(); 173 inode->i_gid = config.setgid ? config.gid : current_fsgid();
165 inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME; 174 inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME;
175 inode->i_ino = number + 2;
166 init_special_inode(inode, S_IFCHR|config.mode, device); 176 init_special_inode(inode, S_IFCHR|config.mode, device);
167 //inode->i_op = &capifs_file_inode_operations;
168 177
169 if (!IS_ERR(dentry) && !dentry->d_inode) 178 d_instantiate(dentry, inode);
170 d_instantiate(dentry, inode); 179 dget(dentry);
171 mutex_unlock(&capifs_root->d_inode->i_mutex); 180
181unlock_out:
182 mutex_unlock(&root->d_inode->i_mutex);
183
184 return dentry;
172} 185}
173 186
174void capifs_free_ncci(unsigned int number) 187struct dentry *capifs_new_ncci(unsigned int number, dev_t device)
175{ 188{
176 struct dentry *dentry = get_node(number); 189 struct dentry *dentry;
177 190
178 if (!IS_ERR(dentry)) { 191 if (simple_pin_fs(&capifs_fs_type, &capifs_mnt, &capifs_mnt_count) < 0)
179 struct inode *inode = dentry->d_inode; 192 return NULL;
180 if (inode) { 193
181 inode->i_nlink--; 194 dentry = new_ncci(number, device);
182 d_delete(dentry); 195 if (!dentry)
183 dput(dentry); 196 simple_release_fs(&capifs_mnt, &capifs_mnt_count);
184 } 197
198 return dentry;
199}
200
201void capifs_free_ncci(struct dentry *dentry)
202{
203 struct dentry *root = capifs_mnt->mnt_sb->s_root;
204 struct inode *inode;
205
206 if (!dentry)
207 return;
208
209 mutex_lock(&root->d_inode->i_mutex);
210
211 inode = dentry->d_inode;
212 if (inode) {
213 drop_nlink(inode);
214 d_delete(dentry);
185 dput(dentry); 215 dput(dentry);
186 } 216 }
187 mutex_unlock(&capifs_root->d_inode->i_mutex); 217 dput(dentry);
218
219 mutex_unlock(&root->d_inode->i_mutex);
220
221 simple_release_fs(&capifs_mnt, &capifs_mnt_count);
188} 222}
189 223
190static int __init capifs_init(void) 224static int __init capifs_init(void)
191{ 225{
192 char rev[32]; 226 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} 227}
215 228
216static void __exit capifs_exit(void) 229static void __exit capifs_exit(void)
217{ 230{
218 unregister_filesystem(&capifs_fs_type); 231 unregister_filesystem(&capifs_fs_type);
219 mntput(capifs_mnt);
220} 232}
221 233
222EXPORT_SYMBOL(capifs_new_ncci); 234EXPORT_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/kcapi.c b/drivers/isdn/capi/kcapi.c
index dc506ab99cac..ce9b05b9e93a 100644
--- a/drivers/isdn/capi/kcapi.c
+++ b/drivers/isdn/capi/kcapi.c
@@ -34,10 +34,7 @@
34#include <linux/b1lli.h> 34#include <linux/b1lli.h>
35#endif 35#endif
36#include <linux/mutex.h> 36#include <linux/mutex.h>
37 37#include <linux/rcupdate.h>
38static char *revision = "$Revision: 1.1.2.8 $";
39
40/* ------------------------------------------------------------- */
41 38
42static int showcapimsgs = 0; 39static int showcapimsgs = 0;
43 40
@@ -48,12 +45,10 @@ module_param(showcapimsgs, uint, 0);
48 45
49/* ------------------------------------------------------------- */ 46/* ------------------------------------------------------------- */
50 47
51struct capi_notifier { 48struct capictr_event {
52 struct work_struct work; 49 struct work_struct work;
53 unsigned int cmd; 50 unsigned int type;
54 u32 controller; 51 u32 controller;
55 u16 applid;
56 u32 ncci;
57}; 52};
58 53
59/* ------------------------------------------------------------- */ 54/* ------------------------------------------------------------- */
@@ -65,30 +60,31 @@ static char capi_manufakturer[64] = "AVM Berlin";
65#define NCCI2CTRL(ncci) (((ncci) >> 24) & 0x7f) 60#define NCCI2CTRL(ncci) (((ncci) >> 24) & 0x7f)
66 61
67LIST_HEAD(capi_drivers); 62LIST_HEAD(capi_drivers);
68DEFINE_RWLOCK(capi_drivers_list_lock); 63DEFINE_MUTEX(capi_drivers_lock);
69 64
70static DEFINE_RWLOCK(application_lock); 65struct capi_ctr *capi_controller[CAPI_MAXCONTR];
71static DEFINE_MUTEX(controller_mutex); 66DEFINE_MUTEX(capi_controller_lock);
72 67
73struct capi20_appl *capi_applications[CAPI_MAXAPPL]; 68struct capi20_appl *capi_applications[CAPI_MAXAPPL];
74struct capi_ctr *capi_cards[CAPI_MAXCONTR];
75 69
76static int ncards; 70static int ncontrollers;
71
72static BLOCKING_NOTIFIER_HEAD(ctr_notifier_list);
77 73
78/* -------- controller ref counting -------------------------------------- */ 74/* -------- controller ref counting -------------------------------------- */
79 75
80static inline struct capi_ctr * 76static inline struct capi_ctr *
81capi_ctr_get(struct capi_ctr *card) 77capi_ctr_get(struct capi_ctr *ctr)
82{ 78{
83 if (!try_module_get(card->owner)) 79 if (!try_module_get(ctr->owner))
84 return NULL; 80 return NULL;
85 return card; 81 return ctr;
86} 82}
87 83
88static inline void 84static inline void
89capi_ctr_put(struct capi_ctr *card) 85capi_ctr_put(struct capi_ctr *ctr)
90{ 86{
91 module_put(card->owner); 87 module_put(ctr->owner);
92} 88}
93 89
94/* ------------------------------------------------------------- */ 90/* ------------------------------------------------------------- */
@@ -98,7 +94,7 @@ static inline struct capi_ctr *get_capi_ctr_by_nr(u16 contr)
98 if (contr - 1 >= CAPI_MAXCONTR) 94 if (contr - 1 >= CAPI_MAXCONTR)
99 return NULL; 95 return NULL;
100 96
101 return capi_cards[contr - 1]; 97 return capi_controller[contr - 1];
102} 98}
103 99
104static inline struct capi20_appl *get_capi_appl_by_nr(u16 applid) 100static inline struct capi20_appl *get_capi_appl_by_nr(u16 applid)
@@ -106,7 +102,7 @@ static inline struct capi20_appl *get_capi_appl_by_nr(u16 applid)
106 if (applid - 1 >= CAPI_MAXAPPL) 102 if (applid - 1 >= CAPI_MAXAPPL)
107 return NULL; 103 return NULL;
108 104
109 return capi_applications[applid - 1]; 105 return rcu_dereference(capi_applications[applid - 1]);
110} 106}
111 107
112/* -------- util functions ------------------------------------ */ 108/* -------- util functions ------------------------------------ */
@@ -148,106 +144,159 @@ static inline int capi_subcmd_valid(u8 subcmd)
148 144
149/* ------------------------------------------------------------ */ 145/* ------------------------------------------------------------ */
150 146
151static void register_appl(struct capi_ctr *card, u16 applid, capi_register_params *rparam) 147static void
148register_appl(struct capi_ctr *ctr, u16 applid, capi_register_params *rparam)
152{ 149{
153 card = capi_ctr_get(card); 150 ctr = capi_ctr_get(ctr);
154 151
155 if (card) 152 if (ctr)
156 card->register_appl(card, applid, rparam); 153 ctr->register_appl(ctr, applid, rparam);
157 else 154 else
158 printk(KERN_WARNING "%s: cannot get card resources\n", __func__); 155 printk(KERN_WARNING "%s: cannot get controller resources\n",
156 __func__);
159} 157}
160 158
161 159
162static void release_appl(struct capi_ctr *card, u16 applid) 160static void release_appl(struct capi_ctr *ctr, u16 applid)
163{ 161{
164 DBG("applid %#x", applid); 162 DBG("applid %#x", applid);
165 163
166 card->release_appl(card, applid); 164 ctr->release_appl(ctr, applid);
167 capi_ctr_put(card); 165 capi_ctr_put(ctr);
168} 166}
169 167
170/* -------- KCI_CONTRUP --------------------------------------- */
171
172static void notify_up(u32 contr) 168static void notify_up(u32 contr)
173{ 169{
174 struct capi_ctr *card = get_capi_ctr_by_nr(contr);
175 struct capi20_appl *ap; 170 struct capi20_appl *ap;
171 struct capi_ctr *ctr;
176 u16 applid; 172 u16 applid;
177 173
178 if (showcapimsgs & 1) { 174 mutex_lock(&capi_controller_lock);
175
176 if (showcapimsgs & 1)
179 printk(KERN_DEBUG "kcapi: notify up contr %d\n", contr); 177 printk(KERN_DEBUG "kcapi: notify up contr %d\n", contr);
180 } 178
181 if (!card) { 179 ctr = get_capi_ctr_by_nr(contr);
180 if (ctr) {
181 if (ctr->state == CAPI_CTR_RUNNING)
182 goto unlock_out;
183
184 ctr->state = CAPI_CTR_RUNNING;
185
186 for (applid = 1; applid <= CAPI_MAXAPPL; applid++) {
187 ap = get_capi_appl_by_nr(applid);
188 if (!ap)
189 continue;
190 register_appl(ctr, applid, &ap->rparam);
191 }
192
193 wake_up_interruptible_all(&ctr->state_wait_queue);
194 } else
182 printk(KERN_WARNING "%s: invalid contr %d\n", __func__, contr); 195 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 196
194/* -------- KCI_CONTRDOWN ------------------------------------- */ 197unlock_out:
198 mutex_unlock(&capi_controller_lock);
199}
195 200
196static void notify_down(u32 contr) 201static void ctr_down(struct capi_ctr *ctr, int new_state)
197{ 202{
198 struct capi20_appl *ap; 203 struct capi20_appl *ap;
199 u16 applid; 204 u16 applid;
200 205
201 if (showcapimsgs & 1) { 206 if (ctr->state == CAPI_CTR_DETECTED || ctr->state == CAPI_CTR_DETACHED)
202 printk(KERN_DEBUG "kcapi: notify down contr %d\n", contr); 207 return;
203 } 208
209 ctr->state = new_state;
210
211 memset(ctr->manu, 0, sizeof(ctr->manu));
212 memset(&ctr->version, 0, sizeof(ctr->version));
213 memset(&ctr->profile, 0, sizeof(ctr->profile));
214 memset(ctr->serial, 0, sizeof(ctr->serial));
204 215
205 for (applid = 1; applid <= CAPI_MAXAPPL; applid++) { 216 for (applid = 1; applid <= CAPI_MAXAPPL; applid++) {
206 ap = get_capi_appl_by_nr(applid); 217 ap = get_capi_appl_by_nr(applid);
207 if (ap && ap->callback && !ap->release_in_progress) 218 if (ap)
208 ap->callback(KCI_CONTRDOWN, contr, NULL); 219 capi_ctr_put(ctr);
209 } 220 }
221
222 wake_up_interruptible_all(&ctr->state_wait_queue);
210} 223}
211 224
212static void notify_handler(struct work_struct *work) 225static void notify_down(u32 contr)
213{ 226{
214 struct capi_notifier *np = 227 struct capi_ctr *ctr;
215 container_of(work, struct capi_notifier, work);
216 228
217 switch (np->cmd) { 229 mutex_lock(&capi_controller_lock);
218 case KCI_CONTRUP: 230
219 notify_up(np->controller); 231 if (showcapimsgs & 1)
232 printk(KERN_DEBUG "kcapi: notify down contr %d\n", contr);
233
234 ctr = get_capi_ctr_by_nr(contr);
235 if (ctr)
236 ctr_down(ctr, CAPI_CTR_DETECTED);
237 else
238 printk(KERN_WARNING "%s: invalid contr %d\n", __func__, contr);
239
240 mutex_unlock(&capi_controller_lock);
241}
242
243static int
244notify_handler(struct notifier_block *nb, unsigned long val, void *v)
245{
246 u32 contr = (long)v;
247
248 switch (val) {
249 case CAPICTR_UP:
250 notify_up(contr);
220 break; 251 break;
221 case KCI_CONTRDOWN: 252 case CAPICTR_DOWN:
222 notify_down(np->controller); 253 notify_down(contr);
223 break; 254 break;
224 } 255 }
256 return NOTIFY_OK;
257}
258
259static void do_notify_work(struct work_struct *work)
260{
261 struct capictr_event *event =
262 container_of(work, struct capictr_event, work);
225 263
226 kfree(np); 264 blocking_notifier_call_chain(&ctr_notifier_list, event->type,
265 (void *)(long)event->controller);
266 kfree(event);
227} 267}
228 268
229/* 269/*
230 * The notifier will result in adding/deleteing of devices. Devices can 270 * The notifier will result in adding/deleteing of devices. Devices can
231 * only removed in user process, not in bh. 271 * only removed in user process, not in bh.
232 */ 272 */
233static int notify_push(unsigned int cmd, u32 controller, u16 applid, u32 ncci) 273static int notify_push(unsigned int event_type, u32 controller)
234{ 274{
235 struct capi_notifier *np = kmalloc(sizeof(*np), GFP_ATOMIC); 275 struct capictr_event *event = kmalloc(sizeof(*event), GFP_ATOMIC);
236 276
237 if (!np) 277 if (!event)
238 return -ENOMEM; 278 return -ENOMEM;
239 279
240 INIT_WORK(&np->work, notify_handler); 280 INIT_WORK(&event->work, do_notify_work);
241 np->cmd = cmd; 281 event->type = event_type;
242 np->controller = controller; 282 event->controller = controller;
243 np->applid = applid;
244 np->ncci = ncci;
245 283
246 schedule_work(&np->work); 284 schedule_work(&event->work);
247 return 0; 285 return 0;
248} 286}
249 287
250 288int register_capictr_notifier(struct notifier_block *nb)
289{
290 return blocking_notifier_chain_register(&ctr_notifier_list, nb);
291}
292EXPORT_SYMBOL_GPL(register_capictr_notifier);
293
294int unregister_capictr_notifier(struct notifier_block *nb)
295{
296 return blocking_notifier_chain_unregister(&ctr_notifier_list, nb);
297}
298EXPORT_SYMBOL_GPL(unregister_capictr_notifier);
299
251/* -------- Receiver ------------------------------------------ */ 300/* -------- Receiver ------------------------------------------ */
252 301
253static void recv_handler(struct work_struct *work) 302static void recv_handler(struct work_struct *work)
@@ -273,68 +322,70 @@ static void recv_handler(struct work_struct *work)
273 322
274/** 323/**
275 * capi_ctr_handle_message() - handle incoming CAPI message 324 * capi_ctr_handle_message() - handle incoming CAPI message
276 * @card: controller descriptor structure. 325 * @ctr: controller descriptor structure.
277 * @appl: application ID. 326 * @appl: application ID.
278 * @skb: message. 327 * @skb: message.
279 * 328 *
280 * Called by hardware driver to pass a CAPI message to the application. 329 * Called by hardware driver to pass a CAPI message to the application.
281 */ 330 */
282 331
283void capi_ctr_handle_message(struct capi_ctr * card, u16 appl, struct sk_buff *skb) 332void capi_ctr_handle_message(struct capi_ctr *ctr, u16 appl,
333 struct sk_buff *skb)
284{ 334{
285 struct capi20_appl *ap; 335 struct capi20_appl *ap;
286 int showctl = 0; 336 int showctl = 0;
287 u8 cmd, subcmd; 337 u8 cmd, subcmd;
288 unsigned long flags;
289 _cdebbuf *cdb; 338 _cdebbuf *cdb;
290 339
291 if (card->cardstate != CARD_RUNNING) { 340 if (ctr->state != CAPI_CTR_RUNNING) {
292 cdb = capi_message2str(skb->data); 341 cdb = capi_message2str(skb->data);
293 if (cdb) { 342 if (cdb) {
294 printk(KERN_INFO "kcapi: controller [%03d] not active, got: %s", 343 printk(KERN_INFO "kcapi: controller [%03d] not active, got: %s",
295 card->cnr, cdb->buf); 344 ctr->cnr, cdb->buf);
296 cdebbuf_free(cdb); 345 cdebbuf_free(cdb);
297 } else 346 } else
298 printk(KERN_INFO "kcapi: controller [%03d] not active, cannot trace\n", 347 printk(KERN_INFO "kcapi: controller [%03d] not active, cannot trace\n",
299 card->cnr); 348 ctr->cnr);
300 goto error; 349 goto error;
301 } 350 }
302 351
303 cmd = CAPIMSG_COMMAND(skb->data); 352 cmd = CAPIMSG_COMMAND(skb->data);
304 subcmd = CAPIMSG_SUBCOMMAND(skb->data); 353 subcmd = CAPIMSG_SUBCOMMAND(skb->data);
305 if (cmd == CAPI_DATA_B3 && subcmd == CAPI_IND) { 354 if (cmd == CAPI_DATA_B3 && subcmd == CAPI_IND) {
306 card->nrecvdatapkt++; 355 ctr->nrecvdatapkt++;
307 if (card->traceflag > 2) showctl |= 2; 356 if (ctr->traceflag > 2)
357 showctl |= 2;
308 } else { 358 } else {
309 card->nrecvctlpkt++; 359 ctr->nrecvctlpkt++;
310 if (card->traceflag) showctl |= 2; 360 if (ctr->traceflag)
361 showctl |= 2;
311 } 362 }
312 showctl |= (card->traceflag & 1); 363 showctl |= (ctr->traceflag & 1);
313 if (showctl & 2) { 364 if (showctl & 2) {
314 if (showctl & 1) { 365 if (showctl & 1) {
315 printk(KERN_DEBUG "kcapi: got [%03d] id#%d %s len=%u\n", 366 printk(KERN_DEBUG "kcapi: got [%03d] id#%d %s len=%u\n",
316 card->cnr, CAPIMSG_APPID(skb->data), 367 ctr->cnr, CAPIMSG_APPID(skb->data),
317 capi_cmd2str(cmd, subcmd), 368 capi_cmd2str(cmd, subcmd),
318 CAPIMSG_LEN(skb->data)); 369 CAPIMSG_LEN(skb->data));
319 } else { 370 } else {
320 cdb = capi_message2str(skb->data); 371 cdb = capi_message2str(skb->data);
321 if (cdb) { 372 if (cdb) {
322 printk(KERN_DEBUG "kcapi: got [%03d] %s\n", 373 printk(KERN_DEBUG "kcapi: got [%03d] %s\n",
323 card->cnr, cdb->buf); 374 ctr->cnr, cdb->buf);
324 cdebbuf_free(cdb); 375 cdebbuf_free(cdb);
325 } else 376 } else
326 printk(KERN_DEBUG "kcapi: got [%03d] id#%d %s len=%u, cannot trace\n", 377 printk(KERN_DEBUG "kcapi: got [%03d] id#%d %s len=%u, cannot trace\n",
327 card->cnr, CAPIMSG_APPID(skb->data), 378 ctr->cnr, CAPIMSG_APPID(skb->data),
328 capi_cmd2str(cmd, subcmd), 379 capi_cmd2str(cmd, subcmd),
329 CAPIMSG_LEN(skb->data)); 380 CAPIMSG_LEN(skb->data));
330 } 381 }
331 382
332 } 383 }
333 384
334 read_lock_irqsave(&application_lock, flags); 385 rcu_read_lock();
335 ap = get_capi_appl_by_nr(CAPIMSG_APPID(skb->data)); 386 ap = get_capi_appl_by_nr(CAPIMSG_APPID(skb->data));
336 if ((!ap) || (ap->release_in_progress)) { 387 if (!ap) {
337 read_unlock_irqrestore(&application_lock, flags); 388 rcu_read_unlock();
338 cdb = capi_message2str(skb->data); 389 cdb = capi_message2str(skb->data);
339 if (cdb) { 390 if (cdb) {
340 printk(KERN_ERR "kcapi: handle_message: applid %d state released (%s)\n", 391 printk(KERN_ERR "kcapi: handle_message: applid %d state released (%s)\n",
@@ -348,7 +399,7 @@ void capi_ctr_handle_message(struct capi_ctr * card, u16 appl, struct sk_buff *s
348 } 399 }
349 skb_queue_tail(&ap->recv_queue, skb); 400 skb_queue_tail(&ap->recv_queue, skb);
350 schedule_work(&ap->recv_work); 401 schedule_work(&ap->recv_work);
351 read_unlock_irqrestore(&application_lock, flags); 402 rcu_read_unlock();
352 403
353 return; 404 return;
354 405
@@ -360,74 +411,54 @@ EXPORT_SYMBOL(capi_ctr_handle_message);
360 411
361/** 412/**
362 * capi_ctr_ready() - signal CAPI controller ready 413 * capi_ctr_ready() - signal CAPI controller ready
363 * @card: controller descriptor structure. 414 * @ctr: controller descriptor structure.
364 * 415 *
365 * Called by hardware driver to signal that the controller is up and running. 416 * Called by hardware driver to signal that the controller is up and running.
366 */ 417 */
367 418
368void capi_ctr_ready(struct capi_ctr * card) 419void capi_ctr_ready(struct capi_ctr *ctr)
369{ 420{
370 card->cardstate = CARD_RUNNING; 421 printk(KERN_NOTICE "kcapi: controller [%03d] \"%s\" ready.\n",
371 422 ctr->cnr, ctr->name);
372 printk(KERN_NOTICE "kcapi: card [%03d] \"%s\" ready.\n",
373 card->cnr, card->name);
374 423
375 notify_push(KCI_CONTRUP, card->cnr, 0, 0); 424 notify_push(CAPICTR_UP, ctr->cnr);
376} 425}
377 426
378EXPORT_SYMBOL(capi_ctr_ready); 427EXPORT_SYMBOL(capi_ctr_ready);
379 428
380/** 429/**
381 * capi_ctr_down() - signal CAPI controller not ready 430 * capi_ctr_down() - signal CAPI controller not ready
382 * @card: controller descriptor structure. 431 * @ctr: controller descriptor structure.
383 * 432 *
384 * Called by hardware driver to signal that the controller is down and 433 * Called by hardware driver to signal that the controller is down and
385 * unavailable for use. 434 * unavailable for use.
386 */ 435 */
387 436
388void capi_ctr_down(struct capi_ctr * card) 437void capi_ctr_down(struct capi_ctr *ctr)
389{ 438{
390 u16 appl; 439 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 440
414 notify_push(KCI_CONTRDOWN, card->cnr, 0, 0); 441 notify_push(CAPICTR_DOWN, ctr->cnr);
415} 442}
416 443
417EXPORT_SYMBOL(capi_ctr_down); 444EXPORT_SYMBOL(capi_ctr_down);
418 445
419/** 446/**
420 * capi_ctr_suspend_output() - suspend controller 447 * capi_ctr_suspend_output() - suspend controller
421 * @card: controller descriptor structure. 448 * @ctr: controller descriptor structure.
422 * 449 *
423 * Called by hardware driver to stop data flow. 450 * Called by hardware driver to stop data flow.
451 *
452 * Note: The caller is responsible for synchronizing concurrent state changes
453 * as well as invocations of capi_ctr_handle_message.
424 */ 454 */
425 455
426void capi_ctr_suspend_output(struct capi_ctr *card) 456void capi_ctr_suspend_output(struct capi_ctr *ctr)
427{ 457{
428 if (!card->blocked) { 458 if (!ctr->blocked) {
429 printk(KERN_DEBUG "kcapi: card [%03d] suspend\n", card->cnr); 459 printk(KERN_DEBUG "kcapi: controller [%03d] suspend\n",
430 card->blocked = 1; 460 ctr->cnr);
461 ctr->blocked = 1;
431 } 462 }
432} 463}
433 464
@@ -435,16 +466,20 @@ EXPORT_SYMBOL(capi_ctr_suspend_output);
435 466
436/** 467/**
437 * capi_ctr_resume_output() - resume controller 468 * capi_ctr_resume_output() - resume controller
438 * @card: controller descriptor structure. 469 * @ctr: controller descriptor structure.
439 * 470 *
440 * Called by hardware driver to resume data flow. 471 * Called by hardware driver to resume data flow.
472 *
473 * Note: The caller is responsible for synchronizing concurrent state changes
474 * as well as invocations of capi_ctr_handle_message.
441 */ 475 */
442 476
443void capi_ctr_resume_output(struct capi_ctr *card) 477void capi_ctr_resume_output(struct capi_ctr *ctr)
444{ 478{
445 if (card->blocked) { 479 if (ctr->blocked) {
446 printk(KERN_DEBUG "kcapi: card [%03d] resume\n", card->cnr); 480 printk(KERN_DEBUG "kcapi: controller [%03d] resumed\n",
447 card->blocked = 0; 481 ctr->cnr);
482 ctr->blocked = 0;
448 } 483 }
449} 484}
450 485
@@ -454,53 +489,48 @@ EXPORT_SYMBOL(capi_ctr_resume_output);
454 489
455/** 490/**
456 * attach_capi_ctr() - register CAPI controller 491 * attach_capi_ctr() - register CAPI controller
457 * @card: controller descriptor structure. 492 * @ctr: controller descriptor structure.
458 * 493 *
459 * Called by hardware driver to register a controller with the CAPI subsystem. 494 * Called by hardware driver to register a controller with the CAPI subsystem.
460 * Return value: 0 on success, error code < 0 on error 495 * Return value: 0 on success, error code < 0 on error
461 */ 496 */
462 497
463int 498int attach_capi_ctr(struct capi_ctr *ctr)
464attach_capi_ctr(struct capi_ctr *card)
465{ 499{
466 int i; 500 int i;
467 501
468 mutex_lock(&controller_mutex); 502 mutex_lock(&capi_controller_lock);
469 503
470 for (i = 0; i < CAPI_MAXCONTR; i++) { 504 for (i = 0; i < CAPI_MAXCONTR; i++) {
471 if (capi_cards[i] == NULL) 505 if (!capi_controller[i])
472 break; 506 break;
473 } 507 }
474 if (i == CAPI_MAXCONTR) { 508 if (i == CAPI_MAXCONTR) {
475 mutex_unlock(&controller_mutex); 509 mutex_unlock(&capi_controller_lock);
476 printk(KERN_ERR "kcapi: out of controller slots\n"); 510 printk(KERN_ERR "kcapi: out of controller slots\n");
477 return -EBUSY; 511 return -EBUSY;
478 } 512 }
479 capi_cards[i] = card; 513 capi_controller[i] = ctr;
480 514
481 mutex_unlock(&controller_mutex); 515 ctr->nrecvctlpkt = 0;
482 516 ctr->nrecvdatapkt = 0;
483 card->nrecvctlpkt = 0; 517 ctr->nsentctlpkt = 0;
484 card->nrecvdatapkt = 0; 518 ctr->nsentdatapkt = 0;
485 card->nsentctlpkt = 0; 519 ctr->cnr = i + 1;
486 card->nsentdatapkt = 0; 520 ctr->state = CAPI_CTR_DETECTED;
487 card->cnr = i + 1; 521 ctr->blocked = 0;
488 card->cardstate = CARD_DETECTED; 522 ctr->traceflag = showcapimsgs;
489 card->blocked = 0; 523 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 524
501 ncards++; 525 sprintf(ctr->procfn, "capi/controllers/%d", ctr->cnr);
502 printk(KERN_NOTICE "kcapi: Controller [%03d]: %s attached\n", 526 ctr->procent = proc_create_data(ctr->procfn, 0, NULL, ctr->proc_fops, ctr);
503 card->cnr, card->name); 527
528 ncontrollers++;
529
530 mutex_unlock(&capi_controller_lock);
531
532 printk(KERN_NOTICE "kcapi: controller [%03d]: %s attached\n",
533 ctr->cnr, ctr->name);
504 return 0; 534 return 0;
505} 535}
506 536
@@ -508,29 +538,38 @@ EXPORT_SYMBOL(attach_capi_ctr);
508 538
509/** 539/**
510 * detach_capi_ctr() - unregister CAPI controller 540 * detach_capi_ctr() - unregister CAPI controller
511 * @card: controller descriptor structure. 541 * @ctr: controller descriptor structure.
512 * 542 *
513 * Called by hardware driver to remove the registration of a controller 543 * Called by hardware driver to remove the registration of a controller
514 * with the CAPI subsystem. 544 * with the CAPI subsystem.
515 * Return value: 0 on success, error code < 0 on error 545 * Return value: 0 on success, error code < 0 on error
516 */ 546 */
517 547
518int detach_capi_ctr(struct capi_ctr *card) 548int detach_capi_ctr(struct capi_ctr *ctr)
519{ 549{
520 if (card->cardstate != CARD_DETECTED) 550 int err = 0;
521 capi_ctr_down(card);
522 551
523 ncards--; 552 mutex_lock(&capi_controller_lock);
524 553
525 if (card->procent) { 554 ctr_down(ctr, CAPI_CTR_DETACHED);
526 remove_proc_entry(card->procfn, NULL); 555
527 card->procent = NULL; 556 if (capi_controller[ctr->cnr - 1] != ctr) {
557 err = -EINVAL;
558 goto unlock_out;
528 } 559 }
529 capi_cards[card->cnr - 1] = NULL; 560 capi_controller[ctr->cnr - 1] = NULL;
530 printk(KERN_NOTICE "kcapi: Controller [%03d]: %s unregistered\n", 561 ncontrollers--;
531 card->cnr, card->name);
532 562
533 return 0; 563 if (ctr->procent)
564 remove_proc_entry(ctr->procfn, NULL);
565
566 printk(KERN_NOTICE "kcapi: controller [%03d]: %s unregistered\n",
567 ctr->cnr, ctr->name);
568
569unlock_out:
570 mutex_unlock(&capi_controller_lock);
571
572 return err;
534} 573}
535 574
536EXPORT_SYMBOL(detach_capi_ctr); 575EXPORT_SYMBOL(detach_capi_ctr);
@@ -544,11 +583,9 @@ EXPORT_SYMBOL(detach_capi_ctr);
544 583
545void register_capi_driver(struct capi_driver *driver) 584void register_capi_driver(struct capi_driver *driver)
546{ 585{
547 unsigned long flags; 586 mutex_lock(&capi_drivers_lock);
548
549 write_lock_irqsave(&capi_drivers_list_lock, flags);
550 list_add_tail(&driver->list, &capi_drivers); 587 list_add_tail(&driver->list, &capi_drivers);
551 write_unlock_irqrestore(&capi_drivers_list_lock, flags); 588 mutex_unlock(&capi_drivers_lock);
552} 589}
553 590
554EXPORT_SYMBOL(register_capi_driver); 591EXPORT_SYMBOL(register_capi_driver);
@@ -562,11 +599,9 @@ EXPORT_SYMBOL(register_capi_driver);
562 599
563void unregister_capi_driver(struct capi_driver *driver) 600void unregister_capi_driver(struct capi_driver *driver)
564{ 601{
565 unsigned long flags; 602 mutex_lock(&capi_drivers_lock);
566
567 write_lock_irqsave(&capi_drivers_list_lock, flags);
568 list_del(&driver->list); 603 list_del(&driver->list);
569 write_unlock_irqrestore(&capi_drivers_list_lock, flags); 604 mutex_unlock(&capi_drivers_lock);
570} 605}
571 606
572EXPORT_SYMBOL(unregister_capi_driver); 607EXPORT_SYMBOL(unregister_capi_driver);
@@ -584,12 +619,21 @@ EXPORT_SYMBOL(unregister_capi_driver);
584 619
585u16 capi20_isinstalled(void) 620u16 capi20_isinstalled(void)
586{ 621{
622 u16 ret = CAPI_REGNOTINSTALLED;
587 int i; 623 int i;
588 for (i = 0; i < CAPI_MAXCONTR; i++) { 624
589 if (capi_cards[i] && capi_cards[i]->cardstate == CARD_RUNNING) 625 mutex_lock(&capi_controller_lock);
590 return CAPI_NOERROR; 626
591 } 627 for (i = 0; i < CAPI_MAXCONTR; i++)
592 return CAPI_REGNOTINSTALLED; 628 if (capi_controller[i] &&
629 capi_controller[i]->state == CAPI_CTR_RUNNING) {
630 ret = CAPI_NOERROR;
631 break;
632 }
633
634 mutex_unlock(&capi_controller_lock);
635
636 return ret;
593} 637}
594 638
595EXPORT_SYMBOL(capi20_isinstalled); 639EXPORT_SYMBOL(capi20_isinstalled);
@@ -610,46 +654,43 @@ u16 capi20_register(struct capi20_appl *ap)
610{ 654{
611 int i; 655 int i;
612 u16 applid; 656 u16 applid;
613 unsigned long flags;
614 657
615 DBG(""); 658 DBG("");
616 659
617 if (ap->rparam.datablklen < 128) 660 if (ap->rparam.datablklen < 128)
618 return CAPI_LOGBLKSIZETOSMALL; 661 return CAPI_LOGBLKSIZETOSMALL;
619 662
620 write_lock_irqsave(&application_lock, flags); 663 ap->nrecvctlpkt = 0;
664 ap->nrecvdatapkt = 0;
665 ap->nsentctlpkt = 0;
666 ap->nsentdatapkt = 0;
667 mutex_init(&ap->recv_mtx);
668 skb_queue_head_init(&ap->recv_queue);
669 INIT_WORK(&ap->recv_work, recv_handler);
670 ap->release_in_progress = 0;
671
672 mutex_lock(&capi_controller_lock);
621 673
622 for (applid = 1; applid <= CAPI_MAXAPPL; applid++) { 674 for (applid = 1; applid <= CAPI_MAXAPPL; applid++) {
623 if (capi_applications[applid - 1] == NULL) 675 if (capi_applications[applid - 1] == NULL)
624 break; 676 break;
625 } 677 }
626 if (applid > CAPI_MAXAPPL) { 678 if (applid > CAPI_MAXAPPL) {
627 write_unlock_irqrestore(&application_lock, flags); 679 mutex_unlock(&capi_controller_lock);
628 return CAPI_TOOMANYAPPLS; 680 return CAPI_TOOMANYAPPLS;
629 } 681 }
630 682
631 ap->applid = applid; 683 ap->applid = applid;
632 capi_applications[applid - 1] = ap; 684 capi_applications[applid - 1] = ap;
633 685
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++) { 686 for (i = 0; i < CAPI_MAXCONTR; i++) {
648 if (!capi_cards[i] || capi_cards[i]->cardstate != CARD_RUNNING) 687 if (!capi_controller[i] ||
688 capi_controller[i]->state != CAPI_CTR_RUNNING)
649 continue; 689 continue;
650 register_appl(capi_cards[i], applid, &ap->rparam); 690 register_appl(capi_controller[i], applid, &ap->rparam);
651 } 691 }
652 mutex_unlock(&controller_mutex); 692
693 mutex_unlock(&capi_controller_lock);
653 694
654 if (showcapimsgs & 1) { 695 if (showcapimsgs & 1) {
655 printk(KERN_DEBUG "kcapi: appl %d up\n", applid); 696 printk(KERN_DEBUG "kcapi: appl %d up\n", applid);
@@ -673,22 +714,24 @@ EXPORT_SYMBOL(capi20_register);
673u16 capi20_release(struct capi20_appl *ap) 714u16 capi20_release(struct capi20_appl *ap)
674{ 715{
675 int i; 716 int i;
676 unsigned long flags;
677 717
678 DBG("applid %#x", ap->applid); 718 DBG("applid %#x", ap->applid);
679 719
680 write_lock_irqsave(&application_lock, flags); 720 mutex_lock(&capi_controller_lock);
721
681 ap->release_in_progress = 1; 722 ap->release_in_progress = 1;
682 capi_applications[ap->applid - 1] = NULL; 723 capi_applications[ap->applid - 1] = NULL;
683 write_unlock_irqrestore(&application_lock, flags);
684 724
685 mutex_lock(&controller_mutex); 725 synchronize_rcu();
726
686 for (i = 0; i < CAPI_MAXCONTR; i++) { 727 for (i = 0; i < CAPI_MAXCONTR; i++) {
687 if (!capi_cards[i] || capi_cards[i]->cardstate != CARD_RUNNING) 728 if (!capi_controller[i] ||
729 capi_controller[i]->state != CAPI_CTR_RUNNING)
688 continue; 730 continue;
689 release_appl(capi_cards[i], ap->applid); 731 release_appl(capi_controller[i], ap->applid);
690 } 732 }
691 mutex_unlock(&controller_mutex); 733
734 mutex_unlock(&capi_controller_lock);
692 735
693 flush_scheduled_work(); 736 flush_scheduled_work();
694 skb_queue_purge(&ap->recv_queue); 737 skb_queue_purge(&ap->recv_queue);
@@ -713,13 +756,13 @@ EXPORT_SYMBOL(capi20_release);
713 756
714u16 capi20_put_message(struct capi20_appl *ap, struct sk_buff *skb) 757u16 capi20_put_message(struct capi20_appl *ap, struct sk_buff *skb)
715{ 758{
716 struct capi_ctr *card; 759 struct capi_ctr *ctr;
717 int showctl = 0; 760 int showctl = 0;
718 u8 cmd, subcmd; 761 u8 cmd, subcmd;
719 762
720 DBG("applid %#x", ap->applid); 763 DBG("applid %#x", ap->applid);
721 764
722 if (ncards == 0) 765 if (ncontrollers == 0)
723 return CAPI_REGNOTINSTALLED; 766 return CAPI_REGNOTINSTALLED;
724 if ((ap->applid == 0) || ap->release_in_progress) 767 if ((ap->applid == 0) || ap->release_in_progress)
725 return CAPI_ILLAPPNR; 768 return CAPI_ILLAPPNR;
@@ -727,28 +770,33 @@ u16 capi20_put_message(struct capi20_appl *ap, struct sk_buff *skb)
727 || !capi_cmd_valid(CAPIMSG_COMMAND(skb->data)) 770 || !capi_cmd_valid(CAPIMSG_COMMAND(skb->data))
728 || !capi_subcmd_valid(CAPIMSG_SUBCOMMAND(skb->data))) 771 || !capi_subcmd_valid(CAPIMSG_SUBCOMMAND(skb->data)))
729 return CAPI_ILLCMDORSUBCMDORMSGTOSMALL; 772 return CAPI_ILLCMDORSUBCMDORMSGTOSMALL;
730 card = get_capi_ctr_by_nr(CAPIMSG_CONTROLLER(skb->data)); 773
731 if (!card || card->cardstate != CARD_RUNNING) { 774 /*
732 card = get_capi_ctr_by_nr(1); // XXX why? 775 * The controller reference is protected by the existence of the
733 if (!card || card->cardstate != CARD_RUNNING) 776 * application passed to us. We assume that the caller properly
734 return CAPI_REGNOTINSTALLED; 777 * synchronizes this service with capi20_release.
735 } 778 */
736 if (card->blocked) 779 ctr = get_capi_ctr_by_nr(CAPIMSG_CONTROLLER(skb->data));
780 if (!ctr || ctr->state != CAPI_CTR_RUNNING)
781 return CAPI_REGNOTINSTALLED;
782 if (ctr->blocked)
737 return CAPI_SENDQUEUEFULL; 783 return CAPI_SENDQUEUEFULL;
738 784
739 cmd = CAPIMSG_COMMAND(skb->data); 785 cmd = CAPIMSG_COMMAND(skb->data);
740 subcmd = CAPIMSG_SUBCOMMAND(skb->data); 786 subcmd = CAPIMSG_SUBCOMMAND(skb->data);
741 787
742 if (cmd == CAPI_DATA_B3 && subcmd== CAPI_REQ) { 788 if (cmd == CAPI_DATA_B3 && subcmd== CAPI_REQ) {
743 card->nsentdatapkt++; 789 ctr->nsentdatapkt++;
744 ap->nsentdatapkt++; 790 ap->nsentdatapkt++;
745 if (card->traceflag > 2) showctl |= 2; 791 if (ctr->traceflag > 2)
792 showctl |= 2;
746 } else { 793 } else {
747 card->nsentctlpkt++; 794 ctr->nsentctlpkt++;
748 ap->nsentctlpkt++; 795 ap->nsentctlpkt++;
749 if (card->traceflag) showctl |= 2; 796 if (ctr->traceflag)
797 showctl |= 2;
750 } 798 }
751 showctl |= (card->traceflag & 1); 799 showctl |= (ctr->traceflag & 1);
752 if (showctl & 2) { 800 if (showctl & 2) {
753 if (showctl & 1) { 801 if (showctl & 1) {
754 printk(KERN_DEBUG "kcapi: put [%03d] id#%d %s len=%u\n", 802 printk(KERN_DEBUG "kcapi: put [%03d] id#%d %s len=%u\n",
@@ -771,7 +819,7 @@ u16 capi20_put_message(struct capi20_appl *ap, struct sk_buff *skb)
771 CAPIMSG_LEN(skb->data)); 819 CAPIMSG_LEN(skb->data));
772 } 820 }
773 } 821 }
774 return card->send_message(card, skb); 822 return ctr->send_message(ctr, skb);
775} 823}
776 824
777EXPORT_SYMBOL(capi20_put_message); 825EXPORT_SYMBOL(capi20_put_message);
@@ -788,17 +836,25 @@ EXPORT_SYMBOL(capi20_put_message);
788 836
789u16 capi20_get_manufacturer(u32 contr, u8 *buf) 837u16 capi20_get_manufacturer(u32 contr, u8 *buf)
790{ 838{
791 struct capi_ctr *card; 839 struct capi_ctr *ctr;
840 u16 ret;
792 841
793 if (contr == 0) { 842 if (contr == 0) {
794 strlcpy(buf, capi_manufakturer, CAPI_MANUFACTURER_LEN); 843 strlcpy(buf, capi_manufakturer, CAPI_MANUFACTURER_LEN);
795 return CAPI_NOERROR; 844 return CAPI_NOERROR;
796 } 845 }
797 card = get_capi_ctr_by_nr(contr); 846
798 if (!card || card->cardstate != CARD_RUNNING) 847 mutex_lock(&capi_controller_lock);
799 return CAPI_REGNOTINSTALLED; 848
800 strlcpy(buf, card->manu, CAPI_MANUFACTURER_LEN); 849 ctr = get_capi_ctr_by_nr(contr);
801 return CAPI_NOERROR; 850 if (ctr && ctr->state == CAPI_CTR_RUNNING) {
851 strlcpy(buf, ctr->manu, CAPI_MANUFACTURER_LEN);
852 ret = CAPI_NOERROR;
853 } else
854 ret = CAPI_REGNOTINSTALLED;
855
856 mutex_unlock(&capi_controller_lock);
857 return ret;
802} 858}
803 859
804EXPORT_SYMBOL(capi20_get_manufacturer); 860EXPORT_SYMBOL(capi20_get_manufacturer);
@@ -815,18 +871,25 @@ EXPORT_SYMBOL(capi20_get_manufacturer);
815 871
816u16 capi20_get_version(u32 contr, struct capi_version *verp) 872u16 capi20_get_version(u32 contr, struct capi_version *verp)
817{ 873{
818 struct capi_ctr *card; 874 struct capi_ctr *ctr;
875 u16 ret;
819 876
820 if (contr == 0) { 877 if (contr == 0) {
821 *verp = driver_version; 878 *verp = driver_version;
822 return CAPI_NOERROR; 879 return CAPI_NOERROR;
823 } 880 }
824 card = get_capi_ctr_by_nr(contr);
825 if (!card || card->cardstate != CARD_RUNNING)
826 return CAPI_REGNOTINSTALLED;
827 881
828 memcpy((void *) verp, &card->version, sizeof(capi_version)); 882 mutex_lock(&capi_controller_lock);
829 return CAPI_NOERROR; 883
884 ctr = get_capi_ctr_by_nr(contr);
885 if (ctr && ctr->state == CAPI_CTR_RUNNING) {
886 memcpy(verp, &ctr->version, sizeof(capi_version));
887 ret = CAPI_NOERROR;
888 } else
889 ret = CAPI_REGNOTINSTALLED;
890
891 mutex_unlock(&capi_controller_lock);
892 return ret;
830} 893}
831 894
832EXPORT_SYMBOL(capi20_get_version); 895EXPORT_SYMBOL(capi20_get_version);
@@ -843,18 +906,25 @@ EXPORT_SYMBOL(capi20_get_version);
843 906
844u16 capi20_get_serial(u32 contr, u8 *serial) 907u16 capi20_get_serial(u32 contr, u8 *serial)
845{ 908{
846 struct capi_ctr *card; 909 struct capi_ctr *ctr;
910 u16 ret;
847 911
848 if (contr == 0) { 912 if (contr == 0) {
849 strlcpy(serial, driver_serial, CAPI_SERIAL_LEN); 913 strlcpy(serial, driver_serial, CAPI_SERIAL_LEN);
850 return CAPI_NOERROR; 914 return CAPI_NOERROR;
851 } 915 }
852 card = get_capi_ctr_by_nr(contr);
853 if (!card || card->cardstate != CARD_RUNNING)
854 return CAPI_REGNOTINSTALLED;
855 916
856 strlcpy((void *) serial, card->serial, CAPI_SERIAL_LEN); 917 mutex_lock(&capi_controller_lock);
857 return CAPI_NOERROR; 918
919 ctr = get_capi_ctr_by_nr(contr);
920 if (ctr && ctr->state == CAPI_CTR_RUNNING) {
921 strlcpy(serial, ctr->serial, CAPI_SERIAL_LEN);
922 ret = CAPI_NOERROR;
923 } else
924 ret = CAPI_REGNOTINSTALLED;
925
926 mutex_unlock(&capi_controller_lock);
927 return ret;
858} 928}
859 929
860EXPORT_SYMBOL(capi20_get_serial); 930EXPORT_SYMBOL(capi20_get_serial);
@@ -871,23 +941,65 @@ EXPORT_SYMBOL(capi20_get_serial);
871 941
872u16 capi20_get_profile(u32 contr, struct capi_profile *profp) 942u16 capi20_get_profile(u32 contr, struct capi_profile *profp)
873{ 943{
874 struct capi_ctr *card; 944 struct capi_ctr *ctr;
945 u16 ret;
875 946
876 if (contr == 0) { 947 if (contr == 0) {
877 profp->ncontroller = ncards; 948 profp->ncontroller = ncontrollers;
878 return CAPI_NOERROR; 949 return CAPI_NOERROR;
879 } 950 }
880 card = get_capi_ctr_by_nr(contr);
881 if (!card || card->cardstate != CARD_RUNNING)
882 return CAPI_REGNOTINSTALLED;
883 951
884 memcpy((void *) profp, &card->profile, 952 mutex_lock(&capi_controller_lock);
885 sizeof(struct capi_profile)); 953
886 return CAPI_NOERROR; 954 ctr = get_capi_ctr_by_nr(contr);
955 if (ctr && ctr->state == CAPI_CTR_RUNNING) {
956 memcpy(profp, &ctr->profile, sizeof(struct capi_profile));
957 ret = CAPI_NOERROR;
958 } else
959 ret = CAPI_REGNOTINSTALLED;
960
961 mutex_unlock(&capi_controller_lock);
962 return ret;
887} 963}
888 964
889EXPORT_SYMBOL(capi20_get_profile); 965EXPORT_SYMBOL(capi20_get_profile);
890 966
967/* Must be called with capi_controller_lock held. */
968static int wait_on_ctr_state(struct capi_ctr *ctr, unsigned int state)
969{
970 DEFINE_WAIT(wait);
971 int retval = 0;
972
973 ctr = capi_ctr_get(ctr);
974 if (!ctr)
975 return -ESRCH;
976
977 for (;;) {
978 prepare_to_wait(&ctr->state_wait_queue, &wait,
979 TASK_INTERRUPTIBLE);
980
981 if (ctr->state == state)
982 break;
983 if (ctr->state == CAPI_CTR_DETACHED) {
984 retval = -ESRCH;
985 break;
986 }
987 if (signal_pending(current)) {
988 retval = -EINTR;
989 break;
990 }
991
992 mutex_unlock(&capi_controller_lock);
993 schedule();
994 mutex_lock(&capi_controller_lock);
995 }
996 finish_wait(&ctr->state_wait_queue, &wait);
997
998 capi_ctr_put(ctr);
999
1000 return retval;
1001}
1002
891#ifdef AVMB1_COMPAT 1003#ifdef AVMB1_COMPAT
892static int old_capi_manufacturer(unsigned int cmd, void __user *data) 1004static int old_capi_manufacturer(unsigned int cmd, void __user *data)
893{ 1005{
@@ -895,11 +1007,10 @@ static int old_capi_manufacturer(unsigned int cmd, void __user *data)
895 avmb1_extcarddef cdef; 1007 avmb1_extcarddef cdef;
896 avmb1_resetdef rdef; 1008 avmb1_resetdef rdef;
897 capicardparams cparams; 1009 capicardparams cparams;
898 struct capi_ctr *card; 1010 struct capi_ctr *ctr;
899 struct capi_driver *driver = NULL; 1011 struct capi_driver *driver = NULL;
900 capiloaddata ldata; 1012 capiloaddata ldata;
901 struct list_head *l; 1013 struct list_head *l;
902 unsigned long flags;
903 int retval; 1014 int retval;
904 1015
905 switch (cmd) { 1016 switch (cmd) {
@@ -919,7 +1030,8 @@ static int old_capi_manufacturer(unsigned int cmd, void __user *data)
919 cparams.irq = cdef.irq; 1030 cparams.irq = cdef.irq;
920 cparams.cardnr = cdef.cardnr; 1031 cparams.cardnr = cdef.cardnr;
921 1032
922 read_lock_irqsave(&capi_drivers_list_lock, flags); 1033 mutex_lock(&capi_drivers_lock);
1034
923 switch (cdef.cardtype) { 1035 switch (cdef.cardtype) {
924 case AVM_CARDTYPE_B1: 1036 case AVM_CARDTYPE_B1:
925 list_for_each(l, &capi_drivers) { 1037 list_for_each(l, &capi_drivers) {
@@ -940,18 +1052,15 @@ static int old_capi_manufacturer(unsigned int cmd, void __user *data)
940 break; 1052 break;
941 } 1053 }
942 if (!driver) { 1054 if (!driver) {
943 read_unlock_irqrestore(&capi_drivers_list_lock, flags);
944 printk(KERN_ERR "kcapi: driver not loaded.\n"); 1055 printk(KERN_ERR "kcapi: driver not loaded.\n");
945 return -EIO; 1056 retval = -EIO;
946 } 1057 } 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"); 1058 printk(KERN_ERR "kcapi: driver has no add card function.\n");
950 return -EIO; 1059 retval = -EIO;
951 } 1060 } else
1061 retval = driver->add_card(driver, &cparams);
952 1062
953 retval = driver->add_card(driver, &cparams); 1063 mutex_unlock(&capi_drivers_lock);
954 read_unlock_irqrestore(&capi_drivers_list_lock, flags);
955 return retval; 1064 return retval;
956 1065
957 case AVMB1_LOAD: 1066 case AVMB1_LOAD:
@@ -968,27 +1077,30 @@ static int old_capi_manufacturer(unsigned int cmd, void __user *data)
968 sizeof(avmb1_loadandconfigdef))) 1077 sizeof(avmb1_loadandconfigdef)))
969 return -EFAULT; 1078 return -EFAULT;
970 } 1079 }
971 card = get_capi_ctr_by_nr(ldef.contr); 1080
972 if (!card) 1081 mutex_lock(&capi_controller_lock);
973 return -EINVAL; 1082
974 card = capi_ctr_get(card); 1083 ctr = get_capi_ctr_by_nr(ldef.contr);
975 if (!card) 1084 if (!ctr) {
976 return -ESRCH; 1085 retval = -EINVAL;
977 if (card->load_firmware == NULL) { 1086 goto load_unlock_out;
1087 }
1088
1089 if (ctr->load_firmware == NULL) {
978 printk(KERN_DEBUG "kcapi: load: no load function\n"); 1090 printk(KERN_DEBUG "kcapi: load: no load function\n");
979 capi_ctr_put(card); 1091 retval = -ESRCH;
980 return -ESRCH; 1092 goto load_unlock_out;
981 } 1093 }
982 1094
983 if (ldef.t4file.len <= 0) { 1095 if (ldef.t4file.len <= 0) {
984 printk(KERN_DEBUG "kcapi: load: invalid parameter: length of t4file is %d ?\n", ldef.t4file.len); 1096 printk(KERN_DEBUG "kcapi: load: invalid parameter: length of t4file is %d ?\n", ldef.t4file.len);
985 capi_ctr_put(card); 1097 retval = -EINVAL;
986 return -EINVAL; 1098 goto load_unlock_out;
987 } 1099 }
988 if (ldef.t4file.data == NULL) { 1100 if (ldef.t4file.data == NULL) {
989 printk(KERN_DEBUG "kcapi: load: invalid parameter: dataptr is 0\n"); 1101 printk(KERN_DEBUG "kcapi: load: invalid parameter: dataptr is 0\n");
990 capi_ctr_put(card); 1102 retval = -EINVAL;
991 return -EINVAL; 1103 goto load_unlock_out;
992 } 1104 }
993 1105
994 ldata.firmware.user = 1; 1106 ldata.firmware.user = 1;
@@ -998,54 +1110,49 @@ static int old_capi_manufacturer(unsigned int cmd, void __user *data)
998 ldata.configuration.data = ldef.t4config.data; 1110 ldata.configuration.data = ldef.t4config.data;
999 ldata.configuration.len = ldef.t4config.len; 1111 ldata.configuration.len = ldef.t4config.len;
1000 1112
1001 if (card->cardstate != CARD_DETECTED) { 1113 if (ctr->state != CAPI_CTR_DETECTED) {
1002 printk(KERN_INFO "kcapi: load: contr=%d not in detect state\n", ldef.contr); 1114 printk(KERN_INFO "kcapi: load: contr=%d not in detect state\n", ldef.contr);
1003 capi_ctr_put(card); 1115 retval = -EBUSY;
1004 return -EBUSY; 1116 goto load_unlock_out;
1005 } 1117 }
1006 card->cardstate = CARD_LOADING; 1118 ctr->state = CAPI_CTR_LOADING;
1007
1008 retval = card->load_firmware(card, &ldata);
1009 1119
1120 retval = ctr->load_firmware(ctr, &ldata);
1010 if (retval) { 1121 if (retval) {
1011 card->cardstate = CARD_DETECTED; 1122 ctr->state = CAPI_CTR_DETECTED;
1012 capi_ctr_put(card); 1123 goto load_unlock_out;
1013 return retval;
1014 } 1124 }
1015 1125
1016 while (card->cardstate != CARD_RUNNING) { 1126 retval = wait_on_ctr_state(ctr, CAPI_CTR_RUNNING);
1017
1018 msleep_interruptible(100); /* 0.1 sec */
1019 1127
1020 if (signal_pending(current)) { 1128load_unlock_out:
1021 capi_ctr_put(card); 1129 mutex_unlock(&capi_controller_lock);
1022 return -EINTR; 1130 return retval;
1023 }
1024 }
1025 capi_ctr_put(card);
1026 return 0;
1027 1131
1028 case AVMB1_RESETCARD: 1132 case AVMB1_RESETCARD:
1029 if (copy_from_user(&rdef, data, sizeof(avmb1_resetdef))) 1133 if (copy_from_user(&rdef, data, sizeof(avmb1_resetdef)))
1030 return -EFAULT; 1134 return -EFAULT;
1031 card = get_capi_ctr_by_nr(rdef.contr);
1032 if (!card)
1033 return -ESRCH;
1034 1135
1035 if (card->cardstate == CARD_DETECTED) 1136 retval = 0;
1036 return 0;
1037 1137
1038 card->reset_ctr(card); 1138 mutex_lock(&capi_controller_lock);
1039 1139
1040 while (card->cardstate > CARD_DETECTED) { 1140 ctr = get_capi_ctr_by_nr(rdef.contr);
1141 if (!ctr) {
1142 retval = -ESRCH;
1143 goto reset_unlock_out;
1144 }
1041 1145
1042 msleep_interruptible(100); /* 0.1 sec */ 1146 if (ctr->state == CAPI_CTR_DETECTED)
1147 goto reset_unlock_out;
1043 1148
1044 if (signal_pending(current)) 1149 ctr->reset_ctr(ctr);
1045 return -EINTR; 1150
1046 } 1151 retval = wait_on_ctr_state(ctr, CAPI_CTR_DETECTED);
1047 return 0;
1048 1152
1153reset_unlock_out:
1154 mutex_unlock(&capi_controller_lock);
1155 return retval;
1049 } 1156 }
1050 return -EINVAL; 1157 return -EINVAL;
1051} 1158}
@@ -1062,7 +1169,8 @@ static int old_capi_manufacturer(unsigned int cmd, void __user *data)
1062 1169
1063int capi20_manufacturer(unsigned int cmd, void __user *data) 1170int capi20_manufacturer(unsigned int cmd, void __user *data)
1064{ 1171{
1065 struct capi_ctr *card; 1172 struct capi_ctr *ctr;
1173 int retval;
1066 1174
1067 switch (cmd) { 1175 switch (cmd) {
1068#ifdef AVMB1_COMPAT 1176#ifdef AVMB1_COMPAT
@@ -1080,14 +1188,20 @@ int capi20_manufacturer(unsigned int cmd, void __user *data)
1080 if (copy_from_user(&fdef, data, sizeof(kcapi_flagdef))) 1188 if (copy_from_user(&fdef, data, sizeof(kcapi_flagdef)))
1081 return -EFAULT; 1189 return -EFAULT;
1082 1190
1083 card = get_capi_ctr_by_nr(fdef.contr); 1191 mutex_lock(&capi_controller_lock);
1084 if (!card) 1192
1085 return -ESRCH; 1193 ctr = get_capi_ctr_by_nr(fdef.contr);
1194 if (ctr) {
1195 ctr->traceflag = fdef.flag;
1196 printk(KERN_INFO "kcapi: contr [%03d] set trace=%d\n",
1197 ctr->cnr, ctr->traceflag);
1198 retval = 0;
1199 } else
1200 retval = -ESRCH;
1201
1202 mutex_unlock(&capi_controller_lock);
1086 1203
1087 card->traceflag = fdef.flag; 1204 return retval;
1088 printk(KERN_INFO "kcapi: contr [%03d] set trace=%d\n",
1089 card->cnr, card->traceflag);
1090 return 0;
1091 } 1205 }
1092 case KCAPI_CMD_ADDCARD: 1206 case KCAPI_CMD_ADDCARD:
1093 { 1207 {
@@ -1095,7 +1209,6 @@ int capi20_manufacturer(unsigned int cmd, void __user *data)
1095 struct capi_driver *driver = NULL; 1209 struct capi_driver *driver = NULL;
1096 capicardparams cparams; 1210 capicardparams cparams;
1097 kcapi_carddef cdef; 1211 kcapi_carddef cdef;
1098 int retval;
1099 1212
1100 if ((retval = copy_from_user(&cdef, data, sizeof(cdef)))) 1213 if ((retval = copy_from_user(&cdef, data, sizeof(cdef))))
1101 return retval; 1214 return retval;
@@ -1107,6 +1220,8 @@ int capi20_manufacturer(unsigned int cmd, void __user *data)
1107 cparams.cardtype = 0; 1220 cparams.cardtype = 0;
1108 cdef.driver[sizeof(cdef.driver)-1] = 0; 1221 cdef.driver[sizeof(cdef.driver)-1] = 0;
1109 1222
1223 mutex_lock(&capi_drivers_lock);
1224
1110 list_for_each(l, &capi_drivers) { 1225 list_for_each(l, &capi_drivers) {
1111 driver = list_entry(l, struct capi_driver, list); 1226 driver = list_entry(l, struct capi_driver, list);
1112 if (strcmp(driver->name, cdef.driver) == 0) 1227 if (strcmp(driver->name, cdef.driver) == 0)
@@ -1115,15 +1230,15 @@ int capi20_manufacturer(unsigned int cmd, void __user *data)
1115 if (driver == NULL) { 1230 if (driver == NULL) {
1116 printk(KERN_ERR "kcapi: driver \"%s\" not loaded.\n", 1231 printk(KERN_ERR "kcapi: driver \"%s\" not loaded.\n",
1117 cdef.driver); 1232 cdef.driver);
1118 return -ESRCH; 1233 retval = -ESRCH;
1119 } 1234 } 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); 1235 printk(KERN_ERR "kcapi: driver \"%s\" has no add card function.\n", cdef.driver);
1123 return -EIO; 1236 retval = -EIO;
1124 } 1237 } else
1238 retval = driver->add_card(driver, &cparams);
1125 1239
1126 return driver->add_card(driver, &cparams); 1240 mutex_unlock(&capi_drivers_lock);
1241 return retval;
1127 } 1242 }
1128 1243
1129 default: 1244 default:
@@ -1137,30 +1252,6 @@ int capi20_manufacturer(unsigned int cmd, void __user *data)
1137 1252
1138EXPORT_SYMBOL(capi20_manufacturer); 1253EXPORT_SYMBOL(capi20_manufacturer);
1139 1254
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/* ------------------------------------------------------------- */ 1255/* ------------------------------------------------------------- */
1165/* -------- Init & Cleanup ------------------------------------- */ 1256/* -------- Init & Cleanup ------------------------------------- */
1166/* ------------------------------------------------------------- */ 1257/* ------------------------------------------------------------- */
@@ -1169,27 +1260,21 @@ EXPORT_SYMBOL(capi20_set_callback);
1169 * init / exit functions 1260 * init / exit functions
1170 */ 1261 */
1171 1262
1263static struct notifier_block capictr_nb = {
1264 .notifier_call = notify_handler,
1265 .priority = INT_MAX,
1266};
1267
1172static int __init kcapi_init(void) 1268static int __init kcapi_init(void)
1173{ 1269{
1174 char *p; 1270 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 1271
1190 printk(KERN_NOTICE "CAPI Subsystem Rev %s\n", rev); 1272 register_capictr_notifier(&capictr_nb);
1191 1273
1192 return 0; 1274 err = cdebug_init();
1275 if (!err)
1276 kcapi_proc_init();
1277 return err;
1193} 1278}
1194 1279
1195static void __exit kcapi_exit(void) 1280static 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/gigaset/asyncdata.c b/drivers/isdn/gigaset/asyncdata.c
index ccb2a7b7c41d..c5016bd2d94f 100644
--- a/drivers/isdn/gigaset/asyncdata.c
+++ b/drivers/isdn/gigaset/asyncdata.c
@@ -40,6 +40,8 @@ static inline int muststuff(unsigned char c)
40 * Append received bytes to the command response buffer and forward them 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 41 * line by line to the response handler. Exit whenever a mode/state change
42 * might have occurred. 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.
43 * Return value: 45 * Return value:
44 * number of processed bytes 46 * number of processed bytes
45 */ 47 */
@@ -65,14 +67,14 @@ static unsigned cmd_loop(unsigned numbytes, struct inbuf_t *inbuf)
65 /* --v-- fall through --v-- */ 67 /* --v-- fall through --v-- */
66 case '\r': 68 case '\r':
67 /* end of message line, pass to response handler */ 69 /* end of message line, pass to response handler */
68 gig_dbg(DEBUG_TRANSCMD, "%s: End of Message (%d Bytes)",
69 __func__, cbytes);
70 if (cbytes >= MAX_RESP_SIZE) { 70 if (cbytes >= MAX_RESP_SIZE) {
71 dev_warn(cs->dev, "response too large (%d)\n", 71 dev_warn(cs->dev, "response too large (%d)\n",
72 cbytes); 72 cbytes);
73 cbytes = MAX_RESP_SIZE; 73 cbytes = MAX_RESP_SIZE;
74 } 74 }
75 cs->cbytes = cbytes; 75 cs->cbytes = cbytes;
76 gigaset_dbg_buffer(DEBUG_TRANSCMD, "received response",
77 cbytes, cs->respdata);
76 gigaset_handle_modem_response(cs); 78 gigaset_handle_modem_response(cs);
77 cbytes = 0; 79 cbytes = 0;
78 80
diff --git a/drivers/isdn/gigaset/bas-gigaset.c b/drivers/isdn/gigaset/bas-gigaset.c
index 95ebc5129895..0be15c70c16d 100644
--- a/drivers/isdn/gigaset/bas-gigaset.c
+++ b/drivers/isdn/gigaset/bas-gigaset.c
@@ -347,12 +347,7 @@ static inline void error_hangup(struct bc_state *bcs)
347{ 347{
348 struct cardstate *cs = bcs->cs; 348 struct cardstate *cs = bcs->cs;
349 349
350 gig_dbg(DEBUG_ANY, "%s: scheduling HUP for channel %d", 350 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); 351 gigaset_schedule_event(cs);
357} 352}
358 353
@@ -1706,8 +1701,7 @@ static void complete_cb(struct cardstate *cs)
1706 1701
1707 /* unqueue completed buffer */ 1702 /* unqueue completed buffer */
1708 cs->cmdbytes -= cs->curlen; 1703 cs->cmdbytes -= cs->curlen;
1709 gig_dbg(DEBUG_TRANSCMD|DEBUG_LOCKCMD, 1704 gig_dbg(DEBUG_OUTPUT, "write_command: sent %u bytes, %u left",
1710 "write_command: sent %u bytes, %u left",
1711 cs->curlen, cs->cmdbytes); 1705 cs->curlen, cs->cmdbytes);
1712 if (cb->next != NULL) { 1706 if (cb->next != NULL) {
1713 cs->cmdbuf = cb->next; 1707 cs->cmdbuf = cb->next;
@@ -1881,13 +1875,13 @@ static int start_cbsend(struct cardstate *cs)
1881 1875
1882 /* check if suspend requested */ 1876 /* check if suspend requested */
1883 if (ucs->basstate & BS_SUSPEND) { 1877 if (ucs->basstate & BS_SUSPEND) {
1884 gig_dbg(DEBUG_TRANSCMD|DEBUG_LOCKCMD, "suspending"); 1878 gig_dbg(DEBUG_OUTPUT, "suspending");
1885 return -EHOSTUNREACH; 1879 return -EHOSTUNREACH;
1886 } 1880 }
1887 1881
1888 /* check if AT channel is open */ 1882 /* check if AT channel is open */
1889 if (!(ucs->basstate & BS_ATOPEN)) { 1883 if (!(ucs->basstate & BS_ATOPEN)) {
1890 gig_dbg(DEBUG_TRANSCMD|DEBUG_LOCKCMD, "AT channel not open"); 1884 gig_dbg(DEBUG_OUTPUT, "AT channel not open");
1891 rc = req_submit(cs->bcs, HD_OPEN_ATCHANNEL, 0, BAS_TIMEOUT); 1885 rc = req_submit(cs->bcs, HD_OPEN_ATCHANNEL, 0, BAS_TIMEOUT);
1892 if (rc < 0) { 1886 if (rc < 0) {
1893 /* flush command queue */ 1887 /* flush command queue */
@@ -2251,7 +2245,7 @@ static int gigaset_probe(struct usb_interface *interface,
2251 int i, j; 2245 int i, j;
2252 int rc; 2246 int rc;
2253 2247
2254 gig_dbg(DEBUG_ANY, 2248 gig_dbg(DEBUG_INIT,
2255 "%s: Check if device matches .. (Vendor: 0x%x, Product: 0x%x)", 2249 "%s: Check if device matches .. (Vendor: 0x%x, Product: 0x%x)",
2256 __func__, le16_to_cpu(udev->descriptor.idVendor), 2250 __func__, le16_to_cpu(udev->descriptor.idVendor),
2257 le16_to_cpu(udev->descriptor.idProduct)); 2251 le16_to_cpu(udev->descriptor.idProduct));
@@ -2259,7 +2253,7 @@ static int gigaset_probe(struct usb_interface *interface,
2259 /* set required alternate setting */ 2253 /* set required alternate setting */
2260 hostif = interface->cur_altsetting; 2254 hostif = interface->cur_altsetting;
2261 if (hostif->desc.bAlternateSetting != 3) { 2255 if (hostif->desc.bAlternateSetting != 3) {
2262 gig_dbg(DEBUG_ANY, 2256 gig_dbg(DEBUG_INIT,
2263 "%s: wrong alternate setting %d - trying to switch", 2257 "%s: wrong alternate setting %d - trying to switch",
2264 __func__, hostif->desc.bAlternateSetting); 2258 __func__, hostif->desc.bAlternateSetting);
2265 if (usb_set_interface(udev, hostif->desc.bInterfaceNumber, 3) 2259 if (usb_set_interface(udev, hostif->desc.bInterfaceNumber, 3)
diff --git a/drivers/isdn/gigaset/capi.c b/drivers/isdn/gigaset/capi.c
index 3f5cd06af104..6643d6533ccb 100644
--- a/drivers/isdn/gigaset/capi.c
+++ b/drivers/isdn/gigaset/capi.c
@@ -13,6 +13,8 @@
13 13
14#include "gigaset.h" 14#include "gigaset.h"
15#include <linux/ctype.h> 15#include <linux/ctype.h>
16#include <linux/proc_fs.h>
17#include <linux/seq_file.h>
16#include <linux/isdn/capilli.h> 18#include <linux/isdn/capilli.h>
17#include <linux/isdn/capicmd.h> 19#include <linux/isdn/capicmd.h>
18#include <linux/isdn/capiutil.h> 20#include <linux/isdn/capiutil.h>
@@ -169,20 +171,6 @@ static inline void ignore_cstruct_param(struct cardstate *cs, _cstruct param,
169} 171}
170 172
171/* 173/*
172 * check for legal hex digit
173 */
174static inline int ishexdigit(char c)
175{
176 if (c >= '0' && c <= '9')
177 return 1;
178 if (c >= 'A' && c <= 'F')
179 return 1;
180 if (c >= 'a' && c <= 'f')
181 return 1;
182 return 0;
183}
184
185/*
186 * convert hex to binary 174 * convert hex to binary
187 */ 175 */
188static inline u8 hex2bin(char c) 176static inline u8 hex2bin(char c)
@@ -202,7 +190,7 @@ static int encode_ie(char *in, u8 *out, int maxlen)
202{ 190{
203 int l = 0; 191 int l = 0;
204 while (*in) { 192 while (*in) {
205 if (!ishexdigit(in[0]) || !ishexdigit(in[1]) || l >= maxlen) 193 if (!isxdigit(in[0]) || !isxdigit(in[1]) || l >= maxlen)
206 return -1; 194 return -1;
207 out[++l] = (hex2bin(in[0]) << 4) + hex2bin(in[1]); 195 out[++l] = (hex2bin(in[0]) << 4) + hex2bin(in[1]);
208 in += 2; 196 in += 2;
@@ -1425,9 +1413,10 @@ static void do_connect_req(struct gigaset_capi_ctr *iif,
1425 1413
1426 /* queue & schedule EV_DIAL event */ 1414 /* queue & schedule EV_DIAL event */
1427 if (!gigaset_add_event(cs, &bcs->at_state, EV_DIAL, commands, 1415 if (!gigaset_add_event(cs, &bcs->at_state, EV_DIAL, commands,
1428 bcs->at_state.seq_index, NULL)) 1416 bcs->at_state.seq_index, NULL)) {
1429 goto oom; 1417 info = CAPI_MSGOSRESOURCEERR;
1430 gig_dbg(DEBUG_CMD, "scheduling DIAL"); 1418 goto error;
1419 }
1431 gigaset_schedule_event(cs); 1420 gigaset_schedule_event(cs);
1432 ap->connected = APCONN_SETUP; 1421 ap->connected = APCONN_SETUP;
1433 send_conf(iif, ap, skb, CapiSuccess); 1422 send_conf(iif, ap, skb, CapiSuccess);
@@ -1541,7 +1530,6 @@ static void do_connect_resp(struct gigaset_capi_ctr *iif,
1541 if (!gigaset_add_event(cs, &cs->bcs[channel-1].at_state, 1530 if (!gigaset_add_event(cs, &cs->bcs[channel-1].at_state,
1542 EV_ACCEPT, NULL, 0, NULL)) 1531 EV_ACCEPT, NULL, 0, NULL))
1543 return; 1532 return;
1544 gig_dbg(DEBUG_CMD, "scheduling ACCEPT");
1545 gigaset_schedule_event(cs); 1533 gigaset_schedule_event(cs);
1546 return; 1534 return;
1547 1535
@@ -1582,7 +1570,6 @@ static void do_connect_resp(struct gigaset_capi_ctr *iif,
1582 if (!gigaset_add_event(cs, &cs->bcs[channel-1].at_state, 1570 if (!gigaset_add_event(cs, &cs->bcs[channel-1].at_state,
1583 EV_HUP, NULL, 0, NULL)) 1571 EV_HUP, NULL, 0, NULL))
1584 return; 1572 return;
1585 gig_dbg(DEBUG_CMD, "scheduling HUP");
1586 gigaset_schedule_event(cs); 1573 gigaset_schedule_event(cs);
1587 return; 1574 return;
1588 } 1575 }
@@ -1665,11 +1652,9 @@ static void do_connect_b3_resp(struct gigaset_capi_ctr *iif,
1665 /* trigger hangup, causing eventual DISCONNECT_IND */ 1652 /* trigger hangup, causing eventual DISCONNECT_IND */
1666 if (!gigaset_add_event(cs, &bcs->at_state, 1653 if (!gigaset_add_event(cs, &bcs->at_state,
1667 EV_HUP, NULL, 0, NULL)) { 1654 EV_HUP, NULL, 0, NULL)) {
1668 dev_err(cs->dev, "%s: out of memory\n", __func__);
1669 dev_kfree_skb_any(skb); 1655 dev_kfree_skb_any(skb);
1670 return; 1656 return;
1671 } 1657 }
1672 gig_dbg(DEBUG_CMD, "scheduling HUP");
1673 gigaset_schedule_event(cs); 1658 gigaset_schedule_event(cs);
1674 1659
1675 /* emit DISCONNECT_B3_IND */ 1660 /* emit DISCONNECT_B3_IND */
@@ -1768,11 +1753,9 @@ static void do_disconnect_req(struct gigaset_capi_ctr *iif,
1768 1753
1769 /* trigger hangup, causing eventual DISCONNECT_IND */ 1754 /* trigger hangup, causing eventual DISCONNECT_IND */
1770 if (!gigaset_add_event(cs, &bcs->at_state, EV_HUP, NULL, 0, NULL)) { 1755 if (!gigaset_add_event(cs, &bcs->at_state, EV_HUP, NULL, 0, NULL)) {
1771 dev_err(cs->dev, "%s: out of memory\n", __func__);
1772 send_conf(iif, ap, skb, CAPI_MSGOSRESOURCEERR); 1756 send_conf(iif, ap, skb, CAPI_MSGOSRESOURCEERR);
1773 return; 1757 return;
1774 } 1758 }
1775 gig_dbg(DEBUG_CMD, "scheduling HUP");
1776 gigaset_schedule_event(cs); 1759 gigaset_schedule_event(cs);
1777 1760
1778 /* emit reply */ 1761 /* emit reply */
@@ -1815,11 +1798,9 @@ static void do_disconnect_b3_req(struct gigaset_capi_ctr *iif,
1815 /* trigger hangup, causing eventual DISCONNECT_B3_IND */ 1798 /* trigger hangup, causing eventual DISCONNECT_B3_IND */
1816 if (!gigaset_add_event(cs, &cs->bcs[channel-1].at_state, 1799 if (!gigaset_add_event(cs, &cs->bcs[channel-1].at_state,
1817 EV_HUP, NULL, 0, NULL)) { 1800 EV_HUP, NULL, 0, NULL)) {
1818 dev_err(cs->dev, "%s: out of memory\n", __func__);
1819 send_conf(iif, ap, skb, CAPI_MSGOSRESOURCEERR); 1801 send_conf(iif, ap, skb, CAPI_MSGOSRESOURCEERR);
1820 return; 1802 return;
1821 } 1803 }
1822 gig_dbg(DEBUG_CMD, "scheduling HUP");
1823 gigaset_schedule_event(cs); 1804 gigaset_schedule_event(cs);
1824 1805
1825 /* NCPI parameter: not applicable for B3 Transparent */ 1806 /* NCPI parameter: not applicable for B3 Transparent */
@@ -2106,35 +2087,22 @@ static char *gigaset_procinfo(struct capi_ctr *ctr)
2106 return ctr->name; /* ToDo: more? */ 2087 return ctr->name; /* ToDo: more? */
2107} 2088}
2108 2089
2109/** 2090static int gigaset_proc_show(struct seq_file *m, void *v)
2110 * gigaset_ctr_read_proc() - build controller proc file entry
2111 * @page: buffer of PAGE_SIZE bytes for receiving the entry.
2112 * @start: unused.
2113 * @off: unused.
2114 * @count: unused.
2115 * @eof: unused.
2116 * @ctr: controller descriptor structure.
2117 *
2118 * Return value: length of generated entry
2119 */
2120static int gigaset_ctr_read_proc(char *page, char **start, off_t off,
2121 int count, int *eof, struct capi_ctr *ctr)
2122{ 2091{
2092 struct capi_ctr *ctr = m->private;
2123 struct cardstate *cs = ctr->driverdata; 2093 struct cardstate *cs = ctr->driverdata;
2124 char *s; 2094 char *s;
2125 int i; 2095 int i;
2126 int len = 0; 2096
2127 len += sprintf(page+len, "%-16s %s\n", "name", ctr->name); 2097 seq_printf(m, "%-16s %s\n", "name", ctr->name);
2128 len += sprintf(page+len, "%-16s %s %s\n", "dev", 2098 seq_printf(m, "%-16s %s %s\n", "dev",
2129 dev_driver_string(cs->dev), dev_name(cs->dev)); 2099 dev_driver_string(cs->dev), dev_name(cs->dev));
2130 len += sprintf(page+len, "%-16s %d\n", "id", cs->myid); 2100 seq_printf(m, "%-16s %d\n", "id", cs->myid);
2131 if (cs->gotfwver) 2101 if (cs->gotfwver)
2132 len += sprintf(page+len, "%-16s %d.%d.%d.%d\n", "firmware", 2102 seq_printf(m, "%-16s %d.%d.%d.%d\n", "firmware",
2133 cs->fwver[0], cs->fwver[1], cs->fwver[2], cs->fwver[3]); 2103 cs->fwver[0], cs->fwver[1], cs->fwver[2], cs->fwver[3]);
2134 len += sprintf(page+len, "%-16s %d\n", "channels", 2104 seq_printf(m, "%-16s %d\n", "channels", cs->channels);
2135 cs->channels); 2105 seq_printf(m, "%-16s %s\n", "onechannel", cs->onechannel ? "yes" : "no");
2136 len += sprintf(page+len, "%-16s %s\n", "onechannel",
2137 cs->onechannel ? "yes" : "no");
2138 2106
2139 switch (cs->mode) { 2107 switch (cs->mode) {
2140 case M_UNKNOWN: 2108 case M_UNKNOWN:
@@ -2152,7 +2120,7 @@ static int gigaset_ctr_read_proc(char *page, char **start, off_t off,
2152 default: 2120 default:
2153 s = "??"; 2121 s = "??";
2154 } 2122 }
2155 len += sprintf(page+len, "%-16s %s\n", "mode", s); 2123 seq_printf(m, "%-16s %s\n", "mode", s);
2156 2124
2157 switch (cs->mstate) { 2125 switch (cs->mstate) {
2158 case MS_UNINITIALIZED: 2126 case MS_UNINITIALIZED:
@@ -2176,25 +2144,21 @@ static int gigaset_ctr_read_proc(char *page, char **start, off_t off,
2176 default: 2144 default:
2177 s = "??"; 2145 s = "??";
2178 } 2146 }
2179 len += sprintf(page+len, "%-16s %s\n", "mstate", s); 2147 seq_printf(m, "%-16s %s\n", "mstate", s);
2180 2148
2181 len += sprintf(page+len, "%-16s %s\n", "running", 2149 seq_printf(m, "%-16s %s\n", "running", cs->running ? "yes" : "no");
2182 cs->running ? "yes" : "no"); 2150 seq_printf(m, "%-16s %s\n", "connected", cs->connected ? "yes" : "no");
2183 len += sprintf(page+len, "%-16s %s\n", "connected", 2151 seq_printf(m, "%-16s %s\n", "isdn_up", cs->isdn_up ? "yes" : "no");
2184 cs->connected ? "yes" : "no"); 2152 seq_printf(m, "%-16s %s\n", "cidmode", cs->cidmode ? "yes" : "no");
2185 len += sprintf(page+len, "%-16s %s\n", "isdn_up",
2186 cs->isdn_up ? "yes" : "no");
2187 len += sprintf(page+len, "%-16s %s\n", "cidmode",
2188 cs->cidmode ? "yes" : "no");
2189 2153
2190 for (i = 0; i < cs->channels; i++) { 2154 for (i = 0; i < cs->channels; i++) {
2191 len += sprintf(page+len, "[%d]%-13s %d\n", i, "corrupted", 2155 seq_printf(m, "[%d]%-13s %d\n", i, "corrupted",
2192 cs->bcs[i].corrupted); 2156 cs->bcs[i].corrupted);
2193 len += sprintf(page+len, "[%d]%-13s %d\n", i, "trans_down", 2157 seq_printf(m, "[%d]%-13s %d\n", i, "trans_down",
2194 cs->bcs[i].trans_down); 2158 cs->bcs[i].trans_down);
2195 len += sprintf(page+len, "[%d]%-13s %d\n", i, "trans_up", 2159 seq_printf(m, "[%d]%-13s %d\n", i, "trans_up",
2196 cs->bcs[i].trans_up); 2160 cs->bcs[i].trans_up);
2197 len += sprintf(page+len, "[%d]%-13s %d\n", i, "chstate", 2161 seq_printf(m, "[%d]%-13s %d\n", i, "chstate",
2198 cs->bcs[i].chstate); 2162 cs->bcs[i].chstate);
2199 switch (cs->bcs[i].proto2) { 2163 switch (cs->bcs[i].proto2) {
2200 case L2_BITSYNC: 2164 case L2_BITSYNC:
@@ -2209,11 +2173,23 @@ static int gigaset_ctr_read_proc(char *page, char **start, off_t off,
2209 default: 2173 default:
2210 s = "??"; 2174 s = "??";
2211 } 2175 }
2212 len += sprintf(page+len, "[%d]%-13s %s\n", i, "proto2", s); 2176 seq_printf(m, "[%d]%-13s %s\n", i, "proto2", s);
2213 } 2177 }
2214 return len; 2178 return 0;
2215} 2179}
2216 2180
2181static int gigaset_proc_open(struct inode *inode, struct file *file)
2182{
2183 return single_open(file, gigaset_proc_show, PDE(inode)->data);
2184}
2185
2186static const struct file_operations gigaset_proc_fops = {
2187 .owner = THIS_MODULE,
2188 .open = gigaset_proc_open,
2189 .read = seq_read,
2190 .llseek = seq_lseek,
2191 .release = single_release,
2192};
2217 2193
2218static struct capi_driver capi_driver_gigaset = { 2194static struct capi_driver capi_driver_gigaset = {
2219 .name = "gigaset", 2195 .name = "gigaset",
@@ -2256,7 +2232,7 @@ int gigaset_isdn_register(struct cardstate *cs, const char *isdnid)
2256 iif->ctr.release_appl = gigaset_release_appl; 2232 iif->ctr.release_appl = gigaset_release_appl;
2257 iif->ctr.send_message = gigaset_send_message; 2233 iif->ctr.send_message = gigaset_send_message;
2258 iif->ctr.procinfo = gigaset_procinfo; 2234 iif->ctr.procinfo = gigaset_procinfo;
2259 iif->ctr.ctr_read_proc = gigaset_ctr_read_proc; 2235 iif->ctr.proc_fops = &gigaset_proc_fops;
2260 INIT_LIST_HEAD(&iif->appls); 2236 INIT_LIST_HEAD(&iif->appls);
2261 skb_queue_head_init(&iif->sendqueue); 2237 skb_queue_head_init(&iif->sendqueue);
2262 atomic_set(&iif->sendqlen, 0); 2238 atomic_set(&iif->sendqlen, 0);
diff --git a/drivers/isdn/gigaset/common.c b/drivers/isdn/gigaset/common.c
index 664b0c519c3e..85de3399a2f2 100644
--- a/drivers/isdn/gigaset/common.c
+++ b/drivers/isdn/gigaset/common.c
@@ -149,10 +149,8 @@ static int test_timeout(struct at_state_t *at_state)
149 return 0; 149 return 0;
150 } 150 }
151 151
152 if (!gigaset_add_event(at_state->cs, at_state, EV_TIMEOUT, NULL, 152 gigaset_add_event(at_state->cs, at_state, EV_TIMEOUT, NULL,
153 at_state->timer_index, NULL)) 153 at_state->timer_index, NULL);
154 dev_err(at_state->cs->dev, "%s: out of memory\n",
155 __func__);
156 return 1; 154 return 1;
157} 155}
158 156
@@ -180,7 +178,7 @@ static void timer_tick(unsigned long data)
180 if (cs->running) { 178 if (cs->running) {
181 mod_timer(&cs->timer, jiffies + msecs_to_jiffies(GIG_TICK)); 179 mod_timer(&cs->timer, jiffies + msecs_to_jiffies(GIG_TICK));
182 if (timeout) { 180 if (timeout) {
183 gig_dbg(DEBUG_CMD, "scheduling timeout"); 181 gig_dbg(DEBUG_EVENT, "scheduling timeout");
184 tasklet_schedule(&cs->event_tasklet); 182 tasklet_schedule(&cs->event_tasklet);
185 } 183 }
186 } 184 }
@@ -194,14 +192,14 @@ int gigaset_get_channel(struct bc_state *bcs)
194 192
195 spin_lock_irqsave(&bcs->cs->lock, flags); 193 spin_lock_irqsave(&bcs->cs->lock, flags);
196 if (bcs->use_count || !try_module_get(bcs->cs->driver->owner)) { 194 if (bcs->use_count || !try_module_get(bcs->cs->driver->owner)) {
197 gig_dbg(DEBUG_ANY, "could not allocate channel %d", 195 gig_dbg(DEBUG_CHANNEL, "could not allocate channel %d",
198 bcs->channel); 196 bcs->channel);
199 spin_unlock_irqrestore(&bcs->cs->lock, flags); 197 spin_unlock_irqrestore(&bcs->cs->lock, flags);
200 return 0; 198 return 0;
201 } 199 }
202 ++bcs->use_count; 200 ++bcs->use_count;
203 bcs->busy = 1; 201 bcs->busy = 1;
204 gig_dbg(DEBUG_ANY, "allocated channel %d", bcs->channel); 202 gig_dbg(DEBUG_CHANNEL, "allocated channel %d", bcs->channel);
205 spin_unlock_irqrestore(&bcs->cs->lock, flags); 203 spin_unlock_irqrestore(&bcs->cs->lock, flags);
206 return 1; 204 return 1;
207} 205}
@@ -213,7 +211,7 @@ struct bc_state *gigaset_get_free_channel(struct cardstate *cs)
213 211
214 spin_lock_irqsave(&cs->lock, flags); 212 spin_lock_irqsave(&cs->lock, flags);
215 if (!try_module_get(cs->driver->owner)) { 213 if (!try_module_get(cs->driver->owner)) {
216 gig_dbg(DEBUG_ANY, 214 gig_dbg(DEBUG_CHANNEL,
217 "could not get module for allocating channel"); 215 "could not get module for allocating channel");
218 spin_unlock_irqrestore(&cs->lock, flags); 216 spin_unlock_irqrestore(&cs->lock, flags);
219 return NULL; 217 return NULL;
@@ -223,12 +221,12 @@ struct bc_state *gigaset_get_free_channel(struct cardstate *cs)
223 ++cs->bcs[i].use_count; 221 ++cs->bcs[i].use_count;
224 cs->bcs[i].busy = 1; 222 cs->bcs[i].busy = 1;
225 spin_unlock_irqrestore(&cs->lock, flags); 223 spin_unlock_irqrestore(&cs->lock, flags);
226 gig_dbg(DEBUG_ANY, "allocated channel %d", i); 224 gig_dbg(DEBUG_CHANNEL, "allocated channel %d", i);
227 return cs->bcs + i; 225 return cs->bcs + i;
228 } 226 }
229 module_put(cs->driver->owner); 227 module_put(cs->driver->owner);
230 spin_unlock_irqrestore(&cs->lock, flags); 228 spin_unlock_irqrestore(&cs->lock, flags);
231 gig_dbg(DEBUG_ANY, "no free channel"); 229 gig_dbg(DEBUG_CHANNEL, "no free channel");
232 return NULL; 230 return NULL;
233} 231}
234 232
@@ -238,14 +236,15 @@ void gigaset_free_channel(struct bc_state *bcs)
238 236
239 spin_lock_irqsave(&bcs->cs->lock, flags); 237 spin_lock_irqsave(&bcs->cs->lock, flags);
240 if (!bcs->busy) { 238 if (!bcs->busy) {
241 gig_dbg(DEBUG_ANY, "could not free channel %d", bcs->channel); 239 gig_dbg(DEBUG_CHANNEL, "could not free channel %d",
240 bcs->channel);
242 spin_unlock_irqrestore(&bcs->cs->lock, flags); 241 spin_unlock_irqrestore(&bcs->cs->lock, flags);
243 return; 242 return;
244 } 243 }
245 --bcs->use_count; 244 --bcs->use_count;
246 bcs->busy = 0; 245 bcs->busy = 0;
247 module_put(bcs->cs->driver->owner); 246 module_put(bcs->cs->driver->owner);
248 gig_dbg(DEBUG_ANY, "freed channel %d", bcs->channel); 247 gig_dbg(DEBUG_CHANNEL, "freed channel %d", bcs->channel);
249 spin_unlock_irqrestore(&bcs->cs->lock, flags); 248 spin_unlock_irqrestore(&bcs->cs->lock, flags);
250} 249}
251 250
@@ -258,14 +257,15 @@ int gigaset_get_channels(struct cardstate *cs)
258 for (i = 0; i < cs->channels; ++i) 257 for (i = 0; i < cs->channels; ++i)
259 if (cs->bcs[i].use_count) { 258 if (cs->bcs[i].use_count) {
260 spin_unlock_irqrestore(&cs->lock, flags); 259 spin_unlock_irqrestore(&cs->lock, flags);
261 gig_dbg(DEBUG_ANY, "could not allocate all channels"); 260 gig_dbg(DEBUG_CHANNEL,
261 "could not allocate all channels");
262 return 0; 262 return 0;
263 } 263 }
264 for (i = 0; i < cs->channels; ++i) 264 for (i = 0; i < cs->channels; ++i)
265 ++cs->bcs[i].use_count; 265 ++cs->bcs[i].use_count;
266 spin_unlock_irqrestore(&cs->lock, flags); 266 spin_unlock_irqrestore(&cs->lock, flags);
267 267
268 gig_dbg(DEBUG_ANY, "allocated all channels"); 268 gig_dbg(DEBUG_CHANNEL, "allocated all channels");
269 269
270 return 1; 270 return 1;
271} 271}
@@ -275,7 +275,7 @@ void gigaset_free_channels(struct cardstate *cs)
275 unsigned long flags; 275 unsigned long flags;
276 int i; 276 int i;
277 277
278 gig_dbg(DEBUG_ANY, "unblocking all channels"); 278 gig_dbg(DEBUG_CHANNEL, "unblocking all channels");
279 spin_lock_irqsave(&cs->lock, flags); 279 spin_lock_irqsave(&cs->lock, flags);
280 for (i = 0; i < cs->channels; ++i) 280 for (i = 0; i < cs->channels; ++i)
281 --cs->bcs[i].use_count; 281 --cs->bcs[i].use_count;
@@ -287,7 +287,7 @@ void gigaset_block_channels(struct cardstate *cs)
287 unsigned long flags; 287 unsigned long flags;
288 int i; 288 int i;
289 289
290 gig_dbg(DEBUG_ANY, "blocking all channels"); 290 gig_dbg(DEBUG_CHANNEL, "blocking all channels");
291 spin_lock_irqsave(&cs->lock, flags); 291 spin_lock_irqsave(&cs->lock, flags);
292 for (i = 0; i < cs->channels; ++i) 292 for (i = 0; i < cs->channels; ++i)
293 ++cs->bcs[i].use_count; 293 ++cs->bcs[i].use_count;
@@ -338,6 +338,8 @@ struct event_t *gigaset_add_event(struct cardstate *cs,
338 unsigned next, tail; 338 unsigned next, tail;
339 struct event_t *event = NULL; 339 struct event_t *event = NULL;
340 340
341 gig_dbg(DEBUG_EVENT, "queueing event %d", type);
342
341 spin_lock_irqsave(&cs->ev_lock, flags); 343 spin_lock_irqsave(&cs->ev_lock, flags);
342 344
343 tail = cs->ev_tail; 345 tail = cs->ev_tail;
@@ -934,11 +936,8 @@ int gigaset_start(struct cardstate *cs)
934 936
935 if (!gigaset_add_event(cs, &cs->at_state, EV_START, NULL, 0, NULL)) { 937 if (!gigaset_add_event(cs, &cs->at_state, EV_START, NULL, 0, NULL)) {
936 cs->waiting = 0; 938 cs->waiting = 0;
937 dev_err(cs->dev, "%s: out of memory\n", __func__);
938 goto error; 939 goto error;
939 } 940 }
940
941 gig_dbg(DEBUG_CMD, "scheduling START");
942 gigaset_schedule_event(cs); 941 gigaset_schedule_event(cs);
943 942
944 wait_event(cs->waitqueue, !cs->waiting); 943 wait_event(cs->waitqueue, !cs->waiting);
@@ -973,12 +972,8 @@ int gigaset_shutdown(struct cardstate *cs)
973 972
974 cs->waiting = 1; 973 cs->waiting = 1;
975 974
976 if (!gigaset_add_event(cs, &cs->at_state, EV_SHUTDOWN, NULL, 0, NULL)) { 975 if (!gigaset_add_event(cs, &cs->at_state, EV_SHUTDOWN, NULL, 0, NULL))
977 dev_err(cs->dev, "%s: out of memory\n", __func__);
978 goto exit; 976 goto exit;
979 }
980
981 gig_dbg(DEBUG_CMD, "scheduling SHUTDOWN");
982 gigaset_schedule_event(cs); 977 gigaset_schedule_event(cs);
983 978
984 wait_event(cs->waitqueue, !cs->waiting); 979 wait_event(cs->waitqueue, !cs->waiting);
@@ -1004,12 +999,8 @@ void gigaset_stop(struct cardstate *cs)
1004 999
1005 cs->waiting = 1; 1000 cs->waiting = 1;
1006 1001
1007 if (!gigaset_add_event(cs, &cs->at_state, EV_STOP, NULL, 0, NULL)) { 1002 if (!gigaset_add_event(cs, &cs->at_state, EV_STOP, NULL, 0, NULL))
1008 dev_err(cs->dev, "%s: out of memory\n", __func__);
1009 goto exit; 1003 goto exit;
1010 }
1011
1012 gig_dbg(DEBUG_CMD, "scheduling STOP");
1013 gigaset_schedule_event(cs); 1004 gigaset_schedule_event(cs);
1014 1005
1015 wait_event(cs->waitqueue, !cs->waiting); 1006 wait_event(cs->waitqueue, !cs->waiting);
diff --git a/drivers/isdn/gigaset/ev-layer.c b/drivers/isdn/gigaset/ev-layer.c
index ddeb0456d202..c8f89b78b233 100644
--- a/drivers/isdn/gigaset/ev-layer.c
+++ b/drivers/isdn/gigaset/ev-layer.c
@@ -427,7 +427,7 @@ static int isdn_getnum(char *p)
427{ 427{
428 int v = -1; 428 int v = -1;
429 429
430 gig_dbg(DEBUG_TRANSCMD, "string: %s", p); 430 gig_dbg(DEBUG_EVENT, "string: %s", p);
431 431
432 while (*p >= '0' && *p <= '9') 432 while (*p >= '0' && *p <= '9')
433 v = ((v < 0) ? 0 : (v * 10)) + (int) ((*p++) - '0'); 433 v = ((v < 0) ? 0 : (v * 10)) + (int) ((*p++) - '0');
@@ -444,7 +444,7 @@ static int isdn_gethex(char *p)
444 int v = 0; 444 int v = 0;
445 int c; 445 int c;
446 446
447 gig_dbg(DEBUG_TRANSCMD, "string: %s", p); 447 gig_dbg(DEBUG_EVENT, "string: %s", p);
448 448
449 if (!*p) 449 if (!*p)
450 return -1; 450 return -1;
@@ -517,7 +517,6 @@ void gigaset_handle_modem_response(struct cardstate *cs)
517 return; 517 return;
518 } 518 }
519 cs->respdata[len] = 0; 519 cs->respdata[len] = 0;
520 gig_dbg(DEBUG_TRANSCMD, "raw string: '%s'", cs->respdata);
521 argv[0] = cs->respdata; 520 argv[0] = cs->respdata;
522 params = 1; 521 params = 1;
523 if (cs->at_state.getstring) { 522 if (cs->at_state.getstring) {
@@ -552,14 +551,14 @@ void gigaset_handle_modem_response(struct cardstate *cs)
552 for (j = 1; j < params; ++j) 551 for (j = 1; j < params; ++j)
553 argv[j][-1] = 0; 552 argv[j][-1] = 0;
554 553
555 gig_dbg(DEBUG_TRANSCMD, "CMD received: %s", argv[0]); 554 gig_dbg(DEBUG_EVENT, "CMD received: %s", argv[0]);
556 if (cid) { 555 if (cid) {
557 --params; 556 --params;
558 gig_dbg(DEBUG_TRANSCMD, "CID: %s", argv[params]); 557 gig_dbg(DEBUG_EVENT, "CID: %s", argv[params]);
559 } 558 }
560 gig_dbg(DEBUG_TRANSCMD, "available params: %d", params - 1); 559 gig_dbg(DEBUG_EVENT, "available params: %d", params - 1);
561 for (j = 1; j < params; j++) 560 for (j = 1; j < params; j++)
562 gig_dbg(DEBUG_TRANSCMD, "param %d: %s", j, argv[j]); 561 gig_dbg(DEBUG_EVENT, "param %d: %s", j, argv[j]);
563 } 562 }
564 563
565 spin_lock_irqsave(&cs->ev_lock, flags); 564 spin_lock_irqsave(&cs->ev_lock, flags);
@@ -642,7 +641,7 @@ void gigaset_handle_modem_response(struct cardstate *cs)
642 dev_err(cs->dev, "out of memory\n"); 641 dev_err(cs->dev, "out of memory\n");
643 ++curarg; 642 ++curarg;
644 } 643 }
645 gig_dbg(DEBUG_CMD, "string==%s", 644 gig_dbg(DEBUG_EVENT, "string==%s",
646 event->ptr ? (char *) event->ptr : "NULL"); 645 event->ptr ? (char *) event->ptr : "NULL");
647 break; 646 break;
648 case RT_ZCAU: 647 case RT_ZCAU:
@@ -669,7 +668,7 @@ void gigaset_handle_modem_response(struct cardstate *cs)
669 ++curarg; 668 ++curarg;
670 } else 669 } else
671 event->parameter = -1; 670 event->parameter = -1;
672 gig_dbg(DEBUG_CMD, "parameter==%d", event->parameter); 671 gig_dbg(DEBUG_EVENT, "parameter==%d", event->parameter);
673 break; 672 break;
674 } 673 }
675 674
@@ -684,7 +683,7 @@ void gigaset_handle_modem_response(struct cardstate *cs)
684 spin_unlock_irqrestore(&cs->ev_lock, flags); 683 spin_unlock_irqrestore(&cs->ev_lock, flags);
685 684
686 if (curarg != params) 685 if (curarg != params)
687 gig_dbg(DEBUG_ANY, 686 gig_dbg(DEBUG_EVENT,
688 "invalid number of processed parameters: %d/%d", 687 "invalid number of processed parameters: %d/%d",
689 curarg, params); 688 curarg, params);
690} 689}
@@ -705,8 +704,8 @@ static void disconnect(struct at_state_t **at_state_p)
705 /* revert to selected idle mode */ 704 /* revert to selected idle mode */
706 if (!cs->cidmode) { 705 if (!cs->cidmode) {
707 cs->at_state.pending_commands |= PC_UMMODE; 706 cs->at_state.pending_commands |= PC_UMMODE;
707 gig_dbg(DEBUG_EVENT, "Scheduling PC_UMMODE");
708 cs->commands_pending = 1; 708 cs->commands_pending = 1;
709 gig_dbg(DEBUG_CMD, "Scheduling PC_UMMODE");
710 } 709 }
711 spin_unlock_irqrestore(&cs->lock, flags); 710 spin_unlock_irqrestore(&cs->lock, flags);
712 711
@@ -784,15 +783,15 @@ static void init_failed(struct cardstate *cs, int mode)
784static void schedule_init(struct cardstate *cs, int state) 783static void schedule_init(struct cardstate *cs, int state)
785{ 784{
786 if (cs->at_state.pending_commands & PC_INIT) { 785 if (cs->at_state.pending_commands & PC_INIT) {
787 gig_dbg(DEBUG_CMD, "not scheduling PC_INIT again"); 786 gig_dbg(DEBUG_EVENT, "not scheduling PC_INIT again");
788 return; 787 return;
789 } 788 }
790 cs->mstate = state; 789 cs->mstate = state;
791 cs->mode = M_UNKNOWN; 790 cs->mode = M_UNKNOWN;
792 gigaset_block_channels(cs); 791 gigaset_block_channels(cs);
793 cs->at_state.pending_commands |= PC_INIT; 792 cs->at_state.pending_commands |= PC_INIT;
793 gig_dbg(DEBUG_EVENT, "Scheduling PC_INIT");
794 cs->commands_pending = 1; 794 cs->commands_pending = 1;
795 gig_dbg(DEBUG_CMD, "Scheduling PC_INIT");
796} 795}
797 796
798/* 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
@@ -923,7 +922,7 @@ static void start_dial(struct at_state_t *at_state, void *data,
923 } 922 }
924 923
925 at_state->pending_commands |= PC_CID; 924 at_state->pending_commands |= PC_CID;
926 gig_dbg(DEBUG_CMD, "Scheduling PC_CID"); 925 gig_dbg(DEBUG_EVENT, "Scheduling PC_CID");
927 cs->commands_pending = 1; 926 cs->commands_pending = 1;
928 return; 927 return;
929 928
@@ -933,7 +932,7 @@ error:
933 commands[i] = NULL; 932 commands[i] = NULL;
934 } 933 }
935 at_state->pending_commands |= PC_NOCID; 934 at_state->pending_commands |= PC_NOCID;
936 gig_dbg(DEBUG_CMD, "Scheduling PC_NOCID"); 935 gig_dbg(DEBUG_EVENT, "Scheduling PC_NOCID");
937 cs->commands_pending = 1; 936 cs->commands_pending = 1;
938 return; 937 return;
939} 938}
@@ -955,7 +954,7 @@ static void start_accept(struct at_state_t *at_state)
955 dev_err(at_state->cs->dev, "out of memory\n"); 954 dev_err(at_state->cs->dev, "out of memory\n");
956 /* error reset */ 955 /* error reset */
957 at_state->pending_commands |= PC_HUP; 956 at_state->pending_commands |= PC_HUP;
958 gig_dbg(DEBUG_CMD, "Scheduling PC_HUP"); 957 gig_dbg(DEBUG_EVENT, "Scheduling PC_HUP");
959 cs->commands_pending = 1; 958 cs->commands_pending = 1;
960 return; 959 return;
961 } 960 }
@@ -964,7 +963,7 @@ static void start_accept(struct at_state_t *at_state)
964 snprintf(bcs->commands[AT_ISO], 9, "^SISO=%u\r", bcs->channel + 1); 963 snprintf(bcs->commands[AT_ISO], 9, "^SISO=%u\r", bcs->channel + 1);
965 964
966 at_state->pending_commands |= PC_ACCEPT; 965 at_state->pending_commands |= PC_ACCEPT;
967 gig_dbg(DEBUG_CMD, "Scheduling PC_ACCEPT"); 966 gig_dbg(DEBUG_EVENT, "Scheduling PC_ACCEPT");
968 cs->commands_pending = 1; 967 cs->commands_pending = 1;
969} 968}
970 969
@@ -1009,8 +1008,8 @@ static void do_shutdown(struct cardstate *cs)
1009 if (cs->mstate == MS_READY) { 1008 if (cs->mstate == MS_READY) {
1010 cs->mstate = MS_SHUTDOWN; 1009 cs->mstate = MS_SHUTDOWN;
1011 cs->at_state.pending_commands |= PC_SHUTDOWN; 1010 cs->at_state.pending_commands |= PC_SHUTDOWN;
1011 gig_dbg(DEBUG_EVENT, "Scheduling PC_SHUTDOWN");
1012 cs->commands_pending = 1; 1012 cs->commands_pending = 1;
1013 gig_dbg(DEBUG_CMD, "Scheduling PC_SHUTDOWN");
1014 } else 1013 } else
1015 finish_shutdown(cs); 1014 finish_shutdown(cs);
1016} 1015}
@@ -1191,8 +1190,8 @@ static void do_action(int action, struct cardstate *cs,
1191 } 1190 }
1192 spin_unlock_irqrestore(&cs->lock, flags); 1191 spin_unlock_irqrestore(&cs->lock, flags);
1193 cs->at_state.pending_commands |= PC_CIDMODE; 1192 cs->at_state.pending_commands |= PC_CIDMODE;
1193 gig_dbg(DEBUG_EVENT, "Scheduling PC_CIDMODE");
1194 cs->commands_pending = 1; 1194 cs->commands_pending = 1;
1195 gig_dbg(DEBUG_CMD, "Scheduling PC_CIDMODE");
1196 break; 1195 break;
1197 case ACT_FAILINIT: 1196 case ACT_FAILINIT:
1198 dev_warn(cs->dev, "Could not initialize the device.\n"); 1197 dev_warn(cs->dev, "Could not initialize the device.\n");
@@ -1443,7 +1442,7 @@ static void do_action(int action, struct cardstate *cs,
1443 case ACT_GOTVER: 1442 case ACT_GOTVER:
1444 if (cs->gotfwver == 0) { 1443 if (cs->gotfwver == 0) {
1445 cs->gotfwver = 1; 1444 cs->gotfwver = 1;
1446 gig_dbg(DEBUG_ANY, 1445 gig_dbg(DEBUG_EVENT,
1447 "firmware version %02d.%03d.%02d.%02d", 1446 "firmware version %02d.%03d.%02d.%02d",
1448 cs->fwver[0], cs->fwver[1], 1447 cs->fwver[0], cs->fwver[1],
1449 cs->fwver[2], cs->fwver[3]); 1448 cs->fwver[2], cs->fwver[3]);
@@ -1481,8 +1480,8 @@ static void do_action(int action, struct cardstate *cs,
1481 break; 1480 break;
1482 case ACT_HUP: 1481 case ACT_HUP:
1483 at_state->pending_commands |= PC_HUP; 1482 at_state->pending_commands |= PC_HUP;
1483 gig_dbg(DEBUG_EVENT, "Scheduling PC_HUP");
1484 cs->commands_pending = 1; 1484 cs->commands_pending = 1;
1485 gig_dbg(DEBUG_CMD, "Scheduling PC_HUP");
1486 break; 1485 break;
1487 1486
1488 /* hotplug events */ 1487 /* hotplug events */
@@ -1519,10 +1518,10 @@ static void do_action(int action, struct cardstate *cs,
1519 cs->cidmode = ev->parameter; 1518 cs->cidmode = ev->parameter;
1520 if (ev->parameter) { 1519 if (ev->parameter) {
1521 cs->at_state.pending_commands |= PC_CIDMODE; 1520 cs->at_state.pending_commands |= PC_CIDMODE;
1522 gig_dbg(DEBUG_CMD, "Scheduling PC_CIDMODE"); 1521 gig_dbg(DEBUG_EVENT, "Scheduling PC_CIDMODE");
1523 } else { 1522 } else {
1524 cs->at_state.pending_commands |= PC_UMMODE; 1523 cs->at_state.pending_commands |= PC_UMMODE;
1525 gig_dbg(DEBUG_CMD, "Scheduling PC_UMMODE"); 1524 gig_dbg(DEBUG_EVENT, "Scheduling PC_UMMODE");
1526 } 1525 }
1527 cs->commands_pending = 1; 1526 cs->commands_pending = 1;
1528 } 1527 }
@@ -1573,6 +1572,8 @@ static void process_event(struct cardstate *cs, struct event_t *ev)
1573 if (ev->cid >= 0) { 1572 if (ev->cid >= 0) {
1574 at_state = at_state_from_cid(cs, ev->cid); 1573 at_state = at_state_from_cid(cs, ev->cid);
1575 if (!at_state) { 1574 if (!at_state) {
1575 gig_dbg(DEBUG_EVENT, "event %d for invalid cid %d",
1576 ev->type, ev->cid);
1576 gigaset_add_event(cs, &cs->at_state, RSP_WRONG_CID, 1577 gigaset_add_event(cs, &cs->at_state, RSP_WRONG_CID,
1577 NULL, 0, NULL); 1578 NULL, 0, NULL);
1578 return; 1579 return;
@@ -1580,13 +1581,13 @@ static void process_event(struct cardstate *cs, struct event_t *ev)
1580 } else { 1581 } else {
1581 at_state = ev->at_state; 1582 at_state = ev->at_state;
1582 if (at_state_invalid(cs, at_state)) { 1583 if (at_state_invalid(cs, at_state)) {
1583 gig_dbg(DEBUG_ANY, "event for invalid at_state %p", 1584 gig_dbg(DEBUG_EVENT, "event for invalid at_state %p",
1584 at_state); 1585 at_state);
1585 return; 1586 return;
1586 } 1587 }
1587 } 1588 }
1588 1589
1589 gig_dbg(DEBUG_CMD, "connection state %d, event %d", 1590 gig_dbg(DEBUG_EVENT, "connection state %d, event %d",
1590 at_state->ConState, ev->type); 1591 at_state->ConState, ev->type);
1591 1592
1592 bcs = at_state->bcs; 1593 bcs = at_state->bcs;
@@ -1600,11 +1601,11 @@ static void process_event(struct cardstate *cs, struct event_t *ev)
1600 if (ev->parameter != at_state->timer_index 1601 if (ev->parameter != at_state->timer_index
1601 || !at_state->timer_active) { 1602 || !at_state->timer_active) {
1602 ev->type = RSP_NONE; /* old timeout */ 1603 ev->type = RSP_NONE; /* old timeout */
1603 gig_dbg(DEBUG_ANY, "old timeout"); 1604 gig_dbg(DEBUG_EVENT, "old timeout");
1604 } else if (!at_state->waiting) 1605 } else if (!at_state->waiting)
1605 gig_dbg(DEBUG_ANY, "timeout occurred"); 1606 gig_dbg(DEBUG_EVENT, "timeout occurred");
1606 else 1607 else
1607 gig_dbg(DEBUG_ANY, "stopped waiting"); 1608 gig_dbg(DEBUG_EVENT, "stopped waiting");
1608 } 1609 }
1609 spin_unlock_irqrestore(&cs->lock, flags); 1610 spin_unlock_irqrestore(&cs->lock, flags);
1610 1611
@@ -1712,11 +1713,11 @@ static void process_command_flags(struct cardstate *cs)
1712 cs->commands_pending = 0; 1713 cs->commands_pending = 0;
1713 1714
1714 if (cs->cur_at_seq) { 1715 if (cs->cur_at_seq) {
1715 gig_dbg(DEBUG_CMD, "not searching scheduled commands: busy"); 1716 gig_dbg(DEBUG_EVENT, "not searching scheduled commands: busy");
1716 return; 1717 return;
1717 } 1718 }
1718 1719
1719 gig_dbg(DEBUG_CMD, "searching scheduled commands"); 1720 gig_dbg(DEBUG_EVENT, "searching scheduled commands");
1720 1721
1721 sequence = SEQ_NONE; 1722 sequence = SEQ_NONE;
1722 1723
@@ -1857,7 +1858,7 @@ static void process_command_flags(struct cardstate *cs)
1857 switch (cs->mode) { 1858 switch (cs->mode) {
1858 case M_UNIMODEM: 1859 case M_UNIMODEM:
1859 cs->at_state.pending_commands |= PC_CIDMODE; 1860 cs->at_state.pending_commands |= PC_CIDMODE;
1860 gig_dbg(DEBUG_CMD, "Scheduling PC_CIDMODE"); 1861 gig_dbg(DEBUG_EVENT, "Scheduling PC_CIDMODE");
1861 cs->commands_pending = 1; 1862 cs->commands_pending = 1;
1862 return; 1863 return;
1863#ifdef GIG_MAYINITONDIAL 1864#ifdef GIG_MAYINITONDIAL
diff --git a/drivers/isdn/gigaset/gigaset.h b/drivers/isdn/gigaset/gigaset.h
index e963a6c2e86d..1875ab80b335 100644
--- a/drivers/isdn/gigaset/gigaset.h
+++ b/drivers/isdn/gigaset/gigaset.h
@@ -38,7 +38,7 @@
38#define GIG_COMPAT {0, 4, 0, 0} 38#define GIG_COMPAT {0, 4, 0, 0}
39 39
40#define MAX_REC_PARAMS 10 /* Max. number of params in response string */ 40#define MAX_REC_PARAMS 10 /* Max. number of params in response string */
41#define MAX_RESP_SIZE 512 /* Max. size of a response string */ 41#define MAX_RESP_SIZE 511 /* Max. size of a response string */
42 42
43#define MAX_EVENTS 64 /* size of event queue */ 43#define MAX_EVENTS 64 /* size of event queue */
44 44
@@ -78,9 +78,10 @@ enum debuglevel {
78 DEBUG_STREAM = 0x00040, /* application data stream I/O events */ 78 DEBUG_STREAM = 0x00040, /* application data stream I/O events */
79 DEBUG_STREAM_DUMP = 0x00080, /* application data stream content */ 79 DEBUG_STREAM_DUMP = 0x00080, /* application data stream content */
80 DEBUG_LLDATA = 0x00100, /* sent/received LL data */ 80 DEBUG_LLDATA = 0x00100, /* sent/received LL data */
81 DEBUG_EVENT = 0x00200, /* event processing */
81 DEBUG_DRIVER = 0x00400, /* driver structure */ 82 DEBUG_DRIVER = 0x00400, /* driver structure */
82 DEBUG_HDLC = 0x00800, /* M10x HDLC processing */ 83 DEBUG_HDLC = 0x00800, /* M10x HDLC processing */
83 DEBUG_WRITE = 0x01000, /* M105 data write */ 84 DEBUG_CHANNEL = 0x01000, /* channel allocation/deallocation */
84 DEBUG_TRANSCMD = 0x02000, /* AT-COMMANDS+RESPONSES */ 85 DEBUG_TRANSCMD = 0x02000, /* AT-COMMANDS+RESPONSES */
85 DEBUG_MCMD = 0x04000, /* COMMANDS THAT ARE SENT VERY OFTEN */ 86 DEBUG_MCMD = 0x04000, /* COMMANDS THAT ARE SENT VERY OFTEN */
86 DEBUG_INIT = 0x08000, /* (de)allocation+initialization of data 87 DEBUG_INIT = 0x08000, /* (de)allocation+initialization of data
@@ -498,7 +499,7 @@ struct cardstate {
498 spinlock_t ev_lock; 499 spinlock_t ev_lock;
499 500
500 /* current modem response */ 501 /* current modem response */
501 unsigned char respdata[MAX_RESP_SIZE]; 502 unsigned char respdata[MAX_RESP_SIZE+1];
502 unsigned cbytes; 503 unsigned cbytes;
503 504
504 /* private data of hardware drivers */ 505 /* private data of hardware drivers */
@@ -785,8 +786,6 @@ static inline void gigaset_schedule_event(struct cardstate *cs)
785static inline void gigaset_bchannel_down(struct bc_state *bcs) 786static inline void gigaset_bchannel_down(struct bc_state *bcs)
786{ 787{
787 gigaset_add_event(bcs->cs, &bcs->at_state, EV_BC_CLOSED, NULL, 0, NULL); 788 gigaset_add_event(bcs->cs, &bcs->at_state, EV_BC_CLOSED, NULL, 0, NULL);
788
789 gig_dbg(DEBUG_CMD, "scheduling BC_CLOSED");
790 gigaset_schedule_event(bcs->cs); 789 gigaset_schedule_event(bcs->cs);
791} 790}
792 791
@@ -795,8 +794,6 @@ static inline void gigaset_bchannel_down(struct bc_state *bcs)
795static inline void gigaset_bchannel_up(struct bc_state *bcs) 794static inline void gigaset_bchannel_up(struct bc_state *bcs)
796{ 795{
797 gigaset_add_event(bcs->cs, &bcs->at_state, EV_BC_OPEN, NULL, 0, NULL); 796 gigaset_add_event(bcs->cs, &bcs->at_state, EV_BC_OPEN, NULL, 0, NULL);
798
799 gig_dbg(DEBUG_CMD, "scheduling BC_OPEN");
800 gigaset_schedule_event(bcs->cs); 797 gigaset_schedule_event(bcs->cs);
801} 798}
802 799
diff --git a/drivers/isdn/gigaset/i4l.c b/drivers/isdn/gigaset/i4l.c
index c129ee47a8fb..f0acb9dc9e33 100644
--- a/drivers/isdn/gigaset/i4l.c
+++ b/drivers/isdn/gigaset/i4l.c
@@ -216,7 +216,7 @@ static int command_from_LL(isdn_ctrl *cntrl)
216 return -EINVAL; 216 return -EINVAL;
217 217
218 case ISDN_CMD_DIAL: 218 case ISDN_CMD_DIAL:
219 gig_dbg(DEBUG_ANY, 219 gig_dbg(DEBUG_CMD,
220 "ISDN_CMD_DIAL (phone: %s, msn: %s, si1: %d, si2: %d)", 220 "ISDN_CMD_DIAL (phone: %s, msn: %s, si1: %d, si2: %d)",
221 cntrl->parm.setup.phone, cntrl->parm.setup.eazmsn, 221 cntrl->parm.setup.phone, cntrl->parm.setup.eazmsn,
222 cntrl->parm.setup.si1, cntrl->parm.setup.si2); 222 cntrl->parm.setup.si1, cntrl->parm.setup.si2);
@@ -304,11 +304,10 @@ static int command_from_LL(isdn_ctrl *cntrl)
304 gigaset_free_channel(bcs); 304 gigaset_free_channel(bcs);
305 return -ENOMEM; 305 return -ENOMEM;
306 } 306 }
307
308 gig_dbg(DEBUG_CMD, "scheduling DIAL");
309 gigaset_schedule_event(cs); 307 gigaset_schedule_event(cs);
310 break; 308 break;
311 case ISDN_CMD_ACCEPTD: 309 case ISDN_CMD_ACCEPTD:
310 gig_dbg(DEBUG_CMD, "ISDN_CMD_ACCEPTD");
312 if (ch >= cs->channels) { 311 if (ch >= cs->channels) {
313 dev_err(cs->dev, 312 dev_err(cs->dev,
314 "ISDN_CMD_ACCEPTD: invalid channel (%d)\n", ch); 313 "ISDN_CMD_ACCEPTD: invalid channel (%d)\n", ch);
@@ -318,14 +317,11 @@ static int command_from_LL(isdn_ctrl *cntrl)
318 if (!gigaset_add_event(cs, &bcs->at_state, 317 if (!gigaset_add_event(cs, &bcs->at_state,
319 EV_ACCEPT, NULL, 0, NULL)) 318 EV_ACCEPT, NULL, 0, NULL))
320 return -ENOMEM; 319 return -ENOMEM;
321
322 gig_dbg(DEBUG_CMD, "scheduling ACCEPT");
323 gigaset_schedule_event(cs); 320 gigaset_schedule_event(cs);
324 321
325 break; 322 break;
326 case ISDN_CMD_ACCEPTB:
327 break;
328 case ISDN_CMD_HANGUP: 323 case ISDN_CMD_HANGUP:
324 gig_dbg(DEBUG_CMD, "ISDN_CMD_HANGUP");
329 if (ch >= cs->channels) { 325 if (ch >= cs->channels) {
330 dev_err(cs->dev, 326 dev_err(cs->dev,
331 "ISDN_CMD_HANGUP: invalid channel (%d)\n", ch); 327 "ISDN_CMD_HANGUP: invalid channel (%d)\n", ch);
@@ -335,8 +331,6 @@ static int command_from_LL(isdn_ctrl *cntrl)
335 if (!gigaset_add_event(cs, &bcs->at_state, 331 if (!gigaset_add_event(cs, &bcs->at_state,
336 EV_HUP, NULL, 0, NULL)) 332 EV_HUP, NULL, 0, NULL))
337 return -ENOMEM; 333 return -ENOMEM;
338
339 gig_dbg(DEBUG_CMD, "scheduling HUP");
340 gigaset_schedule_event(cs); 334 gigaset_schedule_event(cs);
341 335
342 break; 336 break;
@@ -376,6 +370,7 @@ static int command_from_LL(isdn_ctrl *cntrl)
376 } 370 }
377 break; 371 break;
378 case ISDN_CMD_SETL3: /* Set L3 to given protocol */ 372 case ISDN_CMD_SETL3: /* Set L3 to given protocol */
373 gig_dbg(DEBUG_CMD, "ISDN_CMD_SETL3");
379 if (ch >= cs->channels) { 374 if (ch >= cs->channels) {
380 dev_err(cs->dev, 375 dev_err(cs->dev,
381 "ISDN_CMD_SETL3: invalid channel (%d)\n", ch); 376 "ISDN_CMD_SETL3: invalid channel (%d)\n", ch);
@@ -390,44 +385,9 @@ static int command_from_LL(isdn_ctrl *cntrl)
390 } 385 }
391 386
392 break; 387 break;
393 case ISDN_CMD_PROCEED: 388
394 gig_dbg(DEBUG_ANY, "ISDN_CMD_PROCEED");
395 break;
396 case ISDN_CMD_ALERT:
397 gig_dbg(DEBUG_ANY, "ISDN_CMD_ALERT");
398 if (cntrl->arg >= cs->channels) {
399 dev_err(cs->dev,
400 "ISDN_CMD_ALERT: invalid channel (%d)\n",
401 (int) cntrl->arg);
402 return -EINVAL;
403 }
404 break;
405 case ISDN_CMD_REDIR:
406 gig_dbg(DEBUG_ANY, "ISDN_CMD_REDIR");
407 break;
408 case ISDN_CMD_PROT_IO:
409 gig_dbg(DEBUG_ANY, "ISDN_CMD_PROT_IO");
410 break;
411 case ISDN_CMD_FAXCMD:
412 gig_dbg(DEBUG_ANY, "ISDN_CMD_FAXCMD");
413 break;
414 case ISDN_CMD_GETL2:
415 gig_dbg(DEBUG_ANY, "ISDN_CMD_GETL2");
416 break;
417 case ISDN_CMD_GETL3:
418 gig_dbg(DEBUG_ANY, "ISDN_CMD_GETL3");
419 break;
420 case ISDN_CMD_GETEAZ:
421 gig_dbg(DEBUG_ANY, "ISDN_CMD_GETEAZ");
422 break;
423 case ISDN_CMD_SETSIL:
424 gig_dbg(DEBUG_ANY, "ISDN_CMD_SETSIL");
425 break;
426 case ISDN_CMD_GETSIL:
427 gig_dbg(DEBUG_ANY, "ISDN_CMD_GETSIL");
428 break;
429 default: 389 default:
430 dev_err(cs->dev, "unknown command %d from LL\n", 390 gig_dbg(DEBUG_CMD, "unknown command %d from LL",
431 cntrl->command); 391 cntrl->command);
432 return -EINVAL; 392 return -EINVAL;
433 } 393 }
diff --git a/drivers/isdn/gigaset/interface.c b/drivers/isdn/gigaset/interface.c
index d2260b0055fc..a1bcbc21ff71 100644
--- a/drivers/isdn/gigaset/interface.c
+++ b/drivers/isdn/gigaset/interface.c
@@ -45,8 +45,6 @@ static int if_lock(struct cardstate *cs, int *arg)
45 cs->waiting = 0; 45 cs->waiting = 0;
46 return -ENOMEM; 46 return -ENOMEM;
47 } 47 }
48
49 gig_dbg(DEBUG_CMD, "scheduling IF_LOCK");
50 gigaset_schedule_event(cs); 48 gigaset_schedule_event(cs);
51 49
52 wait_event(cs->waitqueue, !cs->waiting); 50 wait_event(cs->waitqueue, !cs->waiting);
@@ -81,8 +79,6 @@ static int if_version(struct cardstate *cs, unsigned arg[4])
81 cs->waiting = 0; 79 cs->waiting = 0;
82 return -ENOMEM; 80 return -ENOMEM;
83 } 81 }
84
85 gig_dbg(DEBUG_CMD, "scheduling IF_VER");
86 gigaset_schedule_event(cs); 82 gigaset_schedule_event(cs);
87 83
88 wait_event(cs->waitqueue, !cs->waiting); 84 wait_event(cs->waitqueue, !cs->waiting);
@@ -274,7 +270,7 @@ static int if_ioctl(struct tty_struct *tty, struct file *file,
274 ? -EFAULT : 0; 270 ? -EFAULT : 0;
275 break; 271 break;
276 default: 272 default:
277 gig_dbg(DEBUG_ANY, "%s: arg not supported - 0x%04x", 273 gig_dbg(DEBUG_IF, "%s: arg not supported - 0x%04x",
278 __func__, cmd); 274 __func__, cmd);
279 retval = -ENOIOCTLCMD; 275 retval = -ENOIOCTLCMD;
280 } 276 }
@@ -455,7 +451,7 @@ static void if_throttle(struct tty_struct *tty)
455 else if (!cs->open_count) 451 else if (!cs->open_count)
456 dev_warn(cs->dev, "%s: device not opened\n", __func__); 452 dev_warn(cs->dev, "%s: device not opened\n", __func__);
457 else 453 else
458 gig_dbg(DEBUG_ANY, "%s: not implemented\n", __func__); 454 gig_dbg(DEBUG_IF, "%s: not implemented\n", __func__);
459 455
460 mutex_unlock(&cs->mutex); 456 mutex_unlock(&cs->mutex);
461} 457}
@@ -479,7 +475,7 @@ static void if_unthrottle(struct tty_struct *tty)
479 else if (!cs->open_count) 475 else if (!cs->open_count)
480 dev_warn(cs->dev, "%s: device not opened\n", __func__); 476 dev_warn(cs->dev, "%s: device not opened\n", __func__);
481 else 477 else
482 gig_dbg(DEBUG_ANY, "%s: not implemented\n", __func__); 478 gig_dbg(DEBUG_IF, "%s: not implemented\n", __func__);
483 479
484 mutex_unlock(&cs->mutex); 480 mutex_unlock(&cs->mutex);
485} 481}
@@ -630,7 +626,7 @@ void gigaset_if_receive(struct cardstate *cs,
630 spin_lock_irqsave(&cs->lock, flags); 626 spin_lock_irqsave(&cs->lock, flags);
631 tty = cs->tty; 627 tty = cs->tty;
632 if (tty == NULL) 628 if (tty == NULL)
633 gig_dbg(DEBUG_ANY, "receive on closed device"); 629 gig_dbg(DEBUG_IF, "receive on closed device");
634 else { 630 else {
635 tty_buffer_request_room(tty, len); 631 tty_buffer_request_room(tty, len);
636 tty_insert_flip_string(tty, buffer, len); 632 tty_insert_flip_string(tty, buffer, len);
diff --git a/drivers/isdn/gigaset/isocdata.c b/drivers/isdn/gigaset/isocdata.c
index 85394a6ebae8..16fd3bd48883 100644
--- a/drivers/isdn/gigaset/isocdata.c
+++ b/drivers/isdn/gigaset/isocdata.c
@@ -905,29 +905,49 @@ void gigaset_isoc_receive(unsigned char *src, unsigned count,
905 905
906/* == data input =========================================================== */ 906/* == data input =========================================================== */
907 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 */
908static 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)
909{ 915{
910 struct cardstate *cs = inbuf->cs; 916 struct cardstate *cs = inbuf->cs;
911 unsigned cbytes = cs->cbytes; 917 unsigned cbytes = cs->cbytes;
918 unsigned char c;
912 919
913 while (numbytes--) { 920 while (numbytes--) {
914 /* copy next character, check for end of line */ 921 c = *src++;
915 switch (cs->respdata[cbytes] = *src++) { 922 switch (c) {
916 case '\r':
917 case '\n': 923 case '\n':
918 /* end of line */ 924 if (cbytes == 0 && cs->respdata[0] == '\r') {
919 gig_dbg(DEBUG_TRANSCMD, "%s: End of Command (%d Bytes)", 925 /* collapse LF with preceding CR */
920 __func__, cbytes); 926 cs->respdata[0] = 0;
921 if (cbytes >= MAX_RESP_SIZE - 1) 927 break;
922 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 }
923 cs->cbytes = cbytes; 937 cs->cbytes = cbytes;
938 gigaset_dbg_buffer(DEBUG_TRANSCMD, "received response",
939 cbytes, cs->respdata);
924 gigaset_handle_modem_response(cs); 940 gigaset_handle_modem_response(cs);
925 cbytes = 0; 941 cbytes = 0;
942
943 /* store EOL byte for CRLF collapsing */
944 cs->respdata[0] = c;
926 break; 945 break;
927 default: 946 default:
928 /* advance in line buffer, checking for overflow */ 947 /* append to line buffer if possible */
929 if (cbytes < MAX_RESP_SIZE - 1) 948 if (cbytes < MAX_RESP_SIZE)
930 cbytes++; 949 cs->respdata[cbytes] = c;
950 cbytes++;
931 } 951 }
932 } 952 }
933 953
@@ -958,8 +978,6 @@ void gigaset_isoc_input(struct inbuf_t *inbuf)
958 numbytes, src); 978 numbytes, src);
959 gigaset_if_receive(inbuf->cs, src, numbytes); 979 gigaset_if_receive(inbuf->cs, src, numbytes);
960 } else { 980 } else {
961 gigaset_dbg_buffer(DEBUG_CMD, "received response",
962 numbytes, src);
963 cmd_loop(src, numbytes, inbuf); 981 cmd_loop(src, numbytes, inbuf);
964 } 982 }
965 983
diff --git a/drivers/isdn/gigaset/proc.c b/drivers/isdn/gigaset/proc.c
index 758a00c1d2e2..b69f73a0668f 100644
--- a/drivers/isdn/gigaset/proc.c
+++ b/drivers/isdn/gigaset/proc.c
@@ -48,8 +48,6 @@ static ssize_t set_cidmode(struct device *dev, struct device_attribute *attr,
48 mutex_unlock(&cs->mutex); 48 mutex_unlock(&cs->mutex);
49 return -ENOMEM; 49 return -ENOMEM;
50 } 50 }
51
52 gig_dbg(DEBUG_CMD, "scheduling PROC_CIDMODE");
53 gigaset_schedule_event(cs); 51 gigaset_schedule_event(cs);
54 52
55 wait_event(cs->waitqueue, !cs->waiting); 53 wait_event(cs->waitqueue, !cs->waiting);
diff --git a/drivers/isdn/gigaset/usb-gigaset.c b/drivers/isdn/gigaset/usb-gigaset.c
index 3ab1daeb276b..9430a2bbb523 100644
--- a/drivers/isdn/gigaset/usb-gigaset.c
+++ b/drivers/isdn/gigaset/usb-gigaset.c
@@ -628,7 +628,7 @@ static int write_modem(struct cardstate *cs)
628 struct usb_cardstate *ucs = cs->hw.usb; 628 struct usb_cardstate *ucs = cs->hw.usb;
629 unsigned long flags; 629 unsigned long flags;
630 630
631 gig_dbg(DEBUG_WRITE, "len: %d...", bcs->tx_skb->len); 631 gig_dbg(DEBUG_OUTPUT, "len: %d...", bcs->tx_skb->len);
632 632
633 if (!bcs->tx_skb->len) { 633 if (!bcs->tx_skb->len) {
634 dev_kfree_skb_any(bcs->tx_skb); 634 dev_kfree_skb_any(bcs->tx_skb);
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..c38fa0f4c729 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>
@@ -634,18 +636,17 @@ irqreturn_t b1_interrupt(int interrupt, void *devptr)
634} 636}
635 637
636/* ------------------------------------------------------------- */ 638/* ------------------------------------------------------------- */
637int b1ctl_read_proc(char *page, char **start, off_t off, 639static int b1ctl_proc_show(struct seq_file *m, void *v)
638 int count, int *eof, struct capi_ctr *ctrl)
639{ 640{
641 struct capi_ctr *ctrl = m->private;
640 avmctrl_info *cinfo = (avmctrl_info *)(ctrl->driverdata); 642 avmctrl_info *cinfo = (avmctrl_info *)(ctrl->driverdata);
641 avmcard *card = cinfo->card; 643 avmcard *card = cinfo->card;
642 u8 flag; 644 u8 flag;
643 int len = 0;
644 char *s; 645 char *s;
645 646
646 len += sprintf(page+len, "%-16s %s\n", "name", card->name); 647 seq_printf(m, "%-16s %s\n", "name", card->name);
647 len += sprintf(page+len, "%-16s 0x%x\n", "io", card->port); 648 seq_printf(m, "%-16s 0x%x\n", "io", card->port);
648 len += sprintf(page+len, "%-16s %d\n", "irq", card->irq); 649 seq_printf(m, "%-16s %d\n", "irq", card->irq);
649 switch (card->cardtype) { 650 switch (card->cardtype) {
650 case avm_b1isa: s = "B1 ISA"; break; 651 case avm_b1isa: s = "B1 ISA"; break;
651 case avm_b1pci: s = "B1 PCI"; break; 652 case avm_b1pci: s = "B1 PCI"; break;
@@ -658,20 +659,20 @@ int b1ctl_read_proc(char *page, char **start, off_t off,
658 case avm_c2: s = "C2"; break; 659 case avm_c2: s = "C2"; break;
659 default: s = "???"; break; 660 default: s = "???"; break;
660 } 661 }
661 len += sprintf(page+len, "%-16s %s\n", "type", s); 662 seq_printf(m, "%-16s %s\n", "type", s);
662 if (card->cardtype == avm_t1isa) 663 if (card->cardtype == avm_t1isa)
663 len += sprintf(page+len, "%-16s %d\n", "cardnr", card->cardnr); 664 seq_printf(m, "%-16s %d\n", "cardnr", card->cardnr);
664 if ((s = cinfo->version[VER_DRIVER]) != NULL) 665 if ((s = cinfo->version[VER_DRIVER]) != NULL)
665 len += sprintf(page+len, "%-16s %s\n", "ver_driver", s); 666 seq_printf(m, "%-16s %s\n", "ver_driver", s);
666 if ((s = cinfo->version[VER_CARDTYPE]) != NULL) 667 if ((s = cinfo->version[VER_CARDTYPE]) != NULL)
667 len += sprintf(page+len, "%-16s %s\n", "ver_cardtype", s); 668 seq_printf(m, "%-16s %s\n", "ver_cardtype", s);
668 if ((s = cinfo->version[VER_SERIAL]) != NULL) 669 if ((s = cinfo->version[VER_SERIAL]) != NULL)
669 len += sprintf(page+len, "%-16s %s\n", "ver_serial", s); 670 seq_printf(m, "%-16s %s\n", "ver_serial", s);
670 671
671 if (card->cardtype != avm_m1) { 672 if (card->cardtype != avm_m1) {
672 flag = ((u8 *)(ctrl->profile.manu))[3]; 673 flag = ((u8 *)(ctrl->profile.manu))[3];
673 if (flag) 674 if (flag)
674 len += sprintf(page+len, "%-16s%s%s%s%s%s%s%s\n", 675 seq_printf(m, "%-16s%s%s%s%s%s%s%s\n",
675 "protocol", 676 "protocol",
676 (flag & 0x01) ? " DSS1" : "", 677 (flag & 0x01) ? " DSS1" : "",
677 (flag & 0x02) ? " CT1" : "", 678 (flag & 0x02) ? " CT1" : "",
@@ -685,7 +686,7 @@ int b1ctl_read_proc(char *page, char **start, off_t off,
685 if (card->cardtype != avm_m1) { 686 if (card->cardtype != avm_m1) {
686 flag = ((u8 *)(ctrl->profile.manu))[5]; 687 flag = ((u8 *)(ctrl->profile.manu))[5];
687 if (flag) 688 if (flag)
688 len += sprintf(page+len, "%-16s%s%s%s%s\n", 689 seq_printf(m, "%-16s%s%s%s%s\n",
689 "linetype", 690 "linetype",
690 (flag & 0x01) ? " point to point" : "", 691 (flag & 0x01) ? " point to point" : "",
691 (flag & 0x02) ? " point to multipoint" : "", 692 (flag & 0x02) ? " point to multipoint" : "",
@@ -693,16 +694,25 @@ int b1ctl_read_proc(char *page, char **start, off_t off,
693 (flag & 0x04) ? " leased line with D-channel" : "" 694 (flag & 0x04) ? " leased line with D-channel" : ""
694 ); 695 );
695 } 696 }
696 len += sprintf(page+len, "%-16s %s\n", "cardname", cinfo->cardname); 697 seq_printf(m, "%-16s %s\n", "cardname", cinfo->cardname);
697 698
698 if (off+count >= len) 699 return 0;
699 *eof = 1; 700}
700 if (len < off) 701
701 return 0; 702static int b1ctl_proc_open(struct inode *inode, struct file *file)
702 *start = page + off; 703{
703 return ((count < len-off) ? count : len-off); 704 return single_open(file, b1ctl_proc_show, PDE(inode)->data);
704} 705}
705 706
707const struct file_operations b1ctl_proc_fops = {
708 .owner = THIS_MODULE,
709 .open = b1ctl_proc_open,
710 .read = seq_read,
711 .llseek = seq_lseek,
712 .release = single_release,
713};
714EXPORT_SYMBOL(b1ctl_proc_fops);
715
706/* ------------------------------------------------------------- */ 716/* ------------------------------------------------------------- */
707 717
708#ifdef CONFIG_PCI 718#ifdef CONFIG_PCI
@@ -781,8 +791,6 @@ EXPORT_SYMBOL(b1_send_message);
781EXPORT_SYMBOL(b1_parse_version); 791EXPORT_SYMBOL(b1_parse_version);
782EXPORT_SYMBOL(b1_interrupt); 792EXPORT_SYMBOL(b1_interrupt);
783 793
784EXPORT_SYMBOL(b1ctl_read_proc);
785
786static int __init b1_init(void) 794static int __init b1_init(void)
787{ 795{
788 char *p; 796 char *p;
diff --git a/drivers/isdn/hardware/avm/b1dma.c b/drivers/isdn/hardware/avm/b1dma.c
index 0e84aaae43fd..124550d0dbf3 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>
@@ -855,21 +857,20 @@ u16 b1dma_send_message(struct capi_ctr *ctrl, struct sk_buff *skb)
855 857
856/* ------------------------------------------------------------- */ 858/* ------------------------------------------------------------- */
857 859
858int b1dmactl_read_proc(char *page, char **start, off_t off, 860static int b1dmactl_proc_show(struct seq_file *m, void *v)
859 int count, int *eof, struct capi_ctr *ctrl)
860{ 861{
862 struct capi_ctr *ctrl = m->private;
861 avmctrl_info *cinfo = (avmctrl_info *)(ctrl->driverdata); 863 avmctrl_info *cinfo = (avmctrl_info *)(ctrl->driverdata);
862 avmcard *card = cinfo->card; 864 avmcard *card = cinfo->card;
863 u8 flag; 865 u8 flag;
864 int len = 0;
865 char *s; 866 char *s;
866 u32 txoff, txlen, rxoff, rxlen, csr; 867 u32 txoff, txlen, rxoff, rxlen, csr;
867 unsigned long flags; 868 unsigned long flags;
868 869
869 len += sprintf(page+len, "%-16s %s\n", "name", card->name); 870 seq_printf(m, "%-16s %s\n", "name", card->name);
870 len += sprintf(page+len, "%-16s 0x%x\n", "io", card->port); 871 seq_printf(m, "%-16s 0x%x\n", "io", card->port);
871 len += sprintf(page+len, "%-16s %d\n", "irq", card->irq); 872 seq_printf(m, "%-16s %d\n", "irq", card->irq);
872 len += sprintf(page+len, "%-16s 0x%lx\n", "membase", card->membase); 873 seq_printf(m, "%-16s 0x%lx\n", "membase", card->membase);
873 switch (card->cardtype) { 874 switch (card->cardtype) {
874 case avm_b1isa: s = "B1 ISA"; break; 875 case avm_b1isa: s = "B1 ISA"; break;
875 case avm_b1pci: s = "B1 PCI"; break; 876 case avm_b1pci: s = "B1 PCI"; break;
@@ -882,18 +883,18 @@ int b1dmactl_read_proc(char *page, char **start, off_t off,
882 case avm_c2: s = "C2"; break; 883 case avm_c2: s = "C2"; break;
883 default: s = "???"; break; 884 default: s = "???"; break;
884 } 885 }
885 len += sprintf(page+len, "%-16s %s\n", "type", s); 886 seq_printf(m, "%-16s %s\n", "type", s);
886 if ((s = cinfo->version[VER_DRIVER]) != NULL) 887 if ((s = cinfo->version[VER_DRIVER]) != NULL)
887 len += sprintf(page+len, "%-16s %s\n", "ver_driver", s); 888 seq_printf(m, "%-16s %s\n", "ver_driver", s);
888 if ((s = cinfo->version[VER_CARDTYPE]) != NULL) 889 if ((s = cinfo->version[VER_CARDTYPE]) != NULL)
889 len += sprintf(page+len, "%-16s %s\n", "ver_cardtype", s); 890 seq_printf(m, "%-16s %s\n", "ver_cardtype", s);
890 if ((s = cinfo->version[VER_SERIAL]) != NULL) 891 if ((s = cinfo->version[VER_SERIAL]) != NULL)
891 len += sprintf(page+len, "%-16s %s\n", "ver_serial", s); 892 seq_printf(m, "%-16s %s\n", "ver_serial", s);
892 893
893 if (card->cardtype != avm_m1) { 894 if (card->cardtype != avm_m1) {
894 flag = ((u8 *)(ctrl->profile.manu))[3]; 895 flag = ((u8 *)(ctrl->profile.manu))[3];
895 if (flag) 896 if (flag)
896 len += sprintf(page+len, "%-16s%s%s%s%s%s%s%s\n", 897 seq_printf(m, "%-16s%s%s%s%s%s%s%s\n",
897 "protocol", 898 "protocol",
898 (flag & 0x01) ? " DSS1" : "", 899 (flag & 0x01) ? " DSS1" : "",
899 (flag & 0x02) ? " CT1" : "", 900 (flag & 0x02) ? " CT1" : "",
@@ -907,7 +908,7 @@ int b1dmactl_read_proc(char *page, char **start, off_t off,
907 if (card->cardtype != avm_m1) { 908 if (card->cardtype != avm_m1) {
908 flag = ((u8 *)(ctrl->profile.manu))[5]; 909 flag = ((u8 *)(ctrl->profile.manu))[5];
909 if (flag) 910 if (flag)
910 len += sprintf(page+len, "%-16s%s%s%s%s\n", 911 seq_printf(m, "%-16s%s%s%s%s\n",
911 "linetype", 912 "linetype",
912 (flag & 0x01) ? " point to point" : "", 913 (flag & 0x01) ? " point to point" : "",
913 (flag & 0x02) ? " point to multipoint" : "", 914 (flag & 0x02) ? " point to multipoint" : "",
@@ -915,7 +916,7 @@ int b1dmactl_read_proc(char *page, char **start, off_t off,
915 (flag & 0x04) ? " leased line with D-channel" : "" 916 (flag & 0x04) ? " leased line with D-channel" : ""
916 ); 917 );
917 } 918 }
918 len += sprintf(page+len, "%-16s %s\n", "cardname", cinfo->cardname); 919 seq_printf(m, "%-16s %s\n", "cardname", cinfo->cardname);
919 920
920 921
921 spin_lock_irqsave(&card->lock, flags); 922 spin_lock_irqsave(&card->lock, flags);
@@ -930,27 +931,30 @@ int b1dmactl_read_proc(char *page, char **start, off_t off,
930 931
931 spin_unlock_irqrestore(&card->lock, flags); 932 spin_unlock_irqrestore(&card->lock, flags);
932 933
933 len += sprintf(page+len, "%-16s 0x%lx\n", 934 seq_printf(m, "%-16s 0x%lx\n", "csr (cached)", (unsigned long)card->csr);
934 "csr (cached)", (unsigned long)card->csr); 935 seq_printf(m, "%-16s 0x%lx\n", "csr", (unsigned long)csr);
935 len += sprintf(page+len, "%-16s 0x%lx\n", 936 seq_printf(m, "%-16s %lu\n", "txoff", (unsigned long)txoff);
936 "csr", (unsigned long)csr); 937 seq_printf(m, "%-16s %lu\n", "txlen", (unsigned long)txlen);
937 len += sprintf(page+len, "%-16s %lu\n", 938 seq_printf(m, "%-16s %lu\n", "rxoff", (unsigned long)rxoff);
938 "txoff", (unsigned long)txoff); 939 seq_printf(m, "%-16s %lu\n", "rxlen", (unsigned long)rxlen);
939 len += sprintf(page+len, "%-16s %lu\n", 940
940 "txlen", (unsigned long)txlen); 941 return 0;
941 len += sprintf(page+len, "%-16s %lu\n", 942}
942 "rxoff", (unsigned long)rxoff); 943
943 len += sprintf(page+len, "%-16s %lu\n", 944static int b1dmactl_proc_open(struct inode *inode, struct file *file)
944 "rxlen", (unsigned long)rxlen); 945{
945 946 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} 947}
953 948
949const struct file_operations b1dmactl_proc_fops = {
950 .owner = THIS_MODULE,
951 .open = b1dmactl_proc_open,
952 .read = seq_read,
953 .llseek = seq_lseek,
954 .release = single_release,
955};
956EXPORT_SYMBOL(b1dmactl_proc_fops);
957
954/* ------------------------------------------------------------- */ 958/* ------------------------------------------------------------- */
955 959
956EXPORT_SYMBOL(b1dma_reset); 960EXPORT_SYMBOL(b1dma_reset);
@@ -963,7 +967,6 @@ EXPORT_SYMBOL(b1dma_reset_ctr);
963EXPORT_SYMBOL(b1dma_register_appl); 967EXPORT_SYMBOL(b1dma_register_appl);
964EXPORT_SYMBOL(b1dma_release_appl); 968EXPORT_SYMBOL(b1dma_release_appl);
965EXPORT_SYMBOL(b1dma_send_message); 969EXPORT_SYMBOL(b1dma_send_message);
966EXPORT_SYMBOL(b1dmactl_read_proc);
967 970
968static int __init b1dma_init(void) 971static int __init b1dma_init(void)
969{ 972{
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..de6e6b311819 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>
@@ -1062,19 +1064,18 @@ static char *c4_procinfo(struct capi_ctr *ctrl)
1062 return cinfo->infobuf; 1064 return cinfo->infobuf;
1063} 1065}
1064 1066
1065static int c4_read_proc(char *page, char **start, off_t off, 1067static int c4_proc_show(struct seq_file *m, void *v)
1066 int count, int *eof, struct capi_ctr *ctrl)
1067{ 1068{
1069 struct capi_ctr *ctrl = m->private;
1068 avmctrl_info *cinfo = (avmctrl_info *)(ctrl->driverdata); 1070 avmctrl_info *cinfo = (avmctrl_info *)(ctrl->driverdata);
1069 avmcard *card = cinfo->card; 1071 avmcard *card = cinfo->card;
1070 u8 flag; 1072 u8 flag;
1071 int len = 0;
1072 char *s; 1073 char *s;
1073 1074
1074 len += sprintf(page+len, "%-16s %s\n", "name", card->name); 1075 seq_printf(m, "%-16s %s\n", "name", card->name);
1075 len += sprintf(page+len, "%-16s 0x%x\n", "io", card->port); 1076 seq_printf(m, "%-16s 0x%x\n", "io", card->port);
1076 len += sprintf(page+len, "%-16s %d\n", "irq", card->irq); 1077 seq_printf(m, "%-16s %d\n", "irq", card->irq);
1077 len += sprintf(page+len, "%-16s 0x%lx\n", "membase", card->membase); 1078 seq_printf(m, "%-16s 0x%lx\n", "membase", card->membase);
1078 switch (card->cardtype) { 1079 switch (card->cardtype) {
1079 case avm_b1isa: s = "B1 ISA"; break; 1080 case avm_b1isa: s = "B1 ISA"; break;
1080 case avm_b1pci: s = "B1 PCI"; break; 1081 case avm_b1pci: s = "B1 PCI"; break;
@@ -1087,18 +1088,18 @@ static int c4_read_proc(char *page, char **start, off_t off,
1087 case avm_c2: s = "C2"; break; 1088 case avm_c2: s = "C2"; break;
1088 default: s = "???"; break; 1089 default: s = "???"; break;
1089 } 1090 }
1090 len += sprintf(page+len, "%-16s %s\n", "type", s); 1091 seq_printf(m, "%-16s %s\n", "type", s);
1091 if ((s = cinfo->version[VER_DRIVER]) != NULL) 1092 if ((s = cinfo->version[VER_DRIVER]) != NULL)
1092 len += sprintf(page+len, "%-16s %s\n", "ver_driver", s); 1093 seq_printf(m, "%-16s %s\n", "ver_driver", s);
1093 if ((s = cinfo->version[VER_CARDTYPE]) != NULL) 1094 if ((s = cinfo->version[VER_CARDTYPE]) != NULL)
1094 len += sprintf(page+len, "%-16s %s\n", "ver_cardtype", s); 1095 seq_printf(m, "%-16s %s\n", "ver_cardtype", s);
1095 if ((s = cinfo->version[VER_SERIAL]) != NULL) 1096 if ((s = cinfo->version[VER_SERIAL]) != NULL)
1096 len += sprintf(page+len, "%-16s %s\n", "ver_serial", s); 1097 seq_printf(m, "%-16s %s\n", "ver_serial", s);
1097 1098
1098 if (card->cardtype != avm_m1) { 1099 if (card->cardtype != avm_m1) {
1099 flag = ((u8 *)(ctrl->profile.manu))[3]; 1100 flag = ((u8 *)(ctrl->profile.manu))[3];
1100 if (flag) 1101 if (flag)
1101 len += sprintf(page+len, "%-16s%s%s%s%s%s%s%s\n", 1102 seq_printf(m, "%-16s%s%s%s%s%s%s%s\n",
1102 "protocol", 1103 "protocol",
1103 (flag & 0x01) ? " DSS1" : "", 1104 (flag & 0x01) ? " DSS1" : "",
1104 (flag & 0x02) ? " CT1" : "", 1105 (flag & 0x02) ? " CT1" : "",
@@ -1112,7 +1113,7 @@ static int c4_read_proc(char *page, char **start, off_t off,
1112 if (card->cardtype != avm_m1) { 1113 if (card->cardtype != avm_m1) {
1113 flag = ((u8 *)(ctrl->profile.manu))[5]; 1114 flag = ((u8 *)(ctrl->profile.manu))[5];
1114 if (flag) 1115 if (flag)
1115 len += sprintf(page+len, "%-16s%s%s%s%s\n", 1116 seq_printf(m, "%-16s%s%s%s%s\n",
1116 "linetype", 1117 "linetype",
1117 (flag & 0x01) ? " point to point" : "", 1118 (flag & 0x01) ? " point to point" : "",
1118 (flag & 0x02) ? " point to multipoint" : "", 1119 (flag & 0x02) ? " point to multipoint" : "",
@@ -1120,16 +1121,24 @@ static int c4_read_proc(char *page, char **start, off_t off,
1120 (flag & 0x04) ? " leased line with D-channel" : "" 1121 (flag & 0x04) ? " leased line with D-channel" : ""
1121 ); 1122 );
1122 } 1123 }
1123 len += sprintf(page+len, "%-16s %s\n", "cardname", cinfo->cardname); 1124 seq_printf(m, "%-16s %s\n", "cardname", cinfo->cardname);
1124 1125
1125 if (off+count >= len) 1126 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} 1127}
1132 1128
1129static int c4_proc_open(struct inode *inode, struct file *file)
1130{
1131 return single_open(file, c4_proc_show, PDE(inode)->data);
1132}
1133
1134static const struct file_operations c4_proc_fops = {
1135 .owner = THIS_MODULE,
1136 .open = c4_proc_open,
1137 .read = seq_read,
1138 .llseek = seq_lseek,
1139 .release = single_release,
1140};
1141
1133/* ------------------------------------------------------------- */ 1142/* ------------------------------------------------------------- */
1134 1143
1135static int c4_add_card(struct capicardparams *p, struct pci_dev *dev, 1144static int c4_add_card(struct capicardparams *p, struct pci_dev *dev,
@@ -1201,7 +1210,7 @@ static int c4_add_card(struct capicardparams *p, struct pci_dev *dev,
1201 cinfo->capi_ctrl.load_firmware = c4_load_firmware; 1210 cinfo->capi_ctrl.load_firmware = c4_load_firmware;
1202 cinfo->capi_ctrl.reset_ctr = c4_reset_ctr; 1211 cinfo->capi_ctrl.reset_ctr = c4_reset_ctr;
1203 cinfo->capi_ctrl.procinfo = c4_procinfo; 1212 cinfo->capi_ctrl.procinfo = c4_procinfo;
1204 cinfo->capi_ctrl.ctr_read_proc = c4_read_proc; 1213 cinfo->capi_ctrl.proc_fops = &c4_proc_fops;
1205 strcpy(cinfo->capi_ctrl.name, card->name); 1214 strcpy(cinfo->capi_ctrl.name, card->name);
1206 1215
1207 retval = attach_capi_ctr(&cinfo->capi_ctrl); 1216 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..baeeb3c2a3ee 100644
--- a/drivers/isdn/hardware/avm/t1isa.c
+++ b/drivers/isdn/hardware/avm/t1isa.c
@@ -429,7 +429,7 @@ static int t1isa_probe(struct pci_dev *pdev, int cardnr)
429 cinfo->capi_ctrl.load_firmware = t1isa_load_firmware; 429 cinfo->capi_ctrl.load_firmware = t1isa_load_firmware;
430 cinfo->capi_ctrl.reset_ctr = t1isa_reset_ctr; 430 cinfo->capi_ctrl.reset_ctr = t1isa_reset_ctr;
431 cinfo->capi_ctrl.procinfo = t1isa_procinfo; 431 cinfo->capi_ctrl.procinfo = t1isa_procinfo;
432 cinfo->capi_ctrl.ctr_read_proc = b1ctl_read_proc; 432 cinfo->capi_ctrl.proc_fops = &b1ctl_proc_fops;
433 strcpy(cinfo->capi_ctrl.name, card->name); 433 strcpy(cinfo->capi_ctrl.name, card->name);
434 434
435 retval = attach_capi_ctr(&cinfo->capi_ctrl); 435 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..0f073cd73763 100644
--- a/drivers/isdn/hardware/eicon/capimain.c
+++ b/drivers/isdn/hardware/eicon/capimain.c
@@ -13,6 +13,7 @@
13#include <linux/module.h> 13#include <linux/module.h>
14#include <linux/init.h> 14#include <linux/init.h>
15#include <asm/uaccess.h> 15#include <asm/uaccess.h>
16#include <linux/seq_file.h>
16#include <linux/skbuff.h> 17#include <linux/skbuff.h>
17 18
18#include "os_capi.h" 19#include "os_capi.h"
@@ -75,25 +76,32 @@ void diva_os_free_message_buffer(diva_os_message_buffer_s * dmb)
75/* 76/*
76 * proc function for controller info 77 * proc function for controller info
77 */ 78 */
78static int diva_ctl_read_proc(char *page, char **start, off_t off, 79static int diva_ctl_proc_show(struct seq_file *m, void *v)
79 int count, int *eof, struct capi_ctr *ctrl)
80{ 80{
81 struct capi_ctr *ctrl = m->private;
81 diva_card *card = (diva_card *) ctrl->driverdata; 82 diva_card *card = (diva_card *) ctrl->driverdata;
82 int len = 0; 83
83 84 seq_printf(m, "%s\n", ctrl->name);
84 len += sprintf(page + len, "%s\n", ctrl->name); 85 seq_printf(m, "Serial No. : %s\n", ctrl->serial);
85 len += sprintf(page + len, "Serial No. : %s\n", ctrl->serial); 86 seq_printf(m, "Id : %d\n", card->Id);
86 len += sprintf(page + len, "Id : %d\n", card->Id); 87 seq_printf(m, "Channels : %d\n", card->d.channels);
87 len += sprintf(page + len, "Channels : %d\n", card->d.channels); 88
88 89 return 0;
89 if (off + count >= len) 90}
90 *eof = 1; 91
91 if (len < off) 92static int diva_ctl_proc_open(struct inode *inode, struct file *file)
92 return 0; 93{
93 *start = page + off; 94 return single_open(file, diva_ctl_proc_show, NULL);
94 return ((count < len - off) ? count : len - off);
95} 95}
96 96
97static const struct file_operations diva_ctl_proc_fops = {
98 .owner = THIS_MODULE,
99 .open = diva_ctl_proc_open,
100 .read = seq_read,
101 .llseek = seq_lseek,
102 .release = single_release,
103};
104
97/* 105/*
98 * set additional os settings in capi_ctr struct 106 * set additional os settings in capi_ctr struct
99 */ 107 */
@@ -102,7 +110,7 @@ void diva_os_set_controller_struct(struct capi_ctr *ctrl)
102 ctrl->driver_name = DRIVERLNAME; 110 ctrl->driver_name = DRIVERLNAME;
103 ctrl->load_firmware = NULL; 111 ctrl->load_firmware = NULL;
104 ctrl->reset_ctr = NULL; 112 ctrl->reset_ctr = NULL;
105 ctrl->ctr_read_proc = diva_ctl_read_proc; 113 ctrl->proc_fops = &diva_ctl_proc_fops;
106 ctrl->owner = THIS_MODULE; 114 ctrl->owner = THIS_MODULE;
107} 115}
108 116
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/mISDN/hfcmulti.c b/drivers/isdn/hardware/mISDN/hfcmulti.c
index 1a1420d7a828..ad36df9b759c 100644
--- a/drivers/isdn/hardware/mISDN/hfcmulti.c
+++ b/drivers/isdn/hardware/mISDN/hfcmulti.c
@@ -2846,7 +2846,7 @@ mode_hfcmulti(struct hfc_multi *hc, int ch, int protocol, int slot_tx,
2846 int conf; 2846 int conf;
2847 2847
2848 if (ch < 0 || ch > 31) 2848 if (ch < 0 || ch > 31)
2849 return EINVAL; 2849 return -EINVAL;
2850 oslot_tx = hc->chan[ch].slot_tx; 2850 oslot_tx = hc->chan[ch].slot_tx;
2851 oslot_rx = hc->chan[ch].slot_rx; 2851 oslot_rx = hc->chan[ch].slot_rx;
2852 conf = hc->chan[ch].conf; 2852 conf = hc->chan[ch].conf;
diff --git a/drivers/isdn/hardware/mISDN/mISDNinfineon.c b/drivers/isdn/hardware/mISDN/mISDNinfineon.c
index 62441ba53b95..36c6c616a655 100644
--- a/drivers/isdn/hardware/mISDN/mISDNinfineon.c
+++ b/drivers/isdn/hardware/mISDN/mISDNinfineon.c
@@ -1133,6 +1133,7 @@ inf_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
1133 if (err) { 1133 if (err) {
1134 kfree(sc); 1134 kfree(sc);
1135 release_card(card); 1135 release_card(card);
1136 break;
1136 } else 1137 } else
1137 card->sc[i - 1] = sc; 1138 card->sc[i - 1] = sc;
1138 } 1139 }
diff --git a/drivers/isdn/hardware/mISDN/w6692.c b/drivers/isdn/hardware/mISDN/w6692.c
index d3f1077b709b..2952a58c7a61 100644
--- a/drivers/isdn/hardware/mISDN/w6692.c
+++ b/drivers/isdn/hardware/mISDN/w6692.c
@@ -529,6 +529,7 @@ W6692_fill_Bfifo(struct w6692_ch *wch)
529 } 529 }
530} 530}
531 531
532#if 0
532static int 533static int
533setvolume(struct w6692_ch *wch, int mic, struct sk_buff *skb) 534setvolume(struct w6692_ch *wch, int mic, struct sk_buff *skb)
534{ 535{
@@ -571,6 +572,7 @@ enable_pots(struct w6692_ch *wch)
571 WriteW6692(card, W_PCTL, card->pctl); 572 WriteW6692(card, W_PCTL, card->pctl);
572 return 0; 573 return 0;
573} 574}
575#endif
574 576
575static int 577static int
576disable_pots(struct w6692_ch *wch) 578disable_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/avm_pci.c b/drivers/isdn/hisax/avm_pci.c
index 7cabc5a19492..14295a155e71 100644
--- a/drivers/isdn/hisax/avm_pci.c
+++ b/drivers/isdn/hisax/avm_pci.c
@@ -822,7 +822,7 @@ static int __devinit avm_pnp_setup(struct IsdnCardState *cs)
822 822
823#endif /* __ISAPNP__ */ 823#endif /* __ISAPNP__ */
824 824
825#ifndef CONFIG_PCI_LEGACY 825#ifndef CONFIG_PCI
826 826
827static int __devinit avm_pci_setup(struct IsdnCardState *cs) 827static int __devinit avm_pci_setup(struct IsdnCardState *cs)
828{ 828{
@@ -835,7 +835,7 @@ static struct pci_dev *dev_avm __devinitdata = NULL;
835 835
836static int __devinit avm_pci_setup(struct IsdnCardState *cs) 836static int __devinit avm_pci_setup(struct IsdnCardState *cs)
837{ 837{
838 if ((dev_avm = pci_find_device(PCI_VENDOR_ID_AVM, 838 if ((dev_avm = hisax_find_pci_device(PCI_VENDOR_ID_AVM,
839 PCI_DEVICE_ID_AVM_A1, dev_avm))) { 839 PCI_DEVICE_ID_AVM_A1, dev_avm))) {
840 840
841 if (pci_enable_device(dev_avm)) 841 if (pci_enable_device(dev_avm))
@@ -864,7 +864,7 @@ static int __devinit avm_pci_setup(struct IsdnCardState *cs)
864 return (1); 864 return (1);
865} 865}
866 866
867#endif /* CONFIG_PCI_LEGACY */ 867#endif /* CONFIG_PCI */
868 868
869int __devinit 869int __devinit
870setup_avm_pcipnp(struct IsdnCard *card) 870setup_avm_pcipnp(struct IsdnCard *card)
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/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..23c41fcd864e 100644
--- a/drivers/isdn/hisax/elsa.c
+++ b/drivers/isdn/hisax/elsa.c
@@ -1025,7 +1025,7 @@ setup_elsa_pcmcia(struct IsdnCard *card)
1025 cs->irq); 1025 cs->irq);
1026} 1026}
1027 1027
1028#ifdef CONFIG_PCI_LEGACY 1028#ifdef CONFIG_PCI
1029static struct pci_dev *dev_qs1000 __devinitdata = NULL; 1029static struct pci_dev *dev_qs1000 __devinitdata = NULL;
1030static struct pci_dev *dev_qs3000 __devinitdata = NULL; 1030static struct pci_dev *dev_qs3000 __devinitdata = NULL;
1031 1031
@@ -1035,7 +1035,7 @@ setup_elsa_pci(struct IsdnCard *card)
1035 struct IsdnCardState *cs = card->cs; 1035 struct IsdnCardState *cs = card->cs;
1036 1036
1037 cs->subtyp = 0; 1037 cs->subtyp = 0;
1038 if ((dev_qs1000 = pci_find_device(PCI_VENDOR_ID_ELSA, 1038 if ((dev_qs1000 = hisax_find_pci_device(PCI_VENDOR_ID_ELSA,
1039 PCI_DEVICE_ID_ELSA_MICROLINK, dev_qs1000))) { 1039 PCI_DEVICE_ID_ELSA_MICROLINK, dev_qs1000))) {
1040 if (pci_enable_device(dev_qs1000)) 1040 if (pci_enable_device(dev_qs1000))
1041 return(0); 1041 return(0);
@@ -1043,7 +1043,7 @@ setup_elsa_pci(struct IsdnCard *card)
1043 cs->irq = dev_qs1000->irq; 1043 cs->irq = dev_qs1000->irq;
1044 cs->hw.elsa.cfg = pci_resource_start(dev_qs1000, 1); 1044 cs->hw.elsa.cfg = pci_resource_start(dev_qs1000, 1);
1045 cs->hw.elsa.base = pci_resource_start(dev_qs1000, 3); 1045 cs->hw.elsa.base = pci_resource_start(dev_qs1000, 3);
1046 } else if ((dev_qs3000 = pci_find_device(PCI_VENDOR_ID_ELSA, 1046 } else if ((dev_qs3000 = hisax_find_pci_device(PCI_VENDOR_ID_ELSA,
1047 PCI_DEVICE_ID_ELSA_QS3000, dev_qs3000))) { 1047 PCI_DEVICE_ID_ELSA_QS3000, dev_qs3000))) {
1048 if (pci_enable_device(dev_qs3000)) 1048 if (pci_enable_device(dev_qs3000))
1049 return(0); 1049 return(0);
@@ -1093,7 +1093,7 @@ setup_elsa_pci(struct IsdnCard *card)
1093{ 1093{
1094 return (1); 1094 return (1);
1095} 1095}
1096#endif /* CONFIG_PCI_LEGACY */ 1096#endif /* CONFIG_PCI */
1097 1097
1098static int __devinit 1098static int __devinit
1099setup_elsa_common(struct IsdnCard *card) 1099setup_elsa_common(struct IsdnCard *card)
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/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/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/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/isar.c b/drivers/isdn/hisax/isar.c
index bfeb9b6aa043..6bde16c00fb5 100644
--- a/drivers/isdn/hisax/isar.c
+++ b/drivers/isdn/hisax/isar.c
@@ -138,7 +138,7 @@ waitrecmsg(struct IsdnCardState *cs, u_char *len,
138 while((!(cs->BC_Read_Reg(cs, 0, ISAR_IRQBIT) & ISAR_IRQSTA)) && 138 while((!(cs->BC_Read_Reg(cs, 0, ISAR_IRQBIT) & ISAR_IRQSTA)) &&
139 (timeout++ < maxdelay)) 139 (timeout++ < maxdelay))
140 udelay(1); 140 udelay(1);
141 if (timeout >= maxdelay) { 141 if (timeout > maxdelay) {
142 printk(KERN_WARNING"isar recmsg IRQSTA timeout\n"); 142 printk(KERN_WARNING"isar recmsg IRQSTA timeout\n");
143 return(0); 143 return(0);
144 } 144 }
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/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..9d6e864023fe 100644
--- a/drivers/isdn/hisax/w6692.c
+++ b/drivers/isdn/hisax/w6692.c
@@ -1007,7 +1007,7 @@ setup_w6692(struct IsdnCard *card)
1007 return (0); 1007 return (0);
1008 1008
1009 while (id_list[id_idx].vendor_id) { 1009 while (id_list[id_idx].vendor_id) {
1010 dev_w6692 = pci_find_device(id_list[id_idx].vendor_id, 1010 dev_w6692 = hisax_find_pci_device(id_list[id_idx].vendor_id,
1011 id_list[id_idx].device_id, 1011 id_list[id_idx].device_id,
1012 dev_w6692); 1012 dev_w6692);
1013 if (dev_w6692) { 1013 if (dev_w6692) {
diff --git a/drivers/isdn/hysdn/hycapi.c b/drivers/isdn/hysdn/hycapi.c
index 4ffaa14b9fc4..fe874afa4f81 100644
--- a/drivers/isdn/hysdn/hycapi.c
+++ b/drivers/isdn/hysdn/hycapi.c
@@ -11,6 +11,8 @@
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>
@@ -432,26 +434,16 @@ static u16 hycapi_send_message(struct capi_ctr *ctrl, struct sk_buff *skb)
432 return retval; 434 return retval;
433} 435}
434 436
435/********************************************************************* 437static 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{ 438{
439 struct capi_ctr *ctrl = m->private;
445 hycapictrl_info *cinfo = (hycapictrl_info *)(ctrl->driverdata); 440 hycapictrl_info *cinfo = (hycapictrl_info *)(ctrl->driverdata);
446 hysdn_card *card = cinfo->card; 441 hysdn_card *card = cinfo->card;
447 int len = 0;
448 char *s; 442 char *s;
449#ifdef HYCAPI_PRINTFNAMES 443
450 printk(KERN_NOTICE "hycapi_read_proc\n"); 444 seq_printf(m, "%-16s %s\n", "name", cinfo->cardname);
451#endif 445 seq_printf(m, "%-16s 0x%x\n", "io", card->iobase);
452 len += sprintf(page+len, "%-16s %s\n", "name", cinfo->cardname); 446 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 447
456 switch (card->brdtype) { 448 switch (card->brdtype) {
457 case BD_PCCARD: s = "HYSDN Hycard"; break; 449 case BD_PCCARD: s = "HYSDN Hycard"; break;
@@ -461,24 +453,32 @@ static int hycapi_read_proc(char *page, char **start, off_t off,
461 case BD_PLEXUS: s = "HYSDN Plexus30"; break; 453 case BD_PLEXUS: s = "HYSDN Plexus30"; break;
462 default: s = "???"; break; 454 default: s = "???"; break;
463 } 455 }
464 len += sprintf(page+len, "%-16s %s\n", "type", s); 456 seq_printf(m, "%-16s %s\n", "type", s);
465 if ((s = cinfo->version[VER_DRIVER]) != NULL) 457 if ((s = cinfo->version[VER_DRIVER]) != NULL)
466 len += sprintf(page+len, "%-16s %s\n", "ver_driver", s); 458 seq_printf(m, "%-16s %s\n", "ver_driver", s);
467 if ((s = cinfo->version[VER_CARDTYPE]) != NULL) 459 if ((s = cinfo->version[VER_CARDTYPE]) != NULL)
468 len += sprintf(page+len, "%-16s %s\n", "ver_cardtype", s); 460 seq_printf(m, "%-16s %s\n", "ver_cardtype", s);
469 if ((s = cinfo->version[VER_SERIAL]) != NULL) 461 if ((s = cinfo->version[VER_SERIAL]) != NULL)
470 len += sprintf(page+len, "%-16s %s\n", "ver_serial", s); 462 seq_printf(m, "%-16s %s\n", "ver_serial", s);
471 463
472 len += sprintf(page+len, "%-16s %s\n", "cardname", cinfo->cardname); 464 seq_printf(m, "%-16s %s\n", "cardname", cinfo->cardname);
473 465
474 if (off+count >= len) 466 return 0;
475 *eof = 1; 467}
476 if (len < off) 468
477 return 0; 469static int hycapi_proc_open(struct inode *inode, struct file *file)
478 *start = page + off; 470{
479 return ((count < len-off) ? count : len-off); 471 return single_open(file, hycapi_proc_show, PDE(inode)->data);
480} 472}
481 473
474static const struct file_operations hycapi_proc_fops = {
475 .owner = THIS_MODULE,
476 .open = hycapi_proc_open,
477 .read = seq_read,
478 .llseek = seq_lseek,
479 .release = single_release,
480};
481
482/************************************************************** 482/**************************************************************
483hycapi_load_firmware 483hycapi_load_firmware
484 484
@@ -774,7 +774,7 @@ hycapi_capi_create(hysdn_card *card)
774 ctrl->load_firmware = hycapi_load_firmware; 774 ctrl->load_firmware = hycapi_load_firmware;
775 ctrl->reset_ctr = hycapi_reset_ctr; 775 ctrl->reset_ctr = hycapi_reset_ctr;
776 ctrl->procinfo = hycapi_procinfo; 776 ctrl->procinfo = hycapi_procinfo;
777 ctrl->ctr_read_proc = hycapi_read_proc; 777 ctrl->proc_fops = &hycapi_proc_fops;
778 strcpy(ctrl->name, cinfo->cardname); 778 strcpy(ctrl->name, cinfo->cardname);
779 ctrl->owner = THIS_MODULE; 779 ctrl->owner = THIS_MODULE;
780 780
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