summaryrefslogtreecommitdiff
path: root/net/nfc/netlink.c
diff options
context:
space:
mode:
authorJohn W. Linville <linville@tuxdriver.com>2012-09-28 14:55:00 (GMT)
committerJohn W. Linville <linville@tuxdriver.com>2012-09-28 14:55:43 (GMT)
commit97ea6d0f3eb019891038cd2dfddb749d6bf219be (patch)
tree3b7d2f31ab27b4cd5546b0ab72bb9a0c3bdfd008 /net/nfc/netlink.c
parent8a14e8bf386434732eed6678120fe52acee6244a (diff)
parent50b78b2a6500d0e97c204c1b6c51df8c17358bbe (diff)
downloadlinux-fsl-qoriq-97ea6d0f3eb019891038cd2dfddb749d6bf219be.tar.xz
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>
Diffstat (limited to 'net/nfc/netlink.c')
-rw-r--r--net/nfc/netlink.c46
1 files changed, 39 insertions, 7 deletions
diff --git a/net/nfc/netlink.c b/net/nfc/netlink.c
index 4c51714..baa6af9 100644
--- a/net/nfc/netlink.c
+++ b/net/nfc/netlink.c
@@ -761,31 +761,63 @@ static struct genl_ops nfc_genl_ops[] = {
},
};
-static int nfc_genl_rcv_nl_event(struct notifier_block *this,
- unsigned long event, void *ptr)
+
+struct urelease_work {
+ struct work_struct w;
+ int pid;
+};
+
+static void nfc_urelease_event_work(struct work_struct *work)
{
- struct netlink_notify *n = ptr;
+ struct urelease_work *w = container_of(work, struct urelease_work, w);
struct class_dev_iter iter;
struct nfc_dev *dev;
- if (event != NETLINK_URELEASE || n->protocol != NETLINK_GENERIC)
- goto out;
+ pr_debug("pid %d\n", w->pid);
- pr_debug("NETLINK_URELEASE event from id %d\n", n->pid);
+ mutex_lock(&nfc_devlist_mutex);
nfc_device_iter_init(&iter);
dev = nfc_device_iter_next(&iter);
while (dev) {
- if (dev->genl_data.poll_req_pid == n->pid) {
+ mutex_lock(&dev->genl_data.genl_data_mutex);
+
+ if (dev->genl_data.poll_req_pid == w->pid) {
nfc_stop_poll(dev);
dev->genl_data.poll_req_pid = 0;
}
+
+ mutex_unlock(&dev->genl_data.genl_data_mutex);
+
dev = nfc_device_iter_next(&iter);
}
nfc_device_iter_exit(&iter);
+ mutex_unlock(&nfc_devlist_mutex);
+
+ kfree(w);
+}
+
+static int nfc_genl_rcv_nl_event(struct notifier_block *this,
+ unsigned long event, void *ptr)
+{
+ struct netlink_notify *n = ptr;
+ struct urelease_work *w;
+
+ if (event != NETLINK_URELEASE || n->protocol != NETLINK_GENERIC)
+ goto out;
+
+ pr_debug("NETLINK_URELEASE event from id %d\n", n->pid);
+
+ w = kmalloc(sizeof(*w), GFP_ATOMIC);
+ if (w) {
+ INIT_WORK((struct work_struct *) w, nfc_urelease_event_work);
+ w->pid = n->pid;
+ schedule_work((struct work_struct *) w);
+ }
+
out:
return NOTIFY_DONE;
}