diff options
Diffstat (limited to 'drivers/bluetooth')
-rw-r--r-- | drivers/bluetooth/Makefile | 2 | ||||
-rw-r--r-- | drivers/bluetooth/ath3k.c | 4 | ||||
-rw-r--r-- | drivers/bluetooth/bfusb.c | 31 | ||||
-rw-r--r-- | drivers/bluetooth/bluecard_cs.c | 30 | ||||
-rw-r--r-- | drivers/bluetooth/bpa10x.c | 11 | ||||
-rw-r--r-- | drivers/bluetooth/bt3c_cs.c | 30 | ||||
-rw-r--r-- | drivers/bluetooth/btmrvl_drv.h | 12 | ||||
-rw-r--r-- | drivers/bluetooth/btmrvl_main.c | 295 | ||||
-rw-r--r-- | drivers/bluetooth/btmrvl_sdio.c | 23 | ||||
-rw-r--r-- | drivers/bluetooth/btmrvl_sdio.h | 2 | ||||
-rw-r--r-- | drivers/bluetooth/btsdio.c | 6 | ||||
-rw-r--r-- | drivers/bluetooth/btuart_cs.c | 30 | ||||
-rw-r--r-- | drivers/bluetooth/btusb.c | 22 | ||||
-rw-r--r-- | drivers/bluetooth/btwilink.c | 9 | ||||
-rw-r--r-- | drivers/bluetooth/dtl1_cs.c | 30 | ||||
-rw-r--r-- | drivers/bluetooth/hci_bcsp.c | 5 | ||||
-rw-r--r-- | drivers/bluetooth/hci_h4.c | 24 | ||||
-rw-r--r-- | drivers/bluetooth/hci_h5.c | 2 | ||||
-rw-r--r-- | drivers/bluetooth/hci_ldisc.c | 12 | ||||
-rw-r--r-- | drivers/bluetooth/hci_ll.c | 14 | ||||
-rw-r--r-- | drivers/bluetooth/hci_vhci.c | 179 |
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, ¶m, 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"); |