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

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


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

The 2nd NFC pull request for 3.7.

- A couple of wrong context sleep fixes.
- An LLCP rwlock intizialisation fix.
- A missing mutex unlocking for pn533.
- LLCP raw sockets support. This is going to be used for NFC sniffing.
- A build fix for llc_shdlc. It fixes a build error triggered by code that's
  living in wireless-next.

Signed-off-by: default avatarJohn W. Linville <linville@tuxdriver.com>
parents 8a14e8bf 50b78b2a
Loading
Loading
Loading
Loading
+8 −7
Original line number Diff line number Diff line
@@ -716,7 +716,7 @@ static int pn533_send_cmd_frame_async(struct pn533 *dev,
					void *arg, gfp_t flags)
{
	struct pn533_cmd *cmd;
	int rc;
	int rc = 0;

	nfc_dev_dbg(&dev->interface->dev, "%s", __func__);

@@ -729,16 +729,16 @@ static int pn533_send_cmd_frame_async(struct pn533 *dev,
		if (!rc)
			dev->cmd_pending = 1;

		mutex_unlock(&dev->cmd_lock);

		return rc;
		goto unlock;
	}

	nfc_dev_dbg(&dev->interface->dev, "%s Queueing command", __func__);

	cmd = kzalloc(sizeof(struct pn533_cmd), flags);
	if (!cmd)
		return -ENOMEM;
	if (!cmd) {
		rc = -ENOMEM;
		goto unlock;
	}

	INIT_LIST_HEAD(&cmd->queue);
	cmd->out_frame = out_frame;
@@ -750,9 +750,10 @@ static int pn533_send_cmd_frame_async(struct pn533 *dev,

	list_add_tail(&cmd->queue, &dev->cmd_queue);

unlock:
	mutex_unlock(&dev->cmd_lock);

	return 0;
	return rc;
}

struct pn533_sync_cmd_response {
+11 −0
Original line number Diff line number Diff line
@@ -183,4 +183,15 @@ struct sockaddr_nfc_llcp {

#define NFC_HEADER_SIZE 1

/**
 * Pseudo-header info for raw socket packets
 * First byte is the adapter index
 * Second byte contains flags
 *  - 0x01 - Direction (0=RX, 1=TX)
 *  - 0x02-0x80 - Reserved
 **/
#define NFC_LLCP_RAW_HEADER_SIZE	2
#define NFC_LLCP_DIRECTION_RX		0x00
#define NFC_LLCP_DIRECTION_TX		0x01

#endif /*__LINUX_NFC_H */
+2 −0
Original line number Diff line number Diff line
@@ -312,6 +312,8 @@ int nfc_llcp_send_symm(struct nfc_dev *dev)

	skb = llcp_add_header(skb, 0, 0, LLCP_PDU_SYMM);

	nfc_llcp_send_to_raw_sock(local, skb, NFC_LLCP_DIRECTION_TX);

	return nfc_data_exchange(dev, local->target_idx, skb,
				 nfc_llcp_recv, local);
}
+53 −7
Original line number Diff line number Diff line
@@ -56,7 +56,7 @@ static void nfc_llcp_socket_release(struct nfc_llcp_local *local, bool listen)
	sk_for_each_safe(sk, node, tmp, &local->sockets.head) {
		llcp_sock = nfc_llcp_sock(sk);

		lock_sock(sk);
		bh_lock_sock(sk);

		if (sk->sk_state == LLCP_CONNECTED)
			nfc_put_device(llcp_sock->dev);
@@ -68,26 +68,26 @@ static void nfc_llcp_socket_release(struct nfc_llcp_local *local, bool listen)
			list_for_each_entry_safe(lsk, n, &llcp_sock->accept_queue,
						 accept_queue) {
				accept_sk = &lsk->sk;
				lock_sock(accept_sk);
				bh_lock_sock(accept_sk);

				nfc_llcp_accept_unlink(accept_sk);

				accept_sk->sk_state = LLCP_CLOSED;

				release_sock(accept_sk);
				bh_unlock_sock(accept_sk);

				sock_orphan(accept_sk);
			}

			if (listen == true) {
				release_sock(sk);
				bh_unlock_sock(sk);
				continue;
			}
		}

		sk->sk_state = LLCP_CLOSED;

		release_sock(sk);
		bh_unlock_sock(sk);

		sock_orphan(sk);

@@ -558,6 +558,46 @@ static void nfc_llcp_set_nrns(struct nfc_llcp_sock *sock, struct sk_buff *pdu)
	sock->recv_ack_n = (sock->recv_n - 1) % 16;
}

void nfc_llcp_send_to_raw_sock(struct nfc_llcp_local *local,
			       struct sk_buff *skb, u8 direction)
{
	struct hlist_node *node;
	struct sk_buff *skb_copy = NULL, *nskb;
	struct sock *sk;
	u8 *data;

	read_lock(&local->raw_sockets.lock);

	sk_for_each(sk, node, &local->raw_sockets.head) {
		if (sk->sk_state != LLCP_BOUND)
			continue;

		if (skb_copy == NULL) {
			skb_copy = __pskb_copy(skb, NFC_LLCP_RAW_HEADER_SIZE,
					       GFP_ATOMIC);

			if (skb_copy == NULL)
				continue;

			data = skb_push(skb_copy, NFC_LLCP_RAW_HEADER_SIZE);

			data[0] = local->dev ? local->dev->idx : 0xFF;
			data[1] = direction;
		}

		nskb = skb_clone(skb_copy, GFP_ATOMIC);
		if (!nskb)
			continue;

		if (sock_queue_rcv_skb(sk, nskb))
			kfree_skb(nskb);
	}

	read_unlock(&local->raw_sockets.lock);

	kfree_skb(skb_copy);
}

static void nfc_llcp_tx_work(struct work_struct *work)
{
	struct nfc_llcp_local *local = container_of(work, struct nfc_llcp_local,
@@ -578,6 +618,9 @@ static void nfc_llcp_tx_work(struct work_struct *work)
				       DUMP_PREFIX_OFFSET, 16, 1,
				       skb->data, skb->len, true);

			nfc_llcp_send_to_raw_sock(local, skb,
						  NFC_LLCP_DIRECTION_TX);

			ret = nfc_data_exchange(local->dev, local->target_idx,
						skb, nfc_llcp_recv, local);

@@ -1022,6 +1065,8 @@ static void nfc_llcp_rx_work(struct work_struct *work)
		print_hex_dump(KERN_DEBUG, "LLCP Rx: ", DUMP_PREFIX_OFFSET,
			       16, 1, skb->data, skb->len, true);

	nfc_llcp_send_to_raw_sock(local, skb, NFC_LLCP_DIRECTION_RX);

	switch (ptype) {
	case LLCP_PDU_SYMM:
		pr_debug("SYMM\n");
@@ -1156,8 +1201,9 @@ int nfc_llcp_register_device(struct nfc_dev *ndev)

	INIT_WORK(&local->timeout_work, nfc_llcp_timeout_work);

	local->sockets.lock = __RW_LOCK_UNLOCKED(local->sockets.lock);
	local->connecting_sockets.lock = __RW_LOCK_UNLOCKED(local->connecting_sockets.lock);
	rwlock_init(&local->sockets.lock);
	rwlock_init(&local->connecting_sockets.lock);
	rwlock_init(&local->raw_sockets.lock);

	nfc_llcp_build_gb(local);

+3 −0
Original line number Diff line number Diff line
@@ -86,6 +86,7 @@ struct nfc_llcp_local {
	/* sockets array */
	struct llcp_sock_list sockets;
	struct llcp_sock_list connecting_sockets;
	struct llcp_sock_list raw_sockets;
};

struct nfc_llcp_sock {
@@ -184,6 +185,8 @@ u8 nfc_llcp_get_sdp_ssap(struct nfc_llcp_local *local,
u8 nfc_llcp_get_local_ssap(struct nfc_llcp_local *local);
void nfc_llcp_put_ssap(struct nfc_llcp_local *local, u8 ssap);
int nfc_llcp_queue_i_frames(struct nfc_llcp_sock *sock);
void nfc_llcp_send_to_raw_sock(struct nfc_llcp_local *local,
			       struct sk_buff *skb, u8 direction);

/* Sock API */
struct sock *nfc_llcp_sock_alloc(struct socket *sock, int type, gfp_t gfp);
Loading