diff options
author | Thierry Escande <thierry.escande@collabora.com> | 2016-07-08 09:52:43 -0400 |
---|---|---|
committer | Samuel Ortiz <sameo@linux.intel.com> | 2016-07-10 19:59:37 -0400 |
commit | e073eb6797191abe2fe30ca643ab0cc3d8e1e534 (patch) | |
tree | edf85a1d4546d3143eb6e6b8109d14a217b636de | |
parent | 482333b277de181ce80c833d84f2598e2527b267 (diff) |
NFC: digital: Rework ACK PDU handling in initiator mode
With this patch, ACK PDU sk_buffs are now freed and code has been
refactored for better errors handling.
Signed-off-by: Thierry Escande <thierry.escande@collabora.com>
Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
-rw-r--r-- | net/nfc/digital_dep.c | 40 |
1 files changed, 27 insertions, 13 deletions
diff --git a/net/nfc/digital_dep.c b/net/nfc/digital_dep.c index e0268777ab18..03bfc74745f7 100644 --- a/net/nfc/digital_dep.c +++ b/net/nfc/digital_dep.c | |||
@@ -782,6 +782,12 @@ static void digital_in_recv_dep_res(struct nfc_digital_dev *ddev, void *arg, | |||
782 | break; | 782 | break; |
783 | 783 | ||
784 | case DIGITAL_NFC_DEP_PFB_ACK_NACK_PDU: | 784 | case DIGITAL_NFC_DEP_PFB_ACK_NACK_PDU: |
785 | if (DIGITAL_NFC_DEP_NACK_BIT_SET(pfb)) { | ||
786 | PROTOCOL_ERR("14.12.4.5"); | ||
787 | rc = -EIO; | ||
788 | goto exit; | ||
789 | } | ||
790 | |||
785 | if (DIGITAL_NFC_DEP_PFB_PNI(pfb) != ddev->curr_nfc_dep_pni) { | 791 | if (DIGITAL_NFC_DEP_PFB_PNI(pfb) != ddev->curr_nfc_dep_pni) { |
786 | PROTOCOL_ERR("14.12.3.3"); | 792 | PROTOCOL_ERR("14.12.3.3"); |
787 | rc = -EIO; | 793 | rc = -EIO; |
@@ -791,22 +797,25 @@ static void digital_in_recv_dep_res(struct nfc_digital_dev *ddev, void *arg, | |||
791 | ddev->curr_nfc_dep_pni = | 797 | ddev->curr_nfc_dep_pni = |
792 | DIGITAL_NFC_DEP_PFB_PNI(ddev->curr_nfc_dep_pni + 1); | 798 | DIGITAL_NFC_DEP_PFB_PNI(ddev->curr_nfc_dep_pni + 1); |
793 | 799 | ||
794 | if (ddev->chaining_skb && !DIGITAL_NFC_DEP_NACK_BIT_SET(pfb)) { | 800 | if (!ddev->chaining_skb) { |
795 | kfree_skb(ddev->saved_skb); | 801 | PROTOCOL_ERR("14.12.4.3"); |
796 | ddev->saved_skb = NULL; | 802 | rc = -EIO; |
803 | goto exit; | ||
804 | } | ||
797 | 805 | ||
798 | rc = digital_in_send_dep_req(ddev, NULL, | 806 | /* The initiator has received a valid ACK. Free the last sent |
799 | ddev->chaining_skb, | 807 | * PDU and keep on sending chained skb. |
800 | ddev->data_exch); | 808 | */ |
801 | if (rc) | 809 | kfree_skb(ddev->saved_skb); |
802 | goto error; | 810 | ddev->saved_skb = NULL; |
803 | 811 | ||
804 | return; | 812 | rc = digital_in_send_dep_req(ddev, NULL, |
805 | } | 813 | ddev->chaining_skb, |
814 | ddev->data_exch); | ||
815 | if (rc) | ||
816 | goto error; | ||
806 | 817 | ||
807 | pr_err("Received a ACK/NACK PDU\n"); | 818 | goto free_resp; |
808 | rc = -EINVAL; | ||
809 | goto exit; | ||
810 | 819 | ||
811 | case DIGITAL_NFC_DEP_PFB_SUPERVISOR_PDU: | 820 | case DIGITAL_NFC_DEP_PFB_SUPERVISOR_PDU: |
812 | if (!DIGITAL_NFC_DEP_PFB_IS_TIMEOUT(pfb)) { /* ATN */ | 821 | if (!DIGITAL_NFC_DEP_PFB_IS_TIMEOUT(pfb)) { /* ATN */ |
@@ -839,6 +848,11 @@ error: | |||
839 | 848 | ||
840 | if (rc) | 849 | if (rc) |
841 | kfree_skb(resp); | 850 | kfree_skb(resp); |
851 | |||
852 | return; | ||
853 | |||
854 | free_resp: | ||
855 | dev_kfree_skb(resp); | ||
842 | } | 856 | } |
843 | 857 | ||
844 | int digital_in_send_dep_req(struct nfc_digital_dev *ddev, | 858 | int digital_in_send_dep_req(struct nfc_digital_dev *ddev, |