Skip to content

Commit

Permalink
NFC: Add NCI data exchange timer
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Ilan Elias authored and linvjw committed Jan 24, 2012
1 parent 889cbb9 commit c4bf98b
Show file tree
Hide file tree
Showing 3 changed files with 31 additions and 0 deletions.
3 changes: 3 additions & 0 deletions include/net/nfc/nci_core.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ enum {
NCI_DISCOVERY,
NCI_POLL_ACTIVE,
NCI_DATA_EXCHANGE,
NCI_DATA_EXCHANGE_TO,
};

/* NCI timeouts */
Expand All @@ -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;

Expand All @@ -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;
Expand Down
24 changes: 24 additions & 0 deletions net/nfc/nci/core.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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);

Expand Down Expand Up @@ -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));
}
}

Expand Down Expand Up @@ -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 ----- */
Expand Down
4 changes: 4 additions & 0 deletions net/nfc/nci/data.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down

0 comments on commit c4bf98b

Please sign in to comment.