aboutsummaryrefslogtreecommitdiffstats
path: root/net/atm/common.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/atm/common.c')
-rw-r--r--net/atm/common.c445
1 files changed, 248 insertions, 197 deletions
diff --git a/net/atm/common.c b/net/atm/common.c
index d61e051e0a3f..940404a73b3d 100644
--- a/net/atm/common.c
+++ b/net/atm/common.c
@@ -2,6 +2,7 @@
2 2
3/* Written 1995-2000 by Werner Almesberger, EPFL LRC/ICA */ 3/* Written 1995-2000 by Werner Almesberger, EPFL LRC/ICA */
4 4
5#define pr_fmt(fmt) KBUILD_MODNAME ":%s: " fmt, __func__
5 6
6#include <linux/module.h> 7#include <linux/module.h>
7#include <linux/kmod.h> 8#include <linux/kmod.h>
@@ -17,12 +18,12 @@
17#include <linux/skbuff.h> 18#include <linux/skbuff.h>
18#include <linux/bitops.h> 19#include <linux/bitops.h>
19#include <linux/init.h> 20#include <linux/init.h>
21#include <linux/slab.h>
20#include <net/sock.h> /* struct sock */ 22#include <net/sock.h> /* struct sock */
23#include <linux/uaccess.h>
24#include <linux/poll.h>
21 25
22#include <asm/uaccess.h>
23#include <asm/atomic.h> 26#include <asm/atomic.h>
24#include <asm/poll.h>
25
26 27
27#include "resources.h" /* atm_find_dev */ 28#include "resources.h" /* atm_find_dev */
28#include "common.h" /* prototypes */ 29#include "common.h" /* prototypes */
@@ -31,13 +32,17 @@
31#include "signaling.h" /* for WAITING and sigd_attach */ 32#include "signaling.h" /* for WAITING and sigd_attach */
32 33
33struct hlist_head vcc_hash[VCC_HTABLE_SIZE]; 34struct hlist_head vcc_hash[VCC_HTABLE_SIZE];
35EXPORT_SYMBOL(vcc_hash);
36
34DEFINE_RWLOCK(vcc_sklist_lock); 37DEFINE_RWLOCK(vcc_sklist_lock);
38EXPORT_SYMBOL(vcc_sklist_lock);
39
40static ATOMIC_NOTIFIER_HEAD(atm_dev_notify_chain);
35 41
36static void __vcc_insert_socket(struct sock *sk) 42static void __vcc_insert_socket(struct sock *sk)
37{ 43{
38 struct atm_vcc *vcc = atm_sk(sk); 44 struct atm_vcc *vcc = atm_sk(sk);
39 struct hlist_head *head = &vcc_hash[vcc->vci & 45 struct hlist_head *head = &vcc_hash[vcc->vci & (VCC_HTABLE_SIZE - 1)];
40 (VCC_HTABLE_SIZE - 1)];
41 sk->sk_hash = vcc->vci & (VCC_HTABLE_SIZE - 1); 46 sk->sk_hash = vcc->vci & (VCC_HTABLE_SIZE - 1);
42 sk_add_node(sk, head); 47 sk_add_node(sk, head);
43} 48}
@@ -48,6 +53,7 @@ void vcc_insert_socket(struct sock *sk)
48 __vcc_insert_socket(sk); 53 __vcc_insert_socket(sk);
49 write_unlock_irq(&vcc_sklist_lock); 54 write_unlock_irq(&vcc_sklist_lock);
50} 55}
56EXPORT_SYMBOL(vcc_insert_socket);
51 57
52static void vcc_remove_socket(struct sock *sk) 58static void vcc_remove_socket(struct sock *sk)
53{ 59{
@@ -56,45 +62,43 @@ static void vcc_remove_socket(struct sock *sk)
56 write_unlock_irq(&vcc_sklist_lock); 62 write_unlock_irq(&vcc_sklist_lock);
57} 63}
58 64
59 65static struct sk_buff *alloc_tx(struct atm_vcc *vcc, unsigned int size)
60static struct sk_buff *alloc_tx(struct atm_vcc *vcc,unsigned int size)
61{ 66{
62 struct sk_buff *skb; 67 struct sk_buff *skb;
63 struct sock *sk = sk_atm(vcc); 68 struct sock *sk = sk_atm(vcc);
64 69
65 if (sk_wmem_alloc_get(sk) && !atm_may_send(vcc, size)) { 70 if (sk_wmem_alloc_get(sk) && !atm_may_send(vcc, size)) {
66 pr_debug("Sorry: wmem_alloc = %d, size = %d, sndbuf = %d\n", 71 pr_debug("Sorry: wmem_alloc = %d, size = %d, sndbuf = %d\n",
67 sk_wmem_alloc_get(sk), size, 72 sk_wmem_alloc_get(sk), size, sk->sk_sndbuf);
68 sk->sk_sndbuf);
69 return NULL; 73 return NULL;
70 } 74 }
71 while (!(skb = alloc_skb(size, GFP_KERNEL))) 75 while (!(skb = alloc_skb(size, GFP_KERNEL)))
72 schedule(); 76 schedule();
73 pr_debug("AlTx %d += %d\n", sk_wmem_alloc_get(sk), skb->truesize); 77 pr_debug("%d += %d\n", sk_wmem_alloc_get(sk), skb->truesize);
74 atomic_add(skb->truesize, &sk->sk_wmem_alloc); 78 atomic_add(skb->truesize, &sk->sk_wmem_alloc);
75 return skb; 79 return skb;
76} 80}
77 81
78
79EXPORT_SYMBOL(vcc_hash);
80EXPORT_SYMBOL(vcc_sklist_lock);
81EXPORT_SYMBOL(vcc_insert_socket);
82
83static void vcc_sock_destruct(struct sock *sk) 82static void vcc_sock_destruct(struct sock *sk)
84{ 83{
85 if (atomic_read(&sk->sk_rmem_alloc)) 84 if (atomic_read(&sk->sk_rmem_alloc))
86 printk(KERN_DEBUG "vcc_sock_destruct: rmem leakage (%d bytes) detected.\n", atomic_read(&sk->sk_rmem_alloc)); 85 printk(KERN_DEBUG "%s: rmem leakage (%d bytes) detected.\n",
86 __func__, atomic_read(&sk->sk_rmem_alloc));
87 87
88 if (atomic_read(&sk->sk_wmem_alloc)) 88 if (atomic_read(&sk->sk_wmem_alloc))
89 printk(KERN_DEBUG "vcc_sock_destruct: wmem leakage (%d bytes) detected.\n", atomic_read(&sk->sk_wmem_alloc)); 89 printk(KERN_DEBUG "%s: wmem leakage (%d bytes) detected.\n",
90 __func__, atomic_read(&sk->sk_wmem_alloc));
90} 91}
91 92
92static void vcc_def_wakeup(struct sock *sk) 93static void vcc_def_wakeup(struct sock *sk)
93{ 94{
94 read_lock(&sk->sk_callback_lock); 95 struct socket_wq *wq;
95 if (sk_has_sleeper(sk)) 96
96 wake_up(sk->sk_sleep); 97 rcu_read_lock();
97 read_unlock(&sk->sk_callback_lock); 98 wq = rcu_dereference(sk->sk_wq);
99 if (wq_has_sleeper(wq))
100 wake_up(&wq->wait);
101 rcu_read_unlock();
98} 102}
99 103
100static inline int vcc_writable(struct sock *sk) 104static inline int vcc_writable(struct sock *sk)
@@ -107,16 +111,19 @@ static inline int vcc_writable(struct sock *sk)
107 111
108static void vcc_write_space(struct sock *sk) 112static void vcc_write_space(struct sock *sk)
109{ 113{
110 read_lock(&sk->sk_callback_lock); 114 struct socket_wq *wq;
115
116 rcu_read_lock();
111 117
112 if (vcc_writable(sk)) { 118 if (vcc_writable(sk)) {
113 if (sk_has_sleeper(sk)) 119 wq = rcu_dereference(sk->sk_wq);
114 wake_up_interruptible(sk->sk_sleep); 120 if (wq_has_sleeper(wq))
121 wake_up_interruptible(&wq->wait);
115 122
116 sk_wake_async(sk, SOCK_WAKE_SPACE, POLL_OUT); 123 sk_wake_async(sk, SOCK_WAKE_SPACE, POLL_OUT);
117 } 124 }
118 125
119 read_unlock(&sk->sk_callback_lock); 126 rcu_read_unlock();
120} 127}
121 128
122static struct proto vcc_proto = { 129static struct proto vcc_proto = {
@@ -142,8 +149,8 @@ int vcc_create(struct net *net, struct socket *sock, int protocol, int family)
142 149
143 vcc = atm_sk(sk); 150 vcc = atm_sk(sk);
144 vcc->dev = NULL; 151 vcc->dev = NULL;
145 memset(&vcc->local,0,sizeof(struct sockaddr_atmsvc)); 152 memset(&vcc->local, 0, sizeof(struct sockaddr_atmsvc));
146 memset(&vcc->remote,0,sizeof(struct sockaddr_atmsvc)); 153 memset(&vcc->remote, 0, sizeof(struct sockaddr_atmsvc));
147 vcc->qos.txtp.max_sdu = 1 << 16; /* for meta VCs */ 154 vcc->qos.txtp.max_sdu = 1 << 16; /* for meta VCs */
148 atomic_set(&sk->sk_wmem_alloc, 1); 155 atomic_set(&sk->sk_wmem_alloc, 1);
149 atomic_set(&sk->sk_rmem_alloc, 0); 156 atomic_set(&sk->sk_rmem_alloc, 0);
@@ -156,7 +163,6 @@ int vcc_create(struct net *net, struct socket *sock, int protocol, int family)
156 return 0; 163 return 0;
157} 164}
158 165
159
160static void vcc_destroy_socket(struct sock *sk) 166static void vcc_destroy_socket(struct sock *sk)
161{ 167{
162 struct atm_vcc *vcc = atm_sk(sk); 168 struct atm_vcc *vcc = atm_sk(sk);
@@ -171,7 +177,7 @@ static void vcc_destroy_socket(struct sock *sk)
171 vcc->push(vcc, NULL); /* atmarpd has no push */ 177 vcc->push(vcc, NULL); /* atmarpd has no push */
172 178
173 while ((skb = skb_dequeue(&sk->sk_receive_queue)) != NULL) { 179 while ((skb = skb_dequeue(&sk->sk_receive_queue)) != NULL) {
174 atm_return(vcc,skb->truesize); 180 atm_return(vcc, skb->truesize);
175 kfree_skb(skb); 181 kfree_skb(skb);
176 } 182 }
177 183
@@ -182,7 +188,6 @@ static void vcc_destroy_socket(struct sock *sk)
182 vcc_remove_socket(sk); 188 vcc_remove_socket(sk);
183} 189}
184 190
185
186int vcc_release(struct socket *sock) 191int vcc_release(struct socket *sock)
187{ 192{
188 struct sock *sk = sock->sk; 193 struct sock *sk = sock->sk;
@@ -197,7 +202,6 @@ int vcc_release(struct socket *sock)
197 return 0; 202 return 0;
198} 203}
199 204
200
201void vcc_release_async(struct atm_vcc *vcc, int reply) 205void vcc_release_async(struct atm_vcc *vcc, int reply)
202{ 206{
203 struct sock *sk = sk_atm(vcc); 207 struct sock *sk = sk_atm(vcc);
@@ -208,10 +212,24 @@ void vcc_release_async(struct atm_vcc *vcc, int reply)
208 clear_bit(ATM_VF_WAITING, &vcc->flags); 212 clear_bit(ATM_VF_WAITING, &vcc->flags);
209 sk->sk_state_change(sk); 213 sk->sk_state_change(sk);
210} 214}
215EXPORT_SYMBOL(vcc_release_async);
216
217void atm_dev_signal_change(struct atm_dev *dev, char signal)
218{
219 pr_debug("%s signal=%d dev=%p number=%d dev->signal=%d\n",
220 __func__, signal, dev, dev->number, dev->signal);
211 221
222 /* atm driver sending invalid signal */
223 WARN_ON(signal < ATM_PHY_SIG_LOST || signal > ATM_PHY_SIG_FOUND);
212 224
213EXPORT_SYMBOL(vcc_release_async); 225 if (dev->signal == signal)
226 return; /* no change */
214 227
228 dev->signal = signal;
229
230 atomic_notifier_call_chain(&atm_dev_notify_chain, signal, dev);
231}
232EXPORT_SYMBOL(atm_dev_signal_change);
215 233
216void atm_dev_release_vccs(struct atm_dev *dev) 234void atm_dev_release_vccs(struct atm_dev *dev)
217{ 235{
@@ -235,37 +253,37 @@ void atm_dev_release_vccs(struct atm_dev *dev)
235 write_unlock_irq(&vcc_sklist_lock); 253 write_unlock_irq(&vcc_sklist_lock);
236} 254}
237 255
238 256static int adjust_tp(struct atm_trafprm *tp, unsigned char aal)
239static int adjust_tp(struct atm_trafprm *tp,unsigned char aal)
240{ 257{
241 int max_sdu; 258 int max_sdu;
242 259
243 if (!tp->traffic_class) return 0; 260 if (!tp->traffic_class)
261 return 0;
244 switch (aal) { 262 switch (aal) {
245 case ATM_AAL0: 263 case ATM_AAL0:
246 max_sdu = ATM_CELL_SIZE-1; 264 max_sdu = ATM_CELL_SIZE-1;
247 break; 265 break;
248 case ATM_AAL34: 266 case ATM_AAL34:
249 max_sdu = ATM_MAX_AAL34_PDU; 267 max_sdu = ATM_MAX_AAL34_PDU;
250 break; 268 break;
251 default: 269 default:
252 printk(KERN_WARNING "ATM: AAL problems ... " 270 pr_warning("AAL problems ... (%d)\n", aal);
253 "(%d)\n",aal); 271 /* fall through */
254 /* fall through */ 272 case ATM_AAL5:
255 case ATM_AAL5: 273 max_sdu = ATM_MAX_AAL5_PDU;
256 max_sdu = ATM_MAX_AAL5_PDU;
257 } 274 }
258 if (!tp->max_sdu) tp->max_sdu = max_sdu; 275 if (!tp->max_sdu)
259 else if (tp->max_sdu > max_sdu) return -EINVAL; 276 tp->max_sdu = max_sdu;
260 if (!tp->max_cdv) tp->max_cdv = ATM_MAX_CDV; 277 else if (tp->max_sdu > max_sdu)
278 return -EINVAL;
279 if (!tp->max_cdv)
280 tp->max_cdv = ATM_MAX_CDV;
261 return 0; 281 return 0;
262} 282}
263 283
264
265static int check_ci(const struct atm_vcc *vcc, short vpi, int vci) 284static int check_ci(const struct atm_vcc *vcc, short vpi, int vci)
266{ 285{
267 struct hlist_head *head = &vcc_hash[vci & 286 struct hlist_head *head = &vcc_hash[vci & (VCC_HTABLE_SIZE - 1)];
268 (VCC_HTABLE_SIZE - 1)];
269 struct hlist_node *node; 287 struct hlist_node *node;
270 struct sock *s; 288 struct sock *s;
271 struct atm_vcc *walk; 289 struct atm_vcc *walk;
@@ -289,7 +307,6 @@ static int check_ci(const struct atm_vcc *vcc, short vpi, int vci)
289 return 0; 307 return 0;
290} 308}
291 309
292
293static int find_ci(const struct atm_vcc *vcc, short *vpi, int *vci) 310static int find_ci(const struct atm_vcc *vcc, short *vpi, int *vci)
294{ 311{
295 static short p; /* poor man's per-device cache */ 312 static short p; /* poor man's per-device cache */
@@ -327,14 +344,13 @@ static int find_ci(const struct atm_vcc *vcc, short *vpi, int *vci)
327 if ((c == ATM_NOT_RSV_VCI || *vci != ATM_VCI_ANY) && 344 if ((c == ATM_NOT_RSV_VCI || *vci != ATM_VCI_ANY) &&
328 *vpi == ATM_VPI_ANY) { 345 *vpi == ATM_VPI_ANY) {
329 p++; 346 p++;
330 if (p >= 1 << vcc->dev->ci_range.vpi_bits) p = 0; 347 if (p >= 1 << vcc->dev->ci_range.vpi_bits)
348 p = 0;
331 } 349 }
332 } 350 } while (old_p != p || old_c != c);
333 while (old_p != p || old_c != c);
334 return -EADDRINUSE; 351 return -EADDRINUSE;
335} 352}
336 353
337
338static int __vcc_connect(struct atm_vcc *vcc, struct atm_dev *dev, short vpi, 354static int __vcc_connect(struct atm_vcc *vcc, struct atm_dev *dev, short vpi,
339 int vci) 355 int vci)
340{ 356{
@@ -362,37 +378,46 @@ static int __vcc_connect(struct atm_vcc *vcc, struct atm_dev *dev, short vpi,
362 __vcc_insert_socket(sk); 378 __vcc_insert_socket(sk);
363 write_unlock_irq(&vcc_sklist_lock); 379 write_unlock_irq(&vcc_sklist_lock);
364 switch (vcc->qos.aal) { 380 switch (vcc->qos.aal) {
365 case ATM_AAL0: 381 case ATM_AAL0:
366 error = atm_init_aal0(vcc); 382 error = atm_init_aal0(vcc);
367 vcc->stats = &dev->stats.aal0; 383 vcc->stats = &dev->stats.aal0;
368 break; 384 break;
369 case ATM_AAL34: 385 case ATM_AAL34:
370 error = atm_init_aal34(vcc); 386 error = atm_init_aal34(vcc);
371 vcc->stats = &dev->stats.aal34; 387 vcc->stats = &dev->stats.aal34;
372 break; 388 break;
373 case ATM_NO_AAL: 389 case ATM_NO_AAL:
374 /* ATM_AAL5 is also used in the "0 for default" case */ 390 /* ATM_AAL5 is also used in the "0 for default" case */
375 vcc->qos.aal = ATM_AAL5; 391 vcc->qos.aal = ATM_AAL5;
376 /* fall through */ 392 /* fall through */
377 case ATM_AAL5: 393 case ATM_AAL5:
378 error = atm_init_aal5(vcc); 394 error = atm_init_aal5(vcc);
379 vcc->stats = &dev->stats.aal5; 395 vcc->stats = &dev->stats.aal5;
380 break; 396 break;
381 default: 397 default:
382 error = -EPROTOTYPE; 398 error = -EPROTOTYPE;
383 } 399 }
384 if (!error) error = adjust_tp(&vcc->qos.txtp,vcc->qos.aal); 400 if (!error)
385 if (!error) error = adjust_tp(&vcc->qos.rxtp,vcc->qos.aal); 401 error = adjust_tp(&vcc->qos.txtp, vcc->qos.aal);
402 if (!error)
403 error = adjust_tp(&vcc->qos.rxtp, vcc->qos.aal);
386 if (error) 404 if (error)
387 goto fail; 405 goto fail;
388 pr_debug("VCC %d.%d, AAL %d\n",vpi,vci,vcc->qos.aal); 406 pr_debug("VCC %d.%d, AAL %d\n", vpi, vci, vcc->qos.aal);
389 pr_debug(" TX: %d, PCR %d..%d, SDU %d\n",vcc->qos.txtp.traffic_class, 407 pr_debug(" TX: %d, PCR %d..%d, SDU %d\n",
390 vcc->qos.txtp.min_pcr,vcc->qos.txtp.max_pcr,vcc->qos.txtp.max_sdu); 408 vcc->qos.txtp.traffic_class,
391 pr_debug(" RX: %d, PCR %d..%d, SDU %d\n",vcc->qos.rxtp.traffic_class, 409 vcc->qos.txtp.min_pcr,
392 vcc->qos.rxtp.min_pcr,vcc->qos.rxtp.max_pcr,vcc->qos.rxtp.max_sdu); 410 vcc->qos.txtp.max_pcr,
411 vcc->qos.txtp.max_sdu);
412 pr_debug(" RX: %d, PCR %d..%d, SDU %d\n",
413 vcc->qos.rxtp.traffic_class,
414 vcc->qos.rxtp.min_pcr,
415 vcc->qos.rxtp.max_pcr,
416 vcc->qos.rxtp.max_sdu);
393 417
394 if (dev->ops->open) { 418 if (dev->ops->open) {
395 if ((error = dev->ops->open(vcc))) 419 error = dev->ops->open(vcc);
420 if (error)
396 goto fail; 421 goto fail;
397 } 422 }
398 return 0; 423 return 0;
@@ -406,14 +431,13 @@ fail_module_put:
406 return error; 431 return error;
407} 432}
408 433
409
410int vcc_connect(struct socket *sock, int itf, short vpi, int vci) 434int vcc_connect(struct socket *sock, int itf, short vpi, int vci)
411{ 435{
412 struct atm_dev *dev; 436 struct atm_dev *dev;
413 struct atm_vcc *vcc = ATM_SD(sock); 437 struct atm_vcc *vcc = ATM_SD(sock);
414 int error; 438 int error;
415 439
416 pr_debug("vcc_connect (vpi %d, vci %d)\n",vpi,vci); 440 pr_debug("(vpi %d, vci %d)\n", vpi, vci);
417 if (sock->state == SS_CONNECTED) 441 if (sock->state == SS_CONNECTED)
418 return -EISCONN; 442 return -EISCONN;
419 if (sock->state != SS_UNCONNECTED) 443 if (sock->state != SS_UNCONNECTED)
@@ -422,30 +446,33 @@ int vcc_connect(struct socket *sock, int itf, short vpi, int vci)
422 return -EINVAL; 446 return -EINVAL;
423 447
424 if (vpi != ATM_VPI_UNSPEC && vci != ATM_VCI_UNSPEC) 448 if (vpi != ATM_VPI_UNSPEC && vci != ATM_VCI_UNSPEC)
425 clear_bit(ATM_VF_PARTIAL,&vcc->flags); 449 clear_bit(ATM_VF_PARTIAL, &vcc->flags);
426 else 450 else
427 if (test_bit(ATM_VF_PARTIAL,&vcc->flags)) 451 if (test_bit(ATM_VF_PARTIAL, &vcc->flags))
428 return -EINVAL; 452 return -EINVAL;
429 pr_debug("vcc_connect (TX: cl %d,bw %d-%d,sdu %d; " 453 pr_debug("(TX: cl %d,bw %d-%d,sdu %d; "
430 "RX: cl %d,bw %d-%d,sdu %d,AAL %s%d)\n", 454 "RX: cl %d,bw %d-%d,sdu %d,AAL %s%d)\n",
431 vcc->qos.txtp.traffic_class,vcc->qos.txtp.min_pcr, 455 vcc->qos.txtp.traffic_class, vcc->qos.txtp.min_pcr,
432 vcc->qos.txtp.max_pcr,vcc->qos.txtp.max_sdu, 456 vcc->qos.txtp.max_pcr, vcc->qos.txtp.max_sdu,
433 vcc->qos.rxtp.traffic_class,vcc->qos.rxtp.min_pcr, 457 vcc->qos.rxtp.traffic_class, vcc->qos.rxtp.min_pcr,
434 vcc->qos.rxtp.max_pcr,vcc->qos.rxtp.max_sdu, 458 vcc->qos.rxtp.max_pcr, vcc->qos.rxtp.max_sdu,
435 vcc->qos.aal == ATM_AAL5 ? "" : vcc->qos.aal == ATM_AAL0 ? "" : 459 vcc->qos.aal == ATM_AAL5 ? "" :
436 " ??? code ",vcc->qos.aal == ATM_AAL0 ? 0 : vcc->qos.aal); 460 vcc->qos.aal == ATM_AAL0 ? "" : " ??? code ",
461 vcc->qos.aal == ATM_AAL0 ? 0 : vcc->qos.aal);
437 if (!test_bit(ATM_VF_HASQOS, &vcc->flags)) 462 if (!test_bit(ATM_VF_HASQOS, &vcc->flags))
438 return -EBADFD; 463 return -EBADFD;
439 if (vcc->qos.txtp.traffic_class == ATM_ANYCLASS || 464 if (vcc->qos.txtp.traffic_class == ATM_ANYCLASS ||
440 vcc->qos.rxtp.traffic_class == ATM_ANYCLASS) 465 vcc->qos.rxtp.traffic_class == ATM_ANYCLASS)
441 return -EINVAL; 466 return -EINVAL;
442 if (likely(itf != ATM_ITF_ANY)) { 467 if (likely(itf != ATM_ITF_ANY)) {
443 dev = try_then_request_module(atm_dev_lookup(itf), "atm-device-%d", itf); 468 dev = try_then_request_module(atm_dev_lookup(itf),
469 "atm-device-%d", itf);
444 } else { 470 } else {
445 dev = NULL; 471 dev = NULL;
446 mutex_lock(&atm_dev_mutex); 472 mutex_lock(&atm_dev_mutex);
447 if (!list_empty(&atm_devs)) { 473 if (!list_empty(&atm_devs)) {
448 dev = list_entry(atm_devs.next, struct atm_dev, dev_list); 474 dev = list_entry(atm_devs.next,
475 struct atm_dev, dev_list);
449 atm_dev_hold(dev); 476 atm_dev_hold(dev);
450 } 477 }
451 mutex_unlock(&atm_dev_mutex); 478 mutex_unlock(&atm_dev_mutex);
@@ -458,13 +485,12 @@ int vcc_connect(struct socket *sock, int itf, short vpi, int vci)
458 return error; 485 return error;
459 } 486 }
460 if (vpi == ATM_VPI_UNSPEC || vci == ATM_VCI_UNSPEC) 487 if (vpi == ATM_VPI_UNSPEC || vci == ATM_VCI_UNSPEC)
461 set_bit(ATM_VF_PARTIAL,&vcc->flags); 488 set_bit(ATM_VF_PARTIAL, &vcc->flags);
462 if (test_bit(ATM_VF_READY,&ATM_SD(sock)->flags)) 489 if (test_bit(ATM_VF_READY, &ATM_SD(sock)->flags))
463 sock->state = SS_CONNECTED; 490 sock->state = SS_CONNECTED;
464 return 0; 491 return 0;
465} 492}
466 493
467
468int vcc_recvmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg, 494int vcc_recvmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg,
469 size_t size, int flags) 495 size_t size, int flags)
470{ 496{
@@ -478,8 +504,8 @@ int vcc_recvmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg,
478 if (flags & ~MSG_DONTWAIT) /* only handle MSG_DONTWAIT */ 504 if (flags & ~MSG_DONTWAIT) /* only handle MSG_DONTWAIT */
479 return -EOPNOTSUPP; 505 return -EOPNOTSUPP;
480 vcc = ATM_SD(sock); 506 vcc = ATM_SD(sock);
481 if (test_bit(ATM_VF_RELEASED,&vcc->flags) || 507 if (test_bit(ATM_VF_RELEASED, &vcc->flags) ||
482 test_bit(ATM_VF_CLOSE,&vcc->flags) || 508 test_bit(ATM_VF_CLOSE, &vcc->flags) ||
483 !test_bit(ATM_VF_READY, &vcc->flags)) 509 !test_bit(ATM_VF_READY, &vcc->flags))
484 return 0; 510 return 0;
485 511
@@ -497,13 +523,12 @@ int vcc_recvmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg,
497 if (error) 523 if (error)
498 return error; 524 return error;
499 sock_recv_ts_and_drops(msg, sk, skb); 525 sock_recv_ts_and_drops(msg, sk, skb);
500 pr_debug("RcvM %d -= %d\n", atomic_read(&sk->sk_rmem_alloc), skb->truesize); 526 pr_debug("%d -= %d\n", atomic_read(&sk->sk_rmem_alloc), skb->truesize);
501 atm_return(vcc, skb->truesize); 527 atm_return(vcc, skb->truesize);
502 skb_free_datagram(sk, skb); 528 skb_free_datagram(sk, skb);
503 return copied; 529 return copied;
504} 530}
505 531
506
507int vcc_sendmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *m, 532int vcc_sendmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *m,
508 size_t total_len) 533 size_t total_len)
509{ 534{
@@ -511,7 +536,7 @@ int vcc_sendmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *m,
511 DEFINE_WAIT(wait); 536 DEFINE_WAIT(wait);
512 struct atm_vcc *vcc; 537 struct atm_vcc *vcc;
513 struct sk_buff *skb; 538 struct sk_buff *skb;
514 int eff,error; 539 int eff, error;
515 const void __user *buff; 540 const void __user *buff;
516 int size; 541 int size;
517 542
@@ -548,9 +573,9 @@ int vcc_sendmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *m,
548 } 573 }
549 574
550 eff = (size+3) & ~3; /* align to word boundary */ 575 eff = (size+3) & ~3; /* align to word boundary */
551 prepare_to_wait(sk->sk_sleep, &wait, TASK_INTERRUPTIBLE); 576 prepare_to_wait(sk_sleep(sk), &wait, TASK_INTERRUPTIBLE);
552 error = 0; 577 error = 0;
553 while (!(skb = alloc_tx(vcc,eff))) { 578 while (!(skb = alloc_tx(vcc, eff))) {
554 if (m->msg_flags & MSG_DONTWAIT) { 579 if (m->msg_flags & MSG_DONTWAIT) {
555 error = -EAGAIN; 580 error = -EAGAIN;
556 break; 581 break;
@@ -560,41 +585,41 @@ int vcc_sendmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *m,
560 error = -ERESTARTSYS; 585 error = -ERESTARTSYS;
561 break; 586 break;
562 } 587 }
563 if (test_bit(ATM_VF_RELEASED,&vcc->flags) || 588 if (test_bit(ATM_VF_RELEASED, &vcc->flags) ||
564 test_bit(ATM_VF_CLOSE,&vcc->flags) || 589 test_bit(ATM_VF_CLOSE, &vcc->flags) ||
565 !test_bit(ATM_VF_READY,&vcc->flags)) { 590 !test_bit(ATM_VF_READY, &vcc->flags)) {
566 error = -EPIPE; 591 error = -EPIPE;
567 send_sig(SIGPIPE, current, 0); 592 send_sig(SIGPIPE, current, 0);
568 break; 593 break;
569 } 594 }
570 prepare_to_wait(sk->sk_sleep, &wait, TASK_INTERRUPTIBLE); 595 prepare_to_wait(sk_sleep(sk), &wait, TASK_INTERRUPTIBLE);
571 } 596 }
572 finish_wait(sk->sk_sleep, &wait); 597 finish_wait(sk_sleep(sk), &wait);
573 if (error) 598 if (error)
574 goto out; 599 goto out;
575 skb->dev = NULL; /* for paths shared with net_device interfaces */ 600 skb->dev = NULL; /* for paths shared with net_device interfaces */
576 ATM_SKB(skb)->atm_options = vcc->atm_options; 601 ATM_SKB(skb)->atm_options = vcc->atm_options;
577 if (copy_from_user(skb_put(skb,size),buff,size)) { 602 if (copy_from_user(skb_put(skb, size), buff, size)) {
578 kfree_skb(skb); 603 kfree_skb(skb);
579 error = -EFAULT; 604 error = -EFAULT;
580 goto out; 605 goto out;
581 } 606 }
582 if (eff != size) memset(skb->data+size,0,eff-size); 607 if (eff != size)
583 error = vcc->dev->ops->send(vcc,skb); 608 memset(skb->data + size, 0, eff-size);
609 error = vcc->dev->ops->send(vcc, skb);
584 error = error ? error : size; 610 error = error ? error : size;
585out: 611out:
586 release_sock(sk); 612 release_sock(sk);
587 return error; 613 return error;
588} 614}
589 615
590
591unsigned int vcc_poll(struct file *file, struct socket *sock, poll_table *wait) 616unsigned int vcc_poll(struct file *file, struct socket *sock, poll_table *wait)
592{ 617{
593 struct sock *sk = sock->sk; 618 struct sock *sk = sock->sk;
594 struct atm_vcc *vcc; 619 struct atm_vcc *vcc;
595 unsigned int mask; 620 unsigned int mask;
596 621
597 sock_poll_wait(file, sk->sk_sleep, wait); 622 sock_poll_wait(file, sk_sleep(sk), wait);
598 mask = 0; 623 mask = 0;
599 624
600 vcc = ATM_SD(sock); 625 vcc = ATM_SD(sock);
@@ -623,8 +648,7 @@ unsigned int vcc_poll(struct file *file, struct socket *sock, poll_table *wait)
623 return mask; 648 return mask;
624} 649}
625 650
626 651static int atm_change_qos(struct atm_vcc *vcc, struct atm_qos *qos)
627static int atm_change_qos(struct atm_vcc *vcc,struct atm_qos *qos)
628{ 652{
629 int error; 653 int error;
630 654
@@ -636,25 +660,31 @@ static int atm_change_qos(struct atm_vcc *vcc,struct atm_qos *qos)
636 qos->rxtp.traffic_class != vcc->qos.rxtp.traffic_class || 660 qos->rxtp.traffic_class != vcc->qos.rxtp.traffic_class ||
637 qos->txtp.traffic_class != vcc->qos.txtp.traffic_class) 661 qos->txtp.traffic_class != vcc->qos.txtp.traffic_class)
638 return -EINVAL; 662 return -EINVAL;
639 error = adjust_tp(&qos->txtp,qos->aal); 663 error = adjust_tp(&qos->txtp, qos->aal);
640 if (!error) error = adjust_tp(&qos->rxtp,qos->aal); 664 if (!error)
641 if (error) return error; 665 error = adjust_tp(&qos->rxtp, qos->aal);
642 if (!vcc->dev->ops->change_qos) return -EOPNOTSUPP; 666 if (error)
667 return error;
668 if (!vcc->dev->ops->change_qos)
669 return -EOPNOTSUPP;
643 if (sk_atm(vcc)->sk_family == AF_ATMPVC) 670 if (sk_atm(vcc)->sk_family == AF_ATMPVC)
644 return vcc->dev->ops->change_qos(vcc,qos,ATM_MF_SET); 671 return vcc->dev->ops->change_qos(vcc, qos, ATM_MF_SET);
645 return svc_change_qos(vcc,qos); 672 return svc_change_qos(vcc, qos);
646} 673}
647 674
648
649static int check_tp(const struct atm_trafprm *tp) 675static int check_tp(const struct atm_trafprm *tp)
650{ 676{
651 /* @@@ Should be merged with adjust_tp */ 677 /* @@@ Should be merged with adjust_tp */
652 if (!tp->traffic_class || tp->traffic_class == ATM_ANYCLASS) return 0; 678 if (!tp->traffic_class || tp->traffic_class == ATM_ANYCLASS)
679 return 0;
653 if (tp->traffic_class != ATM_UBR && !tp->min_pcr && !tp->pcr && 680 if (tp->traffic_class != ATM_UBR && !tp->min_pcr && !tp->pcr &&
654 !tp->max_pcr) return -EINVAL; 681 !tp->max_pcr)
655 if (tp->min_pcr == ATM_MAX_PCR) return -EINVAL; 682 return -EINVAL;
683 if (tp->min_pcr == ATM_MAX_PCR)
684 return -EINVAL;
656 if (tp->min_pcr && tp->max_pcr && tp->max_pcr != ATM_MAX_PCR && 685 if (tp->min_pcr && tp->max_pcr && tp->max_pcr != ATM_MAX_PCR &&
657 tp->min_pcr > tp->max_pcr) return -EINVAL; 686 tp->min_pcr > tp->max_pcr)
687 return -EINVAL;
658 /* 688 /*
659 * We allow pcr to be outside [min_pcr,max_pcr], because later 689 * We allow pcr to be outside [min_pcr,max_pcr], because later
660 * adjustment may still push it in the valid range. 690 * adjustment may still push it in the valid range.
@@ -662,7 +692,6 @@ static int check_tp(const struct atm_trafprm *tp)
662 return 0; 692 return 0;
663} 693}
664 694
665
666static int check_qos(const struct atm_qos *qos) 695static int check_qos(const struct atm_qos *qos)
667{ 696{
668 int error; 697 int error;
@@ -672,9 +701,11 @@ static int check_qos(const struct atm_qos *qos)
672 if (qos->txtp.traffic_class != qos->rxtp.traffic_class && 701 if (qos->txtp.traffic_class != qos->rxtp.traffic_class &&
673 qos->txtp.traffic_class && qos->rxtp.traffic_class && 702 qos->txtp.traffic_class && qos->rxtp.traffic_class &&
674 qos->txtp.traffic_class != ATM_ANYCLASS && 703 qos->txtp.traffic_class != ATM_ANYCLASS &&
675 qos->rxtp.traffic_class != ATM_ANYCLASS) return -EINVAL; 704 qos->rxtp.traffic_class != ATM_ANYCLASS)
705 return -EINVAL;
676 error = check_tp(&qos->txtp); 706 error = check_tp(&qos->txtp);
677 if (error) return error; 707 if (error)
708 return error;
678 return check_tp(&qos->rxtp); 709 return check_tp(&qos->rxtp);
679} 710}
680 711
@@ -690,37 +721,41 @@ int vcc_setsockopt(struct socket *sock, int level, int optname,
690 721
691 vcc = ATM_SD(sock); 722 vcc = ATM_SD(sock);
692 switch (optname) { 723 switch (optname) {
693 case SO_ATMQOS: 724 case SO_ATMQOS:
694 { 725 {
695 struct atm_qos qos; 726 struct atm_qos qos;
696 727
697 if (copy_from_user(&qos,optval,sizeof(qos))) 728 if (copy_from_user(&qos, optval, sizeof(qos)))
698 return -EFAULT; 729 return -EFAULT;
699 error = check_qos(&qos); 730 error = check_qos(&qos);
700 if (error) return error; 731 if (error)
701 if (sock->state == SS_CONNECTED) 732 return error;
702 return atm_change_qos(vcc,&qos); 733 if (sock->state == SS_CONNECTED)
703 if (sock->state != SS_UNCONNECTED) 734 return atm_change_qos(vcc, &qos);
704 return -EBADFD; 735 if (sock->state != SS_UNCONNECTED)
705 vcc->qos = qos; 736 return -EBADFD;
706 set_bit(ATM_VF_HASQOS,&vcc->flags); 737 vcc->qos = qos;
707 return 0; 738 set_bit(ATM_VF_HASQOS, &vcc->flags);
708 } 739 return 0;
709 case SO_SETCLP:
710 if (get_user(value,(unsigned long __user *)optval))
711 return -EFAULT;
712 if (value) vcc->atm_options |= ATM_ATMOPT_CLP;
713 else vcc->atm_options &= ~ATM_ATMOPT_CLP;
714 return 0;
715 default:
716 if (level == SOL_SOCKET) return -EINVAL;
717 break;
718 } 740 }
719 if (!vcc->dev || !vcc->dev->ops->setsockopt) return -EINVAL; 741 case SO_SETCLP:
720 return vcc->dev->ops->setsockopt(vcc,level,optname,optval,optlen); 742 if (get_user(value, (unsigned long __user *)optval))
743 return -EFAULT;
744 if (value)
745 vcc->atm_options |= ATM_ATMOPT_CLP;
746 else
747 vcc->atm_options &= ~ATM_ATMOPT_CLP;
748 return 0;
749 default:
750 if (level == SOL_SOCKET)
751 return -EINVAL;
752 break;
753 }
754 if (!vcc->dev || !vcc->dev->ops->setsockopt)
755 return -EINVAL;
756 return vcc->dev->ops->setsockopt(vcc, level, optname, optval, optlen);
721} 757}
722 758
723
724int vcc_getsockopt(struct socket *sock, int level, int optname, 759int vcc_getsockopt(struct socket *sock, int level, int optname,
725 char __user *optval, int __user *optlen) 760 char __user *optval, int __user *optlen)
726{ 761{
@@ -734,57 +769,73 @@ int vcc_getsockopt(struct socket *sock, int level, int optname,
734 769
735 vcc = ATM_SD(sock); 770 vcc = ATM_SD(sock);
736 switch (optname) { 771 switch (optname) {
737 case SO_ATMQOS: 772 case SO_ATMQOS:
738 if (!test_bit(ATM_VF_HASQOS,&vcc->flags)) 773 if (!test_bit(ATM_VF_HASQOS, &vcc->flags))
739 return -EINVAL; 774 return -EINVAL;
740 return copy_to_user(optval,&vcc->qos,sizeof(vcc->qos)) ? 775 return copy_to_user(optval, &vcc->qos, sizeof(vcc->qos))
741 -EFAULT : 0; 776 ? -EFAULT : 0;
742 case SO_SETCLP: 777 case SO_SETCLP:
743 return put_user(vcc->atm_options & ATM_ATMOPT_CLP ? 1 : 778 return put_user(vcc->atm_options & ATM_ATMOPT_CLP ? 1 : 0,
744 0,(unsigned long __user *)optval) ? -EFAULT : 0; 779 (unsigned long __user *)optval) ? -EFAULT : 0;
745 case SO_ATMPVC: 780 case SO_ATMPVC:
746 { 781 {
747 struct sockaddr_atmpvc pvc; 782 struct sockaddr_atmpvc pvc;
748 783
749 if (!vcc->dev || 784 if (!vcc->dev || !test_bit(ATM_VF_ADDR, &vcc->flags))
750 !test_bit(ATM_VF_ADDR,&vcc->flags)) 785 return -ENOTCONN;
751 return -ENOTCONN; 786 pvc.sap_family = AF_ATMPVC;
752 pvc.sap_family = AF_ATMPVC; 787 pvc.sap_addr.itf = vcc->dev->number;
753 pvc.sap_addr.itf = vcc->dev->number; 788 pvc.sap_addr.vpi = vcc->vpi;
754 pvc.sap_addr.vpi = vcc->vpi; 789 pvc.sap_addr.vci = vcc->vci;
755 pvc.sap_addr.vci = vcc->vci; 790 return copy_to_user(optval, &pvc, sizeof(pvc)) ? -EFAULT : 0;
756 return copy_to_user(optval,&pvc,sizeof(pvc)) ? 791 }
757 -EFAULT : 0; 792 default:
758 } 793 if (level == SOL_SOCKET)
759 default: 794 return -EINVAL;
760 if (level == SOL_SOCKET) return -EINVAL;
761 break; 795 break;
762 } 796 }
763 if (!vcc->dev || !vcc->dev->ops->getsockopt) return -EINVAL; 797 if (!vcc->dev || !vcc->dev->ops->getsockopt)
798 return -EINVAL;
764 return vcc->dev->ops->getsockopt(vcc, level, optname, optval, len); 799 return vcc->dev->ops->getsockopt(vcc, level, optname, optval, len);
765} 800}
766 801
802int register_atmdevice_notifier(struct notifier_block *nb)
803{
804 return atomic_notifier_chain_register(&atm_dev_notify_chain, nb);
805}
806EXPORT_SYMBOL_GPL(register_atmdevice_notifier);
807
808void unregister_atmdevice_notifier(struct notifier_block *nb)
809{
810 atomic_notifier_chain_unregister(&atm_dev_notify_chain, nb);
811}
812EXPORT_SYMBOL_GPL(unregister_atmdevice_notifier);
813
767static int __init atm_init(void) 814static int __init atm_init(void)
768{ 815{
769 int error; 816 int error;
770 817
771 if ((error = proto_register(&vcc_proto, 0)) < 0) 818 error = proto_register(&vcc_proto, 0);
819 if (error < 0)
772 goto out; 820 goto out;
773 821 error = atmpvc_init();
774 if ((error = atmpvc_init()) < 0) { 822 if (error < 0) {
775 printk(KERN_ERR "atmpvc_init() failed with %d\n", error); 823 pr_err("atmpvc_init() failed with %d\n", error);
776 goto out_unregister_vcc_proto; 824 goto out_unregister_vcc_proto;
777 } 825 }
778 if ((error = atmsvc_init()) < 0) { 826 error = atmsvc_init();
779 printk(KERN_ERR "atmsvc_init() failed with %d\n", error); 827 if (error < 0) {
828 pr_err("atmsvc_init() failed with %d\n", error);
780 goto out_atmpvc_exit; 829 goto out_atmpvc_exit;
781 } 830 }
782 if ((error = atm_proc_init()) < 0) { 831 error = atm_proc_init();
783 printk(KERN_ERR "atm_proc_init() failed with %d\n",error); 832 if (error < 0) {
833 pr_err("atm_proc_init() failed with %d\n", error);
784 goto out_atmsvc_exit; 834 goto out_atmsvc_exit;
785 } 835 }
786 if ((error = atm_sysfs_init()) < 0) { 836 error = atm_sysfs_init();
787 printk(KERN_ERR "atm_sysfs_init() failed with %d\n",error); 837 if (error < 0) {
838 pr_err("atm_sysfs_init() failed with %d\n", error);
788 goto out_atmproc_exit; 839 goto out_atmproc_exit;
789 } 840 }
790out: 841out: