aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
Diffstat (limited to 'net')
-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 4c51714ee741..baa6af9500df 100644
--- a/net/nfc/netlink.c
+++ b/net/nfc/netlink.c
@@ -761,31 +761,63 @@ static struct genl_ops nfc_genl_ops[] = {
761 }, 761 },
762}; 762};
763 763
764static int nfc_genl_rcv_nl_event(struct notifier_block *this, 764
765 unsigned long event, void *ptr) 765struct urelease_work {
766 struct work_struct w;
767 int pid;
768};
769
770static void nfc_urelease_event_work(struct work_struct *work)
766{ 771{
767 struct netlink_notify *n = ptr; 772 struct urelease_work *w = container_of(work, struct urelease_work, w);
768 struct class_dev_iter iter; 773 struct class_dev_iter iter;
769 struct nfc_dev *dev; 774 struct nfc_dev *dev;
770 775
771 if (event != NETLINK_URELEASE || n->protocol != NETLINK_GENERIC) 776 pr_debug("pid %d\n", w->pid);
772 goto out;
773 777
774 pr_debug("NETLINK_URELEASE event from id %d\n", n->pid); 778 mutex_lock(&nfc_devlist_mutex);
775 779
776 nfc_device_iter_init(&iter); 780 nfc_device_iter_init(&iter);
777 dev = nfc_device_iter_next(&iter); 781 dev = nfc_device_iter_next(&iter);
778 782
779 while (dev) { 783 while (dev) {
780 if (dev->genl_data.poll_req_pid == n->pid) { 784 mutex_lock(&dev->genl_data.genl_data_mutex);
785
786 if (dev->genl_data.poll_req_pid == w->pid) {
781 nfc_stop_poll(dev); 787 nfc_stop_poll(dev);
782 dev->genl_data.poll_req_pid = 0; 788 dev->genl_data.poll_req_pid = 0;
783 } 789 }
790
791 mutex_unlock(&dev->genl_data.genl_data_mutex);
792
784 dev = nfc_device_iter_next(&iter); 793 dev = nfc_device_iter_next(&iter);
785 } 794 }
786 795
787 nfc_device_iter_exit(&iter); 796 nfc_device_iter_exit(&iter);
788 797
798 mutex_unlock(&nfc_devlist_mutex);
799
800 kfree(w);
801}
802
803static int nfc_genl_rcv_nl_event(struct notifier_block *this,
804 unsigned long event, void *ptr)
805{
806 struct netlink_notify *n = ptr;
807 struct urelease_work *w;
808
809 if (event != NETLINK_URELEASE || n->protocol != NETLINK_GENERIC)
810 goto out;
811
812 pr_debug("NETLINK_URELEASE event from id %d\n", n->pid);
813
814 w = kmalloc(sizeof(*w), GFP_ATOMIC);
815 if (w) {
816 INIT_WORK((struct work_struct *) w, nfc_urelease_event_work);
817 w->pid = n->pid;
818 schedule_work((struct work_struct *) w);
819 }
820
789out: 821out:
790 return NOTIFY_DONE; 822 return NOTIFY_DONE;
791} 823}