hci_h5.c 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176
  1. /*
  2. *
  3. * Bluetooth HCI Three-wire UART driver
  4. *
  5. * Copyright (C) 2012 Intel Corporation
  6. *
  7. *
  8. * This program is free software; you can redistribute it and/or modify
  9. * it under the terms of the GNU General Public License as published by
  10. * the Free Software Foundation; either version 2 of the License, or
  11. * (at your option) any later version.
  12. *
  13. * This program is distributed in the hope that it will be useful,
  14. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16. * GNU General Public License for more details.
  17. *
  18. * You should have received a copy of the GNU General Public License
  19. * along with this program; if not, write to the Free Software
  20. * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  21. *
  22. */
  23. #include <linux/kernel.h>
  24. #include <linux/errno.h>
  25. #include <linux/skbuff.h>
  26. #include <net/bluetooth/bluetooth.h>
  27. #include <net/bluetooth/hci_core.h>
  28. #include "hci_uart.h"
  29. struct h5 {
  30. struct sk_buff_head unack; /* Unack'ed packets queue */
  31. struct sk_buff_head rel; /* Reliable packets queue */
  32. struct sk_buff_head unrel; /* Unreliable packets queue */
  33. struct sk_buff *rx_skb;
  34. bool txack_req;
  35. u8 msgq_txseq;
  36. };
  37. static int h5_open(struct hci_uart *hu)
  38. {
  39. struct h5 *h5;
  40. BT_DBG("hu %p", hu);
  41. h5 = kzalloc(sizeof(*h5), GFP_KERNEL);
  42. if (!h5)
  43. return -ENOMEM;
  44. hu->priv = h5;
  45. skb_queue_head_init(&h5->unack);
  46. skb_queue_head_init(&h5->rel);
  47. skb_queue_head_init(&h5->unrel);
  48. return 0;
  49. }
  50. static int h5_close(struct hci_uart *hu)
  51. {
  52. struct h5 *h5 = hu->priv;
  53. skb_queue_purge(&h5->unack);
  54. skb_queue_purge(&h5->rel);
  55. skb_queue_purge(&h5->unrel);
  56. kfree(h5);
  57. return 0;
  58. }
  59. static int h5_recv(struct hci_uart *hu, void *data, int count)
  60. {
  61. return -ENOSYS;
  62. }
  63. static int h5_enqueue(struct hci_uart *hu, struct sk_buff *skb)
  64. {
  65. struct h5 *h5 = hu->priv;
  66. if (skb->len > 0xfff) {
  67. BT_ERR("Packet too long (%u bytes)", skb->len);
  68. kfree_skb(skb);
  69. return 0;
  70. }
  71. switch (bt_cb(skb)->pkt_type) {
  72. case HCI_ACLDATA_PKT:
  73. case HCI_COMMAND_PKT:
  74. skb_queue_tail(&h5->rel, skb);
  75. break;
  76. case HCI_SCODATA_PKT:
  77. skb_queue_tail(&h5->unrel, skb);
  78. break;
  79. default:
  80. BT_ERR("Unknown packet type %u", bt_cb(skb)->pkt_type);
  81. kfree_skb(skb);
  82. break;
  83. }
  84. return 0;
  85. }
  86. static struct sk_buff *h5_prepare_pkt(struct h5 *h5, struct sk_buff *skb)
  87. {
  88. h5->txack_req = false;
  89. return NULL;
  90. }
  91. static struct sk_buff *h5_prepare_ack(struct h5 *h5)
  92. {
  93. h5->txack_req = false;
  94. return NULL;
  95. }
  96. static struct sk_buff *h5_dequeue(struct hci_uart *hu)
  97. {
  98. struct h5 *h5 = hu->priv;
  99. struct sk_buff *skb, *nskb;
  100. if ((skb = skb_dequeue(&h5->unrel)) != NULL) {
  101. nskb = h5_prepare_pkt(h5, skb);
  102. if (nskb) {
  103. kfree_skb(skb);
  104. return nskb;
  105. }
  106. skb_queue_head(&h5->unrel, skb);
  107. BT_ERR("Could not dequeue pkt because alloc_skb failed");
  108. }
  109. if (h5->txack_req)
  110. return h5_prepare_ack(h5);
  111. return NULL;
  112. }
  113. static int h5_flush(struct hci_uart *hu)
  114. {
  115. BT_DBG("hu %p", hu);
  116. return 0;
  117. }
  118. static struct hci_uart_proto h5p = {
  119. .id = HCI_UART_3WIRE,
  120. .open = h5_open,
  121. .close = h5_close,
  122. .recv = h5_recv,
  123. .enqueue = h5_enqueue,
  124. .dequeue = h5_dequeue,
  125. .flush = h5_flush,
  126. };
  127. int __init h5_init(void)
  128. {
  129. int err = hci_uart_register_proto(&h5p);
  130. if (!err)
  131. BT_INFO("HCI Three-wire UART (H5) protocol initialized");
  132. else
  133. BT_ERR("HCI Three-wire UART (H5) protocol init failed");
  134. return err;
  135. }
  136. int __exit h5_deinit(void)
  137. {
  138. return hci_uart_unregister_proto(&h5p);
  139. }