Loading drivers/bluetooth/hci_h5.c +92 −4 Original line number Diff line number Diff line Loading @@ -30,14 +30,48 @@ #include "hci_uart.h" struct h5 { struct sk_buff_head unack; /* Unack'ed packets queue */ struct sk_buff_head rel; /* Reliable packets queue */ struct sk_buff_head unrel; /* Unreliable packets queue */ struct sk_buff *rx_skb; bool txack_req; u8 msgq_txseq; }; static int h5_open(struct hci_uart *hu) { return -ENOSYS; struct h5 *h5; BT_DBG("hu %p", hu); h5 = kzalloc(sizeof(*h5), GFP_KERNEL); if (!h5) return -ENOMEM; hu->priv = h5; skb_queue_head_init(&h5->unack); skb_queue_head_init(&h5->rel); skb_queue_head_init(&h5->unrel); return 0; } static int h5_close(struct hci_uart *hu) { return -ENOSYS; struct h5 *h5 = hu->priv; skb_queue_purge(&h5->unack); skb_queue_purge(&h5->rel); skb_queue_purge(&h5->unrel); kfree(h5); return 0; } static int h5_recv(struct hci_uart *hu, void *data, int count) Loading @@ -47,17 +81,71 @@ static int h5_recv(struct hci_uart *hu, void *data, int count) static int h5_enqueue(struct hci_uart *hu, struct sk_buff *skb) { return -ENOSYS; struct h5 *h5 = hu->priv; if (skb->len > 0xfff) { BT_ERR("Packet too long (%u bytes)", skb->len); kfree_skb(skb); return 0; } switch (bt_cb(skb)->pkt_type) { case HCI_ACLDATA_PKT: case HCI_COMMAND_PKT: skb_queue_tail(&h5->rel, skb); break; case HCI_SCODATA_PKT: skb_queue_tail(&h5->unrel, skb); break; default: BT_ERR("Unknown packet type %u", bt_cb(skb)->pkt_type); kfree_skb(skb); break; } return 0; } static struct sk_buff *h5_prepare_pkt(struct h5 *h5, struct sk_buff *skb) { h5->txack_req = false; return NULL; } static struct sk_buff *h5_prepare_ack(struct h5 *h5) { h5->txack_req = false; return NULL; } static struct sk_buff *h5_dequeue(struct hci_uart *hu) { struct h5 *h5 = hu->priv; struct sk_buff *skb, *nskb; if ((skb = skb_dequeue(&h5->unrel)) != NULL) { nskb = h5_prepare_pkt(h5, skb); if (nskb) { kfree_skb(skb); return nskb; } skb_queue_head(&h5->unrel, skb); BT_ERR("Could not dequeue pkt because alloc_skb failed"); } if (h5->txack_req) return h5_prepare_ack(h5); return NULL; } static int h5_flush(struct hci_uart *hu) { return -ENOSYS; BT_DBG("hu %p", hu); return 0; } static struct hci_uart_proto h5p = { Loading Loading
drivers/bluetooth/hci_h5.c +92 −4 Original line number Diff line number Diff line Loading @@ -30,14 +30,48 @@ #include "hci_uart.h" struct h5 { struct sk_buff_head unack; /* Unack'ed packets queue */ struct sk_buff_head rel; /* Reliable packets queue */ struct sk_buff_head unrel; /* Unreliable packets queue */ struct sk_buff *rx_skb; bool txack_req; u8 msgq_txseq; }; static int h5_open(struct hci_uart *hu) { return -ENOSYS; struct h5 *h5; BT_DBG("hu %p", hu); h5 = kzalloc(sizeof(*h5), GFP_KERNEL); if (!h5) return -ENOMEM; hu->priv = h5; skb_queue_head_init(&h5->unack); skb_queue_head_init(&h5->rel); skb_queue_head_init(&h5->unrel); return 0; } static int h5_close(struct hci_uart *hu) { return -ENOSYS; struct h5 *h5 = hu->priv; skb_queue_purge(&h5->unack); skb_queue_purge(&h5->rel); skb_queue_purge(&h5->unrel); kfree(h5); return 0; } static int h5_recv(struct hci_uart *hu, void *data, int count) Loading @@ -47,17 +81,71 @@ static int h5_recv(struct hci_uart *hu, void *data, int count) static int h5_enqueue(struct hci_uart *hu, struct sk_buff *skb) { return -ENOSYS; struct h5 *h5 = hu->priv; if (skb->len > 0xfff) { BT_ERR("Packet too long (%u bytes)", skb->len); kfree_skb(skb); return 0; } switch (bt_cb(skb)->pkt_type) { case HCI_ACLDATA_PKT: case HCI_COMMAND_PKT: skb_queue_tail(&h5->rel, skb); break; case HCI_SCODATA_PKT: skb_queue_tail(&h5->unrel, skb); break; default: BT_ERR("Unknown packet type %u", bt_cb(skb)->pkt_type); kfree_skb(skb); break; } return 0; } static struct sk_buff *h5_prepare_pkt(struct h5 *h5, struct sk_buff *skb) { h5->txack_req = false; return NULL; } static struct sk_buff *h5_prepare_ack(struct h5 *h5) { h5->txack_req = false; return NULL; } static struct sk_buff *h5_dequeue(struct hci_uart *hu) { struct h5 *h5 = hu->priv; struct sk_buff *skb, *nskb; if ((skb = skb_dequeue(&h5->unrel)) != NULL) { nskb = h5_prepare_pkt(h5, skb); if (nskb) { kfree_skb(skb); return nskb; } skb_queue_head(&h5->unrel, skb); BT_ERR("Could not dequeue pkt because alloc_skb failed"); } if (h5->txack_req) return h5_prepare_ack(h5); return NULL; } static int h5_flush(struct hci_uart *hu) { return -ENOSYS; BT_DBG("hu %p", hu); return 0; } static struct hci_uart_proto h5p = { Loading