aboutsummaryrefslogtreecommitdiffstats
path: root/net/nfc
diff options
context:
space:
mode:
Diffstat (limited to 'net/nfc')
-rw-r--r--net/nfc/nci/core.c24
-rw-r--r--net/nfc/nci/data.c4
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 */
336static 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
334static int nci_dev_up(struct nfc_dev *nfc_dev) 344static 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;