Skip to content

Commit 97ea6d0

Browse files
committed
Merge tag 'nfc-next-3.7-2' of git://git.kernel.org/pub/scm/linux/kernel/git/sameo/nfc-3.0
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: John W. Linville <linville@tuxdriver.com>
2 parents 8a14e8b + 50b78b2 commit 97ea6d0

File tree

7 files changed

+202
-25
lines changed

7 files changed

+202
-25
lines changed

drivers/nfc/pn533.c

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -716,7 +716,7 @@ static int pn533_send_cmd_frame_async(struct pn533 *dev,
716716
void *arg, gfp_t flags)
717717
{
718718
struct pn533_cmd *cmd;
719-
int rc;
719+
int rc = 0;
720720

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

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

732-
mutex_unlock(&dev->cmd_lock);
733-
734-
return rc;
732+
goto unlock;
735733
}
736734

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

739737
cmd = kzalloc(sizeof(struct pn533_cmd), flags);
740-
if (!cmd)
741-
return -ENOMEM;
738+
if (!cmd) {
739+
rc = -ENOMEM;
740+
goto unlock;
741+
}
742742

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

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

753+
unlock:
753754
mutex_unlock(&dev->cmd_lock);
754755

755-
return 0;
756+
return rc;
756757
}
757758

758759
struct pn533_sync_cmd_response {

include/linux/nfc.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -183,4 +183,15 @@ struct sockaddr_nfc_llcp {
183183

184184
#define NFC_HEADER_SIZE 1
185185

186+
/**
187+
* Pseudo-header info for raw socket packets
188+
* First byte is the adapter index
189+
* Second byte contains flags
190+
* - 0x01 - Direction (0=RX, 1=TX)
191+
* - 0x02-0x80 - Reserved
192+
**/
193+
#define NFC_LLCP_RAW_HEADER_SIZE 2
194+
#define NFC_LLCP_DIRECTION_RX 0x00
195+
#define NFC_LLCP_DIRECTION_TX 0x01
196+
186197
#endif /*__LINUX_NFC_H */

net/nfc/llcp/commands.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -312,6 +312,8 @@ int nfc_llcp_send_symm(struct nfc_dev *dev)
312312

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

315+
nfc_llcp_send_to_raw_sock(local, skb, NFC_LLCP_DIRECTION_TX);
316+
315317
return nfc_data_exchange(dev, local->target_idx, skb,
316318
nfc_llcp_recv, local);
317319
}

net/nfc/llcp/llcp.c

Lines changed: 53 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ static void nfc_llcp_socket_release(struct nfc_llcp_local *local, bool listen)
5656
sk_for_each_safe(sk, node, tmp, &local->sockets.head) {
5757
llcp_sock = nfc_llcp_sock(sk);
5858

59-
lock_sock(sk);
59+
bh_lock_sock(sk);
6060

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

7373
nfc_llcp_accept_unlink(accept_sk);
7474

7575
accept_sk->sk_state = LLCP_CLOSED;
7676

77-
release_sock(accept_sk);
77+
bh_unlock_sock(accept_sk);
7878

7979
sock_orphan(accept_sk);
8080
}
8181

8282
if (listen == true) {
83-
release_sock(sk);
83+
bh_unlock_sock(sk);
8484
continue;
8585
}
8686
}
8787

8888
sk->sk_state = LLCP_CLOSED;
8989

90-
release_sock(sk);
90+
bh_unlock_sock(sk);
9191

9292
sock_orphan(sk);
9393

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

