diff options
Diffstat (limited to 'drivers/isdn')
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 | ||
42 | source "drivers/isdn/mISDN/Kconfig" | ||
43 | |||
44 | source "drivers/isdn/i4l/Kconfig" | 41 | source "drivers/isdn/i4l/Kconfig" |
45 | 42 | ||
46 | menuconfig ISDN_CAPI | 43 | menuconfig 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 | ||
54 | if ISDN_CAPI | 58 | if ISDN_CAPI |
55 | 59 | ||
@@ -61,4 +65,13 @@ endif # ISDN_CAPI | |||
61 | 65 | ||
62 | source "drivers/isdn/gigaset/Kconfig" | 66 | source "drivers/isdn/gigaset/Kconfig" |
63 | 67 | ||
68 | source "drivers/isdn/hysdn/Kconfig" | ||
69 | |||
70 | source "drivers/isdn/mISDN/Kconfig" | ||
71 | |||
72 | config ISDN_HDLC | ||
73 | tristate | ||
74 | select CRC_CCITT | ||
75 | select BITREVERSE | ||
76 | |||
64 | endif # ISDN | 77 | endif # 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 | ||
19 | config ISDN_CAPI_MIDDLEWARE | 19 | config 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 | ||
37 | config ISDN_CAPI_CAPIFS_BOOL | 36 | config 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 | ||
41 | config ISDN_CAPI_CAPIFS | 46 | config 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 | ||
51 | config ISDN_CAPI_CAPIDRV | 51 | config 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 | ||
48 | static char *revision = "$Revision: 1.1.2.7 $"; | 42 | #include "capifs.h" |
49 | 43 | ||
50 | MODULE_DESCRIPTION("CAPI4Linux: Userspace /dev/capi20 interface"); | 44 | MODULE_DESCRIPTION("CAPI4Linux: Userspace /dev/capi20 interface"); |
51 | MODULE_AUTHOR("Carsten Paeth"); | 45 | MODULE_AUTHOR("Carsten Paeth"); |
52 | MODULE_LICENSE("GPL"); | 46 | MODULE_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 | ||
60 | static struct class *capi_class; | 53 | static struct class *capi_class; |
61 | |||
62 | static int capi_major = 68; /* allocated */ | 54 | static int capi_major = 68; /* allocated */ |
55 | |||
56 | module_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 |
66 | static int capi_ttymajor = 191; | 61 | |
67 | static int capi_ttyminors = CAPINC_NR_PORTS; | 62 | static int capi_ttyminors = CAPINC_NR_PORTS; |
68 | #endif /* CONFIG_ISDN_CAPI_MIDDLEWARE */ | ||
69 | 63 | ||
70 | module_param_named(major, capi_major, uint, 0); | ||
71 | #ifdef CONFIG_ISDN_CAPI_MIDDLEWARE | ||
72 | module_param_named(ttymajor, capi_ttymajor, uint, 0); | ||
73 | module_param_named(ttyminors, capi_ttyminors, uint, 0); | 64 | module_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 | ||
84 | struct capidev; | 75 | struct capidev; |
85 | struct capincci; | 76 | struct capincci; |
86 | #ifdef CONFIG_ISDN_CAPI_MIDDLEWARE | ||
87 | struct capiminor; | 77 | struct capiminor; |
88 | 78 | ||
89 | struct datahandle_queue { | 79 | struct ackqueue_entry { |
90 | struct list_head list; | 80 | struct list_head list; |
91 | u16 datahandle; | 81 | u16 datahandle; |
92 | }; | 82 | }; |
93 | 83 | ||
94 | struct capiminor { | 84 | struct 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... . */ | ||
129 | static DEFINE_SPINLOCK(workaround_lock); | ||
130 | 111 | ||
131 | struct capincci { | 112 | struct 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 | ||
156 | static DEFINE_RWLOCK(capidev_list_lock); | 137 | static DEFINE_MUTEX(capidev_list_lock); |
157 | static LIST_HEAD(capidev_list); | 138 | static LIST_HEAD(capidev_list); |
158 | 139 | ||
159 | #ifdef CONFIG_ISDN_CAPI_MIDDLEWARE | 140 | #ifdef CONFIG_ISDN_CAPI_MIDDLEWARE |
160 | static DEFINE_RWLOCK(capiminor_list_lock); | ||
161 | static LIST_HEAD(capiminor_list); | ||
162 | #endif /* CONFIG_ISDN_CAPI_MIDDLEWARE */ | ||
163 | 141 | ||
164 | #ifdef CONFIG_ISDN_CAPI_MIDDLEWARE | 142 | static DEFINE_SPINLOCK(capiminors_lock); |
143 | static struct capiminor **capiminors; | ||
144 | |||
145 | static struct tty_driver *capinc_tty_driver; | ||
146 | |||
165 | /* -------- datahandles --------------------------------------------- */ | 147 | /* -------- datahandles --------------------------------------------- */ |
166 | 148 | ||
167 | static int capincci_add_ack(struct capiminor *mp, u16 datahandle) | 149 | static 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 | ||
186 | static int capiminor_del_ack(struct capiminor *mp, u16 datahandle) | 167 | static 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 | ||
205 | static void capiminor_del_all_ack(struct capiminor *mp) | 185 | static 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 | ||
199 | static const struct tty_port_operations capiminor_port_ops; /* we have none */ | ||
200 | |||
222 | static struct capiminor *capiminor_alloc(struct capi20_appl *ap, u32 ncci) | 201 | static 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 | |||
249 | err_out2: | ||
250 | spin_lock(&capiminors_lock); | ||
251 | capiminors[minor] = NULL; | ||
252 | spin_unlock(&capiminors_lock); | ||
253 | |||
254 | err_out1: | ||
255 | kfree(mp); | ||
256 | return NULL; | ||
270 | } | 257 | } |
271 | 258 | ||
272 | static void capiminor_free(struct capiminor *mp) | 259 | static 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 | ||
288 | static struct capiminor *capiminor_find(unsigned int minor) | 270 | static 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 | |||
283 | static inline void capiminor_put(struct capiminor *mp) | ||
284 | { | ||
285 | kref_put(&mp->kref, capiminor_destroy); | ||
286 | } | ||
287 | |||
288 | static 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 | ||
309 | static struct capincci *capincci_alloc(struct capidev *cdev, u32 ncci) | 301 | static 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 | ||
341 | static void capincci_free(struct capidev *cdev, u32 ncci) | 316 | static 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 | ||
377 | static struct capincci *capincci_find(struct capidev *cdev, u32 ncci) | 334 | static 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 | |||
352 | static inline void | ||
353 | capincci_alloc_minor(struct capidev *cdev, struct capincci *np) { } | ||
354 | static inline void capincci_free_minor(struct capincci *np) { } | ||
389 | 355 | ||
390 | static struct capidev *capidev_alloc(void) | 356 | static 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 | |
363 | static 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 | ||
408 | static void capidev_free(struct capidev *cdev) | 380 | static 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); | 392 | static 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 * | |||
432 | gen_data_b3_resp_for(struct capiminor *mp, struct sk_buff *skb) | 406 | gen_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 | ||
450 | static int handle_recv_skb(struct capiminor *mp, struct sk_buff *skb) | 424 | static 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 | 496 | free_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 | |||
500 | deref_ldisc: | ||
506 | tty_ldisc_deref(ld); | 501 | tty_ldisc_deref(ld); |
507 | return 0; | 502 | |
508 | bad: | 503 | deref_tty: |
509 | tty_ldisc_deref(ld); | 504 | tty_kref_put(tty); |
510 | return -1; | 505 | return ret; |
511 | } | 506 | } |
512 | 507 | ||
513 | static void handle_minor_recv(struct capiminor *mp) | 508 | static 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 | ||
527 | static int handle_minor_send(struct capiminor *mp) | 519 | static 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 | |
685 | unlock_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 | |
820 | register_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 | ||
984 | static int | 984 | static int capi_open(struct inode *inode, struct file *file) |
985 | capi_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 | ||
1000 | static int | 1005 | static int capi_release(struct inode *inode, struct file *file) |
1001 | capi_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 | ||
1026 | static int capinc_tty_open(struct tty_struct * tty, struct file * file) | 1037 | static int |
1038 | capinc_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) | 1054 | static 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; | 1061 | static 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 | ||
1050 | static void capinc_tty_close(struct tty_struct * tty, struct file * file) | 1074 | static 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 | ||
1075 | static int capinc_tty_write(struct tty_struct * tty, | 1081 | static 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 | ||
1119 | static int capinc_tty_put_char(struct tty_struct *tty, unsigned char ch) | 1118 | static 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 | |
1152 | unlock_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 | ||
1163 | static void capinc_tty_flush_chars(struct tty_struct *tty) | 1161 | static 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 | ||
1192 | static int capinc_tty_write_room(struct tty_struct *tty) | 1185 | static 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 | ||
1210 | static int capinc_tty_chars_in_buffer(struct tty_struct *tty) | 1198 | static 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 | ||
1247 | static void capinc_tty_throttle(struct tty_struct * tty) | 1230 | static 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 | ||
1257 | static void capinc_tty_unthrottle(struct tty_struct * tty) | 1239 | static 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 | ||
1272 | static void capinc_tty_stop(struct tty_struct *tty) | 1250 | static 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 | ||
1283 | static void capinc_tty_start(struct tty_struct *tty) | 1260 | static 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 | ||
1298 | static void capinc_tty_hangup(struct tty_struct *tty) | 1271 | static 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 | ||
1305 | static int capinc_tty_break_ctl(struct tty_struct *tty, int state) | 1281 | static 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 | ||
1334 | static struct tty_driver *capinc_tty_driver; | ||
1335 | |||
1336 | static const struct tty_operations capinc_ops = { | 1310 | static 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 | ||
1357 | static int capinc_tty_init(void) | 1333 | static 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 | ||
1393 | static void capinc_tty_exit(void) | 1381 | static 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 | |||
1390 | static inline int capinc_tty_init(void) | ||
1391 | { | ||
1392 | return 0; | ||
1393 | } | ||
1394 | |||
1395 | static 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 | */ |
1410 | static int proc_capidev_read_proc(char *page, char **start, off_t off, | 1405 | static 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 | ||
1435 | endloop: | 1424 | static 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 | ||
1429 | static 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 | */ |
1448 | static int proc_capincci_read_proc(char *page, char **start, off_t off, | 1441 | static 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 | } |
1472 | endloop: | 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; | 1457 | static 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 | ||
1482 | static struct procfsentries { | 1462 | static 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 | ||
1494 | static void __init proc_init(void) | 1470 | static 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 | ||
1506 | static void __exit proc_exit(void) | 1476 | static 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 | ||
1523 | static char rev[32]; | ||
1524 | |||
1525 | static int __init capi_init(void) | 1485 | static 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 | ||
1591 | module_init(capi_init); | 1536 | module_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 | ||
37 | static char *revision = "$Revision: 1.1.2.2 $"; | ||
38 | static int debugmode = 0; | 38 | static int debugmode = 0; |
39 | 39 | ||
40 | MODULE_DESCRIPTION("CAPI4Linux: Interface to ISDN4Linux"); | 40 | MODULE_DESCRIPTION("CAPI4Linux: Interface to ISDN4Linux"); |
@@ -2210,96 +2210,73 @@ static int capidrv_delcontr(u16 contr) | |||
2210 | } | 2210 | } |
2211 | 2211 | ||
2212 | 2212 | ||
2213 | static void lower_callback(unsigned int cmd, u32 contr, void *data) | 2213 | static int |
2214 | lower_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 | */ |
2232 | static int proc_capidrv_read_proc(char *page, char **start, off_t off, | 2237 | static 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 | ||
2250 | static struct procfsentries { | 2247 | static 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; | 2252 | static 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 | ||
2261 | static void __init proc_init(void) | 2260 | static 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 | ||
2273 | static void __exit proc_exit(void) | 2265 | static 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 | ||
2270 | static struct notifier_block capictr_nb = { | ||
2271 | .notifier_call = lower_callback, | ||
2272 | }; | ||
2273 | |||
2287 | static int __init capidrv_init(void) | 2274 | static 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 | ||
2334 | static void __exit capidrv_exit(void) | 2310 | static 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 | ||
2355 | module_init(capidrv_init); | 2318 | module_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 | ||
28 | static 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 | ||
34 | static struct vfsmount *capifs_mnt; | 30 | static struct vfsmount *capifs_mnt; |
35 | static struct dentry *capifs_root; | 31 | static int capifs_mnt_count; |
36 | 32 | ||
37 | static struct { | 33 | static 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 | ||
144 | static struct dentry *get_node(int num) | 140 | static 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 | ||
152 | void 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 | |
181 | unlock_out: | ||
182 | mutex_unlock(&root->d_inode->i_mutex); | ||
183 | |||
184 | return dentry; | ||
172 | } | 185 | } |
173 | 186 | ||
174 | void capifs_free_ncci(unsigned int number) | 187 | struct 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 | |||
201 | void 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 | ||
190 | static int __init capifs_init(void) | 224 | static 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 | ||
216 | static void __exit capifs_exit(void) | 229 | static 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 | ||
222 | EXPORT_SYMBOL(capifs_new_ncci); | 234 | EXPORT_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 | ||
10 | void capifs_new_ncci(unsigned int num, dev_t device); | 10 | #include <linux/dcache.h> |
11 | void capifs_free_ncci(unsigned int num); | 11 | |
12 | #if defined(CONFIG_ISDN_CAPI_CAPIFS) || defined(CONFIG_ISDN_CAPI_CAPIFS_MODULE) | ||
13 | |||
14 | struct dentry *capifs_new_ncci(unsigned int num, dev_t device); | ||
15 | void capifs_free_ncci(struct dentry *dentry); | ||
16 | |||
17 | #else | ||
18 | |||
19 | static inline struct dentry *capifs_new_ncci(unsigned int num, dev_t device) | ||
20 | { | ||
21 | return NULL; | ||
22 | } | ||
23 | |||
24 | static 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> | |
38 | static char *revision = "$Revision: 1.1.2.8 $"; | ||
39 | |||
40 | /* ------------------------------------------------------------- */ | ||
41 | 38 | ||
42 | static int showcapimsgs = 0; | 39 | static int showcapimsgs = 0; |
43 | 40 | ||
@@ -48,12 +45,10 @@ module_param(showcapimsgs, uint, 0); | |||
48 | 45 | ||
49 | /* ------------------------------------------------------------- */ | 46 | /* ------------------------------------------------------------- */ |
50 | 47 | ||
51 | struct capi_notifier { | 48 | struct 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 | ||
67 | LIST_HEAD(capi_drivers); | 62 | LIST_HEAD(capi_drivers); |
68 | DEFINE_RWLOCK(capi_drivers_list_lock); | 63 | DEFINE_MUTEX(capi_drivers_lock); |
69 | 64 | ||
70 | static DEFINE_RWLOCK(application_lock); | 65 | struct capi_ctr *capi_controller[CAPI_MAXCONTR]; |
71 | static DEFINE_MUTEX(controller_mutex); | 66 | DEFINE_MUTEX(capi_controller_lock); |
72 | 67 | ||
73 | struct capi20_appl *capi_applications[CAPI_MAXAPPL]; | 68 | struct capi20_appl *capi_applications[CAPI_MAXAPPL]; |
74 | struct capi_ctr *capi_cards[CAPI_MAXCONTR]; | ||
75 | 69 | ||
76 | static int ncards; | 70 | static int ncontrollers; |
71 | |||
72 | static BLOCKING_NOTIFIER_HEAD(ctr_notifier_list); | ||
77 | 73 | ||
78 | /* -------- controller ref counting -------------------------------------- */ | 74 | /* -------- controller ref counting -------------------------------------- */ |
79 | 75 | ||
80 | static inline struct capi_ctr * | 76 | static inline struct capi_ctr * |
81 | capi_ctr_get(struct capi_ctr *card) | 77 | capi_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 | ||
88 | static inline void | 84 | static inline void |
89 | capi_ctr_put(struct capi_ctr *card) | 85 | capi_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 | ||
104 | static inline struct capi20_appl *get_capi_appl_by_nr(u16 applid) | 100 | static 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 | ||
151 | static void register_appl(struct capi_ctr *card, u16 applid, capi_register_params *rparam) | 147 | static void |
148 | register_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 | ||
162 | static void release_appl(struct capi_ctr *card, u16 applid) | 160 | static 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 | |||
172 | static void notify_up(u32 contr) | 168 | static 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 ------------------------------------- */ | 197 | unlock_out: |
198 | mutex_unlock(&capi_controller_lock); | ||
199 | } | ||
195 | 200 | ||
196 | static void notify_down(u32 contr) | 201 | static 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 | ||
212 | static void notify_handler(struct work_struct *work) | 225 | static 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 | |||
243 | static int | ||
244 | notify_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 | |||
259 | static 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 | */ |
233 | static int notify_push(unsigned int cmd, u32 controller, u16 applid, u32 ncci) | 273 | static 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 | 288 | int register_capictr_notifier(struct notifier_block *nb) | |
289 | { | ||
290 | return blocking_notifier_chain_register(&ctr_notifier_list, nb); | ||
291 | } | ||
292 | EXPORT_SYMBOL_GPL(register_capictr_notifier); | ||
293 | |||
294 | int unregister_capictr_notifier(struct notifier_block *nb) | ||
295 | { | ||
296 | return blocking_notifier_chain_unregister(&ctr_notifier_list, nb); | ||
297 | } | ||
298 | EXPORT_SYMBOL_GPL(unregister_capictr_notifier); | ||
299 | |||
251 | /* -------- Receiver ------------------------------------------ */ | 300 | /* -------- Receiver ------------------------------------------ */ |
252 | 301 | ||
253 | static void recv_handler(struct work_struct *work) | 302 | static 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 | ||
283 | void capi_ctr_handle_message(struct capi_ctr * card, u16 appl, struct sk_buff *skb) | 332 | void 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 | ||
368 | void capi_ctr_ready(struct capi_ctr * card) | 419 | void 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 | ||
378 | EXPORT_SYMBOL(capi_ctr_ready); | 427 | EXPORT_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 | ||
388 | void capi_ctr_down(struct capi_ctr * card) | 437 | void 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 | ||
417 | EXPORT_SYMBOL(capi_ctr_down); | 444 | EXPORT_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 | ||
426 | void capi_ctr_suspend_output(struct capi_ctr *card) | 456 | void 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 | ||
443 | void capi_ctr_resume_output(struct capi_ctr *card) | 477 | void 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 | ||
463 | int | 498 | int attach_capi_ctr(struct capi_ctr *ctr) |
464 | attach_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 | ||
518 | int detach_capi_ctr(struct capi_ctr *card) | 548 | int 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 | |||
569 | unlock_out: | ||
570 | mutex_unlock(&capi_controller_lock); | ||
571 | |||
572 | return err; | ||
534 | } | 573 | } |
535 | 574 | ||
536 | EXPORT_SYMBOL(detach_capi_ctr); | 575 | EXPORT_SYMBOL(detach_capi_ctr); |
@@ -544,11 +583,9 @@ EXPORT_SYMBOL(detach_capi_ctr); | |||
544 | 583 | ||
545 | void register_capi_driver(struct capi_driver *driver) | 584 | void 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 | ||
554 | EXPORT_SYMBOL(register_capi_driver); | 591 | EXPORT_SYMBOL(register_capi_driver); |
@@ -562,11 +599,9 @@ EXPORT_SYMBOL(register_capi_driver); | |||
562 | 599 | ||
563 | void unregister_capi_driver(struct capi_driver *driver) | 600 | void 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 | ||
572 | EXPORT_SYMBOL(unregister_capi_driver); | 607 | EXPORT_SYMBOL(unregister_capi_driver); |
@@ -584,12 +619,21 @@ EXPORT_SYMBOL(unregister_capi_driver); | |||
584 | 619 | ||
585 | u16 capi20_isinstalled(void) | 620 | u16 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 | ||
595 | EXPORT_SYMBOL(capi20_isinstalled); | 639 | EXPORT_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); | |||
673 | u16 capi20_release(struct capi20_appl *ap) | 714 | u16 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 | ||
714 | u16 capi20_put_message(struct capi20_appl *ap, struct sk_buff *skb) | 757 | u16 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 | ||
777 | EXPORT_SYMBOL(capi20_put_message); | 825 | EXPORT_SYMBOL(capi20_put_message); |
@@ -788,17 +836,25 @@ EXPORT_SYMBOL(capi20_put_message); | |||
788 | 836 | ||
789 | u16 capi20_get_manufacturer(u32 contr, u8 *buf) | 837 | u16 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 | ||
804 | EXPORT_SYMBOL(capi20_get_manufacturer); | 860 | EXPORT_SYMBOL(capi20_get_manufacturer); |
@@ -815,18 +871,25 @@ EXPORT_SYMBOL(capi20_get_manufacturer); | |||
815 | 871 | ||
816 | u16 capi20_get_version(u32 contr, struct capi_version *verp) | 872 | u16 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 | ||
832 | EXPORT_SYMBOL(capi20_get_version); | 895 | EXPORT_SYMBOL(capi20_get_version); |
@@ -843,18 +906,25 @@ EXPORT_SYMBOL(capi20_get_version); | |||
843 | 906 | ||
844 | u16 capi20_get_serial(u32 contr, u8 *serial) | 907 | u16 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 | ||
860 | EXPORT_SYMBOL(capi20_get_serial); | 930 | EXPORT_SYMBOL(capi20_get_serial); |
@@ -871,23 +941,65 @@ EXPORT_SYMBOL(capi20_get_serial); | |||
871 | 941 | ||
872 | u16 capi20_get_profile(u32 contr, struct capi_profile *profp) | 942 | u16 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 | ||
889 | EXPORT_SYMBOL(capi20_get_profile); | 965 | EXPORT_SYMBOL(capi20_get_profile); |
890 | 966 | ||
967 | /* Must be called with capi_controller_lock held. */ | ||
968 | static 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 |
892 | static int old_capi_manufacturer(unsigned int cmd, void __user *data) | 1004 | static 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)) { | 1128 | load_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 | ||
1153 | reset_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 | ||
1063 | int capi20_manufacturer(unsigned int cmd, void __user *data) | 1170 | int 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 | ||
1138 | EXPORT_SYMBOL(capi20_manufacturer); | 1253 | EXPORT_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 | |||
1156 | void capi20_set_callback(struct capi20_appl *ap, | ||
1157 | void (*callback) (unsigned int cmd, __u32 contr, void *data)) | ||
1158 | { | ||
1159 | ap->callback = callback; | ||
1160 | } | ||
1161 | |||
1162 | EXPORT_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 | ||
1263 | static struct notifier_block capictr_nb = { | ||
1264 | .notifier_call = notify_handler, | ||
1265 | .priority = INT_MAX, | ||
1266 | }; | ||
1267 | |||
1172 | static int __init kcapi_init(void) | 1268 | static 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 | ||
1195 | static void __exit kcapi_exit(void) | 1280 | static 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 | ||
26 | enum { | 26 | enum { |
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 | ||
32 | extern struct list_head capi_drivers; | 33 | extern struct list_head capi_drivers; |
33 | extern rwlock_t capi_drivers_list_lock; | 34 | extern struct mutex capi_drivers_lock; |
35 | |||
36 | extern struct capi_ctr *capi_controller[CAPI_MAXCONTR]; | ||
37 | extern struct mutex capi_controller_lock; | ||
34 | 38 | ||
35 | extern struct capi20_appl *capi_applications[CAPI_MAXAPPL]; | 39 | extern struct capi20_appl *capi_applications[CAPI_MAXAPPL]; |
36 | extern 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 | ||
18 | static char * | 18 | static char *state2str(unsigned short state) |
19 | cardstate2str(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 | ||
38 | static void *controller_start(struct seq_file *seq, loff_t *pos) | 37 | static 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 | ||
55 | static void controller_stop(struct seq_file *seq, void *v) | 57 | static 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 | ||
59 | static int controller_show(struct seq_file *seq, void *v) | 63 | static 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 | ||
138 | static void * | 142 | static void *applications_start(struct seq_file *seq, loff_t *pos) |
139 | applications_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 | ||
157 | static void | 163 | static void applications_stop(struct seq_file *seq, void *v) |
158 | applications_stop(struct seq_file *seq, void *v) | 164 | __releases(capi_controller_lock) |
159 | { | 165 | { |
166 | mutex_unlock(&capi_controller_lock); | ||
160 | } | 167 | } |
161 | 168 | ||
162 | static int | 169 | static int |
@@ -239,9 +246,9 @@ static const struct file_operations proc_applstats_ops = { | |||
239 | // --------------------------------------------------------------------------- | 246 | // --------------------------------------------------------------------------- |
240 | 247 | ||
241 | static void *capi_driver_start(struct seq_file *seq, loff_t *pos) | 248 | static 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 | ||
253 | static void capi_driver_stop(struct seq_file *seq, void *v) | 260 | static 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 | ||
259 | static int capi_driver_show(struct seq_file *seq, void *v) | 266 | static 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 | */ | ||
174 | static 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 | */ |
188 | static inline u8 hex2bin(char c) | 176 | static 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 | /** | 2090 | static 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 | */ | ||
2120 | static 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 | ||
2181 | static int gigaset_proc_open(struct inode *inode, struct file *file) | ||
2182 | { | ||
2183 | return single_open(file, gigaset_proc_show, PDE(inode)->data); | ||
2184 | } | ||
2185 | |||
2186 | static 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 | ||
2218 | static struct capi_driver capi_driver_gigaset = { | 2194 | static 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) | |||
784 | static void schedule_init(struct cardstate *cs, int state) | 783 | static 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) | |||
785 | static inline void gigaset_bchannel_down(struct bc_state *bcs) | 786 | static 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) | |||
795 | static inline void gigaset_bchannel_up(struct bc_state *bcs) | 794 | static 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 | */ | ||
908 | static void cmd_loop(unsigned char *src, int numbytes, struct inbuf_t *inbuf) | 914 | static 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); | |||
556 | void b1_parse_version(avmctrl_info *card); | 556 | void b1_parse_version(avmctrl_info *card); |
557 | irqreturn_t b1_interrupt(int interrupt, void *devptr); | 557 | irqreturn_t b1_interrupt(int interrupt, void *devptr); |
558 | 558 | ||
559 | int b1ctl_read_proc(char *page, char **start, off_t off, | 559 | extern const struct file_operations b1ctl_proc_fops; |
560 | int count, int *eof, struct capi_ctr *ctrl); | ||
561 | 560 | ||
562 | avmcard_dmainfo *avmcard_dma_alloc(char *name, struct pci_dev *, | 561 | avmcard_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); |
578 | void b1dma_release_appl(struct capi_ctr *ctrl, u16 appl); | 577 | void b1dma_release_appl(struct capi_ctr *ctrl, u16 appl); |
579 | u16 b1dma_send_message(struct capi_ctr *ctrl, struct sk_buff *skb); | 578 | u16 b1dma_send_message(struct capi_ctr *ctrl, struct sk_buff *skb); |
580 | int b1dmactl_read_proc(char *page, char **start, off_t off, | 579 | extern 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 | /* ------------------------------------------------------------- */ |
637 | int b1ctl_read_proc(char *page, char **start, off_t off, | 639 | static 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; | 702 | static 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 | ||
707 | const 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 | }; | ||
714 | EXPORT_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); | |||
781 | EXPORT_SYMBOL(b1_parse_version); | 791 | EXPORT_SYMBOL(b1_parse_version); |
782 | EXPORT_SYMBOL(b1_interrupt); | 792 | EXPORT_SYMBOL(b1_interrupt); |
783 | 793 | ||
784 | EXPORT_SYMBOL(b1ctl_read_proc); | ||
785 | |||
786 | static int __init b1_init(void) | 794 | static 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 | ||
858 | int b1dmactl_read_proc(char *page, char **start, off_t off, | 860 | static 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", | 944 | static 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 | ||
949 | const 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 | }; | ||
956 | EXPORT_SYMBOL(b1dmactl_proc_fops); | ||
957 | |||
954 | /* ------------------------------------------------------------- */ | 958 | /* ------------------------------------------------------------- */ |
955 | 959 | ||
956 | EXPORT_SYMBOL(b1dma_reset); | 960 | EXPORT_SYMBOL(b1dma_reset); |
@@ -963,7 +967,6 @@ EXPORT_SYMBOL(b1dma_reset_ctr); | |||
963 | EXPORT_SYMBOL(b1dma_register_appl); | 967 | EXPORT_SYMBOL(b1dma_register_appl); |
964 | EXPORT_SYMBOL(b1dma_release_appl); | 968 | EXPORT_SYMBOL(b1dma_release_appl); |
965 | EXPORT_SYMBOL(b1dma_send_message); | 969 | EXPORT_SYMBOL(b1dma_send_message); |
966 | EXPORT_SYMBOL(b1dmactl_read_proc); | ||
967 | 970 | ||
968 | static int __init b1dma_init(void) | 971 | static 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 | ||
1065 | static int c4_read_proc(char *page, char **start, off_t off, | 1067 | static 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 | ||
1129 | static int c4_proc_open(struct inode *inode, struct file *file) | ||
1130 | { | ||
1131 | return single_open(file, c4_proc_show, PDE(inode)->data); | ||
1132 | } | ||
1133 | |||
1134 | static 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 | ||
1135 | static int c4_add_card(struct capicardparams *p, struct pci_dev *dev, | 1144 | static 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 | */ |
78 | static int diva_ctl_read_proc(char *page, char **start, off_t off, | 79 | static 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) | 92 | static 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 | ||
97 | static 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 | ||
65 | static int | 66 | static int divadidd_proc_show(struct seq_file *m, void *v) |
66 | proc_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 | ||
81 | static int divadidd_proc_open(struct inode *inode, struct file *file) | ||
82 | { | ||
83 | return single_open(file, divadidd_proc_show, NULL); | ||
84 | } | ||
85 | |||
86 | static 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 | |||
88 | static int DIVA_INIT_FUNCTION create_proc(void) | 94 | static 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); | |||
86 | extern struct proc_dir_entry *proc_net_eicon; | 87 | extern struct proc_dir_entry *proc_net_eicon; |
87 | static struct proc_dir_entry *um_idi_proc_entry = NULL; | 88 | static struct proc_dir_entry *um_idi_proc_entry = NULL; |
88 | 89 | ||
89 | static int | 90 | static int um_idi_proc_show(struct seq_file *m, void *v) |
90 | um_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; | 105 | static 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 | ||
110 | static 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 | |||
112 | static int DIVA_INIT_FUNCTION create_um_idi_proc(void) | 118 | static 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 | /* | 145 | static 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 | */ | ||
147 | static int | ||
148 | write_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 | /* | 172 | static 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 | */ | ||
178 | static int | ||
179 | write_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 | 199 | static int d_l1_down_proc_show(struct seq_file *m, void *v) | |
207 | /* | ||
208 | ** read dynamic_l1_down | ||
209 | */ | ||
210 | static int | ||
211 | read_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) | 211 | static 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 | /* | 216 | static 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, |
234 | static int | 219 | .read = seq_read, |
235 | read_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 | |||
225 | static 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) | 237 | static 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 | /* | 242 | static const struct file_operations grp_opt_proc_fops = { |
256 | ** info write | 243 | .owner = THIS_MODULE, |
257 | */ | 244 | .open = grp_opt_proc_open, |
258 | static int | 245 | .read = seq_read, |
259 | info_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 | |||
251 | static 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 | /* | 272 | static int info_proc_show(struct seq_file *m, void *v) |
281 | ** info read | ||
282 | */ | ||
283 | static int | ||
284 | info_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; | 336 | static 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 | ||
341 | static 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 | ||
532 | static int | 533 | static int |
533 | setvolume(struct w6692_ch *wch, int mic, struct sk_buff *skb) | 534 | setvolume(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 | ||
575 | static int | 577 | static int |
576 | disable_pots(struct w6692_ch *wch) | 578 | disable_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 | ||
110 | config HISAX_TELESPCI | 110 | config 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 | ||
238 | config HISAX_NETJET | 238 | config 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 | ||
249 | config HISAX_NETJET_U | 249 | config 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 | ||
288 | config HISAX_BKM_A4T | 288 | config 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 | ||
298 | config HISAX_SCT_QUADRO | 298 | config 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 | ||
317 | config HISAX_HFC_PCI | 317 | config 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 | ||
326 | config HISAX_W6692 | 326 | config 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 | ||
342 | config HISAX_ENTERNOW_PCI | 342 | config 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 | ||
413 | config HISAX_FRITZ_PCIPNP | 413 | config 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 | ||
827 | static int __devinit avm_pci_setup(struct IsdnCardState *cs) | 827 | static int __devinit avm_pci_setup(struct IsdnCardState *cs) |
828 | { | 828 | { |
@@ -835,7 +835,7 @@ static struct pci_dev *dev_avm __devinitdata = NULL; | |||
835 | 835 | ||
836 | static int __devinit avm_pci_setup(struct IsdnCardState *cs) | 836 | static 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 | ||
869 | int __devinit | 869 | int __devinit |
870 | setup_avm_pcipnp(struct IsdnCard *card) | 870 | setup_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 |
1152 | static struct pci_dev *dev_diva __devinitdata = NULL; | 1152 | static struct pci_dev *dev_diva __devinitdata = NULL; |
1153 | static struct pci_dev *dev_diva_u __devinitdata = NULL; | 1153 | static struct pci_dev *dev_diva_u __devinitdata = NULL; |
1154 | static struct pci_dev *dev_diva201 __devinitdata = NULL; | 1154 | static 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 | ||
1234 | static int __devinit setup_diva_pci(struct IsdnCard *card) | 1234 | static 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 | ||
1241 | int __devinit | 1241 | int __devinit |
1242 | setup_diva(struct IsdnCard *card) | 1242 | setup_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 |
1029 | static struct pci_dev *dev_qs1000 __devinitdata = NULL; | 1029 | static struct pci_dev *dev_qs1000 __devinitdata = NULL; |
1030 | static struct pci_dev *dev_qs3000 __devinitdata = NULL; | 1030 | static 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 | ||
1098 | static int __devinit | 1098 | static int __devinit |
1099 | setup_elsa_common(struct IsdnCard *card) | 1099 | setup_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 |
535 | static struct pci_dev *dev_tel __devinitdata = NULL; | 535 | static struct pci_dev *dev_tel __devinitdata = NULL; |
536 | 536 | ||
537 | static int __devinit | 537 | static 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 | ||
625 | int __devinit | 625 | int __devinit |
626 | setup_gazel(struct IsdnCard *card) | 626 | setup_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); | |||
1323 | char *HiSax_getrev(const char *revision); | 1323 | char *HiSax_getrev(const char *revision); |
1324 | int TeiNew(void); | 1324 | int TeiNew(void); |
1325 | void TeiFree(void); | 1325 | void 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 | */ | ||
1336 | static 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 |
602 | static struct pci_dev *dev_sedl __devinitdata = NULL; | 602 | static struct pci_dev *dev_sedl __devinitdata = NULL; |
603 | 603 | ||
604 | static int __devinit | 604 | static 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 | ||
678 | int __devinit | 678 | int __devinit |
679 | setup_sedlbauer(struct IsdnCard *card) | 679 | setup_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 | /********************************************************************* | 437 | static int hycapi_proc_show(struct seq_file *m, void *v) |
436 | hycapi_read_proc | ||
437 | |||
438 | Informations provided in the /proc/capi-entries. | ||
439 | |||
440 | *********************************************************************/ | ||
441 | |||
442 | static 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; | 469 | static 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 | ||
474 | static 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 | /************************************************************** |
483 | hycapi_load_firmware | 483 | hycapi_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 | ||
135 | source "drivers/isdn/act2000/Kconfig" | 135 | source "drivers/isdn/act2000/Kconfig" |
136 | 136 | ||
137 | source "drivers/isdn/hysdn/Kconfig" | ||
138 | |||
139 | endmenu | 137 | endmenu |
140 | # end ISDN_I4L | 138 | # end ISDN_I4L |
141 | endif | 139 | endif |
142 | 140 | ||
143 | config ISDN_HDLC | ||
144 | tristate | ||
145 | select CRC_CCITT | ||
146 | select BITREVERSE | ||
147 | |||