diff options
Diffstat (limited to 'net/nfc')
-rw-r--r-- | net/nfc/nci/core.c | 24 | ||||
-rw-r--r-- | net/nfc/nci/data.c | 4 |
2 files changed, 28 insertions, 0 deletions
diff --git a/net/nfc/nci/core.c b/net/nfc/nci/core.c index 7650139a1a05..815d28a0ed9d 100644 --- a/net/nfc/nci/core.c +++ b/net/nfc/nci/core.c | |||
@@ -286,6 +286,7 @@ static int nci_close_device(struct nci_dev *ndev) | |||
286 | 286 | ||
287 | if (!test_and_clear_bit(NCI_UP, &ndev->flags)) { | 287 | if (!test_and_clear_bit(NCI_UP, &ndev->flags)) { |
288 | del_timer_sync(&ndev->cmd_timer); | 288 | del_timer_sync(&ndev->cmd_timer); |
289 | del_timer_sync(&ndev->data_timer); | ||
289 | mutex_unlock(&ndev->req_lock); | 290 | mutex_unlock(&ndev->req_lock); |
290 | return 0; | 291 | return 0; |
291 | } | 292 | } |
@@ -331,6 +332,15 @@ static void nci_cmd_timer(unsigned long arg) | |||
331 | queue_work(ndev->cmd_wq, &ndev->cmd_work); | 332 | queue_work(ndev->cmd_wq, &ndev->cmd_work); |
332 | } | 333 | } |
333 | 334 | ||
335 | /* NCI data exchange timer function */ | ||
336 | static void nci_data_timer(unsigned long arg) | ||
337 | { | ||
338 | struct nci_dev *ndev = (void *) arg; | ||
339 | |||
340 | set_bit(NCI_DATA_EXCHANGE_TO, &ndev->flags); | ||
341 | queue_work(ndev->rx_wq, &ndev->rx_work); | ||
342 | } | ||
343 | |||
334 | static int nci_dev_up(struct nfc_dev *nfc_dev) | 344 | static int nci_dev_up(struct nfc_dev *nfc_dev) |
335 | { | 345 | { |
336 | struct nci_dev *ndev = nfc_get_drvdata(nfc_dev); | 346 | struct nci_dev *ndev = nfc_get_drvdata(nfc_dev); |
@@ -585,6 +595,8 @@ int nci_register_device(struct nci_dev *ndev) | |||
585 | 595 | ||
586 | setup_timer(&ndev->cmd_timer, nci_cmd_timer, | 596 | setup_timer(&ndev->cmd_timer, nci_cmd_timer, |
587 | (unsigned long) ndev); | 597 | (unsigned long) ndev); |
598 | setup_timer(&ndev->data_timer, nci_data_timer, | ||
599 | (unsigned long) ndev); | ||
588 | 600 | ||
589 | mutex_init(&ndev->req_lock); | 601 | mutex_init(&ndev->req_lock); |
590 | 602 | ||
@@ -722,6 +734,9 @@ static void nci_tx_work(struct work_struct *work) | |||
722 | nci_plen(skb->data)); | 734 | nci_plen(skb->data)); |
723 | 735 | ||
724 | nci_send_frame(skb); | 736 | nci_send_frame(skb); |
737 | |||
738 | mod_timer(&ndev->data_timer, | ||
739 | jiffies + msecs_to_jiffies(NCI_DATA_TIMEOUT)); | ||
725 | } | 740 | } |
726 | } | 741 | } |
727 | 742 | ||
@@ -753,6 +768,15 @@ static void nci_rx_work(struct work_struct *work) | |||
753 | break; | 768 | break; |
754 | } | 769 | } |
755 | } | 770 | } |
771 | |||
772 | /* check if a data exchange timout has occurred */ | ||
773 | if (test_bit(NCI_DATA_EXCHANGE_TO, &ndev->flags)) { | ||
774 | /* complete the data exchange transaction, if exists */ | ||
775 | if (test_bit(NCI_DATA_EXCHANGE, &ndev->flags)) | ||
776 | nci_data_exchange_complete(ndev, NULL, -ETIMEDOUT); | ||
777 | |||
778 | clear_bit(NCI_DATA_EXCHANGE_TO, &ndev->flags); | ||
779 | } | ||
756 | } | 780 | } |
757 | 781 | ||
758 | /* ----- NCI TX CMD worker thread ----- */ | 782 | /* ----- NCI TX CMD worker thread ----- */ |
diff --git a/net/nfc/nci/data.c b/net/nfc/nci/data.c index e5756b30e602..7880ae924d5e 100644 --- a/net/nfc/nci/data.c +++ b/net/nfc/nci/data.c | |||
@@ -44,6 +44,10 @@ void nci_data_exchange_complete(struct nci_dev *ndev, | |||
44 | 44 | ||
45 | pr_debug("len %d, err %d\n", skb ? skb->len : 0, err); | 45 | pr_debug("len %d, err %d\n", skb ? skb->len : 0, err); |
46 | 46 | ||
47 | /* data exchange is complete, stop the data timer */ | ||
48 | del_timer_sync(&ndev->data_timer); | ||
49 | clear_bit(NCI_DATA_EXCHANGE_TO, &ndev->flags); | ||
50 | |||
47 | if (cb) { | 51 | if (cb) { |
48 | ndev->data_exchange_cb = NULL; | 52 | ndev->data_exchange_cb = NULL; |
49 | ndev->data_exchange_cb_context = 0; | 53 | ndev->data_exchange_cb_context = 0; |