561+
void nfc_llcp_send_to_raw_sock(struct nfc_llcp_local *local,
562+
struct sk_buff *skb, u8 direction)
563+
{
564+
struct hlist_node *node;
565+
struct sk_buff *skb_copy = NULL, *nskb;
566+
struct sock *sk;
567+
u8 *data;
568+
569+
read_lock(&local->raw_sockets.lock);
570+
571+
sk_for_each(sk, node, &local->raw_sockets.head) {
572+
if (sk->sk_state != LLCP_BOUND)
573+
continue;
574+
575+
if (skb_copy == NULL) {
576+
skb_copy = __pskb_copy(skb, NFC_LLCP_RAW_HEADER_SIZE,
577+
GFP_ATOMIC);
578+
579+
if (skb_copy == NULL)
580+
continue;
581+
582+
data = skb_push(skb_copy, NFC_LLCP_RAW_HEADER_SIZE);
583+
584+
data[0] = local->dev ? local->dev->idx : 0xFF;
585+
data[1] = direction;
586+
}
587+
588+
nskb = skb_clone(skb_copy, GFP_ATOMIC);
589+
if (!nskb)
590+
continue;
591+
592+
if (sock_queue_rcv_skb(sk, nskb))
593+
kfree_skb(nskb);
594+
}
595+
596+
read_unlock(&local->raw_sockets.lock);
597+
598+
kfree_skb(skb_copy);
599+
}
600+
561601
static void nfc_llcp_tx_work(struct work_struct *work)
562602
{
563603
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)
578618
DUMP_PREFIX_OFFSET, 16, 1,
579619
skb->data, skb->len, true);
580620

621+
nfc_llcp_send_to_raw_sock(local, skb,
622+
NFC_LLCP_DIRECTION_TX);
623+
581624
ret = nfc_data_exchange(local->dev, local->target_idx,
582625
skb, nfc_llcp_recv, local);
583626

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

1068+
nfc_llcp_send_to_raw_sock(local, skb, NFC_LLCP_DIRECTION_RX);
1069+
10251070
switch (ptype) {
10261071
case LLCP_PDU_SYMM:
10271072
pr_debug("SYMM\n");
@@ -1156,8 +1201,9 @@ int nfc_llcp_register_device(struct nfc_dev *ndev)
11561201

11571202
INIT_WORK(&local->timeout_work, nfc_llcp_timeout_work);
11581203

1159-
local->sockets.lock = __RW_LOCK_UNLOCKED(local->sockets.lock);
1160-
local->connecting_sockets.lock = __RW_LOCK_UNLOCKED(local->connecting_sockets.lock);
1204+
rwlock_init(&local->sockets.lock);
1205+
rwlock_init(&local->connecting_sockets.lock);
1206+
rwlock_init(&local->raw_sockets.lock);
11611207

11621208
nfc_llcp_build_gb(local);
11631209

net/nfc/llcp/llcp.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,7 @@ struct nfc_llcp_local {
8686
/* sockets array */
8787
struct llcp_sock_list sockets;
8888
struct llcp_sock_list connecting_sockets;
89+
struct llcp_sock_list raw_sockets;
8990
};
9091

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

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

net/nfc/llcp/sock.c

Lines changed: 86 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,60 @@ static int llcp_sock_bind(struct socket *sock, struct sockaddr *addr, int alen)
142142
return ret;
143143
}
144144

