aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/bluetooth
diff options
context:
space:
mode:
authorGustavo F. Padovan <padovan@profusion.mobi>2010-07-24 00:46:57 -0400
committerMarcel Holtmann <marcel@holtmann.org>2010-07-27 15:34:53 -0400
commite9da101f6d0c9a8fda9f78a80365ba2a9f75603f (patch)
tree76f630d8eb7939a6377eb344fd17126466c5398b /drivers/bluetooth
parentda5f6c37eee040775997191d1a1bc91c0c1e51eb (diff)
Bluetooth: Use hci_recv_stream_fragment() in UART driver
Use the new hci_recv_stream_fragment() to reassembly incoming UART streams. Signed-off-by: Gustavo F. Padovan <padovan@profusion.mobi> Tested-by: Ville Tervo <ville.tervo@nokia.com> Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
Diffstat (limited to 'drivers/bluetooth')
-rw-r--r--drivers/bluetooth/hci_h4.c103
1 files changed, 2 insertions, 101 deletions
diff --git a/drivers/bluetooth/hci_h4.c b/drivers/bluetooth/hci_h4.c
index 3f038f5308a4..b2cf50e3cafb 100644
--- a/drivers/bluetooth/hci_h4.c
+++ b/drivers/bluetooth/hci_h4.c
@@ -151,107 +151,8 @@ static inline int h4_check_data_len(struct h4_struct *h4, int len)
151/* Recv data */ 151/* Recv data */
152static int h4_recv(struct hci_uart *hu, void *data, int count) 152static int h4_recv(struct hci_uart *hu, void *data, int count)
153{ 153{
154 struct h4_struct *h4 = hu->priv; 154 if (hci_recv_stream_fragment(hu->hdev, data, count) < 0)
155 register char *ptr; 155 BT_ERR("Frame Reassembly Failed");
156 struct hci_event_hdr *eh;
157 struct hci_acl_hdr *ah;
158 struct hci_sco_hdr *sh;
159 register int len, type, dlen;
160
161 BT_DBG("hu %p count %d rx_state %ld rx_count %ld",
162 hu, count, h4->rx_state, h4->rx_count);
163
164 ptr = data;
165 while (count) {
166 if (h4->rx_count) {
167 len = min_t(unsigned int, h4->rx_count, count);
168 memcpy(skb_put(h4->rx_skb, len), ptr, len);
169 h4->rx_count -= len; count -= len; ptr += len;
170
171 if (h4->rx_count)
172 continue;
173
174 switch (h4->rx_state) {
175 case H4_W4_DATA:
176 BT_DBG("Complete data");
177
178 hci_recv_frame(h4->rx_skb);
179
180 h4->rx_state = H4_W4_PACKET_TYPE;
181 h4->rx_skb = NULL;
182 continue;
183
184 case H4_W4_EVENT_HDR:
185 eh = hci_event_hdr(h4->rx_skb);
186
187 BT_DBG("Event header: evt 0x%2.2x plen %d", eh->evt, eh->plen);
188
189 h4_check_data_len(h4, eh->plen);
190 continue;
191
192 case H4_W4_ACL_HDR:
193 ah = hci_acl_hdr(h4->rx_skb);
194 dlen = __le16_to_cpu(ah->dlen);
195
196 BT_DBG("ACL header: dlen %d", dlen);
197
198 h4_check_data_len(h4, dlen);
199 continue;
200
201 case H4_W4_SCO_HDR:
202 sh = hci_sco_hdr(h4->rx_skb);
203
204 BT_DBG("SCO header: dlen %d", sh->dlen);
205
206 h4_check_data_len(h4, sh->dlen);
207 continue;
208 }
209 }
210
211 /* H4_W4_PACKET_TYPE */
212 switch (*ptr) {
213 case HCI_EVENT_PKT:
214 BT_DBG("Event packet");
215 h4->rx_state = H4_W4_EVENT_HDR;
216 h4->rx_count = HCI_EVENT_HDR_SIZE;
217 type = HCI_EVENT_PKT;
218 break;
219
220 case HCI_ACLDATA_PKT:
221 BT_DBG("ACL packet");
222 h4->rx_state = H4_W4_ACL_HDR;
223 h4->rx_count = HCI_ACL_HDR_SIZE;
224 type = HCI_ACLDATA_PKT;
225 break;
226
227 case HCI_SCODATA_PKT:
228 BT_DBG("SCO packet");
229 h4->rx_state = H4_W4_SCO_HDR;
230 h4->rx_count = HCI_SCO_HDR_SIZE;
231 type = HCI_SCODATA_PKT;
232 break;
233
234 default:
235 BT_ERR("Unknown HCI packet type %2.2x", (__u8)*ptr);
236 hu->hdev->stat.err_rx++;
237 ptr++; count--;
238 continue;
239 };
240
241 ptr++; count--;
242
243 /* Allocate packet */
244 h4->rx_skb = bt_skb_alloc(HCI_MAX_FRAME_SIZE, GFP_ATOMIC);
245 if (!h4->rx_skb) {
246 BT_ERR("Can't allocate mem for new packet");
247 h4->rx_state = H4_W4_PACKET_TYPE;
248 h4->rx_count = 0;
249 return -ENOMEM;
250 }
251
252 h4->rx_skb->dev = (void *) hu->hdev;
253 bt_cb(h4->rx_skb)->pkt_type = type;
254 }
255 156
256 return count; 157 return count;
257} 158}