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>
This commit is contained in:
Thierry Escande 2016-07-08 15:52:43 +02:00 committed by Samuel Ortiz
parent 482333b277
commit e073eb6797
1 changed files with 28 additions and 14 deletions

View File

@ -782,6 +782,12 @@ static void digital_in_recv_dep_res(struct nfc_digital_dev *ddev, void *arg,
break; break;
case DIGITAL_NFC_DEP_PFB_ACK_NACK_PDU: case DIGITAL_NFC_DEP_PFB_ACK_NACK_PDU:
if (DIGITAL_NFC_DEP_NACK_BIT_SET(pfb)) {
PROTOCOL_ERR("14.12.4.5");
rc = -EIO;
goto exit;
}
if (DIGITAL_NFC_DEP_PFB_PNI(pfb) != ddev->curr_nfc_dep_pni) { if (DIGITAL_NFC_DEP_PFB_PNI(pfb) != ddev->curr_nfc_dep_pni) {
PROTOCOL_ERR("14.12.3.3"); PROTOCOL_ERR("14.12.3.3");
rc = -EIO; rc = -EIO;
@ -791,22 +797,25 @@ static void digital_in_recv_dep_res(struct nfc_digital_dev *ddev, void *arg,
ddev->curr_nfc_dep_pni = ddev->curr_nfc_dep_pni =
DIGITAL_NFC_DEP_PFB_PNI(ddev->curr_nfc_dep_pni + 1); DIGITAL_NFC_DEP_PFB_PNI(ddev->curr_nfc_dep_pni + 1);
if (ddev->chaining_skb && !DIGITAL_NFC_DEP_NACK_BIT_SET(pfb)) { if (!ddev->chaining_skb) {
kfree_skb(ddev->saved_skb); PROTOCOL_ERR("14.12.4.3");
ddev->saved_skb = NULL; rc = -EIO;
goto exit;
rc = digital_in_send_dep_req(ddev, NULL,
ddev->chaining_skb,
ddev->data_exch);
if (rc)
goto error;
return;
} }
pr_err("Received a ACK/NACK PDU\n"); /* The initiator has received a valid ACK. Free the last sent
rc = -EINVAL; * PDU and keep on sending chained skb.
goto exit; */
kfree_skb(ddev->saved_skb);
ddev->saved_skb = NULL;
rc = digital_in_send_dep_req(ddev, NULL,
ddev->chaining_skb,
ddev->data_exch);
if (rc)
goto error;
goto free_resp;
case DIGITAL_NFC_DEP_PFB_SUPERVISOR_PDU: case DIGITAL_NFC_DEP_PFB_SUPERVISOR_PDU:
if (!DIGITAL_NFC_DEP_PFB_IS_TIMEOUT(pfb)) { /* ATN */ if (!DIGITAL_NFC_DEP_PFB_IS_TIMEOUT(pfb)) { /* ATN */
@ -839,6 +848,11 @@ error:
if (rc) if (rc)
kfree_skb(resp); kfree_skb(resp);
return;
free_resp:
dev_kfree_skb(resp);
} }
int digital_in_send_dep_req(struct nfc_digital_dev *ddev, int digital_in_send_dep_req(struct nfc_digital_dev *ddev,