145+
static int llcp_raw_sock_bind(struct socket *sock, struct sockaddr *addr,
146+
int alen)
147+
{
148+
struct sock *sk = sock->sk;
149+
struct nfc_llcp_sock *llcp_sock = nfc_llcp_sock(sk);
150+
struct nfc_llcp_local *local;
151+
struct nfc_dev *dev;
152+
struct sockaddr_nfc_llcp llcp_addr;
153+
int len, ret = 0;
154+
155+
if (!addr || addr->sa_family != AF_NFC)
156+
return -EINVAL;
157+
158+
pr_debug("sk %p addr %p family %d\n", sk, addr, addr->sa_family);
159+
160+
memset(&llcp_addr, 0, sizeof(llcp_addr));
161+
len = min_t(unsigned int, sizeof(llcp_addr), alen);
162+
memcpy(&llcp_addr, addr, len);
163+
164+
lock_sock(sk);
165+
166+
if (sk->sk_state != LLCP_CLOSED) {
167+
ret = -EBADFD;
168+
goto error;
169+
}
170+
171+
dev = nfc_get_device(llcp_addr.dev_idx);
172+
if (dev == NULL) {
173+
ret = -ENODEV;
174+
goto error;
175+
}
176+
177+
local = nfc_llcp_find_local(dev);
178+
if (local == NULL) {
179+
ret = -ENODEV;
180+
goto put_dev;
181+
}
182+
183+
llcp_sock->dev = dev;
184+
llcp_sock->local = nfc_llcp_local_get(local);
185+
llcp_sock->nfc_protocol = llcp_addr.nfc_protocol;
186+
187+
nfc_llcp_sock_link(&local->raw_sockets, sk);
188+
189+
sk->sk_state = LLCP_BOUND;
190+
191+
put_dev:
192+
nfc_put_device(dev);
193+
194+
error:
195+
release_sock(sk);
196+
return ret;
197+
}
198+
145199
static int llcp_sock_listen(struct socket *sock, int backlog)
146200
{
147201
struct sock *sk = sock->sk;
@@ -418,7 +472,10 @@ static int llcp_sock_release(struct socket *sock)
418472

419473
release_sock(sk);
420474

421-
nfc_llcp_sock_unlink(&local->sockets, sk);
475+
if (sock->type == SOCK_RAW)
476+
nfc_llcp_sock_unlink(&local->raw_sockets, sk);
477+
else
478+
nfc_llcp_sock_unlink(&local->sockets, sk);
422479

423480
out:
424481
sock_orphan(sk);
@@ -614,7 +671,7 @@ static int llcp_sock_recvmsg(struct kiocb *iocb, struct socket *sock,
614671
if (!(flags & MSG_PEEK)) {
615672

616673
/* SOCK_STREAM: re-queue skb if it contains unreceived data */
617-
if (sk->sk_type == SOCK_STREAM) {
674+
if (sk->sk_type == SOCK_STREAM || sk->sk_type == SOCK_RAW) {
618675
skb_pull(skb, copied);
619676
if (skb->len) {
620677
skb_queue_head(&sk->sk_receive_queue, skb);
@@ -655,6 +712,26 @@ static const struct proto_ops llcp_sock_ops = {
655712
.mmap = sock_no_mmap,
656713
};
657714

715+
static const struct proto_ops llcp_rawsock_ops = {
716+
.family = PF_NFC,
717+
.owner = THIS_MODULE,
718+
.bind = llcp_raw_sock_bind,
719+
.connect = sock_no_connect,
720+
.release = llcp_sock_release,
721+
.socketpair = sock_no_socketpair,
722+
.accept = sock_no_accept,
723+
.getname = llcp_sock_getname,
724+
.poll = llcp_sock_poll,
725+
.ioctl = sock_no_ioctl,
726+
.listen = sock_no_listen,
727+
.shutdown = sock_no_shutdown,
728+
.setsockopt = sock_no_setsockopt,
729+
.getsockopt = sock_no_getsockopt,
730+
.sendmsg = sock_no_sendmsg,
731+
.recvmsg = llcp_sock_recvmsg,
732+
.mmap = sock_no_mmap,
733+
};
734+
658735
static void llcp_sock_destruct(struct sock *sk)
659736
{
660737
struct nfc_llcp_sock *llcp_sock = nfc_llcp_sock(sk);
@@ -732,10 +809,15 @@ static int llcp_sock_create(struct net *net, struct socket *sock,
732809

733810
pr_debug("%p\n", sock);
734811

735-
if (sock->type != SOCK_STREAM && sock->type != SOCK_DGRAM)
812+
if (sock->type != SOCK_STREAM &&
813+
sock->type != SOCK_DGRAM &&
814+
sock->type != SOCK_RAW)
736815
return -ESOCKTNOSUPPORT;
737816

738-
sock->ops = &llcp_sock_ops;
817+
if (sock->type == SOCK_RAW)
818+
sock->ops = &llcp_rawsock_ops;
819+
else
820+
sock->ops = &llcp_sock_ops;
739821

740822
sk = nfc_llcp_sock_alloc(sock, sock->type, GFP_ATOMIC);
741823
if (sk == NULL)

0 commit comments

Comments
 (0)