aboutsummaryrefslogtreecommitdiffstats
path: root/net/nfc
diff options
context:
space:
mode:
authorChristophe Ricard <christophe.ricard@gmail.com>2015-10-25 17:54:20 -0400
committerSamuel Ortiz <sameo@linux.intel.com>2015-10-26 01:53:11 -0400
commit500c4ef02277eaadbfe20537f963b6221f6ac007 (patch)
treebc0675ce1c6f0f7e9ba8bd1e403ab871a4082dd9 /net/nfc
parenta1269dd116319335db6d73013a31c038486c813e (diff)
NFC: nci: Fix incorrect data chaining when sending data
When sending HCI data over NCI, cmd information should be present only on the first packet. Each packet shall be specifically allocated and sent to the NCI layer. Cc: stable@vger.kernel.org Signed-off-by: Christophe Ricard <christophe-h.ricard@st.com> Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
Diffstat (limited to 'net/nfc')
-rw-r--r--net/nfc/nci/hci.c20
1 files changed, 13 insertions, 7 deletions
diff --git a/net/nfc/nci/hci.c b/net/nfc/nci/hci.c
index 609f92283d1b..321889ee2107 100644
--- a/net/nfc/nci/hci.c
+++ b/net/nfc/nci/hci.c
@@ -146,18 +146,18 @@ static int nci_hci_send_data(struct nci_dev *ndev, u8 pipe,
146 if (!conn_info) 146 if (!conn_info)
147 return -EPROTO; 147 return -EPROTO;
148 148
149 skb = nci_skb_alloc(ndev, 2 + conn_info->max_pkt_payload_len + 149 i = 0;
150 skb = nci_skb_alloc(ndev, conn_info->max_pkt_payload_len +
150 NCI_DATA_HDR_SIZE, GFP_KERNEL); 151 NCI_DATA_HDR_SIZE, GFP_KERNEL);
151 if (!skb) 152 if (!skb)
152 return -ENOMEM; 153 return -ENOMEM;
153 154
154 skb_reserve(skb, 2 + NCI_DATA_HDR_SIZE); 155 skb_reserve(skb, NCI_DATA_HDR_SIZE + 2);
155 *skb_push(skb, 1) = data_type; 156 *skb_push(skb, 1) = data_type;
156 157
157 i = 0;
158 len = conn_info->max_pkt_payload_len;
159
160 do { 158 do {
159 len = conn_info->max_pkt_payload_len;
160
161 /* If last packet add NCI_HFP_NO_CHAINING */ 161 /* If last packet add NCI_HFP_NO_CHAINING */
162 if (i + conn_info->max_pkt_payload_len - 162 if (i + conn_info->max_pkt_payload_len -
163 (skb->len + 1) >= data_len) { 163 (skb->len + 1) >= data_len) {
@@ -177,9 +177,15 @@ static int nci_hci_send_data(struct nci_dev *ndev, u8 pipe,
177 return r; 177 return r;
178 178
179 i += len; 179 i += len;
180
180 if (i < data_len) { 181 if (i < data_len) {
181 skb_trim(skb, 0); 182 skb = nci_skb_alloc(ndev,
182 skb_pull(skb, len); 183 conn_info->max_pkt_payload_len +
184 NCI_DATA_HDR_SIZE, GFP_KERNEL);
185 if (!skb)
186 return -ENOMEM;
187
188 skb_reserve(skb, NCI_DATA_HDR_SIZE + 1);
183 } 189 }
184 } while (i < data_len); 190 } while (i < data_len);
185 191