diff options
Diffstat (limited to 'net/nfc/llcp/sock.c')
-rw-r--r-- | net/nfc/llcp/sock.c | 47 |
1 files changed, 19 insertions, 28 deletions
diff --git a/net/nfc/llcp/sock.c b/net/nfc/llcp/sock.c index 3f339b19d140..30e3cc71be7a 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 | ||
@@ -379,15 +379,6 @@ static int llcp_sock_release(struct socket *sock) | |||
379 | goto out; | 379 | goto out; |
380 | } | 380 | } |
381 | 381 | ||
382 | mutex_lock(&local->socket_lock); | ||
383 | |||
384 | if (llcp_sock == local->sockets[llcp_sock->ssap]) | ||
385 | local->sockets[llcp_sock->ssap] = NULL; | ||
386 | else | ||
387 | list_del_init(&llcp_sock->list); | ||
388 | |||
389 | mutex_unlock(&local->socket_lock); | ||
390 | |||
391 | lock_sock(sk); | 382 | lock_sock(sk); |
392 | 383 | ||
393 | /* Send a DISC */ | 384 | /* Send a DISC */ |
@@ -412,14 +403,12 @@ static int llcp_sock_release(struct socket *sock) | |||
412 | } | 403 | } |
413 | } | 404 | } |
414 | 405 | ||
415 | /* Freeing the SAP */ | 406 | nfc_llcp_put_ssap(llcp_sock->local, llcp_sock->ssap); |
416 | if ((sk->sk_state == LLCP_CONNECTED | ||
417 | && llcp_sock->ssap > LLCP_LOCAL_SAP_OFFSET) || | ||
418 | sk->sk_state == LLCP_BOUND || sk->sk_state == LLCP_LISTEN) | ||
419 | nfc_llcp_put_ssap(llcp_sock->local, llcp_sock->ssap); | ||
420 | 407 | ||
421 | release_sock(sk); | 408 | release_sock(sk); |
422 | 409 | ||
410 | nfc_llcp_sock_unlink(&local->sockets, sk); | ||
411 | |||
423 | out: | 412 | out: |
424 | sock_orphan(sk); | 413 | sock_orphan(sk); |
425 | sock_put(sk); | 414 | sock_put(sk); |
@@ -487,7 +476,8 @@ static int llcp_sock_connect(struct socket *sock, struct sockaddr *_addr, | |||
487 | } | 476 | } |
488 | 477 | ||
489 | llcp_sock->dev = dev; | 478 | llcp_sock->dev = dev; |
490 | llcp_sock->local = local; | 479 | llcp_sock->local = nfc_llcp_local_get(local); |
480 | llcp_sock->miu = llcp_sock->local->remote_miu; | ||
491 | llcp_sock->ssap = nfc_llcp_get_local_ssap(local); | 481 | llcp_sock->ssap = nfc_llcp_get_local_ssap(local); |
492 | if (llcp_sock->ssap == LLCP_SAP_MAX) { | 482 | if (llcp_sock->ssap == LLCP_SAP_MAX) { |
493 | ret = -ENOMEM; | 483 | ret = -ENOMEM; |
@@ -505,21 +495,26 @@ static int llcp_sock_connect(struct socket *sock, struct sockaddr *_addr, | |||
505 | llcp_sock->service_name_len, | 495 | llcp_sock->service_name_len, |
506 | GFP_KERNEL); | 496 | GFP_KERNEL); |
507 | 497 | ||
508 | local->sockets[llcp_sock->ssap] = llcp_sock; | 498 | nfc_llcp_sock_link(&local->connecting_sockets, sk); |
509 | 499 | ||
510 | ret = nfc_llcp_send_connect(llcp_sock); | 500 | ret = nfc_llcp_send_connect(llcp_sock); |
511 | if (ret) | 501 | if (ret) |
512 | goto put_dev; | 502 | goto sock_unlink; |
513 | 503 | ||
514 | ret = sock_wait_state(sk, LLCP_CONNECTED, | 504 | ret = sock_wait_state(sk, LLCP_CONNECTED, |
515 | sock_sndtimeo(sk, flags & O_NONBLOCK)); | 505 | sock_sndtimeo(sk, flags & O_NONBLOCK)); |
516 | if (ret) | 506 | if (ret) |
517 | goto put_dev; | 507 | goto sock_unlink; |
518 | 508 | ||
519 | release_sock(sk); | 509 | release_sock(sk); |
520 | 510 | ||
521 | return 0; | 511 | return 0; |
522 | 512 | ||
513 | sock_unlink: | ||
514 | nfc_llcp_put_ssap(local, llcp_sock->ssap); | ||
515 | |||
516 | nfc_llcp_sock_unlink(&local->connecting_sockets, sk); | ||
517 | |||
523 | put_dev: | 518 | put_dev: |
524 | nfc_put_device(dev); | 519 | nfc_put_device(dev); |
525 | 520 | ||
@@ -684,13 +679,14 @@ struct sock *nfc_llcp_sock_alloc(struct socket *sock, int type, gfp_t gfp) | |||
684 | 679 | ||
685 | llcp_sock->ssap = 0; | 680 | llcp_sock->ssap = 0; |
686 | llcp_sock->dsap = LLCP_SAP_SDP; | 681 | llcp_sock->dsap = LLCP_SAP_SDP; |
682 | llcp_sock->rw = LLCP_DEFAULT_RW; | ||
683 | llcp_sock->miu = LLCP_DEFAULT_MIU; | ||
687 | llcp_sock->send_n = llcp_sock->send_ack_n = 0; | 684 | llcp_sock->send_n = llcp_sock->send_ack_n = 0; |
688 | llcp_sock->recv_n = llcp_sock->recv_ack_n = 0; | 685 | llcp_sock->recv_n = llcp_sock->recv_ack_n = 0; |
689 | llcp_sock->remote_ready = 1; | 686 | llcp_sock->remote_ready = 1; |
690 | skb_queue_head_init(&llcp_sock->tx_queue); | 687 | skb_queue_head_init(&llcp_sock->tx_queue); |
691 | skb_queue_head_init(&llcp_sock->tx_pending_queue); | 688 | skb_queue_head_init(&llcp_sock->tx_pending_queue); |
692 | skb_queue_head_init(&llcp_sock->tx_backlog_queue); | 689 | skb_queue_head_init(&llcp_sock->tx_backlog_queue); |
693 | INIT_LIST_HEAD(&llcp_sock->list); | ||
694 | INIT_LIST_HEAD(&llcp_sock->accept_queue); | 690 | INIT_LIST_HEAD(&llcp_sock->accept_queue); |
695 | 691 | ||
696 | if (sock != NULL) | 692 | if (sock != NULL) |
@@ -701,8 +697,6 @@ struct sock *nfc_llcp_sock_alloc(struct socket *sock, int type, gfp_t gfp) | |||
701 | 697 | ||
702 | void nfc_llcp_sock_free(struct nfc_llcp_sock *sock) | 698 | void nfc_llcp_sock_free(struct nfc_llcp_sock *sock) |
703 | { | 699 | { |
704 | struct nfc_llcp_local *local = sock->local; | ||
705 | |||
706 | kfree(sock->service_name); | 700 | kfree(sock->service_name); |
707 | 701 | ||
708 | skb_queue_purge(&sock->tx_queue); | 702 | skb_queue_purge(&sock->tx_queue); |
@@ -711,12 +705,9 @@ void nfc_llcp_sock_free(struct nfc_llcp_sock *sock) | |||
711 | 705 | ||
712 | list_del_init(&sock->accept_queue); | 706 | list_del_init(&sock->accept_queue); |
713 | 707 | ||
714 | if (local != NULL && sock == local->sockets[sock->ssap]) | ||
715 | local->sockets[sock->ssap] = NULL; | ||
716 | else | ||
717 | list_del_init(&sock->list); | ||
718 | |||
719 | sock->parent = NULL; | 708 | sock->parent = NULL; |
709 | |||
710 | nfc_llcp_local_put(sock->local); | ||
720 | } | 711 | } |
721 | 712 | ||
722 | static int llcp_sock_create(struct net *net, struct socket *sock, | 713 | static int llcp_sock_create(struct net *net, struct socket *sock, |