diff options
author | Ilan Elias <ilane@ti.com> | 2011-09-22 04:36:19 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2011-09-27 14:34:05 -0400 |
commit | 38f04c6b1b682f1879441e2925403ad9aff9e229 (patch) | |
tree | cfd23b3e84b078049b69b81a0fe10f4442ca503f /net | |
parent | de054799b7ffee8ce1e3971a8dcd7816ccf04977 (diff) |
NFC: protect nci_data_exchange transactions
Protect 'cb' and 'cb_context' arguments in nci_data_exchange.
In fact, this implements a queue with max length of 1 data
exchange transactions in parallel.
Signed-off-by: Ilan Elias <ilane@ti.com>
Acked-by: Lauro Ramos Venancio <lauro.venancio@openbossa.org>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'net')
-rw-r--r-- | net/nfc/nci/core.c | 10 | ||||
-rw-r--r-- | net/nfc/nci/data.c | 2 | ||||
-rw-r--r-- | net/nfc/nci/ntf.c | 2 |
3 files changed, 12 insertions, 2 deletions
diff --git a/net/nfc/nci/core.c b/net/nfc/nci/core.c index 9f17e8ec0ab9..1e6b20f2bc99 100644 --- a/net/nfc/nci/core.c +++ b/net/nfc/nci/core.c | |||
@@ -453,6 +453,7 @@ static int nci_data_exchange(struct nfc_dev *nfc_dev, __u32 target_idx, | |||
453 | void *cb_context) | 453 | void *cb_context) |
454 | { | 454 | { |
455 | struct nci_dev *ndev = nfc_get_drvdata(nfc_dev); | 455 | struct nci_dev *ndev = nfc_get_drvdata(nfc_dev); |
456 | int rc; | ||
456 | 457 | ||
457 | nfc_dbg("entry, target_idx %d, len %d", target_idx, skb->len); | 458 | nfc_dbg("entry, target_idx %d, len %d", target_idx, skb->len); |
458 | 459 | ||
@@ -461,11 +462,18 @@ static int nci_data_exchange(struct nfc_dev *nfc_dev, __u32 target_idx, | |||
461 | return -EINVAL; | 462 | return -EINVAL; |
462 | } | 463 | } |
463 | 464 | ||
465 | if (test_and_set_bit(NCI_DATA_EXCHANGE, &ndev->flags)) | ||
466 | return -EBUSY; | ||
467 | |||
464 | /* store cb and context to be used on receiving data */ | 468 | /* store cb and context to be used on receiving data */ |
465 | ndev->data_exchange_cb = cb; | 469 | ndev->data_exchange_cb = cb; |
466 | ndev->data_exchange_cb_context = cb_context; | 470 | ndev->data_exchange_cb_context = cb_context; |
467 | 471 | ||
468 | return nci_send_data(ndev, ndev->conn_id, skb); | 472 | rc = nci_send_data(ndev, ndev->conn_id, skb); |
473 | if (rc) | ||
474 | clear_bit(NCI_DATA_EXCHANGE, &ndev->flags); | ||
475 | |||
476 | return rc; | ||
469 | } | 477 | } |
470 | 478 | ||
471 | static struct nfc_ops nci_nfc_ops = { | 479 | static struct nfc_ops nci_nfc_ops = { |
diff --git a/net/nfc/nci/data.c b/net/nfc/nci/data.c index 141790ada4aa..e5ed90fc1a9c 100644 --- a/net/nfc/nci/data.c +++ b/net/nfc/nci/data.c | |||
@@ -54,6 +54,8 @@ void nci_data_exchange_complete(struct nci_dev *ndev, | |||
54 | /* no waiting callback, free skb */ | 54 | /* no waiting callback, free skb */ |
55 | kfree_skb(skb); | 55 | kfree_skb(skb); |
56 | } | 56 | } |
57 | |||
58 | clear_bit(NCI_DATA_EXCHANGE, &ndev->flags); | ||
57 | } | 59 | } |
58 | 60 | ||
59 | /* ----------------- NCI TX Data ----------------- */ | 61 | /* ----------------- NCI TX Data ----------------- */ |
diff --git a/net/nfc/nci/ntf.c b/net/nfc/nci/ntf.c index 8dd75352ab6c..96633f5cda4f 100644 --- a/net/nfc/nci/ntf.c +++ b/net/nfc/nci/ntf.c | |||
@@ -215,7 +215,7 @@ static void nci_rf_deactivate_ntf_packet(struct nci_dev *ndev, | |||
215 | } | 215 | } |
216 | 216 | ||
217 | /* complete the data exchange transaction, if exists */ | 217 | /* complete the data exchange transaction, if exists */ |
218 | if (ndev->data_exchange_cb) | 218 | if (test_bit(NCI_DATA_EXCHANGE, &ndev->flags)) |
219 | nci_data_exchange_complete(ndev, NULL, -EIO); | 219 | nci_data_exchange_complete(ndev, NULL, -EIO); |
220 | } | 220 | } |
221 | 221 | ||