aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
Diffstat (limited to 'net')
-rw-r--r--net/atm/svc.c249
1 files changed, 125 insertions, 124 deletions
diff --git a/net/atm/svc.c b/net/atm/svc.c
index 251ddbc42e4b..3ba9a45a51ac 100644
--- a/net/atm/svc.c
+++ b/net/atm/svc.c
@@ -19,14 +19,15 @@
19#include <linux/atmdev.h> 19#include <linux/atmdev.h>
20#include <linux/bitops.h> 20#include <linux/bitops.h>
21#include <net/sock.h> /* for sock_no_* */ 21#include <net/sock.h> /* for sock_no_* */
22#include <asm/uaccess.h> 22#include <linux/uaccess.h>
23 23
24#include "resources.h" 24#include "resources.h"
25#include "common.h" /* common for PVCs and SVCs */ 25#include "common.h" /* common for PVCs and SVCs */
26#include "signaling.h" 26#include "signaling.h"
27#include "addr.h" 27#include "addr.h"
28 28
29static int svc_create(struct net *net, struct socket *sock, int protocol, int kern); 29static int svc_create(struct net *net, struct socket *sock, int protocol,
30 int kern);
30 31
31/* 32/*
32 * Note: since all this is still nicely synchronized with the signaling demon, 33 * Note: since all this is still nicely synchronized with the signaling demon,
@@ -35,25 +36,25 @@ static int svc_create(struct net *net, struct socket *sock, int protocol, int ke
35 */ 36 */
36 37
37 38
38static int svc_shutdown(struct socket *sock,int how) 39static int svc_shutdown(struct socket *sock, int how)
39{ 40{
40 return 0; 41 return 0;
41} 42}
42 43
43
44static void svc_disconnect(struct atm_vcc *vcc) 44static void svc_disconnect(struct atm_vcc *vcc)
45{ 45{
46 DEFINE_WAIT(wait); 46 DEFINE_WAIT(wait);
47 struct sk_buff *skb; 47 struct sk_buff *skb;
48 struct sock *sk = sk_atm(vcc); 48 struct sock *sk = sk_atm(vcc);
49 49
50 pr_debug("%p\n",vcc); 50 pr_debug("%p\n", vcc);
51 if (test_bit(ATM_VF_REGIS,&vcc->flags)) { 51 if (test_bit(ATM_VF_REGIS, &vcc->flags)) {
52 prepare_to_wait(sk->sk_sleep, &wait, TASK_UNINTERRUPTIBLE); 52 prepare_to_wait(sk->sk_sleep, &wait, TASK_UNINTERRUPTIBLE);
53 sigd_enq(vcc,as_close,NULL,NULL,NULL); 53 sigd_enq(vcc, as_close, NULL, NULL, NULL);
54 while (!test_bit(ATM_VF_RELEASED,&vcc->flags) && sigd) { 54 while (!test_bit(ATM_VF_RELEASED, &vcc->flags) && sigd) {
55 schedule(); 55 schedule();
56 prepare_to_wait(sk->sk_sleep, &wait, TASK_UNINTERRUPTIBLE); 56 prepare_to_wait(sk->sk_sleep, &wait,
57 TASK_UNINTERRUPTIBLE);
57 } 58 }
58 finish_wait(sk->sk_sleep, &wait); 59 finish_wait(sk->sk_sleep, &wait);
59 } 60 }
@@ -62,35 +63,35 @@ static void svc_disconnect(struct atm_vcc *vcc)
62 while ((skb = skb_dequeue(&sk->sk_receive_queue)) != NULL) { 63 while ((skb = skb_dequeue(&sk->sk_receive_queue)) != NULL) {
63 atm_return(vcc, skb->truesize); 64 atm_return(vcc, skb->truesize);
64 pr_debug("LISTEN REL\n"); 65 pr_debug("LISTEN REL\n");
65 sigd_enq2(NULL,as_reject,vcc,NULL,NULL,&vcc->qos,0); 66 sigd_enq2(NULL, as_reject, vcc, NULL, NULL, &vcc->qos, 0);
66 dev_kfree_skb(skb); 67 dev_kfree_skb(skb);
67 } 68 }
68 clear_bit(ATM_VF_REGIS, &vcc->flags); 69 clear_bit(ATM_VF_REGIS, &vcc->flags);
69 /* ... may retry later */ 70 /* ... may retry later */
70} 71}
71 72
72
73static int svc_release(struct socket *sock) 73static int svc_release(struct socket *sock)
74{ 74{
75 struct sock *sk = sock->sk; 75 struct sock *sk = sock->sk;
76 struct atm_vcc *vcc; 76 struct atm_vcc *vcc;
77 77
78 if (sk) { 78 if (sk) {
79 vcc = ATM_SD(sock); 79 vcc = ATM_SD(sock);
80 pr_debug("%p\n", vcc); 80 pr_debug("%p\n", vcc);
81 clear_bit(ATM_VF_READY, &vcc->flags); 81 clear_bit(ATM_VF_READY, &vcc->flags);
82 /* VCC pointer is used as a reference, so we must not free it 82 /*
83 (thereby subjecting it to re-use) before all pending connections 83 * VCC pointer is used as a reference,
84 are closed */ 84 * so we must not free it (thereby subjecting it to re-use)
85 * before all pending connections are closed
86 */
85 svc_disconnect(vcc); 87 svc_disconnect(vcc);
86 vcc_release(sock); 88 vcc_release(sock);
87 } 89 }
88 return 0; 90 return 0;
89} 91}
90 92
91 93static int svc_bind(struct socket *sock, struct sockaddr *sockaddr,
92static int svc_bind(struct socket *sock,struct sockaddr *sockaddr, 94 int sockaddr_len)
93 int sockaddr_len)
94{ 95{
95 DEFINE_WAIT(wait); 96 DEFINE_WAIT(wait);
96 struct sock *sk = sock->sk; 97 struct sock *sk = sock->sk;
@@ -115,38 +116,37 @@ static int svc_bind(struct socket *sock,struct sockaddr *sockaddr,
115 error = -EAFNOSUPPORT; 116 error = -EAFNOSUPPORT;
116 goto out; 117 goto out;
117 } 118 }
118 clear_bit(ATM_VF_BOUND,&vcc->flags); 119 clear_bit(ATM_VF_BOUND, &vcc->flags);
119 /* failing rebind will kill old binding */ 120 /* failing rebind will kill old binding */
120 /* @@@ check memory (de)allocation on rebind */ 121 /* @@@ check memory (de)allocation on rebind */
121 if (!test_bit(ATM_VF_HASQOS,&vcc->flags)) { 122 if (!test_bit(ATM_VF_HASQOS, &vcc->flags)) {
122 error = -EBADFD; 123 error = -EBADFD;
123 goto out; 124 goto out;
124 } 125 }
125 vcc->local = *addr; 126 vcc->local = *addr;
126 set_bit(ATM_VF_WAITING, &vcc->flags); 127 set_bit(ATM_VF_WAITING, &vcc->flags);
127 prepare_to_wait(sk->sk_sleep, &wait, TASK_UNINTERRUPTIBLE); 128 prepare_to_wait(sk->sk_sleep, &wait, TASK_UNINTERRUPTIBLE);
128 sigd_enq(vcc,as_bind,NULL,NULL,&vcc->local); 129 sigd_enq(vcc, as_bind, NULL, NULL, &vcc->local);
129 while (test_bit(ATM_VF_WAITING, &vcc->flags) && sigd) { 130 while (test_bit(ATM_VF_WAITING, &vcc->flags) && sigd) {
130 schedule(); 131 schedule();
131 prepare_to_wait(sk->sk_sleep, &wait, TASK_UNINTERRUPTIBLE); 132 prepare_to_wait(sk->sk_sleep, &wait, TASK_UNINTERRUPTIBLE);
132 } 133 }
133 finish_wait(sk->sk_sleep, &wait); 134 finish_wait(sk->sk_sleep, &wait);
134 clear_bit(ATM_VF_REGIS,&vcc->flags); /* doesn't count */ 135 clear_bit(ATM_VF_REGIS, &vcc->flags); /* doesn't count */
135 if (!sigd) { 136 if (!sigd) {
136 error = -EUNATCH; 137 error = -EUNATCH;
137 goto out; 138 goto out;
138 } 139 }
139 if (!sk->sk_err) 140 if (!sk->sk_err)
140 set_bit(ATM_VF_BOUND,&vcc->flags); 141 set_bit(ATM_VF_BOUND, &vcc->flags);
141 error = -sk->sk_err; 142 error = -sk->sk_err;
142out: 143out:
143 release_sock(sk); 144 release_sock(sk);
144 return error; 145 return error;
145} 146}
146 147
147 148static int svc_connect(struct socket *sock, struct sockaddr *sockaddr,
148static int svc_connect(struct socket *sock,struct sockaddr *sockaddr, 149 int sockaddr_len, int flags)
149 int sockaddr_len,int flags)
150{ 150{
151 DEFINE_WAIT(wait); 151 DEFINE_WAIT(wait);
152 struct sock *sk = sock->sk; 152 struct sock *sk = sock->sk;
@@ -154,7 +154,7 @@ static int svc_connect(struct socket *sock,struct sockaddr *sockaddr,
154 struct atm_vcc *vcc = ATM_SD(sock); 154 struct atm_vcc *vcc = ATM_SD(sock);
155 int error; 155 int error;
156 156
157 pr_debug("%p\n",vcc); 157 pr_debug("%p\n", vcc);
158 lock_sock(sk); 158 lock_sock(sk);
159 if (sockaddr_len != sizeof(struct sockaddr_atmsvc)) { 159 if (sockaddr_len != sizeof(struct sockaddr_atmsvc)) {
160 error = -EINVAL; 160 error = -EINVAL;
@@ -202,7 +202,7 @@ static int svc_connect(struct socket *sock,struct sockaddr *sockaddr,
202 vcc->remote = *addr; 202 vcc->remote = *addr;
203 set_bit(ATM_VF_WAITING, &vcc->flags); 203 set_bit(ATM_VF_WAITING, &vcc->flags);
204 prepare_to_wait(sk->sk_sleep, &wait, TASK_INTERRUPTIBLE); 204 prepare_to_wait(sk->sk_sleep, &wait, TASK_INTERRUPTIBLE);
205 sigd_enq(vcc,as_connect,NULL,NULL,&vcc->remote); 205 sigd_enq(vcc, as_connect, NULL, NULL, &vcc->remote);
206 if (flags & O_NONBLOCK) { 206 if (flags & O_NONBLOCK) {
207 finish_wait(sk->sk_sleep, &wait); 207 finish_wait(sk->sk_sleep, &wait);
208 sock->state = SS_CONNECTING; 208 sock->state = SS_CONNECTING;
@@ -213,7 +213,8 @@ static int svc_connect(struct socket *sock,struct sockaddr *sockaddr,
213 while (test_bit(ATM_VF_WAITING, &vcc->flags) && sigd) { 213 while (test_bit(ATM_VF_WAITING, &vcc->flags) && sigd) {
214 schedule(); 214 schedule();
215 if (!signal_pending(current)) { 215 if (!signal_pending(current)) {
216 prepare_to_wait(sk->sk_sleep, &wait, TASK_INTERRUPTIBLE); 216 prepare_to_wait(sk->sk_sleep, &wait,
217 TASK_INTERRUPTIBLE);
217 continue; 218 continue;
218 } 219 }
219 pr_debug("*ABORT*\n"); 220 pr_debug("*ABORT*\n");
@@ -229,20 +230,22 @@ static int svc_connect(struct socket *sock,struct sockaddr *sockaddr,
229 * Kernel <--okay---- Demon 230 * Kernel <--okay---- Demon
230 * Kernel <--close--- Demon 231 * Kernel <--close--- Demon
231 */ 232 */
232 sigd_enq(vcc,as_close,NULL,NULL,NULL); 233 sigd_enq(vcc, as_close, NULL, NULL, NULL);
233 while (test_bit(ATM_VF_WAITING, &vcc->flags) && sigd) { 234 while (test_bit(ATM_VF_WAITING, &vcc->flags) && sigd) {
234 prepare_to_wait(sk->sk_sleep, &wait, TASK_INTERRUPTIBLE); 235 prepare_to_wait(sk->sk_sleep, &wait,
236 TASK_INTERRUPTIBLE);
235 schedule(); 237 schedule();
236 } 238 }
237 if (!sk->sk_err) 239 if (!sk->sk_err)
238 while (!test_bit(ATM_VF_RELEASED,&vcc->flags) 240 while (!test_bit(ATM_VF_RELEASED, &vcc->flags) &&
239 && sigd) { 241 sigd) {
240 prepare_to_wait(sk->sk_sleep, &wait, TASK_INTERRUPTIBLE); 242 prepare_to_wait(sk->sk_sleep, &wait,
243 TASK_INTERRUPTIBLE);
241 schedule(); 244 schedule();
242 } 245 }
243 clear_bit(ATM_VF_REGIS,&vcc->flags); 246 clear_bit(ATM_VF_REGIS, &vcc->flags);
244 clear_bit(ATM_VF_RELEASED,&vcc->flags); 247 clear_bit(ATM_VF_RELEASED, &vcc->flags);
245 clear_bit(ATM_VF_CLOSE,&vcc->flags); 248 clear_bit(ATM_VF_CLOSE, &vcc->flags);
246 /* we're gone now but may connect later */ 249 /* we're gone now but may connect later */
247 error = -EINTR; 250 error = -EINTR;
248 break; 251 break;
@@ -270,17 +273,17 @@ static int svc_connect(struct socket *sock,struct sockaddr *sockaddr,
270/* 273/*
271 * #endif 274 * #endif
272 */ 275 */
273 if (!(error = vcc_connect(sock, vcc->itf, vcc->vpi, vcc->vci))) 276 error = vcc_connect(sock, vcc->itf, vcc->vpi, vcc->vci);
277 if (!error)
274 sock->state = SS_CONNECTED; 278 sock->state = SS_CONNECTED;
275 else 279 else
276 (void) svc_disconnect(vcc); 280 (void)svc_disconnect(vcc);
277out: 281out:
278 release_sock(sk); 282 release_sock(sk);
279 return error; 283 return error;
280} 284}
281 285
282 286static int svc_listen(struct socket *sock, int backlog)
283static int svc_listen(struct socket *sock,int backlog)
284{ 287{
285 DEFINE_WAIT(wait); 288 DEFINE_WAIT(wait);
286 struct sock *sk = sock->sk; 289 struct sock *sk = sock->sk;
@@ -290,17 +293,17 @@ static int svc_listen(struct socket *sock,int backlog)
290 pr_debug("%p\n", vcc); 293 pr_debug("%p\n", vcc);
291 lock_sock(sk); 294 lock_sock(sk);
292 /* let server handle listen on unbound sockets */ 295 /* let server handle listen on unbound sockets */
293 if (test_bit(ATM_VF_SESSION,&vcc->flags)) { 296 if (test_bit(ATM_VF_SESSION, &vcc->flags)) {
294 error = -EINVAL; 297 error = -EINVAL;
295 goto out; 298 goto out;
296 } 299 }
297 if (test_bit(ATM_VF_LISTEN, &vcc->flags)) { 300 if (test_bit(ATM_VF_LISTEN, &vcc->flags)) {
298 error = -EADDRINUSE; 301 error = -EADDRINUSE;
299 goto out; 302 goto out;
300 } 303 }
301 set_bit(ATM_VF_WAITING, &vcc->flags); 304 set_bit(ATM_VF_WAITING, &vcc->flags);
302 prepare_to_wait(sk->sk_sleep, &wait, TASK_UNINTERRUPTIBLE); 305 prepare_to_wait(sk->sk_sleep, &wait, TASK_UNINTERRUPTIBLE);
303 sigd_enq(vcc,as_listen,NULL,NULL,&vcc->local); 306 sigd_enq(vcc, as_listen, NULL, NULL, &vcc->local);
304 while (test_bit(ATM_VF_WAITING, &vcc->flags) && sigd) { 307 while (test_bit(ATM_VF_WAITING, &vcc->flags) && sigd) {
305 schedule(); 308 schedule();
306 prepare_to_wait(sk->sk_sleep, &wait, TASK_UNINTERRUPTIBLE); 309 prepare_to_wait(sk->sk_sleep, &wait, TASK_UNINTERRUPTIBLE);
@@ -310,7 +313,7 @@ static int svc_listen(struct socket *sock,int backlog)
310 error = -EUNATCH; 313 error = -EUNATCH;
311 goto out; 314 goto out;
312 } 315 }
313 set_bit(ATM_VF_LISTEN,&vcc->flags); 316 set_bit(ATM_VF_LISTEN, &vcc->flags);
314 vcc_insert_socket(sk); 317 vcc_insert_socket(sk);
315 sk->sk_max_ack_backlog = backlog > 0 ? backlog : ATM_BACKLOG_DEFAULT; 318 sk->sk_max_ack_backlog = backlog > 0 ? backlog : ATM_BACKLOG_DEFAULT;
316 error = -sk->sk_err; 319 error = -sk->sk_err;
@@ -319,8 +322,7 @@ out:
319 return error; 322 return error;
320} 323}
321 324
322 325static int svc_accept(struct socket *sock, struct socket *newsock, int flags)
323static int svc_accept(struct socket *sock,struct socket *newsock,int flags)
324{ 326{
325 struct sock *sk = sock->sk; 327 struct sock *sk = sock->sk;
326 struct sk_buff *skb; 328 struct sk_buff *skb;
@@ -344,8 +346,9 @@ static int svc_accept(struct socket *sock,struct socket *newsock,int flags)
344 prepare_to_wait(sk->sk_sleep, &wait, TASK_INTERRUPTIBLE); 346 prepare_to_wait(sk->sk_sleep, &wait, TASK_INTERRUPTIBLE);
345 while (!(skb = skb_dequeue(&sk->sk_receive_queue)) && 347 while (!(skb = skb_dequeue(&sk->sk_receive_queue)) &&
346 sigd) { 348 sigd) {
347 if (test_bit(ATM_VF_RELEASED,&old_vcc->flags)) break; 349 if (test_bit(ATM_VF_RELEASED, &old_vcc->flags))
348 if (test_bit(ATM_VF_CLOSE,&old_vcc->flags)) { 350 break;
351 if (test_bit(ATM_VF_CLOSE, &old_vcc->flags)) {
349 error = -sk->sk_err; 352 error = -sk->sk_err;
350 break; 353 break;
351 } 354 }
@@ -360,7 +363,8 @@ static int svc_accept(struct socket *sock,struct socket *newsock,int flags)
360 error = -ERESTARTSYS; 363 error = -ERESTARTSYS;
361 break; 364 break;
362 } 365 }
363 prepare_to_wait(sk->sk_sleep, &wait, TASK_INTERRUPTIBLE); 366 prepare_to_wait(sk->sk_sleep, &wait,
367 TASK_INTERRUPTIBLE);
364 } 368 }
365 finish_wait(sk->sk_sleep, &wait); 369 finish_wait(sk->sk_sleep, &wait);
366 if (error) 370 if (error)
@@ -369,31 +373,34 @@ static int svc_accept(struct socket *sock,struct socket *newsock,int flags)
369 error = -EUNATCH; 373 error = -EUNATCH;
370 goto out; 374 goto out;
371 } 375 }
372 msg = (struct atmsvc_msg *) skb->data; 376 msg = (struct atmsvc_msg *)skb->data;
373 new_vcc->qos = msg->qos; 377 new_vcc->qos = msg->qos;
374 set_bit(ATM_VF_HASQOS,&new_vcc->flags); 378 set_bit(ATM_VF_HASQOS, &new_vcc->flags);
375 new_vcc->remote = msg->svc; 379 new_vcc->remote = msg->svc;
376 new_vcc->local = msg->local; 380 new_vcc->local = msg->local;
377 new_vcc->sap = msg->sap; 381 new_vcc->sap = msg->sap;
378 error = vcc_connect(newsock, msg->pvc.sap_addr.itf, 382 error = vcc_connect(newsock, msg->pvc.sap_addr.itf,
379 msg->pvc.sap_addr.vpi, msg->pvc.sap_addr.vci); 383 msg->pvc.sap_addr.vpi,
384 msg->pvc.sap_addr.vci);
380 dev_kfree_skb(skb); 385 dev_kfree_skb(skb);
381 sk->sk_ack_backlog--; 386 sk->sk_ack_backlog--;
382 if (error) { 387 if (error) {
383 sigd_enq2(NULL,as_reject,old_vcc,NULL,NULL, 388 sigd_enq2(NULL, as_reject, old_vcc, NULL, NULL,
384 &old_vcc->qos,error); 389 &old_vcc->qos, error);
385 error = error == -EAGAIN ? -EBUSY : error; 390 error = error == -EAGAIN ? -EBUSY : error;
386 goto out; 391 goto out;
387 } 392 }
388 /* wait should be short, so we ignore the non-blocking flag */ 393 /* wait should be short, so we ignore the non-blocking flag */
389 set_bit(ATM_VF_WAITING, &new_vcc->flags); 394 set_bit(ATM_VF_WAITING, &new_vcc->flags);
390 prepare_to_wait(sk_atm(new_vcc)->sk_sleep, &wait, TASK_UNINTERRUPTIBLE); 395 prepare_to_wait(sk_atm(new_vcc)->sk_sleep, &wait,
391 sigd_enq(new_vcc,as_accept,old_vcc,NULL,NULL); 396 TASK_UNINTERRUPTIBLE);
397 sigd_enq(new_vcc, as_accept, old_vcc, NULL, NULL);
392 while (test_bit(ATM_VF_WAITING, &new_vcc->flags) && sigd) { 398 while (test_bit(ATM_VF_WAITING, &new_vcc->flags) && sigd) {
393 release_sock(sk); 399 release_sock(sk);
394 schedule(); 400 schedule();
395 lock_sock(sk); 401 lock_sock(sk);
396 prepare_to_wait(sk_atm(new_vcc)->sk_sleep, &wait, TASK_UNINTERRUPTIBLE); 402 prepare_to_wait(sk_atm(new_vcc)->sk_sleep, &wait,
403 TASK_UNINTERRUPTIBLE);
397 } 404 }
398 finish_wait(sk_atm(new_vcc)->sk_sleep, &wait); 405 finish_wait(sk_atm(new_vcc)->sk_sleep, &wait);
399 if (!sigd) { 406 if (!sigd) {
@@ -413,39 +420,37 @@ out:
413 return error; 420 return error;
414} 421}
415 422
416 423static int svc_getname(struct socket *sock, struct sockaddr *sockaddr,
417static int svc_getname(struct socket *sock,struct sockaddr *sockaddr, 424 int *sockaddr_len, int peer)
418 int *sockaddr_len,int peer)
419{ 425{
420 struct sockaddr_atmsvc *addr; 426 struct sockaddr_atmsvc *addr;
421 427
422 *sockaddr_len = sizeof(struct sockaddr_atmsvc); 428 *sockaddr_len = sizeof(struct sockaddr_atmsvc);
423 addr = (struct sockaddr_atmsvc *) sockaddr; 429 addr = (struct sockaddr_atmsvc *) sockaddr;
424 memcpy(addr,peer ? &ATM_SD(sock)->remote : &ATM_SD(sock)->local, 430 memcpy(addr, peer ? &ATM_SD(sock)->remote : &ATM_SD(sock)->local,
425 sizeof(struct sockaddr_atmsvc)); 431 sizeof(struct sockaddr_atmsvc));
426 return 0; 432 return 0;
427} 433}
428 434
429 435int svc_change_qos(struct atm_vcc *vcc, struct atm_qos *qos)
430int svc_change_qos(struct atm_vcc *vcc,struct atm_qos *qos)
431{ 436{
432 struct sock *sk = sk_atm(vcc); 437 struct sock *sk = sk_atm(vcc);
433 DEFINE_WAIT(wait); 438 DEFINE_WAIT(wait);
434 439
435 set_bit(ATM_VF_WAITING, &vcc->flags); 440 set_bit(ATM_VF_WAITING, &vcc->flags);
436 prepare_to_wait(sk->sk_sleep, &wait, TASK_UNINTERRUPTIBLE); 441 prepare_to_wait(sk->sk_sleep, &wait, TASK_UNINTERRUPTIBLE);
437 sigd_enq2(vcc,as_modify,NULL,NULL,&vcc->local,qos,0); 442 sigd_enq2(vcc, as_modify, NULL, NULL, &vcc->local, qos, 0);
438 while (test_bit(ATM_VF_WAITING, &vcc->flags) && 443 while (test_bit(ATM_VF_WAITING, &vcc->flags) &&
439 !test_bit(ATM_VF_RELEASED, &vcc->flags) && sigd) { 444 !test_bit(ATM_VF_RELEASED, &vcc->flags) && sigd) {
440 schedule(); 445 schedule();
441 prepare_to_wait(sk->sk_sleep, &wait, TASK_UNINTERRUPTIBLE); 446 prepare_to_wait(sk->sk_sleep, &wait, TASK_UNINTERRUPTIBLE);
442 } 447 }
443 finish_wait(sk->sk_sleep, &wait); 448 finish_wait(sk->sk_sleep, &wait);
444 if (!sigd) return -EUNATCH; 449 if (!sigd)
450 return -EUNATCH;
445 return -sk->sk_err; 451 return -sk->sk_err;
446} 452}
447 453
448
449static int svc_setsockopt(struct socket *sock, int level, int optname, 454static int svc_setsockopt(struct socket *sock, int level, int optname,
450 char __user *optval, unsigned int optlen) 455 char __user *optval, unsigned int optlen)
451{ 456{
@@ -455,37 +460,35 @@ static int svc_setsockopt(struct socket *sock, int level, int optname,
455 460
456 lock_sock(sk); 461 lock_sock(sk);
457 switch (optname) { 462 switch (optname) {
458 case SO_ATMSAP: 463 case SO_ATMSAP:
459 if (level != SOL_ATM || optlen != sizeof(struct atm_sap)) { 464 if (level != SOL_ATM || optlen != sizeof(struct atm_sap)) {
460 error = -EINVAL; 465 error = -EINVAL;
461 goto out; 466 goto out;
462 } 467 }
463 if (copy_from_user(&vcc->sap, optval, optlen)) { 468 if (copy_from_user(&vcc->sap, optval, optlen)) {
464 error = -EFAULT; 469 error = -EFAULT;
465 goto out; 470 goto out;
466 } 471 }
467 set_bit(ATM_VF_HASSAP, &vcc->flags); 472 set_bit(ATM_VF_HASSAP, &vcc->flags);
468 break; 473 break;
469 case SO_MULTIPOINT: 474 case SO_MULTIPOINT:
470 if (level != SOL_ATM || optlen != sizeof(int)) { 475 if (level != SOL_ATM || optlen != sizeof(int)) {
471 error = -EINVAL; 476 error = -EINVAL;
472 goto out; 477 goto out;
473 } 478 }
474 if (get_user(value, (int __user *) optval)) { 479 if (get_user(value, (int __user *)optval)) {
475 error = -EFAULT; 480 error = -EFAULT;
476 goto out; 481 goto out;
477 } 482 }
478 if (value == 1) { 483 if (value == 1)
479 set_bit(ATM_VF_SESSION, &vcc->flags); 484 set_bit(ATM_VF_SESSION, &vcc->flags);
480 } else if (value == 0) { 485 else if (value == 0)
481 clear_bit(ATM_VF_SESSION, &vcc->flags); 486 clear_bit(ATM_VF_SESSION, &vcc->flags);
482 } else { 487 else
483 error = -EINVAL; 488 error = -EINVAL;
484 } 489 break;
485 break; 490 default:
486 default: 491 error = vcc_setsockopt(sock, level, optname, optval, optlen);
487 error = vcc_setsockopt(sock, level, optname,
488 optval, optlen);
489 } 492 }
490 493
491out: 494out:
@@ -493,9 +496,8 @@ out:
493 return error; 496 return error;
494} 497}
495 498
496 499static int svc_getsockopt(struct socket *sock, int level, int optname,
497static int svc_getsockopt(struct socket *sock,int level,int optname, 500 char __user *optval, int __user *optlen)
498 char __user *optval,int __user *optlen)
499{ 501{
500 struct sock *sk = sock->sk; 502 struct sock *sk = sock->sk;
501 int error = 0, len; 503 int error = 0, len;
@@ -522,7 +524,6 @@ out:
522 return error; 524 return error;
523} 525}
524 526
525
526static int svc_addparty(struct socket *sock, struct sockaddr *sockaddr, 527static int svc_addparty(struct socket *sock, struct sockaddr *sockaddr,
527 int sockaddr_len, int flags) 528 int sockaddr_len, int flags)
528{ 529{
@@ -553,7 +554,6 @@ out:
553 return error; 554 return error;
554} 555}
555 556
556
557static int svc_dropparty(struct socket *sock, int ep_ref) 557static int svc_dropparty(struct socket *sock, int ep_ref)
558{ 558{
559 DEFINE_WAIT(wait); 559 DEFINE_WAIT(wait);
@@ -580,7 +580,6 @@ out:
580 return error; 580 return error;
581} 581}
582 582
583
584static int svc_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) 583static int svc_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
585{ 584{
586 int error, ep_ref; 585 int error, ep_ref;
@@ -588,29 +587,31 @@ static int svc_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
588 struct atm_vcc *vcc = ATM_SD(sock); 587 struct atm_vcc *vcc = ATM_SD(sock);
589 588
590 switch (cmd) { 589 switch (cmd) {
591 case ATM_ADDPARTY: 590 case ATM_ADDPARTY:
592 if (!test_bit(ATM_VF_SESSION, &vcc->flags)) 591 if (!test_bit(ATM_VF_SESSION, &vcc->flags))
593 return -EINVAL; 592 return -EINVAL;
594 if (copy_from_user(&sa, (void __user *) arg, sizeof(sa))) 593 if (copy_from_user(&sa, (void __user *) arg, sizeof(sa)))
595 return -EFAULT; 594 return -EFAULT;
596 error = svc_addparty(sock, (struct sockaddr *) &sa, sizeof(sa), 0); 595 error = svc_addparty(sock, (struct sockaddr *)&sa, sizeof(sa),
597 break; 596 0);
598 case ATM_DROPPARTY: 597 break;
599 if (!test_bit(ATM_VF_SESSION, &vcc->flags)) 598 case ATM_DROPPARTY:
600 return -EINVAL; 599 if (!test_bit(ATM_VF_SESSION, &vcc->flags))
601 if (copy_from_user(&ep_ref, (void __user *) arg, sizeof(int))) 600 return -EINVAL;
602 return -EFAULT; 601 if (copy_from_user(&ep_ref, (void __user *) arg, sizeof(int)))
603 error = svc_dropparty(sock, ep_ref); 602 return -EFAULT;
604 break; 603 error = svc_dropparty(sock, ep_ref);
605 default: 604 break;
606 error = vcc_ioctl(sock, cmd, arg); 605 default:
606 error = vcc_ioctl(sock, cmd, arg);
607 } 607 }
608 608
609 return error; 609 return error;
610} 610}
611 611
612#ifdef CONFIG_COMPAT 612#ifdef CONFIG_COMPAT
613static int svc_compat_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) 613static int svc_compat_ioctl(struct socket *sock, unsigned int cmd,
614 unsigned long arg)
614{ 615{
615 /* The definition of ATM_ADDPARTY uses the size of struct atm_iobuf. 616 /* The definition of ATM_ADDPARTY uses the size of struct atm_iobuf.
616 But actually it takes a struct sockaddr_atmsvc, which doesn't need 617 But actually it takes a struct sockaddr_atmsvc, which doesn't need
@@ -661,13 +662,13 @@ static int svc_create(struct net *net, struct socket *sock, int protocol,
661 662
662 sock->ops = &svc_proto_ops; 663 sock->ops = &svc_proto_ops;
663 error = vcc_create(net, sock, protocol, AF_ATMSVC); 664 error = vcc_create(net, sock, protocol, AF_ATMSVC);
664 if (error) return error; 665 if (error)
666 return error;
665 ATM_SD(sock)->local.sas_family = AF_ATMSVC; 667 ATM_SD(sock)->local.sas_family = AF_ATMSVC;
666 ATM_SD(sock)->remote.sas_family = AF_ATMSVC; 668 ATM_SD(sock)->remote.sas_family = AF_ATMSVC;
667 return 0; 669 return 0;
668} 670}
669 671
670
671static const struct net_proto_family svc_family_ops = { 672static const struct net_proto_family svc_family_ops = {
672 .family = PF_ATMSVC, 673 .family = PF_ATMSVC,
673 .create = svc_create, 674 .create = svc_create,