Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit de121989 authored by John W. Linville's avatar John W. Linville
Browse files


Samuel Ortiz <sameo@linux.intel.com> says:

This is the first NFC pull request for 3.9 fixes

With this one we have:

- A fix for properly decreasing socket ack log.
- A timer and works cleanup upon NFC device removal.
- A monitoroing socket cleanup round from llcp_socket_release.
- A proper error report to pending sockets upon NFC device removal.

Signed-off-by: default avatarJohn W. Linville <linville@tuxdriver.com>
parents 66489978 3bbc0ceb
Loading
Loading
Loading
Loading
+53 −9
Original line number Diff line number Diff line
@@ -68,7 +68,8 @@ static void nfc_llcp_socket_purge(struct nfc_llcp_sock *sock)
	}
}

static void nfc_llcp_socket_release(struct nfc_llcp_local *local, bool listen)
static void nfc_llcp_socket_release(struct nfc_llcp_local *local, bool listen,
				    int err)
{
	struct sock *sk;
	struct hlist_node *tmp;
@@ -100,7 +101,10 @@ static void nfc_llcp_socket_release(struct nfc_llcp_local *local, bool listen)

				nfc_llcp_accept_unlink(accept_sk);

				if (err)
					accept_sk->sk_err = err;
				accept_sk->sk_state = LLCP_CLOSED;
				accept_sk->sk_state_change(sk);

				bh_unlock_sock(accept_sk);

@@ -123,7 +127,10 @@ static void nfc_llcp_socket_release(struct nfc_llcp_local *local, bool listen)
			continue;
		}

		if (err)
			sk->sk_err = err;
		sk->sk_state = LLCP_CLOSED;
		sk->sk_state_change(sk);

		bh_unlock_sock(sk);

@@ -133,6 +140,36 @@ static void nfc_llcp_socket_release(struct nfc_llcp_local *local, bool listen)
	}

	write_unlock(&local->sockets.lock);

	/*
	 * If we want to keep the listening sockets alive,
	 * we don't touch the RAW ones.
	 */
	if (listen == true)
		return;

	write_lock(&local->raw_sockets.lock);

	sk_for_each_safe(sk, tmp, &local->raw_sockets.head) {
		llcp_sock = nfc_llcp_sock(sk);

		bh_lock_sock(sk);

		nfc_llcp_socket_purge(llcp_sock);

		if (err)
			sk->sk_err = err;
		sk->sk_state = LLCP_CLOSED;
		sk->sk_state_change(sk);

		bh_unlock_sock(sk);

		sock_orphan(sk);

		sk_del_node_init(sk);
	}

	write_unlock(&local->raw_sockets.lock);
}

struct nfc_llcp_local *nfc_llcp_local_get(struct nfc_llcp_local *local)
@@ -142,20 +179,25 @@ struct nfc_llcp_local *nfc_llcp_local_get(struct nfc_llcp_local *local)
	return local;
}

static void local_release(struct kref *ref)
static void local_cleanup(struct nfc_llcp_local *local, bool listen)
{
	struct nfc_llcp_local *local;

	local = container_of(ref, struct nfc_llcp_local, ref);

	list_del(&local->list);
	nfc_llcp_socket_release(local, false);
	nfc_llcp_socket_release(local, listen, ENXIO);
	del_timer_sync(&local->link_timer);
	skb_queue_purge(&local->tx_queue);
	cancel_work_sync(&local->tx_work);
	cancel_work_sync(&local->rx_work);
	cancel_work_sync(&local->timeout_work);
	kfree_skb(local->rx_pending);
}

static void local_release(struct kref *ref)
{
	struct nfc_llcp_local *local;

	local = container_of(ref, struct nfc_llcp_local, ref);

	list_del(&local->list);
	local_cleanup(local, false);
	kfree(local);
}

@@ -1348,7 +1390,7 @@ void nfc_llcp_mac_is_down(struct nfc_dev *dev)
		return;

	/* Close and purge all existing sockets */
	nfc_llcp_socket_release(local, true);
	nfc_llcp_socket_release(local, true, 0);
}

void nfc_llcp_mac_is_up(struct nfc_dev *dev, u32 target_idx,
@@ -1427,6 +1469,8 @@ void nfc_llcp_unregister_device(struct nfc_dev *dev)
		return;
	}

	local_cleanup(local, false);

	nfc_llcp_local_put(local);
}

+2 −0
Original line number Diff line number Diff line
@@ -278,6 +278,8 @@ struct sock *nfc_llcp_accept_dequeue(struct sock *parent,

			pr_debug("Returning sk state %d\n", sk->sk_state);

			sk_acceptq_removed(parent);

			return sk;
		}