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.c47
1 files changed, 19 insertions, 28 deletions
diff --git a/net/nfc/llcp/sock.c b/net/nfc/llcp/sock.c
index 17a707db40eb..2c0b317344b7 100644
--- a/net/nfc/llcp/sock.c
+++ b/net/nfc/llcp/sock.c
@@ -111,7 +111,7 @@ static int llcp_sock_bind(struct socket *sock, struct sockaddr *addr, int alen)
111 } 111 }
112 112
113 llcp_sock->dev = dev; 113 llcp_sock->dev = dev;
114 llcp_sock->local = local; 114 llcp_sock->local = nfc_llcp_local_get(local);
115 llcp_sock->nfc_protocol = llcp_addr.nfc_protocol; 115 llcp_sock->nfc_protocol = llcp_addr.nfc_protocol;
116 llcp_sock->service_name_len = min_t(unsigned int, 116 llcp_sock->service_name_len = min_t(unsigned int,
117 llcp_addr.service_name_len, 117 llcp_addr.service_name_len,
@@ -124,7 +124,7 @@ static int llcp_sock_bind(struct socket *sock, struct sockaddr *addr, int alen)
124 if (llcp_sock->ssap == LLCP_MAX_SAP) 124 if (llcp_sock->ssap == LLCP_MAX_SAP)
125 goto put_dev; 125 goto put_dev;
126 126
127 local->sockets[llcp_sock->ssap] = llcp_sock; 127 nfc_llcp_sock_link(&local->sockets, sk);
128 128
129 pr_debug("Socket bound to SAP %d\n", llcp_sock->ssap); 129 pr_debug("Socket bound to SAP %d\n", llcp_sock->ssap);
130 130
@@ -382,15 +382,6 @@ static int llcp_sock_release(struct socket *sock)
382 goto out; 382 goto out;
383 } 383 }
384 384
385 mutex_lock(&local->socket_lock);
386
387 if (llcp_sock == local->sockets[llcp_sock->ssap])
388 local->sockets[llcp_sock->ssap] = NULL;
389 else
390 list_del_init(&llcp_sock->list);
391
392 mutex_unlock(&local->socket_lock);
393
394 lock_sock(sk); 385 lock_sock(sk);
395 386
396 /* Send a DISC */ 387 /* Send a DISC */
@@ -415,14 +406,12 @@ static int llcp_sock_release(struct socket *sock)
415 } 406 }
416 } 407 }
417 408
418 /* Freeing the SAP */ 409 nfc_llcp_put_ssap(llcp_sock->local, llcp_sock->ssap);
419 if ((sk->sk_state == LLCP_CONNECTED
420 && llcp_sock->ssap > LLCP_LOCAL_SAP_OFFSET) ||
421 sk->sk_state == LLCP_BOUND || sk->sk_state == LLCP_LISTEN)
422 nfc_llcp_put_ssap(llcp_sock->local, llcp_sock->ssap);
423 410
424 release_sock(sk); 411 release_sock(sk);
425 412
413 nfc_llcp_sock_unlink(&local->sockets, sk);
414
426out: 415out:
427 sock_orphan(sk); 416 sock_orphan(sk);
428 sock_put(sk); 417 sock_put(sk);
@@ -490,7 +479,8 @@ static int llcp_sock_connect(struct socket *sock, struct sockaddr *_addr,
490 } 479 }
491 480
492 llcp_sock->dev = dev; 481 llcp_sock->dev = dev;
493 llcp_sock->local = local; 482 llcp_sock->local = nfc_llcp_local_get(local);
483 llcp_sock->miu = llcp_sock->local->remote_miu;
494 llcp_sock->ssap = nfc_llcp_get_local_ssap(local); 484 llcp_sock->ssap = nfc_llcp_get_local_ssap(local);
495 if (llcp_sock->ssap == LLCP_SAP_MAX) { 485 if (llcp_sock->ssap == LLCP_SAP_MAX) {
496 ret = -ENOMEM; 486 ret = -ENOMEM;
@@ -508,21 +498,26 @@ static int llcp_sock_connect(struct socket *sock, struct sockaddr *_addr,
508 llcp_sock->service_name_len, 498 llcp_sock->service_name_len,
509 GFP_KERNEL); 499 GFP_KERNEL);
510 500
511 local->sockets[llcp_sock->ssap] = llcp_sock; 501 nfc_llcp_sock_link(&local->connecting_sockets, sk);
512 502
513 ret = nfc_llcp_send_connect(llcp_sock); 503 ret = nfc_llcp_send_connect(llcp_sock);
514 if (ret) 504 if (ret)
515 goto put_dev; 505 goto sock_unlink;
516 506
517 ret = sock_wait_state(sk, LLCP_CONNECTED, 507 ret = sock_wait_state(sk, LLCP_CONNECTED,
518 sock_sndtimeo(sk, flags & O_NONBLOCK)); 508 sock_sndtimeo(sk, flags & O_NONBLOCK));
519 if (ret) 509 if (ret)
520 goto put_dev; 510 goto sock_unlink;
521 511
522 release_sock(sk); 512 release_sock(sk);
523 513
524 return 0; 514 return 0;
525 515
516sock_unlink:
517 nfc_llcp_put_ssap(local, llcp_sock->ssap);
518
519 nfc_llcp_sock_unlink(&local->connecting_sockets, sk);
520
526put_dev: 521put_dev:
527 nfc_put_device(dev); 522 nfc_put_device(dev);
528 523
@@ -687,13 +682,14 @@ struct sock *nfc_llcp_sock_alloc(struct socket *sock, int type, gfp_t gfp)
687 682
688 llcp_sock->ssap = 0; 683 llcp_sock->ssap = 0;
689 llcp_sock->dsap = LLCP_SAP_SDP; 684 llcp_sock->dsap = LLCP_SAP_SDP;
685 llcp_sock->rw = LLCP_DEFAULT_RW;
686 llcp_sock->miu = LLCP_DEFAULT_MIU;
690 llcp_sock->send_n = llcp_sock->send_ack_n = 0; 687 llcp_sock->send_n = llcp_sock->send_ack_n = 0;
691 llcp_sock->recv_n = llcp_sock->recv_ack_n = 0; 688 llcp_sock->recv_n = llcp_sock->recv_ack_n = 0;
692 llcp_sock->remote_ready = 1; 689 llcp_sock->remote_ready = 1;
693 skb_queue_head_init(&llcp_sock->tx_queue); 690 skb_queue_head_init(&llcp_sock->tx_queue);
694 skb_queue_head_init(&llcp_sock->tx_pending_queue); 691 skb_queue_head_init(&llcp_sock->tx_pending_queue);
695 skb_queue_head_init(&llcp_sock->tx_backlog_queue); 692 skb_queue_head_init(&llcp_sock->tx_backlog_queue);
696 INIT_LIST_HEAD(&llcp_sock->list);
697 INIT_LIST_HEAD(&llcp_sock->accept_queue); 693 INIT_LIST_HEAD(&llcp_sock->accept_queue);
698 694
699 if (sock != NULL) 695 if (sock != NULL)
@@ -704,8 +700,6 @@ struct sock *nfc_llcp_sock_alloc(struct socket *sock, int type, gfp_t gfp)
704 700
705void nfc_llcp_sock_free(struct nfc_llcp_sock *sock) 701void nfc_llcp_sock_free(struct nfc_llcp_sock *sock)
706{ 702{
707 struct nfc_llcp_local *local = sock->local;
708
709 kfree(sock->service_name); 703 kfree(sock->service_name);
710 704
711 skb_queue_purge(&sock->tx_queue); 705 skb_queue_purge(&sock->tx_queue);
@@ -714,12 +708,9 @@ void nfc_llcp_sock_free(struct nfc_llcp_sock *sock)
714 708
715 list_del_init(&sock->accept_queue); 709 list_del_init(&sock->accept_queue);
716 710
717 if (local != NULL && sock == local->sockets[sock->ssap])
718 local->sockets[sock->ssap] = NULL;
719 else
720 list_del_init(&sock->list);
721
722 sock->parent = NULL; 711 sock->parent = NULL;
712
713 nfc_llcp_local_put(sock->local);
723} 714}
724 715
725static int llcp_sock_create(struct net *net, struct socket *sock, 716static int llcp_sock_create(struct net *net, struct socket *sock,