diff options
Diffstat (limited to 'net/nfc/core.c')
-rw-r--r-- | net/nfc/core.c | 50 |
1 files changed, 25 insertions, 25 deletions
diff --git a/net/nfc/core.c b/net/nfc/core.c index aa64ea441676..25522e56d350 100644 --- a/net/nfc/core.c +++ b/net/nfc/core.c | |||
@@ -338,7 +338,7 @@ int nfc_activate_target(struct nfc_dev *dev, u32 target_idx, u32 protocol) | |||
338 | dev->active_target = target; | 338 | dev->active_target = target; |
339 | dev->rf_mode = NFC_RF_INITIATOR; | 339 | dev->rf_mode = NFC_RF_INITIATOR; |
340 | 340 | ||
341 | if (dev->ops->check_presence) | 341 | if (dev->ops->check_presence && !dev->shutting_down) |
342 | mod_timer(&dev->check_pres_timer, jiffies + | 342 | mod_timer(&dev->check_pres_timer, jiffies + |
343 | msecs_to_jiffies(NFC_CHECK_PRES_FREQ_MS)); | 343 | msecs_to_jiffies(NFC_CHECK_PRES_FREQ_MS)); |
344 | } | 344 | } |
@@ -429,7 +429,7 @@ int nfc_data_exchange(struct nfc_dev *dev, u32 target_idx, struct sk_buff *skb, | |||
429 | rc = dev->ops->im_transceive(dev, dev->active_target, skb, cb, | 429 | rc = dev->ops->im_transceive(dev, dev->active_target, skb, cb, |
430 | cb_context); | 430 | cb_context); |
431 | 431 | ||
432 | if (!rc && dev->ops->check_presence) | 432 | if (!rc && dev->ops->check_presence && !dev->shutting_down) |
433 | mod_timer(&dev->check_pres_timer, jiffies + | 433 | mod_timer(&dev->check_pres_timer, jiffies + |
434 | msecs_to_jiffies(NFC_CHECK_PRES_FREQ_MS)); | 434 | msecs_to_jiffies(NFC_CHECK_PRES_FREQ_MS)); |
435 | } else if (dev->rf_mode == NFC_RF_TARGET && dev->ops->tm_send != NULL) { | 435 | } else if (dev->rf_mode == NFC_RF_TARGET && dev->ops->tm_send != NULL) { |
@@ -684,11 +684,6 @@ static void nfc_release(struct device *d) | |||
684 | 684 | ||
685 | pr_debug("dev_name=%s\n", dev_name(&dev->dev)); | 685 | pr_debug("dev_name=%s\n", dev_name(&dev->dev)); |
686 | 686 | ||
687 | if (dev->ops->check_presence) { | ||
688 | del_timer_sync(&dev->check_pres_timer); | ||
689 | cancel_work_sync(&dev->check_pres_work); | ||
690 | } | ||
691 | |||
692 | nfc_genl_data_exit(&dev->genl_data); | 687 | nfc_genl_data_exit(&dev->genl_data); |
693 | kfree(dev->targets); | 688 | kfree(dev->targets); |
694 | kfree(dev); | 689 | kfree(dev); |
@@ -706,15 +701,16 @@ static void nfc_check_pres_work(struct work_struct *work) | |||
706 | rc = dev->ops->check_presence(dev, dev->active_target); | 701 | rc = dev->ops->check_presence(dev, dev->active_target); |
707 | if (rc == -EOPNOTSUPP) | 702 | if (rc == -EOPNOTSUPP) |
708 | goto exit; | 703 | goto exit; |
709 | if (!rc) { | 704 | if (rc) { |
710 | mod_timer(&dev->check_pres_timer, jiffies + | ||
711 | msecs_to_jiffies(NFC_CHECK_PRES_FREQ_MS)); | ||
712 | } else { | ||
713 | u32 active_target_idx = dev->active_target->idx; | 705 | u32 active_target_idx = dev->active_target->idx; |
714 | device_unlock(&dev->dev); | 706 | device_unlock(&dev->dev); |
715 | nfc_target_lost(dev, active_target_idx); | 707 | nfc_target_lost(dev, active_target_idx); |
716 | return; | 708 | return; |
717 | } | 709 | } |
710 | |||
711 | if (!dev->shutting_down) | ||
712 | mod_timer(&dev->check_pres_timer, jiffies + | ||
713 | msecs_to_jiffies(NFC_CHECK_PRES_FREQ_MS)); | ||
718 | } | 714 | } |
719 | 715 | ||
720 | exit: | 716 | exit: |
@@ -761,6 +757,7 @@ struct nfc_dev *nfc_get_device(unsigned int idx) | |||
761 | */ | 757 | */ |
762 | struct nfc_dev *nfc_allocate_device(struct nfc_ops *ops, | 758 | struct nfc_dev *nfc_allocate_device(struct nfc_ops *ops, |
763 | u32 supported_protocols, | 759 | u32 supported_protocols, |
760 | u32 supported_se, | ||
764 | int tx_headroom, int tx_tailroom) | 761 | int tx_headroom, int tx_tailroom) |
765 | { | 762 | { |
766 | struct nfc_dev *dev; | 763 | struct nfc_dev *dev; |
@@ -778,6 +775,8 @@ struct nfc_dev *nfc_allocate_device(struct nfc_ops *ops, | |||
778 | 775 | ||
779 | dev->ops = ops; | 776 | dev->ops = ops; |
780 | dev->supported_protocols = supported_protocols; | 777 | dev->supported_protocols = supported_protocols; |
778 | dev->supported_se = supported_se; | ||
779 | dev->active_se = NFC_SE_NONE; | ||
781 | dev->tx_headroom = tx_headroom; | 780 | dev->tx_headroom = tx_headroom; |
782 | dev->tx_tailroom = tx_tailroom; | 781 | dev->tx_tailroom = tx_tailroom; |
783 | 782 | ||
@@ -853,26 +852,27 @@ void nfc_unregister_device(struct nfc_dev *dev) | |||
853 | 852 | ||
854 | id = dev->idx; | 853 | id = dev->idx; |
855 | 854 | ||
856 | mutex_lock(&nfc_devlist_mutex); | 855 | if (dev->ops->check_presence) { |
857 | nfc_devlist_generation++; | 856 | device_lock(&dev->dev); |
858 | 857 | dev->shutting_down = true; | |
859 | /* lock to avoid unregistering a device while an operation | 858 | device_unlock(&dev->dev); |
860 | is in progress */ | 859 | del_timer_sync(&dev->check_pres_timer); |
861 | device_lock(&dev->dev); | 860 | cancel_work_sync(&dev->check_pres_work); |
862 | device_del(&dev->dev); | 861 | } |
863 | device_unlock(&dev->dev); | ||
864 | 862 | ||
865 | mutex_unlock(&nfc_devlist_mutex); | 863 | rc = nfc_genl_device_removed(dev); |
864 | if (rc) | ||
865 | pr_debug("The userspace won't be notified that the device %s " | ||
866 | "was removed\n", dev_name(&dev->dev)); | ||
866 | 867 | ||
867 | nfc_llcp_unregister_device(dev); | 868 | nfc_llcp_unregister_device(dev); |
868 | 869 | ||
869 | rc = nfc_genl_device_removed(dev); | 870 | mutex_lock(&nfc_devlist_mutex); |
870 | if (rc) | 871 | nfc_devlist_generation++; |
871 | pr_debug("The userspace won't be notified that the device %s was removed\n", | 872 | device_del(&dev->dev); |
872 | dev_name(&dev->dev)); | 873 | mutex_unlock(&nfc_devlist_mutex); |
873 | 874 | ||
874 | ida_simple_remove(&nfc_index_ida, id); | 875 | ida_simple_remove(&nfc_index_ida, id); |
875 | |||
876 | } | 876 | } |
877 | EXPORT_SYMBOL(nfc_unregister_device); | 877 | EXPORT_SYMBOL(nfc_unregister_device); |
878 | 878 | ||