summaryrefslogtreecommitdiffstats
path: root/net/nfc
diff options
context:
space:
mode:
authorSamuel Ortiz <sameo@linux.intel.com>2012-06-22 14:48:11 +0200
committerJohn W. Linville <linville@tuxdriver.com>2012-07-09 16:42:17 -0400
commitcbbf472181bd5d6229decda96b34b0c2bbcb3050 (patch)
tree152e06ea436fcc419af1604a2f118f6be0ff33c9 /net/nfc
parent4d22ea1532ba5730b665343e513d813c108c84ff (diff)
NFC: Release LLCP SAP when the owner is released
The LLCP SAP should only be freed when the socket owning it is released. As long as the socket is alive, the SAP should be reserved in order to e.g. send the right wks array when bringing the MAC up. Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
Diffstat (limited to 'net/nfc')
-rw-r--r--net/nfc/llcp/llcp.c13
-rw-r--r--net/nfc/llcp/llcp.h3
-rw-r--r--net/nfc/llcp/sock.c9
3 files changed, 11 insertions, 14 deletions
diff --git a/net/nfc/llcp/llcp.c b/net/nfc/llcp/llcp.c
index 0c8d25e53ff..1031abd13fc 100644
--- a/net/nfc/llcp/llcp.c
+++ b/net/nfc/llcp/llcp.c
@@ -131,17 +131,6 @@ int nfc_llcp_local_put(struct nfc_llcp_local *local)
return kref_put(&local->ref, local_release);
}
-static void nfc_llcp_clear_sdp(struct nfc_llcp_local *local)
-{
- mutex_lock(&local->sdp_lock);
-
- local->local_wks = 0;
- local->local_sdp = 0;
- local->local_sap = 0;
-
- mutex_unlock(&local->sdp_lock);
-}
-
static void nfc_llcp_timeout_work(struct work_struct *work)
{
struct nfc_llcp_local *local = container_of(work, struct nfc_llcp_local,
@@ -993,8 +982,6 @@ void nfc_llcp_mac_is_down(struct nfc_dev *dev)
if (local == NULL)
return;
- nfc_llcp_clear_sdp(local);
-
/* Close and purge all existing sockets */
nfc_llcp_socket_release(local, true);
}
diff --git a/net/nfc/llcp/llcp.h b/net/nfc/llcp/llcp.h
index 7286c86982f..374cc4779af 100644
--- a/net/nfc/llcp/llcp.h
+++ b/net/nfc/llcp/llcp.h
@@ -113,6 +113,9 @@ struct nfc_llcp_sock {
/* Is the remote peer ready to receive */
u8 remote_ready;
+ /* Reserved source SAP */
+ u8 reserved_ssap;
+
struct sk_buff_head tx_queue;
struct sk_buff_head tx_pending_queue;
struct sk_buff_head tx_backlog_queue;
diff --git a/net/nfc/llcp/sock.c b/net/nfc/llcp/sock.c
index b08e99d2c71..211cb234f7a 100644
--- a/net/nfc/llcp/sock.c
+++ b/net/nfc/llcp/sock.c
@@ -124,6 +124,8 @@ static int llcp_sock_bind(struct socket *sock, struct sockaddr *addr, int alen)
if (llcp_sock->ssap == LLCP_MAX_SAP)
goto put_dev;
+ llcp_sock->reserved_ssap = llcp_sock->ssap;
+
nfc_llcp_sock_link(&local->sockets, sk);
pr_debug("Socket bound to SAP %d\n", llcp_sock->ssap);
@@ -409,7 +411,8 @@ static int llcp_sock_release(struct socket *sock)
}
}
- nfc_llcp_put_ssap(llcp_sock->local, llcp_sock->ssap);
+ if (llcp_sock->reserved_ssap < LLCP_SAP_MAX)
+ nfc_llcp_put_ssap(llcp_sock->local, llcp_sock->ssap);
release_sock(sk);
@@ -489,6 +492,9 @@ static int llcp_sock_connect(struct socket *sock, struct sockaddr *_addr,
ret = -ENOMEM;
goto put_dev;
}
+
+ llcp_sock->reserved_ssap = llcp_sock->ssap;
+
if (addr->service_name_len == 0)
llcp_sock->dsap = addr->dsap;
else
@@ -690,6 +696,7 @@ struct sock *nfc_llcp_sock_alloc(struct socket *sock, int type, gfp_t gfp)
llcp_sock->send_n = llcp_sock->send_ack_n = 0;
llcp_sock->recv_n = llcp_sock->recv_ack_n = 0;
llcp_sock->remote_ready = 1;
+ llcp_sock->reserved_ssap = LLCP_SAP_MAX;
skb_queue_head_init(&llcp_sock->tx_queue);
skb_queue_head_init(&llcp_sock->tx_pending_queue);
skb_queue_head_init(&llcp_sock->tx_backlog_queue);