Skip to content

Commit

Permalink
[Bluetooth] Use hci_recv_fragment() within HCI USB driver
Browse files Browse the repository at this point in the history
This patch modifies the HCI USB driver to use the new helper function
for reassembling HCI data packets and events.

Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
  • Loading branch information
Marcel Holtmann committed Jul 11, 2007
1 parent ef22201 commit babf4d4
Show file tree
Hide file tree
Showing 2 changed files with 4 additions and 89 deletions.
88 changes: 2 additions & 86 deletions drivers/bluetooth/hci_usb.c
Original file line number Diff line number Diff line change
Expand Up @@ -199,7 +199,6 @@ static void hci_usb_tx_complete(struct urb *urb);
#define __pending_q(husb, type) (&husb->pending_q[type-1])
#define __completed_q(husb, type) (&husb->completed_q[type-1])
#define __transmit_q(husb, type) (&husb->transmit_q[type-1])
#define __reassembly(husb, type) (husb->reassembly[type-1])

static inline struct _urb *__get_completed(struct hci_usb *husb, int type)
{
Expand Down Expand Up @@ -429,12 +428,6 @@ static void hci_usb_unlink_urbs(struct hci_usb *husb)
kfree(urb->transfer_buffer);
_urb_free(_urb);
}

/* Release reassembly buffers */
if (husb->reassembly[i]) {
kfree_skb(husb->reassembly[i]);
husb->reassembly[i] = NULL;
}
}
}

Expand Down Expand Up @@ -671,83 +664,6 @@ static int hci_usb_send_frame(struct sk_buff *skb)
return 0;
}

static inline int __recv_frame(struct hci_usb *husb, int type, void *data, int count)
{
BT_DBG("%s type %d data %p count %d", husb->hdev->name, type, data, count);

husb->hdev->stat.byte_rx += count;

while (count) {
struct sk_buff *skb = __reassembly(husb, type);
struct { int expect; } *scb;
int len = 0;

if (!skb) {
/* Start of the frame */

switch (type) {
case HCI_EVENT_PKT:
if (count >= HCI_EVENT_HDR_SIZE) {
struct hci_event_hdr *h = data;
len = HCI_EVENT_HDR_SIZE + h->plen;
} else
return -EILSEQ;
break;

case HCI_ACLDATA_PKT:
if (count >= HCI_ACL_HDR_SIZE) {
struct hci_acl_hdr *h = data;
len = HCI_ACL_HDR_SIZE + __le16_to_cpu(h->dlen);
} else
return -EILSEQ;
break;
#ifdef CONFIG_BT_HCIUSB_SCO
case HCI_SCODATA_PKT:
if (count >= HCI_SCO_HDR_SIZE) {
struct hci_sco_hdr *h = data;
len = HCI_SCO_HDR_SIZE + h->dlen;
} else
return -EILSEQ;
break;
#endif
}
BT_DBG("new packet len %d", len);

skb = bt_skb_alloc(len, GFP_ATOMIC);
if (!skb) {
BT_ERR("%s no memory for the packet", husb->hdev->name);
return -ENOMEM;
}
skb->dev = (void *) husb->hdev;
bt_cb(skb)->pkt_type = type;

__reassembly(husb, type) = skb;

scb = (void *) skb->cb;
scb->expect = len;
} else {
/* Continuation */
scb = (void *) skb->cb;
len = scb->expect;
}

len = min(len, count);

memcpy(skb_put(skb, len), data, len);

scb->expect -= len;
if (!scb->expect) {
/* Complete frame */
__reassembly(husb, type) = NULL;
bt_cb(skb)->pkt_type = type;
hci_recv_frame(skb);
}

count -= len; data += len;
}
return 0;
}

static void hci_usb_rx_complete(struct urb *urb)
{
struct _urb *_urb = container_of(urb, struct _urb, urb);
Expand Down Expand Up @@ -776,15 +692,15 @@ static void hci_usb_rx_complete(struct urb *urb)
urb->iso_frame_desc[i].actual_length);

if (!urb->iso_frame_desc[i].status)
__recv_frame(husb, _urb->type,
hci_recv_fragment(husb->hdev, _urb->type,
urb->transfer_buffer + urb->iso_frame_desc[i].offset,
urb->iso_frame_desc[i].actual_length);
}
#else
;
#endif
} else {
err = __recv_frame(husb, _urb->type, urb->transfer_buffer, count);
err = hci_recv_fragment(husb->hdev, _urb->type, urb->transfer_buffer, count);
if (err < 0) {
BT_ERR("%s corrupted packet: type %d count %d",
husb->hdev->name, _urb->type, count);
Expand Down
5 changes: 2 additions & 3 deletions drivers/bluetooth/hci_usb.h
Original file line number Diff line number Diff line change
Expand Up @@ -102,9 +102,9 @@ struct hci_usb {
struct hci_dev *hdev;

unsigned long state;

struct usb_device *udev;

struct usb_host_endpoint *bulk_in_ep;
struct usb_host_endpoint *bulk_out_ep;
struct usb_host_endpoint *intr_in_ep;
Expand All @@ -116,7 +116,6 @@ struct hci_usb {
__u8 ctrl_req;

struct sk_buff_head transmit_q[4];
struct sk_buff *reassembly[4]; /* Reassembly buffers */

rwlock_t completion_lock;

Expand Down

0 comments on commit babf4d4

Please sign in to comment.