Skip to content

Commit 943cc59

Browse files
holtmannJohan Hedberg
authored and
Johan Hedberg
committed
Bluetooth: bpa10x: Use h4_recv_buf helper for frame reassembly
The manually coded frame reassembly is actually broken. The h4_recv_buf helper from the UART driver is a perfect fit for frame reassembly for this driver. So just export that function and use it here as well. Signed-off-by: Marcel Holtmann <marcel@holtmann.org> Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
1 parent 881f7e8 commit 943cc59

File tree

3 files changed

+29
-109
lines changed

3 files changed

+29
-109
lines changed

drivers/bluetooth/Kconfig

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -184,6 +184,7 @@ config BT_HCIBCM203X
184184
config BT_HCIBPA10X
185185
tristate "HCI BPA10x USB driver"
186186
depends on USB
187+
select BT_HCIUART_H4
187188
help
188189
Bluetooth HCI BPA10x USB driver.
189190
This driver provides support for the Digianswer BPA 100/105 Bluetooth

drivers/bluetooth/bpa10x.c

Lines changed: 27 additions & 109 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,9 @@
3535
#include <net/bluetooth/bluetooth.h>
3636
#include <net/bluetooth/hci_core.h>
3737

38-
#define VERSION "0.10"
38+
#include "hci_uart.h"
39+
40+
#define VERSION "0.11"
3941

4042
static const struct usb_device_id bpa10x_table[] = {
4143
/* Tektronix BPA 100/105 (Digianswer) */
@@ -56,112 +58,6 @@ struct bpa10x_data {
5658
struct sk_buff *rx_skb[2];
5759
};
5860

59-
#define HCI_VENDOR_HDR_SIZE 5
60-
61-
struct hci_vendor_hdr {
62-
__u8 type;
63-
__le16 snum;
64-
__le16 dlen;
65-
} __packed;
66-
67-
static int bpa10x_recv(struct hci_dev *hdev, int queue, void *buf, int count)
68-
{
69-
struct bpa10x_data *data = hci_get_drvdata(hdev);
70-
71-
BT_DBG("%s queue %d buffer %p count %d", hdev->name,
72-
queue, buf, count);
73-
74-
if (queue < 0 || queue > 1)
75-
return -EILSEQ;
76-
77-
hdev->stat.byte_rx += count;
78-
79-
while (count) {
80-
struct sk_buff *skb = data->rx_skb[queue];
81-
struct { __u8 type; int expect; } *scb;
82-
int type, len = 0;
83-
84-
if (!skb) {
85-
/* Start of the frame */
86-
87-
type = *((__u8 *) buf);
88-
count--; buf++;
89-
90-
switch (type) {
91-
case HCI_EVENT_PKT:
92-
if (count >= HCI_EVENT_HDR_SIZE) {
93-
struct hci_event_hdr *h = buf;
94-
len = HCI_EVENT_HDR_SIZE + h->plen;
95-
} else
96-
return -EILSEQ;
97-
break;
98-
99-
case HCI_ACLDATA_PKT:
100-
if (count >= HCI_ACL_HDR_SIZE) {
101-
struct hci_acl_hdr *h = buf;
102-
len = HCI_ACL_HDR_SIZE +
103-
__le16_to_cpu(h->dlen);
104-
} else
105-
return -EILSEQ;
106-
break;
107-
108-
case HCI_SCODATA_PKT:
109-
if (count >= HCI_SCO_HDR_SIZE) {
110-
struct hci_sco_hdr *h = buf;
111-
len = HCI_SCO_HDR_SIZE + h->dlen;
112-
} else
113-
return -EILSEQ;
114-
break;
115-
116-
case HCI_VENDOR_PKT:
117-
if (count >= HCI_VENDOR_HDR_SIZE) {
118-
struct hci_vendor_hdr *h = buf;
119-
len = HCI_VENDOR_HDR_SIZE +
120-
__le16_to_cpu(h->dlen);
121-
} else
122-
return -EILSEQ;
123-
break;
124-
}
125-
126-
skb = bt_skb_alloc(len, GFP_ATOMIC);
127-
if (!skb) {
128-
BT_ERR("%s no memory for packet", hdev->name);
129-
return -ENOMEM;
130-
}
131-
132-
data->rx_skb[queue] = skb;
133-
134-
scb = (void *) skb->cb;
135-
scb->type = type;
136-
scb->expect = len;
137-
} else {
138-
/* Continuation */
139-
140-
scb = (void *) skb->cb;
141-
len = scb->expect;
142-
}
143-
144-
len = min(len, count);
145-
146-
memcpy(skb_put(skb, len), buf, len);
147-
148-
scb->expect -= len;
149-
150-
if (scb->expect == 0) {
151-
/* Complete frame */
152-
153-
data->rx_skb[queue] = NULL;
154-
155-
bt_cb(skb)->pkt_type = scb->type;
156-
hci_recv_frame(hdev, skb);
157-
}
158-
159-
count -= len; buf += len;
160-
}
161-
162-
return 0;
163-
}
164-
16561
static void bpa10x_tx_complete(struct urb *urb)
16662
{
16763
struct sk_buff *skb = urb->context;
@@ -184,6 +80,22 @@ static void bpa10x_tx_complete(struct urb *urb)
18480
kfree_skb(skb);
18581
}
18682

83+
#define HCI_VENDOR_HDR_SIZE 5
84+
85+
#define HCI_RECV_VENDOR \
86+
.type = HCI_VENDOR_PKT, \
87+
.hlen = HCI_VENDOR_HDR_SIZE, \
88+
.loff = 3, \
89+
.lsize = 2, \
90+
.maxlen = HCI_MAX_FRAME_SIZE
91+
92+
static const struct h4_recv_pkt bpa10x_recv_pkts[] = {
93+
{ H4_RECV_ACL, .recv = hci_recv_frame },
94+
{ H4_RECV_SCO, .recv = hci_recv_frame },
95+
{ H4_RECV_EVENT, .recv = hci_recv_frame },
96+
{ HCI_RECV_VENDOR, .recv = hci_recv_diag },
97+
};
98+
18799
static void bpa10x_rx_complete(struct urb *urb)
188100
{
189101
struct hci_dev *hdev = urb->context;
@@ -197,11 +109,17 @@ static void bpa10x_rx_complete(struct urb *urb)
197109
return;
198110

199111
if (urb->status == 0) {
200-
if (bpa10x_recv(hdev, usb_pipebulk(urb->pipe),
112+
bool idx = usb_pipebulk(urb->pipe);
113+
114+
data->rx_skb[idx] = h4_recv_buf(hdev, data->rx_skb[idx],
201115
urb->transfer_buffer,
202-
urb->actual_length) < 0) {
116+
urb->actual_length,
117+
bpa10x_recv_pkts,
118+
ARRAY_SIZE(bpa10x_recv_pkts));
119+
if (IS_ERR(data->rx_skb[idx])) {
203120
BT_ERR("%s corrupted event packet", hdev->name);
204121
hdev->stat.err_rx++;
122+
data->rx_skb[idx] = NULL;
205123
}
206124
}
207125

drivers/bluetooth/hci_h4.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -266,3 +266,4 @@ struct sk_buff *h4_recv_buf(struct hci_dev *hdev, struct sk_buff *skb,
266266

267267
return skb;
268268
}
269+
EXPORT_SYMBOL_GPL(h4_recv_buf);

0 commit comments

Comments
 (0)