aboutsummaryrefslogtreecommitdiffstats
path: root/net/nfc/llcp/sock.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/nfc/llcp/sock.c')
-rw-r--r--net/nfc/llcp/sock.c57
1 files changed, 55 insertions, 2 deletions
diff --git a/net/nfc/llcp/sock.c b/net/nfc/llcp/sock.c
index c13e02ebdef9..3f339b19d140 100644
--- a/net/nfc/llcp/sock.c
+++ b/net/nfc/llcp/sock.c
@@ -27,6 +27,42 @@
27#include "../nfc.h" 27#include "../nfc.h"
28#include "llcp.h" 28#include "llcp.h"
29 29
30static int sock_wait_state(struct sock *sk, int state, unsigned long timeo)
31{
32 DECLARE_WAITQUEUE(wait, current);
33 int err = 0;
34
35 pr_debug("sk %p", sk);
36
37 add_wait_queue(sk_sleep(sk), &wait);
38 set_current_state(TASK_INTERRUPTIBLE);
39
40 while (sk->sk_state != state) {
41 if (!timeo) {
42 err = -EINPROGRESS;
43 break;
44 }
45
46 if (signal_pending(current)) {
47 err = sock_intr_errno(timeo);
48 break;
49 }
50
51 release_sock(sk);
52 timeo = schedule_timeout(timeo);
53 lock_sock(sk);
54 set_current_state(TASK_INTERRUPTIBLE);
55
56 err = sock_error(sk);
57 if (err)
58 break;
59 }
60
61 __set_current_state(TASK_RUNNING);
62 remove_wait_queue(sk_sleep(sk), &wait);
63 return err;
64}
65
30static struct proto llcp_sock_proto = { 66static struct proto llcp_sock_proto = {
31 .name = "NFC_LLCP", 67 .name = "NFC_LLCP",
32 .owner = THIS_MODULE, 68 .owner = THIS_MODULE,
@@ -304,11 +340,24 @@ static unsigned int llcp_sock_poll(struct file *file, struct socket *sock,
304 mask |= POLLERR; 340 mask |= POLLERR;
305 341
306 if (!skb_queue_empty(&sk->sk_receive_queue)) 342 if (!skb_queue_empty(&sk->sk_receive_queue))
307 mask |= POLLIN; 343 mask |= POLLIN | POLLRDNORM;
308 344
309 if (sk->sk_state == LLCP_CLOSED) 345 if (sk->sk_state == LLCP_CLOSED)
310 mask |= POLLHUP; 346 mask |= POLLHUP;
311 347
348 if (sk->sk_shutdown & RCV_SHUTDOWN)
349 mask |= POLLRDHUP | POLLIN | POLLRDNORM;
350
351 if (sk->sk_shutdown == SHUTDOWN_MASK)
352 mask |= POLLHUP;
353
354 if (sock_writeable(sk))
355 mask |= POLLOUT | POLLWRNORM | POLLWRBAND;
356 else
357 set_bit(SOCK_ASYNC_NOSPACE, &sk->sk_socket->flags);
358
359 pr_debug("mask 0x%x\n", mask);
360
312 return mask; 361 return mask;
313} 362}
314 363
@@ -462,9 +511,13 @@ static int llcp_sock_connect(struct socket *sock, struct sockaddr *_addr,
462 if (ret) 511 if (ret)
463 goto put_dev; 512 goto put_dev;
464 513
465 sk->sk_state = LLCP_CONNECTED; 514 ret = sock_wait_state(sk, LLCP_CONNECTED,
515 sock_sndtimeo(sk, flags & O_NONBLOCK));
516 if (ret)
517 goto put_dev;
466 518
467 release_sock(sk); 519 release_sock(sk);
520
468 return 0; 521 return 0;
469 522
470put_dev: 523put_dev: