diff options
author | Gustavo F. Padovan <padovan@profusion.mobi> | 2010-07-24 00:46:57 -0400 |
---|---|---|
committer | Marcel Holtmann <marcel@holtmann.org> | 2010-07-27 15:34:53 -0400 |
commit | e9da101f6d0c9a8fda9f78a80365ba2a9f75603f (patch) | |
tree | 76f630d8eb7939a6377eb344fd17126466c5398b /drivers/bluetooth | |
parent | da5f6c37eee040775997191d1a1bc91c0c1e51eb (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.c | 103 |
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 */ |
152 | static int h4_recv(struct hci_uart *hu, void *data, int count) | 152 | static 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 | } |