NFC: Add NCI data exchange timer
Add NCI data exchange timer to catch timeouts, and call the data exchange callback with an error. Signed-off-by: Ilan Elias <ilane@ti.com> Acked-by: Samuel Ortiz <sameo@linux.intel.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
This commit is contained in:
parent
889cbb911a
commit
c4bf98b220
@ -41,6 +41,7 @@ enum {
|
||||
NCI_DISCOVERY,
|
||||
NCI_POLL_ACTIVE,
|
||||
NCI_DATA_EXCHANGE,
|
||||
NCI_DATA_EXCHANGE_TO,
|
||||
};
|
||||
|
||||
/* NCI timeouts */
|
||||
@ -49,6 +50,7 @@ enum {
|
||||
#define NCI_RF_DISC_TIMEOUT 5000
|
||||
#define NCI_RF_DEACTIVATE_TIMEOUT 30000
|
||||
#define NCI_CMD_TIMEOUT 5000
|
||||
#define NCI_DATA_TIMEOUT 700
|
||||
|
||||
struct nci_dev;
|
||||
|
||||
@ -74,6 +76,7 @@ struct nci_dev {
|
||||
atomic_t credits_cnt;
|
||||
|
||||
struct timer_list cmd_timer;
|
||||
struct timer_list data_timer;
|
||||
|
||||
struct workqueue_struct *cmd_wq;
|
||||
struct work_struct cmd_work;
|
||||
|
@ -286,6 +286,7 @@ static int nci_close_device(struct nci_dev *ndev)
|
||||
|
||||
if (!test_and_clear_bit(NCI_UP, &ndev->flags)) {
|
||||
del_timer_sync(&ndev->cmd_timer);
|
||||
del_timer_sync(&ndev->data_timer);
|
||||
mutex_unlock(&ndev->req_lock);
|
||||
return 0;
|
||||
}
|
||||
@ -331,6 +332,15 @@ static void nci_cmd_timer(unsigned long arg)
|
||||
queue_work(ndev->cmd_wq, &ndev->cmd_work);
|
||||
}
|
||||
|
||||
/* NCI data exchange timer function */
|
||||
static void nci_data_timer(unsigned long arg)
|
||||
{
|
||||
struct nci_dev *ndev = (void *) arg;
|
||||
|
||||
set_bit(NCI_DATA_EXCHANGE_TO, &ndev->flags);
|
||||
queue_work(ndev->rx_wq, &ndev->rx_work);
|
||||
}
|
||||
|
||||
static int nci_dev_up(struct nfc_dev *nfc_dev)
|
||||
{
|
||||
struct nci_dev *ndev = nfc_get_drvdata(nfc_dev);
|
||||
@ -585,6 +595,8 @@ int nci_register_device(struct nci_dev *ndev)
|
||||
|
||||
setup_timer(&ndev->cmd_timer, nci_cmd_timer,
|
||||
(unsigned long) ndev);
|
||||
setup_timer(&ndev->data_timer, nci_data_timer,
|
||||
(unsigned long) ndev);
|
||||
|
||||
mutex_init(&ndev->req_lock);
|
||||
|
||||
@ -722,6 +734,9 @@ static void nci_tx_work(struct work_struct *work)
|
||||
nci_plen(skb->data));
|
||||
|
||||
nci_send_frame(skb);
|
||||
|
||||
mod_timer(&ndev->data_timer,
|
||||
jiffies + msecs_to_jiffies(NCI_DATA_TIMEOUT));
|
||||
}
|
||||
}
|
||||
|
||||
@ -753,6 +768,15 @@ static void nci_rx_work(struct work_struct *work)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* check if a data exchange timout has occurred */
|
||||
if (test_bit(NCI_DATA_EXCHANGE_TO, &ndev->flags)) {
|
||||
/* complete the data exchange transaction, if exists */
|
||||
if (test_bit(NCI_DATA_EXCHANGE, &ndev->flags))
|
||||
nci_data_exchange_complete(ndev, NULL, -ETIMEDOUT);
|
||||
|
||||
clear_bit(NCI_DATA_EXCHANGE_TO, &ndev->flags);
|
||||
}
|
||||
}
|
||||
|
||||
/* ----- NCI TX CMD worker thread ----- */
|
||||
|
@ -44,6 +44,10 @@ void nci_data_exchange_complete(struct nci_dev *ndev,
|
||||
|
||||
pr_debug("len %d, err %d\n", skb ? skb->len : 0, err);
|
||||
|
||||
/* data exchange is complete, stop the data timer */
|
||||
del_timer_sync(&ndev->data_timer);
|
||||
clear_bit(NCI_DATA_EXCHANGE_TO, &ndev->flags);
|
||||
|
||||
if (cb) {
|
||||
ndev->data_exchange_cb = NULL;
|
||||
ndev->data_exchange_cb_context = 0;
|
||||
|
Loading…
Reference in New Issue
Block a user