aboutsummaryrefslogtreecommitdiffstats
path: root/net/nfc/netlink.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/nfc/netlink.c')
-rw-r--r--net/nfc/netlink.c68
1 files changed, 50 insertions, 18 deletions
diff --git a/net/nfc/netlink.c b/net/nfc/netlink.c
index 4c51714ee741..c1b5285cbde7 100644
--- a/net/nfc/netlink.c
+++ b/net/nfc/netlink.c
@@ -58,7 +58,7 @@ static int nfc_genl_send_target(struct sk_buff *msg, struct nfc_target *target,
58{ 58{
59 void *hdr; 59 void *hdr;
60 60
61 hdr = genlmsg_put(msg, NETLINK_CB(cb->skb).pid, cb->nlh->nlmsg_seq, 61 hdr = genlmsg_put(msg, NETLINK_CB(cb->skb).portid, cb->nlh->nlmsg_seq,
62 &nfc_genl_family, flags, NFC_CMD_GET_TARGET); 62 &nfc_genl_family, flags, NFC_CMD_GET_TARGET);
63 if (!hdr) 63 if (!hdr)
64 return -EMSGSIZE; 64 return -EMSGSIZE;
@@ -165,7 +165,7 @@ int nfc_genl_targets_found(struct nfc_dev *dev)
165 struct sk_buff *msg; 165 struct sk_buff *msg;
166 void *hdr; 166 void *hdr;
167 167
168 dev->genl_data.poll_req_pid = 0; 168 dev->genl_data.poll_req_portid = 0;
169 169
170 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_ATOMIC); 170 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_ATOMIC);
171 if (!msg) 171 if (!msg)
@@ -347,13 +347,13 @@ free_msg:
347} 347}
348 348
349static int nfc_genl_send_device(struct sk_buff *msg, struct nfc_dev *dev, 349static int nfc_genl_send_device(struct sk_buff *msg, struct nfc_dev *dev,
350 u32 pid, u32 seq, 350 u32 portid, u32 seq,
351 struct netlink_callback *cb, 351 struct netlink_callback *cb,
352 int flags) 352 int flags)
353{ 353{
354 void *hdr; 354 void *hdr;
355 355
356 hdr = genlmsg_put(msg, pid, seq, &nfc_genl_family, flags, 356 hdr = genlmsg_put(msg, portid, seq, &nfc_genl_family, flags,
357 NFC_CMD_GET_DEVICE); 357 NFC_CMD_GET_DEVICE);
358 if (!hdr) 358 if (!hdr)
359 return -EMSGSIZE; 359 return -EMSGSIZE;
@@ -401,7 +401,7 @@ static int nfc_genl_dump_devices(struct sk_buff *skb,
401 while (dev) { 401 while (dev) {
402 int rc; 402 int rc;
403 403
404 rc = nfc_genl_send_device(skb, dev, NETLINK_CB(cb->skb).pid, 404 rc = nfc_genl_send_device(skb, dev, NETLINK_CB(cb->skb).portid,
405 cb->nlh->nlmsg_seq, cb, NLM_F_MULTI); 405 cb->nlh->nlmsg_seq, cb, NLM_F_MULTI);
406 if (rc < 0) 406 if (rc < 0)
407 break; 407 break;
@@ -520,7 +520,7 @@ static int nfc_genl_get_device(struct sk_buff *skb, struct genl_info *info)
520 goto out_putdev; 520 goto out_putdev;
521 } 521 }
522 522
523 rc = nfc_genl_send_device(msg, dev, info->snd_pid, info->snd_seq, 523 rc = nfc_genl_send_device(msg, dev, info->snd_portid, info->snd_seq,
524 NULL, 0); 524 NULL, 0);
525 if (rc < 0) 525 if (rc < 0)
526 goto out_free; 526 goto out_free;
@@ -611,7 +611,7 @@ static int nfc_genl_start_poll(struct sk_buff *skb, struct genl_info *info)
611 611
612 rc = nfc_start_poll(dev, im_protocols, tm_protocols); 612 rc = nfc_start_poll(dev, im_protocols, tm_protocols);
613 if (!rc) 613 if (!rc)
614 dev->genl_data.poll_req_pid = info->snd_pid; 614 dev->genl_data.poll_req_portid = info->snd_portid;
615 615
616 mutex_unlock(&dev->genl_data.genl_data_mutex); 616 mutex_unlock(&dev->genl_data.genl_data_mutex);
617 617
@@ -645,13 +645,13 @@ static int nfc_genl_stop_poll(struct sk_buff *skb, struct genl_info *info)
645 645
646 mutex_lock(&dev->genl_data.genl_data_mutex); 646 mutex_lock(&dev->genl_data.genl_data_mutex);
647 647
648 if (dev->genl_data.poll_req_pid != info->snd_pid) { 648 if (dev->genl_data.poll_req_portid != info->snd_portid) {
649 rc = -EBUSY; 649 rc = -EBUSY;
650 goto out; 650 goto out;
651 } 651 }
652 652
653 rc = nfc_stop_poll(dev); 653 rc = nfc_stop_poll(dev);
654 dev->genl_data.poll_req_pid = 0; 654 dev->genl_data.poll_req_portid = 0;
655 655
656out: 656out:
657 mutex_unlock(&dev->genl_data.genl_data_mutex); 657 mutex_unlock(&dev->genl_data.genl_data_mutex);
@@ -761,38 +761,70 @@ 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 portid;
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("portid %d\n", w->portid);
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_portid == w->portid) {
781 nfc_stop_poll(dev); 787 nfc_stop_poll(dev);
782 dev->genl_data.poll_req_pid = 0; 788 dev->genl_data.poll_req_portid = 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->portid);
813
814 w = kmalloc(sizeof(*w), GFP_ATOMIC);
815 if (w) {
816 INIT_WORK((struct work_struct *) w, nfc_urelease_event_work);
817 w->portid = n->portid;
818 schedule_work((struct work_struct *) w);
819 }
820
789out: 821out:
790 return NOTIFY_DONE; 822 return NOTIFY_DONE;
791} 823}
792 824
793void nfc_genl_data_init(struct nfc_genl_data *genl_data) 825void nfc_genl_data_init(struct nfc_genl_data *genl_data)
794{ 826{
795 genl_data->poll_req_pid = 0; 827 genl_data->poll_req_portid = 0;
796 mutex_init(&genl_data->genl_data_mutex); 828 mutex_init(&genl_data->genl_data_mutex);
797} 829}
798 830