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 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 | |||
426 | out: | 415 | out: |
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 | ||
516 | sock_unlink: | ||
517 | nfc_llcp_put_ssap(local, llcp_sock->ssap); | ||
518 | |||
519 | nfc_llcp_sock_unlink(&local->connecting_sockets, sk); | ||
520 | |||
526 | put_dev: | 521 | put_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 | ||
705 | void nfc_llcp_sock_free(struct nfc_llcp_sock *sock) | 701 | void 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 | ||
725 | static int llcp_sock_create(struct net *net, struct socket *sock, | 716 | static int llcp_sock_create(struct net *net, struct socket *sock, |