Register HCI device
Signed-off-by: Fabien Parent <fparent@baylibre.com>
diff --git a/btmtk_sdio.c b/btmtk_sdio.c
index 516e729..1f571ca 100644
--- a/btmtk_sdio.c
+++ b/btmtk_sdio.c
@@ -70,6 +70,7 @@
static wait_queue_head_t fw_log_inq;
static struct fasync_struct *fasync;
/*static int btmtk_woble_state = BTMTK_WOBLE_STATE_UNKNOWN;*/
+static struct hci_dev *hdev;
static int need_reset_stack;
static int need_set_i2s = 0;
@@ -2416,6 +2417,19 @@
bt_cb(fops_skb)->pkt_type = type;
memcpy(fops_skb->data, skb->data, buf_len);
+
+ {
+ struct sk_buff *skb_hci = bt_skb_alloc(buf_len, GFP_KERNEL);
+ skb_put(skb_hci, buf_len);
+
+ memcpy(skb_hci->data, fops_skb->data, buf_len);
+ hci_skb_pkt_type(skb_hci) = type;
+
+ ret = hci_recv_frame(hdev, skb_hci);
+ if (ret < 0)
+ printk(KERN_ERR "XXX: error recv frame: %d\n", ret);
+ }
+
fops_skb->len = buf_len;
lock_unsleepable_lock(&(metabuffer.spin_lock));
skb_queue_tail(&g_priv->adapter->fops_queue, fops_skb);
@@ -2936,6 +2950,29 @@
}
#endif
+static int btsdio_open(struct hci_dev *hdev)
+{
+ return 0;
+}
+
+static int btsdio_close(struct hci_dev *hdev)
+{
+ return 0;
+}
+
+static int btsdio_flush(struct hci_dev *hdev)
+{
+ return 0;
+}
+
+static int btsdio_send_frame(struct hci_dev *hdev, struct sk_buff *skb)
+{
+ skb_queue_tail(&g_priv->adapter->tx_queue, skb);
+ wake_up_interruptible(&g_priv->main_thread.wait_q);
+
+ return 0;
+}
+
static int btmtk_sdio_probe(struct sdio_func *func,
const struct sdio_device_id *id)
{
@@ -3075,6 +3112,31 @@
btmtk_stereo_reg_irq();
#endif
+ hdev = hci_alloc_dev();
+ if (!hdev)
+ return -ENOMEM;
+
+ hdev->bus = HCI_SDIO;
+
+ if (id->class == SDIO_CLASS_BT_AMP)
+ hdev->dev_type = HCI_AMP;
+ else
+ hdev->dev_type = HCI_PRIMARY;
+
+ SET_HCIDEV_DEV(hdev, &func->dev);
+
+ hdev->open = btsdio_open;
+ hdev->close = btsdio_close;
+ hdev->flush = btsdio_flush;
+ hdev->send = btsdio_send_frame;
+
+ ret = hci_register_dev(hdev);
+ if (ret < 0) {
+ pr_err("XXX: Failed to register HCI: %d\n", ret);
+ hci_free_dev(hdev);
+ return ret;
+ }
+
pr_info("%s normal end\n", __func__);
probe_ready = true;
return 0;
@@ -3089,10 +3151,14 @@
static void btmtk_sdio_remove(struct sdio_func *func)
{
struct btmtk_sdio_card *card;
+ int ret;
pr_info("%s begin user_rmmod %d\n", __func__, user_rmmod);
probe_ready = false;
+ hci_unregister_dev(hdev);
+ hci_free_dev(hdev);
+
#if SUPPORT_BT_STEREO
btmtk_stereo_unreg_irq();
#endif