Renaming hci_recv_fragment to hci_recv_packet_fragment as it will be used
only for reassembling HCI fragments with know packet type.
Signed-off-by: suraj <[email protected]>
---
include/net/bluetooth/hci_core.h | 3 ++-
net/bluetooth/hci_core.c | 5 +++--
2 files changed, 5 insertions(+), 3 deletions(-)
diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
index e42f6ed..65c3c13 100644
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -427,7 +427,8 @@ int hci_inquiry(void __user *arg);
void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb);
int hci_recv_frame(struct sk_buff *skb);
-int hci_recv_fragment(struct hci_dev *hdev, int type, void *data, int count);
+int hci_recv_packet_fragment(struct hci_dev *hdev, int type, void *data,
+ int count);
int hci_register_sysfs(struct hci_dev *hdev);
void hci_unregister_sysfs(struct hci_dev *hdev);
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index 5e83f8e..e7ce432 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -1033,7 +1033,8 @@ EXPORT_SYMBOL(hci_recv_frame);
/* Receive packet type fragment */
#define __reassembly(hdev, type) ((hdev)->reassembly[(type) - 2])
-int hci_recv_fragment(struct hci_dev *hdev, int type, void *data, int count)
+int hci_recv_packet_fragment(struct hci_dev *hdev, int type, void *data,
+ int count)
{
if (type < HCI_ACLDATA_PKT || type > HCI_EVENT_PKT)
return -EILSEQ;
@@ -1112,7 +1113,7 @@ int hci_recv_fragment(struct hci_dev *hdev, int type, void *data, int count)
return 0;
}
-EXPORT_SYMBOL(hci_recv_fragment);
+EXPORT_SYMBOL(hci_recv_packet_fragment);
/* ---- Interface to upper protocols ---- */
--
1.7.0
Hi Marcel,
On 6/2/2010 3:29 AM, Marcel Holtmann wrote:
> Hi Luis,
>
>>>> You want to unify patches 1 and 2. Patches upstream should be atomic so that if you apply it, it should make everything still work. Your first patch removes hci_recv_fragment() and then this one fixes the places that call it, you want to do both in one shot.
>>>
>>> actually I prefer to leave these two patches out for now. Since the
>>> renaming could be done easily later. The important part is actually the
>>> other implementation.
>>
>> Won't that break compilation on the first patch since all existing
>> code users no longer have the exported symbol available?
>
> no. The important change here is for the H4 specific stream fragment
> handling. The rest is just a renaming. So 3/3 is the important patch and
> 1/2 and 2/2 are just cosmetic changes.
>
> Regards
>
> Marcel
>
>
I will send 3/3 as a separate patch for you to verify.
Regards
Suraj
Hi Luis,
> > > You want to unify patches 1 and 2. Patches upstream should be atomic so that if you apply it, it should make everything still work. Your first patch removes hci_recv_fragment() and then this one fixes the places that call it, you want to do both in one shot.
> >
> > actually I prefer to leave these two patches out for now. Since the
> > renaming could be done easily later. The important part is actually the
> > other implementation.
>
> Won't that break compilation on the first patch since all existing
> code users no longer have the exported symbol available?
no. The important change here is for the H4 specific stream fragment
handling. The rest is just a renaming. So 3/3 is the important patch and
1/2 and 2/2 are just cosmetic changes.
Regards
Marcel
On Tue, Jun 01, 2010 at 12:59:13PM -0700, Marcel Holtmann wrote:
> Hi Luis,
>
> > You want to unify patches 1 and 2. Patches upstream should be atomic so that if you apply it, it should make everything still work. Your first patch removes hci_recv_fragment() and then this one fixes the places that call it, you want to do both in one shot.
>
> actually I prefer to leave these two patches out for now. Since the
> renaming could be done easily later. The important part is actually the
> other implementation.
Won't that break compilation on the first patch since all existing
code users no longer have the exported symbol available?
Luis
Hi Luis,
> You want to unify patches 1 and 2. Patches upstream should be atomic so that if you apply it, it should make everything still work. Your first patch removes hci_recv_fragment() and then this one fixes the places that call it, you want to do both in one shot.
actually I prefer to leave these two patches out for now. Since the
renaming could be done easily later. The important part is actually the
other implementation.
Regards
Marcel
You want to unify patches 1 and 2. Patches upstream should be atomic so tha=
t if you apply it, it should make everything still work. Your first patch =
removes hci_recv_fragment() and then this one fixes the places that call it=
, you want to do both in one shot.
Luis
________________________________________
From: Suraj Sumangala
Sent: Tuesday, June 01, 2010 1:08 AM
To: [email protected]
Cc: [email protected]; Luis Rodriguez; Jothikumar Mothilal
Subject: [PATCH 2/3] Replace hci_recv_fragment calls
Replace all usages of hci_recv_fragment calls with
hci_recv_packet_fragment
Signed-off-by: suraj <[email protected]>
---
drivers/bluetooth/btusb.c | 6 +++---
1 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c
index 5d9cc53..50aa8d1 100644
--- a/drivers/bluetooth/btusb.c
+++ b/drivers/bluetooth/btusb.c
@@ -211,7 +211,7 @@ static void btusb_intr_complete(struct urb *urb)
if (urb->status =3D=3D 0) {
hdev->stat.byte_rx +=3D urb->actual_length;
- if (hci_recv_fragment(hdev, HCI_EVENT_PKT,
+ if (hci_recv_packet_fragment(hdev, HCI_EVENT_PKT,
urb->transfer_buffer,
urb->actual_length) < 0) {
BT_ERR("%s corrupted event packet", hdev->name);
@@ -295,7 +295,7 @@ static void btusb_bulk_complete(struct urb *urb)
if (urb->status =3D=3D 0) {
hdev->stat.byte_rx +=3D urb->actual_length;
- if (hci_recv_fragment(hdev, HCI_ACLDATA_PKT,
+ if (hci_recv_packet_fragment(hdev, HCI_ACLDATA_PKT,
urb->transfer_buffer,
urb->actual_length) < 0) {
BT_ERR("%s corrupted ACL packet", hdev->name);
@@ -384,7 +384,7 @@ static void btusb_isoc_complete(struct urb *urb)
hdev->stat.byte_rx +=3D length;
- if (hci_recv_fragment(hdev, HCI_SCODATA_PKT,
+ if (hci_recv_packet_fragment(hdev, HCI_SCODATA_PKT,
urb->transfer_buffer + offs=
et,
length) < 0=
) {
BT_ERR("%s corrupted SCO packet", hdev->nam=
e);
--
1.7.0
Implemented hci_recv_stream_fragment to reassemble HCI packets received from a data stream
with packet type not known.
Signed-off-by: suraj <[email protected]>
---
include/net/bluetooth/hci_core.h | 1 +
net/bluetooth/hci_core.c | 104 ++++++++++++++++++++++++++++++++++++++
2 files changed, 105 insertions(+), 0 deletions(-)
diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
index 65c3c13..9892c26 100644
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -429,6 +429,7 @@ void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb);
int hci_recv_frame(struct sk_buff *skb);
int hci_recv_packet_fragment(struct hci_dev *hdev, int type, void *data,
int count);
+int hci_recv_stream_fragment(struct hci_dev *hdev, void *data, int count);
int hci_register_sysfs(struct hci_dev *hdev);
void hci_unregister_sysfs(struct hci_dev *hdev);
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index e7ce432..1587dc8 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -1033,6 +1033,110 @@ EXPORT_SYMBOL(hci_recv_frame);
/* Receive packet type fragment */
#define __reassembly(hdev, type) ((hdev)->reassembly[(type) - 2])
+#define __get_max_rx_size(type) \
+ (((type) == HCI_ACLDATA_PKT) ? \
+ HCI_MAX_FRAME_SIZE : \
+ ((type) == HCI_EVENT_PKT) ? HCI_MAX_EVENT_SIZE :\
+ HCI_MAX_SCO_SIZE)
+
+#define __get_header_len(type) \
+ (((type) == HCI_ACLDATA_PKT) ? \
+ HCI_ACL_HDR_SIZE : \
+ ((type) == HCI_EVENT_PKT) ? HCI_EVENT_HDR_SIZE :\
+ HCI_SCO_HDR_SIZE)
+
+/* Receive fragment from data streams */
+int hci_recv_stream_fragment(struct hci_dev *hdev, void *data, int count)
+{
+ int type;
+
+ while (count) {
+ /*
+ * Reuse first pointer from reassembly array
+ */
+ struct sk_buff *skb = __reassembly(hdev, HCI_ACLDATA_PKT);
+
+ struct { int expect; int pkt_type; } *scb;
+ int len = 0;
+
+ if (!skb) {
+ struct { char type; } *pkt;
+
+ /* Start of the frame */
+ pkt = data;
+ type = pkt->type;
+
+ if (type < HCI_ACLDATA_PKT || type > HCI_EVENT_PKT)
+ return -EILSEQ;
+
+ len = __get_max_rx_size(type);
+
+ skb = bt_skb_alloc(len, GFP_ATOMIC);
+ if (!skb)
+ return -ENOMEM;
+
+ scb = (void *) skb->cb;
+ scb->expect = __get_header_len(type);
+ scb->pkt_type = type;
+
+ skb->dev = (void *) hdev;
+ __reassembly(hdev, HCI_ACLDATA_PKT) = skb;
+
+ data++;
+ count--;
+
+ continue;
+ } else {
+ /* Continue of frame */
+ scb = (void *) skb->cb;
+ len = min(scb->expect, count);
+ type = scb->pkt_type;
+
+ memcpy(skb_put(skb, len), data, len);
+
+ count -= len;
+ data += len;
+ scb->expect -= len;
+ }
+
+ switch (type) {
+ case HCI_EVENT_PKT:
+ if (skb->len == HCI_EVENT_HDR_SIZE) {
+ struct hci_event_hdr *h = hci_event_hdr(skb);
+ scb->expect = h->plen;
+ }
+ break;
+
+ case HCI_ACLDATA_PKT:
+ if (skb->len == HCI_ACL_HDR_SIZE) {
+ struct hci_acl_hdr *h = hci_acl_hdr(skb);
+ scb->expect = __le16_to_cpu(h->dlen);
+ }
+ break;
+
+ case HCI_SCODATA_PKT:
+ if (skb->len == HCI_SCO_HDR_SIZE) {
+ struct hci_sco_hdr *h = hci_sco_hdr(skb);
+ scb->expect = h->dlen;
+ }
+ break;
+ }
+
+ if (scb->expect == 0) {
+ /* Complete frame */
+
+ __reassembly(hdev, HCI_ACLDATA_PKT) = NULL;
+
+ bt_cb(skb)->pkt_type = type;
+ hci_recv_frame(skb);
+ }
+
+ }
+ return 0;
+}
+EXPORT_SYMBOL(hci_recv_stream_fragment);
+
+/* Receive packet fragment with known packet type */
int hci_recv_packet_fragment(struct hci_dev *hdev, int type, void *data,
int count)
{
--
1.7.0
Replace all usages of hci_recv_fragment calls with
hci_recv_packet_fragment
Signed-off-by: suraj <[email protected]>
---
drivers/bluetooth/btusb.c | 6 +++---
1 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c
index 5d9cc53..50aa8d1 100644
--- a/drivers/bluetooth/btusb.c
+++ b/drivers/bluetooth/btusb.c
@@ -211,7 +211,7 @@ static void btusb_intr_complete(struct urb *urb)
if (urb->status == 0) {
hdev->stat.byte_rx += urb->actual_length;
- if (hci_recv_fragment(hdev, HCI_EVENT_PKT,
+ if (hci_recv_packet_fragment(hdev, HCI_EVENT_PKT,
urb->transfer_buffer,
urb->actual_length) < 0) {
BT_ERR("%s corrupted event packet", hdev->name);
@@ -295,7 +295,7 @@ static void btusb_bulk_complete(struct urb *urb)
if (urb->status == 0) {
hdev->stat.byte_rx += urb->actual_length;
- if (hci_recv_fragment(hdev, HCI_ACLDATA_PKT,
+ if (hci_recv_packet_fragment(hdev, HCI_ACLDATA_PKT,
urb->transfer_buffer,
urb->actual_length) < 0) {
BT_ERR("%s corrupted ACL packet", hdev->name);
@@ -384,7 +384,7 @@ static void btusb_isoc_complete(struct urb *urb)
hdev->stat.byte_rx += length;
- if (hci_recv_fragment(hdev, HCI_SCODATA_PKT,
+ if (hci_recv_packet_fragment(hdev, HCI_SCODATA_PKT,
urb->transfer_buffer + offset,
length) < 0) {
BT_ERR("%s corrupted SCO packet", hdev->name);
--
1.7.0