summaryrefslogtreecommitdiff
path: root/drivers/bluetooth
diff options
context:
space:
mode:
authorScott Wood <scottwood@freescale.com>2014-04-07 23:49:35 (GMT)
committerScott Wood <scottwood@freescale.com>2014-04-07 23:49:35 (GMT)
commit62b8c978ee6b8d135d9e7953221de58000dba986 (patch)
tree683b04b2e627f6710c22c151b23c8cc9a165315e /drivers/bluetooth
parent78fd82238d0e5716578c326404184a27ba67fd6e (diff)
downloadlinux-fsl-qoriq-62b8c978ee6b8d135d9e7953221de58000dba986.tar.xz
Rewind v3.13-rc3+ (78fd82238d0e5716) to v3.12
Diffstat (limited to 'drivers/bluetooth')
-rw-r--r--drivers/bluetooth/Makefile2
-rw-r--r--drivers/bluetooth/ath3k.c4
-rw-r--r--drivers/bluetooth/bfusb.c31
-rw-r--r--drivers/bluetooth/bluecard_cs.c30
-rw-r--r--drivers/bluetooth/bpa10x.c11
-rw-r--r--drivers/bluetooth/bt3c_cs.c30
-rw-r--r--drivers/bluetooth/btmrvl_drv.h12
-rw-r--r--drivers/bluetooth/btmrvl_main.c295
-rw-r--r--drivers/bluetooth/btmrvl_sdio.c23
-rw-r--r--drivers/bluetooth/btmrvl_sdio.h2
-rw-r--r--drivers/bluetooth/btsdio.c6
-rw-r--r--drivers/bluetooth/btuart_cs.c30
-rw-r--r--drivers/bluetooth/btusb.c22
-rw-r--r--drivers/bluetooth/btwilink.c9
-rw-r--r--drivers/bluetooth/dtl1_cs.c30
-rw-r--r--drivers/bluetooth/hci_bcsp.c5
-rw-r--r--drivers/bluetooth/hci_h4.c24
-rw-r--r--drivers/bluetooth/hci_h5.c2
-rw-r--r--drivers/bluetooth/hci_ldisc.c12
-rw-r--r--drivers/bluetooth/hci_ll.c14
-rw-r--r--drivers/bluetooth/hci_vhci.c179
21 files changed, 377 insertions, 396 deletions
diff --git a/drivers/bluetooth/Makefile b/drivers/bluetooth/Makefile
index 9fe8a87..4afae20 100644
--- a/drivers/bluetooth/Makefile
+++ b/drivers/bluetooth/Makefile
@@ -30,5 +30,3 @@ hci_uart-$(CONFIG_BT_HCIUART_LL) += hci_ll.o
hci_uart-$(CONFIG_BT_HCIUART_ATH3K) += hci_ath.o
hci_uart-$(CONFIG_BT_HCIUART_3WIRE) += hci_h5.o
hci_uart-objs := $(hci_uart-y)
-
-ccflags-y += -D__CHECK_ENDIAN__
diff --git a/drivers/bluetooth/ath3k.c b/drivers/bluetooth/ath3k.c
index 6bfc1bb..0a327f4 100644
--- a/drivers/bluetooth/ath3k.c
+++ b/drivers/bluetooth/ath3k.c
@@ -57,7 +57,7 @@ struct ath3k_version {
unsigned char reserved[0x07];
};
-static const struct usb_device_id ath3k_table[] = {
+static struct usb_device_id ath3k_table[] = {
/* Atheros AR3011 */
{ USB_DEVICE(0x0CF3, 0x3000) },
@@ -112,7 +112,7 @@ MODULE_DEVICE_TABLE(usb, ath3k_table);
#define BTUSB_ATH3012 0x80
/* This table is to load patch and sysconfig files
* for AR3012 */
-static const struct usb_device_id ath3k_blist_tbl[] = {
+static struct usb_device_id ath3k_blist_tbl[] = {
/* Atheros AR3012 with sflash firmware*/
{ USB_DEVICE(0x0CF3, 0x0036), .driver_info = BTUSB_ATH3012 },
diff --git a/drivers/bluetooth/bfusb.c b/drivers/bluetooth/bfusb.c
index 3138699..995aee9 100644
--- a/drivers/bluetooth/bfusb.c
+++ b/drivers/bluetooth/bfusb.c
@@ -42,7 +42,7 @@
static struct usb_driver bfusb_driver;
-static const struct usb_device_id bfusb_table[] = {
+static struct usb_device_id bfusb_table[] = {
/* AVM BlueFRITZ! USB */
{ USB_DEVICE(0x057c, 0x2200) },
@@ -318,6 +318,7 @@ static inline int bfusb_recv_block(struct bfusb_data *data, int hdr, unsigned ch
return -ENOMEM;
}
+ skb->dev = (void *) data->hdev;
bt_cb(skb)->pkt_type = pkt_type;
data->reassembly = skb;
@@ -332,7 +333,7 @@ static inline int bfusb_recv_block(struct bfusb_data *data, int hdr, unsigned ch
memcpy(skb_put(data->reassembly, len), buf, len);
if (hdr & 0x08) {
- hci_recv_frame(data->hdev, data->reassembly);
+ hci_recv_frame(data->reassembly);
data->reassembly = NULL;
}
@@ -464,18 +465,26 @@ static int bfusb_close(struct hci_dev *hdev)
return 0;
}
-static int bfusb_send_frame(struct hci_dev *hdev, struct sk_buff *skb)
+static int bfusb_send_frame(struct sk_buff *skb)
{
- struct bfusb_data *data = hci_get_drvdata(hdev);
+ struct hci_dev *hdev = (struct hci_dev *) skb->dev;
+ struct bfusb_data *data;
struct sk_buff *nskb;
unsigned char buf[3];
int sent = 0, size, count;
BT_DBG("hdev %p skb %p type %d len %d", hdev, skb, bt_cb(skb)->pkt_type, skb->len);
+ if (!hdev) {
+ BT_ERR("Frame for unknown HCI device (hdev=NULL)");
+ return -ENODEV;
+ }
+
if (!test_bit(HCI_RUNNING, &hdev->flags))
return -EBUSY;
+ data = hci_get_drvdata(hdev);
+
switch (bt_cb(skb)->pkt_type) {
case HCI_COMMAND_PKT:
hdev->stat.cmd_tx++;
@@ -535,6 +544,11 @@ static int bfusb_send_frame(struct hci_dev *hdev, struct sk_buff *skb)
return 0;
}
+static int bfusb_ioctl(struct hci_dev *hdev, unsigned int cmd, unsigned long arg)
+{
+ return -ENOIOCTLCMD;
+}
+
static int bfusb_load_firmware(struct bfusb_data *data,
const unsigned char *firmware, int count)
{
@@ -685,10 +699,11 @@ static int bfusb_probe(struct usb_interface *intf, const struct usb_device_id *i
hci_set_drvdata(hdev, data);
SET_HCIDEV_DEV(hdev, &intf->dev);
- hdev->open = bfusb_open;
- hdev->close = bfusb_close;
- hdev->flush = bfusb_flush;
- hdev->send = bfusb_send_frame;
+ hdev->open = bfusb_open;
+ hdev->close = bfusb_close;
+ hdev->flush = bfusb_flush;
+ hdev->send = bfusb_send_frame;
+ hdev->ioctl = bfusb_ioctl;
if (hci_register_dev(hdev) < 0) {
BT_ERR("Can't register HCI device");
diff --git a/drivers/bluetooth/bluecard_cs.c b/drivers/bluetooth/bluecard_cs.c
index 57427de..6c3e3d4 100644
--- a/drivers/bluetooth/bluecard_cs.c
+++ b/drivers/bluetooth/bluecard_cs.c
@@ -399,6 +399,7 @@ static void bluecard_receive(bluecard_info_t *info, unsigned int offset)
if (info->rx_state == RECV_WAIT_PACKET_TYPE) {
+ info->rx_skb->dev = (void *) info->hdev;
bt_cb(info->rx_skb)->pkt_type = buf[i];
switch (bt_cb(info->rx_skb)->pkt_type) {
@@ -476,7 +477,7 @@ static void bluecard_receive(bluecard_info_t *info, unsigned int offset)
break;
case RECV_WAIT_DATA:
- hci_recv_frame(info->hdev, info->rx_skb);
+ hci_recv_frame(info->rx_skb);
info->rx_skb = NULL;
break;
@@ -658,9 +659,17 @@ static int bluecard_hci_close(struct hci_dev *hdev)
}
-static int bluecard_hci_send_frame(struct hci_dev *hdev, struct sk_buff *skb)
+static int bluecard_hci_send_frame(struct sk_buff *skb)
{
- bluecard_info_t *info = hci_get_drvdata(hdev);
+ bluecard_info_t *info;
+ struct hci_dev *hdev = (struct hci_dev *)(skb->dev);
+
+ if (!hdev) {
+ BT_ERR("Frame for unknown HCI device (hdev=NULL)");
+ return -ENODEV;
+ }
+
+ info = hci_get_drvdata(hdev);
switch (bt_cb(skb)->pkt_type) {
case HCI_COMMAND_PKT:
@@ -684,6 +693,12 @@ static int bluecard_hci_send_frame(struct hci_dev *hdev, struct sk_buff *skb)
}
+static int bluecard_hci_ioctl(struct hci_dev *hdev, unsigned int cmd, unsigned long arg)
+{
+ return -ENOIOCTLCMD;
+}
+
+
/* ======================== Card services HCI interaction ======================== */
@@ -719,10 +734,11 @@ static int bluecard_open(bluecard_info_t *info)
hci_set_drvdata(hdev, info);
SET_HCIDEV_DEV(hdev, &info->p_dev->dev);
- hdev->open = bluecard_hci_open;
- hdev->close = bluecard_hci_close;
- hdev->flush = bluecard_hci_flush;
- hdev->send = bluecard_hci_send_frame;
+ hdev->open = bluecard_hci_open;
+ hdev->close = bluecard_hci_close;
+ hdev->flush = bluecard_hci_flush;
+ hdev->send = bluecard_hci_send_frame;
+ hdev->ioctl = bluecard_hci_ioctl;
id = inb(iobase + 0x30);
diff --git a/drivers/bluetooth/bpa10x.c b/drivers/bluetooth/bpa10x.c
index 8a31991..2fe4a80 100644
--- a/drivers/bluetooth/bpa10x.c
+++ b/drivers/bluetooth/bpa10x.c
@@ -37,7 +37,7 @@
#define VERSION "0.10"
-static const struct usb_device_id bpa10x_table[] = {
+static struct usb_device_id bpa10x_table[] = {
/* Tektronix BPA 100/105 (Digianswer) */
{ USB_DEVICE(0x08fd, 0x0002) },
@@ -129,6 +129,8 @@ static int bpa10x_recv(struct hci_dev *hdev, int queue, void *buf, int count)
return -ENOMEM;
}
+ skb->dev = (void *) hdev;
+
data->rx_skb[queue] = skb;
scb = (void *) skb->cb;
@@ -153,7 +155,7 @@ static int bpa10x_recv(struct hci_dev *hdev, int queue, void *buf, int count)
data->rx_skb[queue] = NULL;
bt_cb(skb)->pkt_type = scb->type;
- hci_recv_frame(hdev, skb);
+ hci_recv_frame(skb);
}
count -= len; buf += len;
@@ -350,8 +352,9 @@ static int bpa10x_flush(struct hci_dev *hdev)
return 0;
}
-static int bpa10x_send_frame(struct hci_dev *hdev, struct sk_buff *skb)
+static int bpa10x_send_frame(struct sk_buff *skb)
{
+ struct hci_dev *hdev = (struct hci_dev *) skb->dev;
struct bpa10x_data *data = hci_get_drvdata(hdev);
struct usb_ctrlrequest *dr;
struct urb *urb;
@@ -363,8 +366,6 @@ static int bpa10x_send_frame(struct hci_dev *hdev, struct sk_buff *skb)
if (!test_bit(HCI_RUNNING, &hdev->flags))
return -EBUSY;
- skb->dev = (void *) hdev;
-
urb = usb_alloc_urb(0, GFP_ATOMIC);
if (!urb)
return -ENOMEM;
diff --git a/drivers/bluetooth/bt3c_cs.c b/drivers/bluetooth/bt3c_cs.c
index 73d8799..a1aaa3b 100644
--- a/drivers/bluetooth/bt3c_cs.c
+++ b/drivers/bluetooth/bt3c_cs.c
@@ -247,6 +247,7 @@ static void bt3c_receive(bt3c_info_t *info)
if (info->rx_state == RECV_WAIT_PACKET_TYPE) {
+ info->rx_skb->dev = (void *) info->hdev;
bt_cb(info->rx_skb)->pkt_type = inb(iobase + DATA_L);
inb(iobase + DATA_H);
//printk("bt3c: PACKET_TYPE=%02x\n", bt_cb(info->rx_skb)->pkt_type);
@@ -317,7 +318,7 @@ static void bt3c_receive(bt3c_info_t *info)
break;
case RECV_WAIT_DATA:
- hci_recv_frame(info->hdev, info->rx_skb);
+ hci_recv_frame(info->rx_skb);
info->rx_skb = NULL;
break;
@@ -415,11 +416,19 @@ static int bt3c_hci_close(struct hci_dev *hdev)
}
-static int bt3c_hci_send_frame(struct hci_dev *hdev, struct sk_buff *skb)
+static int bt3c_hci_send_frame(struct sk_buff *skb)
{
- bt3c_info_t *info = hci_get_drvdata(hdev);
+ bt3c_info_t *info;
+ struct hci_dev *hdev = (struct hci_dev *)(skb->dev);
unsigned long flags;
+ if (!hdev) {
+ BT_ERR("Frame for unknown HCI device (hdev=NULL)");
+ return -ENODEV;
+ }
+
+ info = hci_get_drvdata(hdev);
+
switch (bt_cb(skb)->pkt_type) {
case HCI_COMMAND_PKT:
hdev->stat.cmd_tx++;
@@ -446,6 +455,12 @@ static int bt3c_hci_send_frame(struct hci_dev *hdev, struct sk_buff *skb)
}
+static int bt3c_hci_ioctl(struct hci_dev *hdev, unsigned int cmd, unsigned long arg)
+{
+ return -ENOIOCTLCMD;
+}
+
+
/* ======================== Card services HCI interaction ======================== */
@@ -562,10 +577,11 @@ static int bt3c_open(bt3c_info_t *info)
hci_set_drvdata(hdev, info);
SET_HCIDEV_DEV(hdev, &info->p_dev->dev);
- hdev->open = bt3c_hci_open;
- hdev->close = bt3c_hci_close;
- hdev->flush = bt3c_hci_flush;
- hdev->send = bt3c_hci_send_frame;
+ hdev->open = bt3c_hci_open;
+ hdev->close = bt3c_hci_close;
+ hdev->flush = bt3c_hci_flush;
+ hdev->send = bt3c_hci_send_frame;
+ hdev->ioctl = bt3c_hci_ioctl;
/* Load firmware */
err = request_firmware(&firmware, "BT3CPCC.bin", &info->p_dev->dev);
diff --git a/drivers/bluetooth/btmrvl_drv.h b/drivers/bluetooth/btmrvl_drv.h
index f9d1833..27068d1 100644
--- a/drivers/bluetooth/btmrvl_drv.h
+++ b/drivers/bluetooth/btmrvl_drv.h
@@ -23,8 +23,6 @@
#include <linux/bitops.h>
#include <linux/slab.h>
#include <net/bluetooth/bluetooth.h>
-#include <linux/ctype.h>
-#include <linux/firmware.h>
#define BTM_HEADER_LEN 4
#define BTM_UPLD_SIZE 2312
@@ -43,8 +41,6 @@ struct btmrvl_thread {
struct btmrvl_device {
void *card;
struct hci_dev *hcidev;
- struct device *dev;
- const char *cal_data;
u8 dev_type;
@@ -95,7 +91,6 @@ struct btmrvl_private {
#define BT_CMD_HOST_SLEEP_CONFIG 0x59
#define BT_CMD_HOST_SLEEP_ENABLE 0x5A
#define BT_CMD_MODULE_CFG_REQ 0x5B
-#define BT_CMD_LOAD_CONFIG_DATA 0x61
/* Sub-commands: Module Bringup/Shutdown Request/Response */
#define MODULE_BRINGUP_REQ 0xF1
@@ -121,8 +116,11 @@ struct btmrvl_private {
#define PS_SLEEP 0x01
#define PS_AWAKE 0x00
-#define BT_CMD_DATA_SIZE 32
-#define BT_CAL_DATA_SIZE 28
+struct btmrvl_cmd {
+ __le16 ocf_ogf;
+ u8 length;
+ u8 data[4];
+} __packed;
struct btmrvl_event {
u8 ec; /* event counter */
diff --git a/drivers/bluetooth/btmrvl_main.c b/drivers/bluetooth/btmrvl_main.c
index 5cf31c4..9a9f518 100644
--- a/drivers/bluetooth/btmrvl_main.c
+++ b/drivers/bluetooth/btmrvl_main.c
@@ -57,7 +57,8 @@ bool btmrvl_check_evtpkt(struct btmrvl_private *priv, struct sk_buff *skb)
ocf = hci_opcode_ocf(opcode);
ogf = hci_opcode_ogf(opcode);
- if (priv->btmrvl_dev.sendcmdflag) {
+ if (ocf == BT_CMD_MODULE_CFG_REQ &&
+ priv->btmrvl_dev.sendcmdflag) {
priv->btmrvl_dev.sendcmdflag = false;
priv->adapter->cmd_complete = true;
wake_up_interruptible(&priv->adapter->cmd_wait_q);
@@ -115,6 +116,7 @@ int btmrvl_process_event(struct btmrvl_private *priv, struct sk_buff *skb)
adapter->hs_state = HS_ACTIVATED;
if (adapter->psmode)
adapter->ps_state = PS_SLEEP;
+ wake_up_interruptible(&adapter->cmd_wait_q);
BT_DBG("HS ACTIVATED!");
} else {
BT_DBG("HS Enable failed");
@@ -166,50 +168,45 @@ exit:
}
EXPORT_SYMBOL_GPL(btmrvl_process_event);
-static int btmrvl_send_sync_cmd(struct btmrvl_private *priv, u16 cmd_no,
- const void *param, u8 len)
+int btmrvl_send_module_cfg_cmd(struct btmrvl_private *priv, int subcmd)
{
struct sk_buff *skb;
- struct hci_command_hdr *hdr;
+ struct btmrvl_cmd *cmd;
+ int ret = 0;
- skb = bt_skb_alloc(HCI_COMMAND_HDR_SIZE + len, GFP_ATOMIC);
+ skb = bt_skb_alloc(sizeof(*cmd), GFP_ATOMIC);
if (skb == NULL) {
BT_ERR("No free skb");
return -ENOMEM;
}
- hdr = (struct hci_command_hdr *)skb_put(skb, HCI_COMMAND_HDR_SIZE);
- hdr->opcode = cpu_to_le16(hci_opcode_pack(OGF, cmd_no));
- hdr->plen = len;
-
- if (len)
- memcpy(skb_put(skb, len), param, len);
+ cmd = (struct btmrvl_cmd *) skb_put(skb, sizeof(*cmd));
+ cmd->ocf_ogf = cpu_to_le16(hci_opcode_pack(OGF, BT_CMD_MODULE_CFG_REQ));
+ cmd->length = 1;
+ cmd->data[0] = subcmd;
bt_cb(skb)->pkt_type = MRVL_VENDOR_PKT;
+ skb->dev = (void *) priv->btmrvl_dev.hcidev;
skb_queue_head(&priv->adapter->tx_queue, skb);
priv->btmrvl_dev.sendcmdflag = true;
priv->adapter->cmd_complete = false;
+ BT_DBG("Queue module cfg Command");
+
wake_up_interruptible(&priv->main_thread.wait_q);
if (!wait_event_interruptible_timeout(priv->adapter->cmd_wait_q,
priv->adapter->cmd_complete,
- msecs_to_jiffies(WAIT_UNTIL_CMD_RESP)))
- return -ETIMEDOUT;
-
- return 0;
-}
-
-int btmrvl_send_module_cfg_cmd(struct btmrvl_private *priv, int subcmd)
-{
- int ret;
+ msecs_to_jiffies(WAIT_UNTIL_CMD_RESP))) {
+ ret = -ETIMEDOUT;
+ BT_ERR("module_cfg_cmd(%x): timeout: %d",
+ subcmd, priv->btmrvl_dev.sendcmdflag);
+ }
- ret = btmrvl_send_sync_cmd(priv, BT_CMD_MODULE_CFG_REQ, &subcmd, 1);
- if (ret)
- BT_ERR("module_cfg_cmd(%x) failed\n", subcmd);
+ BT_DBG("module cfg Command done");
return ret;
}
@@ -217,36 +214,61 @@ EXPORT_SYMBOL_GPL(btmrvl_send_module_cfg_cmd);
int btmrvl_send_hscfg_cmd(struct btmrvl_private *priv)
{
- int ret;
- u8 param[2];
+ struct sk_buff *skb;
+ struct btmrvl_cmd *cmd;
- param[0] = (priv->btmrvl_dev.gpio_gap & 0xff00) >> 8;
- param[1] = (u8) (priv->btmrvl_dev.gpio_gap & 0x00ff);
+ skb = bt_skb_alloc(sizeof(*cmd), GFP_ATOMIC);
+ if (!skb) {
+ BT_ERR("No free skb");
+ return -ENOMEM;
+ }
- BT_DBG("Sending HSCFG Command, gpio=0x%x, gap=0x%x",
- param[0], param[1]);
+ cmd = (struct btmrvl_cmd *) skb_put(skb, sizeof(*cmd));
+ cmd->ocf_ogf = cpu_to_le16(hci_opcode_pack(OGF,
+ BT_CMD_HOST_SLEEP_CONFIG));
+ cmd->length = 2;
+ cmd->data[0] = (priv->btmrvl_dev.gpio_gap & 0xff00) >> 8;
+ cmd->data[1] = (u8) (priv->btmrvl_dev.gpio_gap & 0x00ff);
- ret = btmrvl_send_sync_cmd(priv, BT_CMD_HOST_SLEEP_CONFIG, param, 2);
- if (ret)
- BT_ERR("HSCFG command failed\n");
+ bt_cb(skb)->pkt_type = MRVL_VENDOR_PKT;
- return ret;
+ skb->dev = (void *) priv->btmrvl_dev.hcidev;
+ skb_queue_head(&priv->adapter->tx_queue, skb);
+
+ BT_DBG("Queue HSCFG Command, gpio=0x%x, gap=0x%x", cmd->data[0],
+ cmd->data[1]);
+
+ return 0;
}
EXPORT_SYMBOL_GPL(btmrvl_send_hscfg_cmd);
int btmrvl_enable_ps(struct btmrvl_private *priv)
{
- int ret;
- u8 param;
+ struct sk_buff *skb;
+ struct btmrvl_cmd *cmd;
+
+ skb = bt_skb_alloc(sizeof(*cmd), GFP_ATOMIC);
+ if (skb == NULL) {
+ BT_ERR("No free skb");
+ return -ENOMEM;
+ }
+
+ cmd = (struct btmrvl_cmd *) skb_put(skb, sizeof(*cmd));
+ cmd->ocf_ogf = cpu_to_le16(hci_opcode_pack(OGF,
+ BT_CMD_AUTO_SLEEP_MODE));
+ cmd->length = 1;
if (priv->btmrvl_dev.psmode)
- param = BT_PS_ENABLE;
+ cmd->data[0] = BT_PS_ENABLE;
else
- param = BT_PS_DISABLE;
+ cmd->data[0] = BT_PS_DISABLE;
- ret = btmrvl_send_sync_cmd(priv, BT_CMD_AUTO_SLEEP_MODE, &param, 1);
- if (ret)
- BT_ERR("PSMODE command failed\n");
+ bt_cb(skb)->pkt_type = MRVL_VENDOR_PKT;
+
+ skb->dev = (void *) priv->btmrvl_dev.hcidev;
+ skb_queue_head(&priv->adapter->tx_queue, skb);
+
+ BT_DBG("Queue PSMODE Command:%d", cmd->data[0]);
return 0;
}
@@ -254,11 +276,37 @@ EXPORT_SYMBOL_GPL(btmrvl_enable_ps);
int btmrvl_enable_hs(struct btmrvl_private *priv)
{
- int ret;
+ struct sk_buff *skb;
+ struct btmrvl_cmd *cmd;
+ int ret = 0;
+
+ skb = bt_skb_alloc(sizeof(*cmd), GFP_ATOMIC);
+ if (skb == NULL) {
+ BT_ERR("No free skb");
+ return -ENOMEM;
+ }
- ret = btmrvl_send_sync_cmd(priv, BT_CMD_HOST_SLEEP_ENABLE, NULL, 0);
- if (ret)
- BT_ERR("Host sleep enable command failed\n");
+ cmd = (struct btmrvl_cmd *) skb_put(skb, sizeof(*cmd));
+ cmd->ocf_ogf = cpu_to_le16(hci_opcode_pack(OGF, BT_CMD_HOST_SLEEP_ENABLE));
+ cmd->length = 0;
+
+ bt_cb(skb)->pkt_type = MRVL_VENDOR_PKT;
+
+ skb->dev = (void *) priv->btmrvl_dev.hcidev;
+ skb_queue_head(&priv->adapter->tx_queue, skb);
+
+ BT_DBG("Queue hs enable Command");
+
+ wake_up_interruptible(&priv->main_thread.wait_q);
+
+ if (!wait_event_interruptible_timeout(priv->adapter->cmd_wait_q,
+ priv->adapter->hs_state,
+ msecs_to_jiffies(WAIT_UNTIL_HS_STATE_CHANGED))) {
+ ret = -ETIMEDOUT;
+ BT_ERR("timeout: %d, %d,%d", priv->adapter->hs_state,
+ priv->adapter->ps_state,
+ priv->adapter->wakeup_tries);
+ }
return ret;
}
@@ -355,12 +403,26 @@ static void btmrvl_free_adapter(struct btmrvl_private *priv)
priv->adapter = NULL;
}
-static int btmrvl_send_frame(struct hci_dev *hdev, struct sk_buff *skb)
+static int btmrvl_ioctl(struct hci_dev *hdev,
+ unsigned int cmd, unsigned long arg)
{
- struct btmrvl_private *priv = hci_get_drvdata(hdev);
+ return -ENOIOCTLCMD;
+}
+
+static int btmrvl_send_frame(struct sk_buff *skb)
+{
+ struct hci_dev *hdev = (struct hci_dev *) skb->dev;
+ struct btmrvl_private *priv = NULL;
BT_DBG("type=%d, len=%d", skb->pkt_type, skb->len);
+ if (!hdev) {
+ BT_ERR("Frame for unknown HCI device");
+ return -ENODEV;
+ }
+
+ priv = hci_get_drvdata(hdev);
+
if (!test_bit(HCI_RUNNING, &hdev->flags)) {
BT_ERR("Failed testing HCI_RUNING, flags=%lx", hdev->flags);
print_hex_dump_bytes("data: ", DUMP_PREFIX_OFFSET,
@@ -418,137 +480,6 @@ static int btmrvl_open(struct hci_dev *hdev)
}
/*
- * This function parses provided calibration data input. It should contain
- * hex bytes separated by space or new line character. Here is an example.
- * 00 1C 01 37 FF FF FF FF 02 04 7F 01
- * CE BA 00 00 00 2D C6 C0 00 00 00 00
- * 00 F0 00 00
- */
-static int btmrvl_parse_cal_cfg(const u8 *src, u32 len, u8 *dst, u32 dst_size)
-{
- const u8 *s = src;
- u8 *d = dst;
- int ret;
- u8 tmp[3];
-
- tmp[2] = '\0';
- while ((s - src) <= len - 2) {
- if (isspace(*s)) {
- s++;
- continue;
- }
-
- if (isxdigit(*s)) {
- if ((d - dst) >= dst_size) {
- BT_ERR("calibration data file too big!!!");
- return -EINVAL;
- }
-
- memcpy(tmp, s, 2);
-
- ret = kstrtou8(tmp, 16, d++);
- if (ret < 0)
- return ret;
-
- s += 2;
- } else {
- return -EINVAL;
- }
- }
- if (d == dst)
- return -EINVAL;
-
- return 0;
-}
-
-static int btmrvl_load_cal_data(struct btmrvl_private *priv,
- u8 *config_data)
-{
- int i, ret;
- u8 data[BT_CMD_DATA_SIZE];
-
- data[0] = 0x00;
- data[1] = 0x00;
- data[2] = 0x00;
- data[3] = BT_CMD_DATA_SIZE - 4;
-
- /* Swap cal-data bytes. Each four bytes are swapped. Considering 4
- * byte SDIO header offset, mapping of input and output bytes will be
- * {3, 2, 1, 0} -> {0+4, 1+4, 2+4, 3+4},
- * {7, 6, 5, 4} -> {4+4, 5+4, 6+4, 7+4} */
- for (i = 4; i < BT_CMD_DATA_SIZE; i++)
- data[i] = config_data[(i / 4) * 8 - 1 - i];
-
- print_hex_dump_bytes("Calibration data: ",
- DUMP_PREFIX_OFFSET, data, BT_CMD_DATA_SIZE);
-
- ret = btmrvl_send_sync_cmd(priv, BT_CMD_LOAD_CONFIG_DATA, data,
- BT_CMD_DATA_SIZE);
- if (ret)
- BT_ERR("Failed to download caibration data\n");
-
- return 0;
-}
-
-static int
-btmrvl_process_cal_cfg(struct btmrvl_private *priv, u8 *data, u32 size)
-{
- u8 cal_data[BT_CAL_DATA_SIZE];
- int ret;
-
- ret = btmrvl_parse_cal_cfg(data, size, cal_data, sizeof(cal_data));
- if (ret)
- return ret;
-
- ret = btmrvl_load_cal_data(priv, cal_data);
- if (ret) {
- BT_ERR("Fail to load calibrate data");
- return ret;
- }
-
- return 0;
-}
-
-static int btmrvl_cal_data_config(struct btmrvl_private *priv)
-{
- const struct firmware *cfg;
- int ret;
- const char *cal_data = priv->btmrvl_dev.cal_data;
-
- if (!cal_data)
- return 0;
-
- ret = request_firmware(&cfg, cal_data, priv->btmrvl_dev.dev);
- if (ret < 0) {
- BT_DBG("Failed to get %s file, skipping cal data download",
- cal_data);
- return 0;
- }
-
- ret = btmrvl_process_cal_cfg(priv, (u8 *)cfg->data, cfg->size);
- release_firmware(cfg);
- return ret;
-}
-
-static int btmrvl_setup(struct hci_dev *hdev)
-{
- struct btmrvl_private *priv = hci_get_drvdata(hdev);
-
- btmrvl_send_module_cfg_cmd(priv, MODULE_BRINGUP_REQ);
-
- if (btmrvl_cal_data_config(priv))
- BT_ERR("Set cal data failed");
-
- priv->btmrvl_dev.psmode = 1;
- btmrvl_enable_ps(priv);
-
- priv->btmrvl_dev.gpio_gap = 0xffff;
- btmrvl_send_hscfg_cmd(priv);
-
- return 0;
-}
-
-/*
* This function handles the event generated by firmware, rx data
* received from firmware, and tx data sent from kernel.
*/
@@ -635,12 +566,14 @@ int btmrvl_register_hdev(struct btmrvl_private *priv)
priv->btmrvl_dev.hcidev = hdev;
hci_set_drvdata(hdev, priv);
- hdev->bus = HCI_SDIO;
- hdev->open = btmrvl_open;
+ hdev->bus = HCI_SDIO;
+ hdev->open = btmrvl_open;
hdev->close = btmrvl_close;
hdev->flush = btmrvl_flush;
- hdev->send = btmrvl_send_frame;
- hdev->setup = btmrvl_setup;
+ hdev->send = btmrvl_send_frame;
+ hdev->ioctl = btmrvl_ioctl;
+
+ btmrvl_send_module_cfg_cmd(priv, MODULE_BRINGUP_REQ);
hdev->dev_type = priv->btmrvl_dev.dev_type;
diff --git a/drivers/bluetooth/btmrvl_sdio.c b/drivers/bluetooth/btmrvl_sdio.c
index fabcf5b..00da6df 100644
--- a/drivers/bluetooth/btmrvl_sdio.c
+++ b/drivers/bluetooth/btmrvl_sdio.c
@@ -18,6 +18,7 @@
* this warranty disclaimer.
**/
+#include <linux/firmware.h>
#include <linux/slab.h>
#include <linux/mmc/sdio_ids.h>
@@ -101,7 +102,6 @@ static const struct btmrvl_sdio_card_reg btmrvl_reg_88xx = {
static const struct btmrvl_sdio_device btmrvl_sdio_sd8688 = {
.helper = "mrvl/sd8688_helper.bin",
.firmware = "mrvl/sd8688.bin",
- .cal_data = NULL,
.reg = &btmrvl_reg_8688,
.sd_blksz_fw_dl = 64,
};
@@ -109,7 +109,6 @@ static const struct btmrvl_sdio_device btmrvl_sdio_sd8688 = {
static const struct btmrvl_sdio_device btmrvl_sdio_sd8787 = {
.helper = NULL,
.firmware = "mrvl/sd8787_uapsta.bin",
- .cal_data = NULL,
.reg = &btmrvl_reg_87xx,
.sd_blksz_fw_dl = 256,
};
@@ -117,7 +116,6 @@ static const struct btmrvl_sdio_device btmrvl_sdio_sd8787 = {
static const struct btmrvl_sdio_device btmrvl_sdio_sd8797 = {
.helper = NULL,
.firmware = "mrvl/sd8797_uapsta.bin",
- .cal_data = "mrvl/sd8797_caldata.conf",
.reg = &btmrvl_reg_87xx,
.sd_blksz_fw_dl = 256,
};
@@ -125,7 +123,6 @@ static const struct btmrvl_sdio_device btmrvl_sdio_sd8797 = {
static const struct btmrvl_sdio_device btmrvl_sdio_sd8897 = {
.helper = NULL,
.firmware = "mrvl/sd8897_uapsta.bin",
- .cal_data = NULL,
.reg = &btmrvl_reg_88xx,
.sd_blksz_fw_dl = 256,
};
@@ -600,14 +597,15 @@ static int btmrvl_sdio_card_to_host(struct btmrvl_private *priv)
case HCI_SCODATA_PKT:
case HCI_EVENT_PKT:
bt_cb(skb)->pkt_type = type;
+ skb->dev = (void *)hdev;
skb_put(skb, buf_len);
skb_pull(skb, SDIO_HEADER_LEN);
if (type == HCI_EVENT_PKT) {
if (btmrvl_check_evtpkt(priv, skb))
- hci_recv_frame(hdev, skb);
+ hci_recv_frame(skb);
} else {
- hci_recv_frame(hdev, skb);
+ hci_recv_frame(skb);
}
hdev->stat.byte_rx += buf_len;
@@ -615,11 +613,12 @@ static int btmrvl_sdio_card_to_host(struct btmrvl_private *priv)
case MRVL_VENDOR_PKT:
bt_cb(skb)->pkt_type = HCI_VENDOR_PKT;
+ skb->dev = (void *)hdev;
skb_put(skb, buf_len);
skb_pull(skb, SDIO_HEADER_LEN);
if (btmrvl_process_event(priv, skb))
- hci_recv_frame(hdev, skb);
+ hci_recv_frame(skb);
hdev->stat.byte_rx += buf_len;
break;
@@ -1007,7 +1006,6 @@ static int btmrvl_sdio_probe(struct sdio_func *func,
struct btmrvl_sdio_device *data = (void *) id->driver_data;
card->helper = data->helper;
card->firmware = data->firmware;
- card->cal_data = data->cal_data;
card->reg = data->reg;
card->sd_blksz_fw_dl = data->sd_blksz_fw_dl;
}
@@ -1036,8 +1034,6 @@ static int btmrvl_sdio_probe(struct sdio_func *func,
}
card->priv = priv;
- priv->btmrvl_dev.dev = &card->func->dev;
- priv->btmrvl_dev.cal_data = card->cal_data;
/* Initialize the interface specific function pointers */
priv->hw_host_to_card = btmrvl_sdio_host_to_card;
@@ -1050,6 +1046,12 @@ static int btmrvl_sdio_probe(struct sdio_func *func,
goto disable_host_int;
}
+ priv->btmrvl_dev.psmode = 1;
+ btmrvl_enable_ps(priv);
+
+ priv->btmrvl_dev.gpio_gap = 0xffff;
+ btmrvl_send_hscfg_cmd(priv);
+
return 0;
disable_host_int:
@@ -1220,5 +1222,4 @@ MODULE_FIRMWARE("mrvl/sd8688_helper.bin");
MODULE_FIRMWARE("mrvl/sd8688.bin");
MODULE_FIRMWARE("mrvl/sd8787_uapsta.bin");
MODULE_FIRMWARE("mrvl/sd8797_uapsta.bin");
-MODULE_FIRMWARE("mrvl/sd8797_caldata.conf");
MODULE_FIRMWARE("mrvl/sd8897_uapsta.bin");
diff --git a/drivers/bluetooth/btmrvl_sdio.h b/drivers/bluetooth/btmrvl_sdio.h
index 6872d9e..43d35a6 100644
--- a/drivers/bluetooth/btmrvl_sdio.h
+++ b/drivers/bluetooth/btmrvl_sdio.h
@@ -85,7 +85,6 @@ struct btmrvl_sdio_card {
u32 ioport;
const char *helper;
const char *firmware;
- const char *cal_data;
const struct btmrvl_sdio_card_reg *reg;
u16 sd_blksz_fw_dl;
u8 rx_unit;
@@ -95,7 +94,6 @@ struct btmrvl_sdio_card {
struct btmrvl_sdio_device {
const char *helper;
const char *firmware;
- const char *cal_data;
const struct btmrvl_sdio_card_reg *reg;
u16 sd_blksz_fw_dl;
};
diff --git a/drivers/bluetooth/btsdio.c b/drivers/bluetooth/btsdio.c
index b61440a..4a99097 100644
--- a/drivers/bluetooth/btsdio.c
+++ b/drivers/bluetooth/btsdio.c
@@ -157,9 +157,10 @@ static int btsdio_rx_packet(struct btsdio_data *data)
data->hdev->stat.byte_rx += len;
+ skb->dev = (void *) data->hdev;
bt_cb(skb)->pkt_type = hdr[3];
- err = hci_recv_frame(data->hdev, skb);
+ err = hci_recv_frame(skb);
if (err < 0)
return err;
@@ -254,8 +255,9 @@ static int btsdio_flush(struct hci_dev *hdev)
return 0;
}
-static int btsdio_send_frame(struct hci_dev *hdev, struct sk_buff *skb)
+static int btsdio_send_frame(struct sk_buff *skb)
{
+ struct hci_dev *hdev = (struct hci_dev *) skb->dev;
struct btsdio_data *data = hci_get_drvdata(hdev);
BT_DBG("%s", hdev->name);
diff --git a/drivers/bluetooth/btuart_cs.c b/drivers/bluetooth/btuart_cs.c
index a03ecc2..beb262f 100644
--- a/drivers/bluetooth/btuart_cs.c
+++ b/drivers/bluetooth/btuart_cs.c
@@ -198,6 +198,7 @@ static void btuart_receive(btuart_info_t *info)
if (info->rx_state == RECV_WAIT_PACKET_TYPE) {
+ info->rx_skb->dev = (void *) info->hdev;
bt_cb(info->rx_skb)->pkt_type = inb(iobase + UART_RX);
switch (bt_cb(info->rx_skb)->pkt_type) {
@@ -264,7 +265,7 @@ static void btuart_receive(btuart_info_t *info)
break;
case RECV_WAIT_DATA:
- hci_recv_frame(info->hdev, info->rx_skb);
+ hci_recv_frame(info->rx_skb);
info->rx_skb = NULL;
break;
@@ -423,9 +424,17 @@ static int btuart_hci_close(struct hci_dev *hdev)
}
-static int btuart_hci_send_frame(struct hci_dev *hdev, struct sk_buff *skb)
+static int btuart_hci_send_frame(struct sk_buff *skb)
{
- btuart_info_t *info = hci_get_drvdata(hdev);
+ btuart_info_t *info;
+ struct hci_dev *hdev = (struct hci_dev *)(skb->dev);
+
+ if (!hdev) {
+ BT_ERR("Frame for unknown HCI device (hdev=NULL)");
+ return -ENODEV;
+ }
+
+ info = hci_get_drvdata(hdev);
switch (bt_cb(skb)->pkt_type) {
case HCI_COMMAND_PKT:
@@ -449,6 +458,12 @@ static int btuart_hci_send_frame(struct hci_dev *hdev, struct sk_buff *skb)
}
+static int btuart_hci_ioctl(struct hci_dev *hdev, unsigned int cmd, unsigned long arg)
+{
+ return -ENOIOCTLCMD;
+}
+
+
/* ======================== Card services HCI interaction ======================== */
@@ -480,10 +495,11 @@ static int btuart_open(btuart_info_t *info)
hci_set_drvdata(hdev, info);
SET_HCIDEV_DEV(hdev, &info->p_dev->dev);
- hdev->open = btuart_hci_open;
- hdev->close = btuart_hci_close;
- hdev->flush = btuart_hci_flush;
- hdev->send = btuart_hci_send_frame;
+ hdev->open = btuart_hci_open;
+ hdev->close = btuart_hci_close;
+ hdev->flush = btuart_hci_flush;
+ hdev->send = btuart_hci_send_frame;
+ hdev->ioctl = btuart_hci_ioctl;
spin_lock_irqsave(&(info->lock), flags);
diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c
index c0ff34f..f3dfc0a 100644
--- a/drivers/bluetooth/btusb.c
+++ b/drivers/bluetooth/btusb.c
@@ -50,7 +50,7 @@ static struct usb_driver btusb_driver;
#define BTUSB_ATH3012 0x80
#define BTUSB_INTEL 0x100
-static const struct usb_device_id btusb_table[] = {
+static struct usb_device_id btusb_table[] = {
/* Generic Bluetooth USB device */
{ USB_DEVICE_INFO(0xe0, 0x01, 0x01) },
@@ -121,7 +121,7 @@ static const struct usb_device_id btusb_table[] = {
MODULE_DEVICE_TABLE(usb, btusb_table);
-static const struct usb_device_id blacklist_table[] = {
+static struct usb_device_id blacklist_table[] = {
/* CSR BlueCore devices */
{ USB_DEVICE(0x0a12, 0x0001), .driver_info = BTUSB_CSR },
@@ -716,8 +716,9 @@ static int btusb_flush(struct hci_dev *hdev)
return 0;
}
-static int btusb_send_frame(struct hci_dev *hdev, struct sk_buff *skb)
+static int btusb_send_frame(struct sk_buff *skb)
{
+ struct hci_dev *hdev = (struct hci_dev *) skb->dev;
struct btusb_data *data = hci_get_drvdata(hdev);
struct usb_ctrlrequest *dr;
struct urb *urb;
@@ -729,8 +730,6 @@ static int btusb_send_frame(struct hci_dev *hdev, struct sk_buff *skb)
if (!test_bit(HCI_RUNNING, &hdev->flags))
return -EBUSY;
- skb->dev = (void *) hdev;
-
switch (bt_cb(skb)->pkt_type) {
case HCI_COMMAND_PKT:
urb = usb_alloc_urb(0, GFP_ATOMIC);
@@ -775,7 +774,7 @@ static int btusb_send_frame(struct hci_dev *hdev, struct sk_buff *skb)
break;
case HCI_SCODATA_PKT:
- if (!data->isoc_tx_ep || hci_conn_num(hdev, SCO_LINK) < 1)
+ if (!data->isoc_tx_ep || hdev->conn_hash.sco_num < 1)
return -ENODEV;
urb = usb_alloc_urb(BTUSB_MAX_ISOC_FRAMES, GFP_ATOMIC);
@@ -834,8 +833,8 @@ static void btusb_notify(struct hci_dev *hdev, unsigned int evt)
BT_DBG("%s evt %d", hdev->name, evt);
- if (hci_conn_num(hdev, SCO_LINK) != data->sco_num) {
- data->sco_num = hci_conn_num(hdev, SCO_LINK);
+ if (hdev->conn_hash.sco_num != data->sco_num) {
+ data->sco_num = hdev->conn_hash.sco_num;
schedule_work(&data->work);
}
}
@@ -890,7 +889,7 @@ static void btusb_work(struct work_struct *work)
int new_alts;
int err;
- if (data->sco_num > 0) {
+ if (hdev->conn_hash.sco_num > 0) {
if (!test_bit(BTUSB_DID_ISO_RESUME, &data->flags)) {
err = usb_autopm_get_interface(data->isoc ? data->isoc : data->intf);
if (err < 0) {
@@ -904,9 +903,9 @@ static void btusb_work(struct work_struct *work)
if (hdev->voice_setting & 0x0020) {
static const int alts[3] = { 2, 4, 5 };
- new_alts = alts[data->sco_num - 1];
+ new_alts = alts[hdev->conn_hash.sco_num - 1];
} else {
- new_alts = data->sco_num;
+ new_alts = hdev->conn_hash.sco_num;
}
if (data->isoc_altsetting != new_alts) {
@@ -1629,6 +1628,7 @@ static struct usb_driver btusb_driver = {
#ifdef CONFIG_PM
.suspend = btusb_suspend,
.resume = btusb_resume,
+ .reset_resume = btusb_resume,
#endif
.id_table = btusb_table,
.supports_autosuspend = 1,
diff --git a/drivers/bluetooth/btwilink.c b/drivers/bluetooth/btwilink.c
index f038dba..60abf59 100644
--- a/drivers/bluetooth/btwilink.c
+++ b/drivers/bluetooth/btwilink.c
@@ -108,8 +108,10 @@ static long st_receive(void *priv_data, struct sk_buff *skb)
return -EFAULT;
}
+ skb->dev = (void *) lhst->hdev;
+
/* Forward skb to HCI core layer */
- err = hci_recv_frame(lhst->hdev, skb);
+ err = hci_recv_frame(skb);
if (err < 0) {
BT_ERR("Unable to push skb to HCI core(%d)", err);
return err;
@@ -251,11 +253,14 @@ static int ti_st_close(struct hci_dev *hdev)
return err;
}
-static int ti_st_send_frame(struct hci_dev *hdev, struct sk_buff *skb)
+static int ti_st_send_frame(struct sk_buff *skb)
{
+ struct hci_dev *hdev;
struct ti_st *hst;
long len;
+ hdev = (struct hci_dev *)skb->dev;
+
if (!test_bit(HCI_RUNNING, &hdev->flags))
return -EBUSY;
diff --git a/drivers/bluetooth/dtl1_cs.c b/drivers/bluetooth/dtl1_cs.c
index 52eed1f..33f3a69 100644
--- a/drivers/bluetooth/dtl1_cs.c
+++ b/drivers/bluetooth/dtl1_cs.c
@@ -256,8 +256,9 @@ static void dtl1_receive(dtl1_info_t *info)
case 0x83:
case 0x84:
/* send frame to the HCI layer */
+ info->rx_skb->dev = (void *) info->hdev;
bt_cb(info->rx_skb)->pkt_type &= 0x0f;
- hci_recv_frame(info->hdev, info->rx_skb);
+ hci_recv_frame(info->rx_skb);
break;
default:
/* unknown packet */
@@ -382,12 +383,20 @@ static int dtl1_hci_close(struct hci_dev *hdev)
}
-static int dtl1_hci_send_frame(struct hci_dev *hdev, struct sk_buff *skb)
+static int dtl1_hci_send_frame(struct sk_buff *skb)
{
- dtl1_info_t *info = hci_get_drvdata(hdev);
+ dtl1_info_t *info;
+ struct hci_dev *hdev = (struct hci_dev *)(skb->dev);
struct sk_buff *s;
nsh_t nsh;
+ if (!hdev) {
+ BT_ERR("Frame for unknown HCI device (hdev=NULL)");
+ return -ENODEV;
+ }
+
+ info = hci_get_drvdata(hdev);
+
switch (bt_cb(skb)->pkt_type) {
case HCI_COMMAND_PKT:
hdev->stat.cmd_tx++;
@@ -429,6 +438,12 @@ static int dtl1_hci_send_frame(struct hci_dev *hdev, struct sk_buff *skb)
}
+static int dtl1_hci_ioctl(struct hci_dev *hdev, unsigned int cmd, unsigned long arg)
+{
+ return -ENOIOCTLCMD;
+}
+
+
/* ======================== Card services HCI interaction ======================== */
@@ -462,10 +477,11 @@ static int dtl1_open(dtl1_info_t *info)
hci_set_drvdata(hdev, info);
SET_HCIDEV_DEV(hdev, &info->p_dev->dev);
- hdev->open = dtl1_hci_open;
- hdev->close = dtl1_hci_close;
- hdev->flush = dtl1_hci_flush;
- hdev->send = dtl1_hci_send_frame;
+ hdev->open = dtl1_hci_open;
+ hdev->close = dtl1_hci_close;
+ hdev->flush = dtl1_hci_flush;
+ hdev->send = dtl1_hci_send_frame;
+ hdev->ioctl = dtl1_hci_ioctl;
spin_lock_irqsave(&(info->lock), flags);
diff --git a/drivers/bluetooth/hci_bcsp.c b/drivers/bluetooth/hci_bcsp.c
index 0bc87f7..57e502e 100644
--- a/drivers/bluetooth/hci_bcsp.c
+++ b/drivers/bluetooth/hci_bcsp.c
@@ -522,7 +522,7 @@ static void bcsp_complete_rx_pkt(struct hci_uart *hu)
memcpy(skb_push(bcsp->rx_skb, HCI_EVENT_HDR_SIZE), &hdr, HCI_EVENT_HDR_SIZE);
bt_cb(bcsp->rx_skb)->pkt_type = HCI_EVENT_PKT;
- hci_recv_frame(hu->hdev, bcsp->rx_skb);
+ hci_recv_frame(bcsp->rx_skb);
} else {
BT_ERR ("Packet for unknown channel (%u %s)",
bcsp->rx_skb->data[1] & 0x0f,
@@ -536,7 +536,7 @@ static void bcsp_complete_rx_pkt(struct hci_uart *hu)
/* Pull out BCSP hdr */
skb_pull(bcsp->rx_skb, 4);
- hci_recv_frame(hu->hdev, bcsp->rx_skb);
+ hci_recv_frame(bcsp->rx_skb);
}
bcsp->rx_state = BCSP_W4_PKT_DELIMITER;
@@ -655,6 +655,7 @@ static int bcsp_recv(struct hci_uart *hu, void *data, int count)
bcsp->rx_count = 0;
return 0;
}
+ bcsp->rx_skb->dev = (void *) hu->hdev;
break;
}
break;
diff --git a/drivers/bluetooth/hci_h4.c b/drivers/bluetooth/hci_h4.c
index 7048a58..8ae9f1e 100644
--- a/drivers/bluetooth/hci_h4.c
+++ b/drivers/bluetooth/hci_h4.c
@@ -124,6 +124,30 @@ static int h4_enqueue(struct hci_uart *hu, struct sk_buff *skb)
return 0;
}
+static inline int h4_check_data_len(struct h4_struct *h4, int len)
+{
+ int room = skb_tailroom(h4->rx_skb);
+
+ BT_DBG("len %d room %d", len, room);
+
+ if (!len) {
+ hci_recv_frame(h4->rx_skb);
+ } else if (len > room) {
+ BT_ERR("Data length is too large");
+ kfree_skb(h4->rx_skb);
+ } else {
+ h4->rx_state = H4_W4_DATA;
+ h4->rx_count = len;
+ return len;
+ }
+
+ h4->rx_state = H4_W4_PACKET_TYPE;
+ h4->rx_skb = NULL;
+ h4->rx_count = 0;
+
+ return 0;
+}
+
/* Recv data */
static int h4_recv(struct hci_uart *hu, void *data, int count)
{
diff --git a/drivers/bluetooth/hci_h5.c b/drivers/bluetooth/hci_h5.c
index f6f4974..b6154d5 100644
--- a/drivers/bluetooth/hci_h5.c
+++ b/drivers/bluetooth/hci_h5.c
@@ -340,7 +340,7 @@ static void h5_complete_rx_pkt(struct hci_uart *hu)
/* Remove Three-wire header */
skb_pull(h5->rx_skb, 4);
- hci_recv_frame(hu->hdev, h5->rx_skb);
+ hci_recv_frame(h5->rx_skb);
h5->rx_skb = NULL;
break;
diff --git a/drivers/bluetooth/hci_ldisc.c b/drivers/bluetooth/hci_ldisc.c
index 6e06f6f..bc68a44 100644
--- a/drivers/bluetooth/hci_ldisc.c
+++ b/drivers/bluetooth/hci_ldisc.c
@@ -234,13 +234,21 @@ static int hci_uart_close(struct hci_dev *hdev)
}
/* Send frames from HCI layer */
-static int hci_uart_send_frame(struct hci_dev *hdev, struct sk_buff *skb)
+static int hci_uart_send_frame(struct sk_buff *skb)
{
- struct hci_uart *hu = hci_get_drvdata(hdev);
+ struct hci_dev* hdev = (struct hci_dev *) skb->dev;
+ struct hci_uart *hu;
+
+ if (!hdev) {
+ BT_ERR("Frame for unknown device (hdev=NULL)");
+ return -ENODEV;
+ }
if (!test_bit(HCI_RUNNING, &hdev->flags))
return -EBUSY;
+ hu = hci_get_drvdata(hdev);
+
BT_DBG("%s: type %d len %d", hdev->name, bt_cb(skb)->pkt_type, skb->len);
hu->proto->enqueue(hu, skb);
diff --git a/drivers/bluetooth/hci_ll.c b/drivers/bluetooth/hci_ll.c
index 69a90b1..cfc7679 100644
--- a/drivers/bluetooth/hci_ll.c
+++ b/drivers/bluetooth/hci_ll.c
@@ -110,6 +110,7 @@ static int send_hcill_cmd(u8 cmd, struct hci_uart *hu)
/* prepare packet */
hcill_packet = (struct hcill_cmd *) skb_put(skb, 1);
hcill_packet->cmd = cmd;
+ skb->dev = (void *) hu->hdev;
/* send packet */
skb_queue_tail(&ll->txq, skb);
@@ -345,14 +346,14 @@ static int ll_enqueue(struct hci_uart *hu, struct sk_buff *skb)
return 0;
}
-static inline int ll_check_data_len(struct hci_dev *hdev, struct ll_struct *ll, int len)
+static inline int ll_check_data_len(struct ll_struct *ll, int len)
{
int room = skb_tailroom(ll->rx_skb);
BT_DBG("len %d room %d", len, room);
if (!len) {
- hci_recv_frame(hdev, ll->rx_skb);
+ hci_recv_frame(ll->rx_skb);
} else if (len > room) {
BT_ERR("Data length is too large");
kfree_skb(ll->rx_skb);
@@ -394,7 +395,7 @@ static int ll_recv(struct hci_uart *hu, void *data, int count)
switch (ll->rx_state) {
case HCILL_W4_DATA:
BT_DBG("Complete data");
- hci_recv_frame(hu->hdev, ll->rx_skb);
+ hci_recv_frame(ll->rx_skb);
ll->rx_state = HCILL_W4_PACKET_TYPE;
ll->rx_skb = NULL;
@@ -405,7 +406,7 @@ static int ll_recv(struct hci_uart *hu, void *data, int count)
BT_DBG("Event header: evt 0x%2.2x plen %d", eh->evt, eh->plen);
- ll_check_data_len(hu->hdev, ll, eh->plen);
+ ll_check_data_len(ll, eh->plen);
continue;
case HCILL_W4_ACL_HDR:
@@ -414,7 +415,7 @@ static int ll_recv(struct hci_uart *hu, void *data, int count)
BT_DBG("ACL header: dlen %d", dlen);
- ll_check_data_len(hu->hdev, ll, dlen);
+ ll_check_data_len(ll, dlen);
continue;
case HCILL_W4_SCO_HDR:
@@ -422,7 +423,7 @@ static int ll_recv(struct hci_uart *hu, void *data, int count)
BT_DBG("SCO header: dlen %d", sh->dlen);
- ll_check_data_len(hu->hdev, ll, sh->dlen);
+ ll_check_data_len(ll, sh->dlen);
continue;
}
}
@@ -493,6 +494,7 @@ static int ll_recv(struct hci_uart *hu, void *data, int count)
return -ENOMEM;
}
+ ll->rx_skb->dev = (void *) hu->hdev;
bt_cb(ll->rx_skb)->pkt_type = type;
}
diff --git a/drivers/bluetooth/hci_vhci.c b/drivers/bluetooth/hci_vhci.c
index 7b16738..d8b7aed 100644
--- a/drivers/bluetooth/hci_vhci.c
+++ b/drivers/bluetooth/hci_vhci.c
@@ -24,7 +24,6 @@
*/
#include <linux/module.h>
-#include <asm/unaligned.h>
#include <linux/kernel.h>
#include <linux/init.h>
@@ -40,17 +39,17 @@
#include <net/bluetooth/bluetooth.h>
#include <net/bluetooth/hci_core.h>
-#define VERSION "1.4"
+#define VERSION "1.3"
static bool amp;
struct vhci_data {
struct hci_dev *hdev;
+ unsigned long flags;
+
wait_queue_head_t read_wait;
struct sk_buff_head readq;
-
- struct delayed_work open_timeout;
};
static int vhci_open_dev(struct hci_dev *hdev)
@@ -81,73 +80,35 @@ static int vhci_flush(struct hci_dev *hdev)
return 0;
}
-static int vhci_send_frame(struct hci_dev *hdev, struct sk_buff *skb)
-{
- struct vhci_data *data = hci_get_drvdata(hdev);
-
- if (!test_bit(HCI_RUNNING, &hdev->flags))
- return -EBUSY;
-
- memcpy(skb_push(skb, 1), &bt_cb(skb)->pkt_type, 1);
- skb_queue_tail(&data->readq, skb);
-
- wake_up_interruptible(&data->read_wait);
- return 0;
-}
-
-static int vhci_create_device(struct vhci_data *data, __u8 dev_type)
+static int vhci_send_frame(struct sk_buff *skb)
{
- struct hci_dev *hdev;
- struct sk_buff *skb;
-
- skb = bt_skb_alloc(4, GFP_KERNEL);
- if (!skb)
- return -ENOMEM;
+ struct hci_dev* hdev = (struct hci_dev *) skb->dev;
+ struct vhci_data *data;
- hdev = hci_alloc_dev();
if (!hdev) {
- kfree_skb(skb);
- return -ENOMEM;
+ BT_ERR("Frame for unknown HCI device (hdev=NULL)");
+ return -ENODEV;
}
- data->hdev = hdev;
-
- hdev->bus = HCI_VIRTUAL;
- hdev->dev_type = dev_type;
- hci_set_drvdata(hdev, data);
-
- hdev->open = vhci_open_dev;
- hdev->close = vhci_close_dev;
- hdev->flush = vhci_flush;
- hdev->send = vhci_send_frame;
-
- if (hci_register_dev(hdev) < 0) {
- BT_ERR("Can't register HCI device");
- hci_free_dev(hdev);
- data->hdev = NULL;
- kfree_skb(skb);
+ if (!test_bit(HCI_RUNNING, &hdev->flags))
return -EBUSY;
- }
- bt_cb(skb)->pkt_type = HCI_VENDOR_PKT;
+ data = hci_get_drvdata(hdev);
- *skb_put(skb, 1) = 0xff;
- *skb_put(skb, 1) = dev_type;
- put_unaligned_le16(hdev->id, skb_put(skb, 2));
+ memcpy(skb_push(skb, 1), &bt_cb(skb)->pkt_type, 1);
skb_queue_tail(&data->readq, skb);
wake_up_interruptible(&data->read_wait);
+
return 0;
}
static inline ssize_t vhci_get_user(struct vhci_data *data,
- const char __user *buf, size_t count)
+ const char __user *buf, size_t count)
{
struct sk_buff *skb;
- __u8 pkt_type, dev_type;
- int ret;
- if (count < 2 || count > HCI_MAX_FRAME_SIZE)
+ if (count > HCI_MAX_FRAME_SIZE)
return -EINVAL;
skb = bt_skb_alloc(count, GFP_KERNEL);
@@ -159,69 +120,27 @@ static inline ssize_t vhci_get_user(struct vhci_data *data,
return -EFAULT;
}
- pkt_type = *((__u8 *) skb->data);
+ skb->dev = (void *) data->hdev;
+ bt_cb(skb)->pkt_type = *((__u8 *) skb->data);
skb_pull(skb, 1);
- switch (pkt_type) {
- case HCI_EVENT_PKT:
- case HCI_ACLDATA_PKT:
- case HCI_SCODATA_PKT:
- if (!data->hdev) {
- kfree_skb(skb);
- return -ENODEV;
- }
-
- bt_cb(skb)->pkt_type = pkt_type;
-
- ret = hci_recv_frame(data->hdev, skb);
- break;
+ hci_recv_frame(skb);
- case HCI_VENDOR_PKT:
- if (data->hdev) {
- kfree_skb(skb);
- return -EBADFD;
- }
-
- cancel_delayed_work_sync(&data->open_timeout);
-
- dev_type = *((__u8 *) skb->data);
- skb_pull(skb, 1);
-
- if (skb->len > 0) {
- kfree_skb(skb);
- return -EINVAL;
- }
-
- kfree_skb(skb);
-
- if (dev_type != HCI_BREDR && dev_type != HCI_AMP)
- return -EINVAL;
-
- ret = vhci_create_device(data, dev_type);
- break;
-
- default:
- kfree_skb(skb);
- return -EINVAL;
- }
-
- return (ret < 0) ? ret : count;
+ return count;
}
static inline ssize_t vhci_put_user(struct vhci_data *data,
- struct sk_buff *skb,
- char __user *buf, int count)
+ struct sk_buff *skb, char __user *buf, int count)
{
char __user *ptr = buf;
- int len;
+ int len, total = 0;
len = min_t(unsigned int, skb->len, count);
if (copy_to_user(ptr, skb->data, len))
return -EFAULT;
- if (!data->hdev)
- return len;
+ total += len;
data->hdev->stat.byte_tx += len;
@@ -229,19 +148,21 @@ static inline ssize_t vhci_put_user(struct vhci_data *data,
case HCI_COMMAND_PKT:
data->hdev->stat.cmd_tx++;
break;
+
case HCI_ACLDATA_PKT:
data->hdev->stat.acl_tx++;
break;
+
case HCI_SCODATA_PKT:
data->hdev->stat.sco_tx++;
break;
}
- return len;
+ return total;
}
static ssize_t vhci_read(struct file *file,
- char __user *buf, size_t count, loff_t *pos)
+ char __user *buf, size_t count, loff_t *pos)
{
struct vhci_data *data = file->private_data;
struct sk_buff *skb;
@@ -264,7 +185,7 @@ static ssize_t vhci_read(struct file *file,
}
ret = wait_event_interruptible(data->read_wait,
- !skb_queue_empty(&data->readq));
+ !skb_queue_empty(&data->readq));
if (ret < 0)
break;
}
@@ -273,7 +194,7 @@ static ssize_t vhci_read(struct file *file,
}
static ssize_t vhci_write(struct file *file,
- const char __user *buf, size_t count, loff_t *pos)
+ const char __user *buf, size_t count, loff_t *pos)
{
struct vhci_data *data = file->private_data;
@@ -292,17 +213,10 @@ static unsigned int vhci_poll(struct file *file, poll_table *wait)
return POLLOUT | POLLWRNORM;
}
-static void vhci_open_timeout(struct work_struct *work)
-{
- struct vhci_data *data = container_of(work, struct vhci_data,
- open_timeout.work);
-
- vhci_create_device(data, amp ? HCI_AMP : HCI_BREDR);
-}
-
static int vhci_open(struct inode *inode, struct file *file)
{
struct vhci_data *data;
+ struct hci_dev *hdev;
data = kzalloc(sizeof(struct vhci_data), GFP_KERNEL);
if (!data)
@@ -311,13 +225,35 @@ static int vhci_open(struct inode *inode, struct file *file)
skb_queue_head_init(&data->readq);
init_waitqueue_head(&data->read_wait);
- INIT_DELAYED_WORK(&data->open_timeout, vhci_open_timeout);
+ hdev = hci_alloc_dev();
+ if (!hdev) {
+ kfree(data);
+ return -ENOMEM;
+ }
+
+ data->hdev = hdev;
+
+ hdev->bus = HCI_VIRTUAL;
+ hci_set_drvdata(hdev, data);
+
+ if (amp)
+ hdev->dev_type = HCI_AMP;
+
+ hdev->open = vhci_open_dev;
+ hdev->close = vhci_close_dev;
+ hdev->flush = vhci_flush;
+ hdev->send = vhci_send_frame;
+
+ if (hci_register_dev(hdev) < 0) {
+ BT_ERR("Can't register HCI device");
+ kfree(data);
+ hci_free_dev(hdev);
+ return -EBUSY;
+ }
file->private_data = data;
nonseekable_open(inode, file);
- schedule_delayed_work(&data->open_timeout, msecs_to_jiffies(1000));
-
return 0;
}
@@ -326,12 +262,8 @@ static int vhci_release(struct inode *inode, struct file *file)
struct vhci_data *data = file->private_data;
struct hci_dev *hdev = data->hdev;
- cancel_delayed_work_sync(&data->open_timeout);
-
- if (hdev) {
- hci_unregister_dev(hdev);
- hci_free_dev(hdev);
- }
+ hci_unregister_dev(hdev);
+ hci_free_dev(hdev);
file->private_data = NULL;
kfree(data);
@@ -377,4 +309,3 @@ MODULE_AUTHOR("Marcel Holtmann <marcel@holtmann.org>");
MODULE_DESCRIPTION("Bluetooth virtual HCI driver ver " VERSION);
MODULE_VERSION(VERSION);
MODULE_LICENSE("GPL");
-MODULE_ALIAS("devname:vhci");