bluetooth: Revert drivers back to 3.0 framework

Undo driver changes that conflict with the BT core code under
net/bluetooth from 3.0
This commit is contained in:
Stephen Boyd 2013-01-18 13:55:11 -08:00
parent 7433537fe2
commit 0389df18a8
22 changed files with 417 additions and 278 deletions

View file

@ -188,7 +188,7 @@ config BT_MRVL
The core driver to support Marvell Bluetooth devices.
This driver is required if you want to support
Marvell Bluetooth devices, such as 8688/8787/8797.
Marvell Bluetooth devices, such as 8688/8787.
Say Y here to compile Marvell Bluetooth driver
into the kernel or say M to compile it as module.

View file

@ -30,7 +30,6 @@
#include <net/bluetooth/bluetooth.h>
#define VERSION "1.0"
#define ATH3K_FIRMWARE "ath3k-1.fw"
#define ATH3K_DNLOAD 0x01
#define ATH3K_GETSTATE 0x05
@ -63,20 +62,12 @@ static struct usb_device_id ath3k_table[] = {
/* Atheros AR3011 with sflash firmware*/
{ USB_DEVICE(0x0CF3, 0x3002) },
{ USB_DEVICE(0x13d3, 0x3304) },
{ USB_DEVICE(0x0930, 0x0215) },
{ USB_DEVICE(0x0489, 0xE03D) },
/* Atheros AR9285 Malbec with sflash firmware */
{ USB_DEVICE(0x03F0, 0x311D) },
/* Atheros AR3012 with sflash firmware*/
{ USB_DEVICE(0x0CF3, 0x3004) },
{ USB_DEVICE(0x0CF3, 0x311D) },
{ USB_DEVICE(0x13d3, 0x3375) },
{ USB_DEVICE(0x04CA, 0x3005) },
{ USB_DEVICE(0x13d3, 0x3362) },
{ USB_DEVICE(0x0CF3, 0xE004) },
/* Atheros AR5BBU12 with sflash firmware */
{ USB_DEVICE(0x0489, 0xE02C) },
@ -93,11 +84,6 @@ static struct usb_device_id ath3k_blist_tbl[] = {
/* Atheros AR3012 with sflash firmware*/
{ USB_DEVICE(0x0cf3, 0x3004), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x0cf3, 0x311D), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x13d3, 0x3375), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x04ca, 0x3005), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x13d3, 0x3362), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x0cf3, 0xe004), .driver_info = BTUSB_ATH3012 },
{ } /* Terminating entry */
};
@ -117,7 +103,7 @@ static int ath3k_load_firmware(struct usb_device *udev,
pipe = usb_sndctrlpipe(udev, 0);
send_buf = kmalloc(BULK_SIZE, GFP_KERNEL);
send_buf = kmalloc(BULK_SIZE, GFP_ATOMIC);
if (!send_buf) {
BT_ERR("Can't allocate memory chunk for firmware");
return -ENOMEM;
@ -188,7 +174,7 @@ static int ath3k_load_fwfile(struct usb_device *udev,
count = firmware->size;
send_buf = kmalloc(BULK_SIZE, GFP_KERNEL);
send_buf = kmalloc(BULK_SIZE, GFP_ATOMIC);
if (!send_buf) {
BT_ERR("Can't allocate memory chunk for firmware");
return -ENOMEM;
@ -412,15 +398,9 @@ static int ath3k_probe(struct usb_interface *intf,
return 0;
}
ret = request_firmware(&firmware, ATH3K_FIRMWARE, &udev->dev);
if (ret < 0) {
if (ret == -ENOENT)
BT_ERR("Firmware file \"%s\" not found",
ATH3K_FIRMWARE);
else
BT_ERR("Firmware file \"%s\" request failed (err=%d)",
ATH3K_FIRMWARE, ret);
return ret;
if (request_firmware(&firmware, "ath3k-1.fw", &udev->dev) < 0) {
BT_ERR("Error loading firmware");
return -EIO;
}
ret = ath3k_load_firmware(udev, firmware);
@ -441,10 +421,22 @@ static struct usb_driver ath3k_driver = {
.id_table = ath3k_table,
};
module_usb_driver(ath3k_driver);
static int __init ath3k_init(void)
{
BT_INFO("Atheros AR30xx firmware driver ver %s", VERSION);
return usb_register(&ath3k_driver);
}
static void __exit ath3k_exit(void)
{
usb_deregister(&ath3k_driver);
}
module_init(ath3k_init);
module_exit(ath3k_exit);
MODULE_AUTHOR("Atheros Communications");
MODULE_DESCRIPTION("Atheros AR30xx firmware driver");
MODULE_VERSION(VERSION);
MODULE_LICENSE("GPL");
MODULE_FIRMWARE(ATH3K_FIRMWARE);
MODULE_FIRMWARE("ath3k-1.fw");

View file

@ -24,7 +24,6 @@
#include <linux/module.h>
#include <linux/atomic.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/slab.h>
@ -66,7 +65,6 @@ struct bcm203x_data {
unsigned long state;
struct work_struct work;
atomic_t shutdown;
struct urb *urb;
unsigned char *buffer;
@ -99,7 +97,6 @@ static void bcm203x_complete(struct urb *urb)
data->state = BCM203X_SELECT_MEMORY;
/* use workqueue to have a small delay */
schedule_work(&data->work);
break;
@ -158,10 +155,7 @@ static void bcm203x_work(struct work_struct *work)
struct bcm203x_data *data =
container_of(work, struct bcm203x_data, work);
if (atomic_read(&data->shutdown))
return;
if (usb_submit_urb(data->urb, GFP_KERNEL) < 0)
if (usb_submit_urb(data->urb, GFP_ATOMIC) < 0)
BT_ERR("Can't submit URB");
}
@ -249,7 +243,6 @@ static int bcm203x_probe(struct usb_interface *intf, const struct usb_device_id
usb_set_intfdata(intf, data);
/* use workqueue to have a small delay */
schedule_work(&data->work);
return 0;
@ -261,9 +254,6 @@ static void bcm203x_disconnect(struct usb_interface *intf)
BT_DBG("intf %p", intf);
atomic_inc(&data->shutdown);
cancel_work_sync(&data->work);
usb_kill_urb(data->urb);
usb_set_intfdata(intf, NULL);
@ -281,7 +271,26 @@ static struct usb_driver bcm203x_driver = {
.id_table = bcm203x_table,
};
module_usb_driver(bcm203x_driver);
static int __init bcm203x_init(void)
{
int err;
BT_INFO("Broadcom Blutonium firmware driver ver %s", VERSION);
err = usb_register(&bcm203x_driver);
if (err < 0)
BT_ERR("Failed to register USB driver");
return err;
}
static void __exit bcm203x_exit(void)
{
usb_deregister(&bcm203x_driver);
}
module_init(bcm203x_init);
module_exit(bcm203x_exit);
MODULE_AUTHOR("Marcel Holtmann <marcel@holtmann.org>");
MODULE_DESCRIPTION("Broadcom Blutonium firmware driver ver " VERSION);

View file

@ -411,7 +411,7 @@ unlock:
static int bfusb_open(struct hci_dev *hdev)
{
struct bfusb_data *data = hci_get_drvdata(hdev);
struct bfusb_data *data = hdev->driver_data;
unsigned long flags;
int i, err;
@ -437,7 +437,7 @@ static int bfusb_open(struct hci_dev *hdev)
static int bfusb_flush(struct hci_dev *hdev)
{
struct bfusb_data *data = hci_get_drvdata(hdev);
struct bfusb_data *data = hdev->driver_data;
BT_DBG("hdev %p bfusb %p", hdev, data);
@ -448,7 +448,7 @@ static int bfusb_flush(struct hci_dev *hdev)
static int bfusb_close(struct hci_dev *hdev)
{
struct bfusb_data *data = hci_get_drvdata(hdev);
struct bfusb_data *data = hdev->driver_data;
unsigned long flags;
BT_DBG("hdev %p bfusb %p", hdev, data);
@ -483,7 +483,7 @@ static int bfusb_send_frame(struct sk_buff *skb)
if (!test_bit(HCI_RUNNING, &hdev->flags))
return -EBUSY;
data = hci_get_drvdata(hdev);
data = hdev->driver_data;
switch (bt_cb(skb)->pkt_type) {
case HCI_COMMAND_PKT:
@ -544,6 +544,15 @@ static int bfusb_send_frame(struct sk_buff *skb)
return 0;
}
static void bfusb_destruct(struct hci_dev *hdev)
{
struct bfusb_data *data = hdev->driver_data;
BT_DBG("hdev %p bfusb %p", hdev, data);
kfree(data);
}
static int bfusb_ioctl(struct hci_dev *hdev, unsigned int cmd, unsigned long arg)
{
return -ENOIOCTLCMD;
@ -559,23 +568,22 @@ static int bfusb_load_firmware(struct bfusb_data *data,
BT_INFO("BlueFRITZ! USB loading firmware");
buf = kmalloc(BFUSB_MAX_BLOCK_SIZE + 3, GFP_KERNEL);
if (!buf) {
BT_ERR("Can't allocate memory chunk for firmware");
return -ENOMEM;
}
pipe = usb_sndctrlpipe(data->udev, 0);
if (usb_control_msg(data->udev, pipe, USB_REQ_SET_CONFIGURATION,
0, 1, 0, NULL, 0, USB_CTRL_SET_TIMEOUT) < 0) {
BT_ERR("Can't change to loading configuration");
kfree(buf);
return -EBUSY;
}
data->udev->toggle[0] = data->udev->toggle[1] = 0;
buf = kmalloc(BFUSB_MAX_BLOCK_SIZE + 3, GFP_ATOMIC);
if (!buf) {
BT_ERR("Can't allocate memory chunk for firmware");
return -ENOMEM;
}
pipe = usb_sndbulkpipe(data->udev, data->bulk_out_ep);
while (count) {
@ -696,15 +704,18 @@ static int bfusb_probe(struct usb_interface *intf, const struct usb_device_id *i
data->hdev = hdev;
hdev->bus = HCI_USB;
hci_set_drvdata(hdev, data);
hdev->driver_data = 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->destruct = bfusb_destruct;
hdev->ioctl = bfusb_ioctl;
hdev->owner = THIS_MODULE;
if (hci_register_dev(hdev) < 0) {
BT_ERR("Can't register HCI device");
hci_free_dev(hdev);
@ -739,9 +750,10 @@ static void bfusb_disconnect(struct usb_interface *intf)
bfusb_close(hdev);
hci_unregister_dev(hdev);
if (hci_unregister_dev(hdev) < 0)
BT_ERR("Can't unregister HCI device %s", hdev->name);
hci_free_dev(hdev);
kfree(data);
}
static struct usb_driver bfusb_driver = {
@ -751,7 +763,26 @@ static struct usb_driver bfusb_driver = {
.id_table = bfusb_table,
};
module_usb_driver(bfusb_driver);
static int __init bfusb_init(void)
{
int err;
BT_INFO("BlueFRITZ! USB driver ver %s", VERSION);
err = usb_register(&bfusb_driver);
if (err < 0)
BT_ERR("Failed to register BlueFRITZ! USB driver");
return err;
}
static void __exit bfusb_exit(void)
{
usb_deregister(&bfusb_driver);
}
module_init(bfusb_init);
module_exit(bfusb_exit);
MODULE_AUTHOR("Marcel Holtmann <marcel@holtmann.org>");
MODULE_DESCRIPTION("BlueFRITZ! USB driver ver " VERSION);

View file

@ -561,7 +561,7 @@ static irqreturn_t bluecard_interrupt(int irq, void *dev_inst)
static int bluecard_hci_set_baud_rate(struct hci_dev *hdev, int baud)
{
bluecard_info_t *info = hci_get_drvdata(hdev);
bluecard_info_t *info = (bluecard_info_t *)(hdev->driver_data);
struct sk_buff *skb;
/* Ericsson baud rate command */
@ -609,7 +609,7 @@ static int bluecard_hci_set_baud_rate(struct hci_dev *hdev, int baud)
static int bluecard_hci_flush(struct hci_dev *hdev)
{
bluecard_info_t *info = hci_get_drvdata(hdev);
bluecard_info_t *info = (bluecard_info_t *)(hdev->driver_data);
/* Drop TX queue */
skb_queue_purge(&(info->txq));
@ -620,7 +620,7 @@ static int bluecard_hci_flush(struct hci_dev *hdev)
static int bluecard_hci_open(struct hci_dev *hdev)
{
bluecard_info_t *info = hci_get_drvdata(hdev);
bluecard_info_t *info = (bluecard_info_t *)(hdev->driver_data);
unsigned int iobase = info->p_dev->resource[0]->start;
if (test_bit(CARD_HAS_PCCARD_ID, &(info->hw_state)))
@ -640,7 +640,7 @@ static int bluecard_hci_open(struct hci_dev *hdev)
static int bluecard_hci_close(struct hci_dev *hdev)
{
bluecard_info_t *info = hci_get_drvdata(hdev);
bluecard_info_t *info = (bluecard_info_t *)(hdev->driver_data);
unsigned int iobase = info->p_dev->resource[0]->start;
if (!test_and_clear_bit(HCI_RUNNING, &(hdev->flags)))
@ -667,7 +667,7 @@ static int bluecard_hci_send_frame(struct sk_buff *skb)
return -ENODEV;
}
info = hci_get_drvdata(hdev);
info = (bluecard_info_t *)(hdev->driver_data);
switch (bt_cb(skb)->pkt_type) {
case HCI_COMMAND_PKT:
@ -691,6 +691,11 @@ static int bluecard_hci_send_frame(struct sk_buff *skb)
}
static void bluecard_hci_destruct(struct hci_dev *hdev)
{
}
static int bluecard_hci_ioctl(struct hci_dev *hdev, unsigned int cmd, unsigned long arg)
{
return -ENOIOCTLCMD;
@ -729,15 +734,18 @@ static int bluecard_open(bluecard_info_t *info)
info->hdev = hdev;
hdev->bus = HCI_PCCARD;
hci_set_drvdata(hdev, info);
hdev->driver_data = 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->destruct = bluecard_hci_destruct;
hdev->ioctl = bluecard_hci_ioctl;
hdev->owner = THIS_MODULE;
id = inb(iobase + 0x30);
if ((id & 0x0f) == 0x02)
@ -836,7 +844,9 @@ static int bluecard_close(bluecard_info_t *info)
/* Turn FPGA off */
outb(0x80, iobase + 0x30);
hci_unregister_dev(hdev);
if (hci_unregister_dev(hdev) < 0)
BT_ERR("Can't unregister HCI device %s", hdev->name);
hci_free_dev(hdev);
return 0;
@ -920,7 +930,7 @@ static void bluecard_release(struct pcmcia_device *link)
pcmcia_disable_device(link);
}
static const struct pcmcia_device_id bluecard_ids[] = {
static struct pcmcia_device_id bluecard_ids[] = {
PCMCIA_DEVICE_PROD_ID12("BlueCard", "LSE041", 0xbaf16fbf, 0x657cc15e),
PCMCIA_DEVICE_PROD_ID12("BTCFCARD", "LSE139", 0xe3987764, 0x2524b59c),
PCMCIA_DEVICE_PROD_ID12("WSS", "LSE039", 0x0a0736ec, 0x24e6dfab),

View file

@ -66,7 +66,7 @@ struct hci_vendor_hdr {
static int bpa10x_recv(struct hci_dev *hdev, int queue, void *buf, int count)
{
struct bpa10x_data *data = hci_get_drvdata(hdev);
struct bpa10x_data *data = hdev->driver_data;
BT_DBG("%s queue %d buffer %p count %d", hdev->name,
queue, buf, count);
@ -189,7 +189,7 @@ done:
static void bpa10x_rx_complete(struct urb *urb)
{
struct hci_dev *hdev = urb->context;
struct bpa10x_data *data = hci_get_drvdata(hdev);
struct bpa10x_data *data = hdev->driver_data;
int err;
BT_DBG("%s urb %p status %d count %d", hdev->name,
@ -219,7 +219,7 @@ static void bpa10x_rx_complete(struct urb *urb)
static inline int bpa10x_submit_intr_urb(struct hci_dev *hdev)
{
struct bpa10x_data *data = hci_get_drvdata(hdev);
struct bpa10x_data *data = hdev->driver_data;
struct urb *urb;
unsigned char *buf;
unsigned int pipe;
@ -260,7 +260,7 @@ static inline int bpa10x_submit_intr_urb(struct hci_dev *hdev)
static inline int bpa10x_submit_bulk_urb(struct hci_dev *hdev)
{
struct bpa10x_data *data = hci_get_drvdata(hdev);
struct bpa10x_data *data = hdev->driver_data;
struct urb *urb;
unsigned char *buf;
unsigned int pipe;
@ -301,7 +301,7 @@ static inline int bpa10x_submit_bulk_urb(struct hci_dev *hdev)
static int bpa10x_open(struct hci_dev *hdev)
{
struct bpa10x_data *data = hci_get_drvdata(hdev);
struct bpa10x_data *data = hdev->driver_data;
int err;
BT_DBG("%s", hdev->name);
@ -329,7 +329,7 @@ error:
static int bpa10x_close(struct hci_dev *hdev)
{
struct bpa10x_data *data = hci_get_drvdata(hdev);
struct bpa10x_data *data = hdev->driver_data;
BT_DBG("%s", hdev->name);
@ -343,7 +343,7 @@ static int bpa10x_close(struct hci_dev *hdev)
static int bpa10x_flush(struct hci_dev *hdev)
{
struct bpa10x_data *data = hci_get_drvdata(hdev);
struct bpa10x_data *data = hdev->driver_data;
BT_DBG("%s", hdev->name);
@ -355,7 +355,7 @@ static int bpa10x_flush(struct hci_dev *hdev)
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 bpa10x_data *data = hdev->driver_data;
struct usb_ctrlrequest *dr;
struct urb *urb;
unsigned int pipe;
@ -432,6 +432,17 @@ static int bpa10x_send_frame(struct sk_buff *skb)
return 0;
}
static void bpa10x_destruct(struct hci_dev *hdev)
{
struct bpa10x_data *data = hdev->driver_data;
BT_DBG("%s", hdev->name);
kfree_skb(data->rx_skb[0]);
kfree_skb(data->rx_skb[1]);
kfree(data);
}
static int bpa10x_probe(struct usb_interface *intf, const struct usb_device_id *id)
{
struct bpa10x_data *data;
@ -459,7 +470,7 @@ static int bpa10x_probe(struct usb_interface *intf, const struct usb_device_id *
}
hdev->bus = HCI_USB;
hci_set_drvdata(hdev, data);
hdev->driver_data = data;
data->hdev = hdev;
@ -469,6 +480,9 @@ static int bpa10x_probe(struct usb_interface *intf, const struct usb_device_id *
hdev->close = bpa10x_close;
hdev->flush = bpa10x_flush;
hdev->send = bpa10x_send_frame;
hdev->destruct = bpa10x_destruct;
hdev->owner = THIS_MODULE;
set_bit(HCI_QUIRK_NO_RESET, &hdev->quirks);
@ -498,9 +512,6 @@ static void bpa10x_disconnect(struct usb_interface *intf)
hci_unregister_dev(data->hdev);
hci_free_dev(data->hdev);
kfree_skb(data->rx_skb[0]);
kfree_skb(data->rx_skb[1]);
kfree(data);
}
static struct usb_driver bpa10x_driver = {
@ -510,7 +521,20 @@ static struct usb_driver bpa10x_driver = {
.id_table = bpa10x_table,
};
module_usb_driver(bpa10x_driver);
static int __init bpa10x_init(void)
{
BT_INFO("Digianswer Bluetooth USB driver ver %s", VERSION);
return usb_register(&bpa10x_driver);
}
static void __exit bpa10x_exit(void)
{
usb_deregister(&bpa10x_driver);
}
module_init(bpa10x_init);
module_exit(bpa10x_exit);
MODULE_AUTHOR("Marcel Holtmann <marcel@holtmann.org>");
MODULE_DESCRIPTION("Digianswer Bluetooth USB driver ver " VERSION);

View file

@ -39,6 +39,7 @@
#include <linux/serial.h>
#include <linux/serial_reg.h>
#include <linux/bitops.h>
#include <asm/system.h>
#include <asm/io.h>
#include <linux/device.h>
@ -388,7 +389,7 @@ static irqreturn_t bt3c_interrupt(int irq, void *dev_inst)
static int bt3c_hci_flush(struct hci_dev *hdev)
{
bt3c_info_t *info = hci_get_drvdata(hdev);
bt3c_info_t *info = (bt3c_info_t *)(hdev->driver_data);
/* Drop TX queue */
skb_queue_purge(&(info->txq));
@ -427,7 +428,7 @@ static int bt3c_hci_send_frame(struct sk_buff *skb)
return -ENODEV;
}
info = hci_get_drvdata(hdev);
info = (bt3c_info_t *) (hdev->driver_data);
switch (bt_cb(skb)->pkt_type) {
case HCI_COMMAND_PKT:
@ -455,6 +456,11 @@ static int bt3c_hci_send_frame(struct sk_buff *skb)
}
static void bt3c_hci_destruct(struct hci_dev *hdev)
{
}
static int bt3c_hci_ioctl(struct hci_dev *hdev, unsigned int cmd, unsigned long arg)
{
return -ENOIOCTLCMD;
@ -574,15 +580,18 @@ static int bt3c_open(bt3c_info_t *info)
info->hdev = hdev;
hdev->bus = HCI_PCCARD;
hci_set_drvdata(hdev, info);
hdev->driver_data = 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->destruct = bt3c_hci_destruct;
hdev->ioctl = bt3c_hci_ioctl;
hdev->owner = THIS_MODULE;
/* Load firmware */
err = request_firmware(&firmware, "BT3CPCC.bin", &info->p_dev->dev);
if (err < 0) {
@ -627,7 +636,9 @@ static int bt3c_close(bt3c_info_t *info)
bt3c_hci_close(hdev);
hci_unregister_dev(hdev);
if (hci_unregister_dev(hdev) < 0)
BT_ERR("Can't unregister HCI device %s", hdev->name);
hci_free_dev(hdev);
return 0;
@ -750,7 +761,7 @@ static void bt3c_release(struct pcmcia_device *link)
}
static const struct pcmcia_device_id bt3c_ids[] = {
static struct pcmcia_device_id bt3c_ids[] = {
PCMCIA_DEVICE_PROD_ID13("3COM", "Bluetooth PC Card", 0xefce0a31, 0xd4ce9b02),
PCMCIA_DEVICE_NULL
};

View file

@ -45,6 +45,12 @@ struct btmrvl_debugfs_data {
struct dentry *txdnldready;
};
static int btmrvl_open_generic(struct inode *inode, struct file *file)
{
file->private_data = inode->i_private;
return 0;
}
static ssize_t btmrvl_hscfgcmd_write(struct file *file,
const char __user *ubuf, size_t count, loff_t *ppos)
{
@ -58,8 +64,6 @@ static ssize_t btmrvl_hscfgcmd_write(struct file *file,
return -EFAULT;
ret = strict_strtol(buf, 10, &result);
if (ret)
return ret;
priv->btmrvl_dev.hscfgcmd = result;
@ -87,7 +91,7 @@ static ssize_t btmrvl_hscfgcmd_read(struct file *file, char __user *userbuf,
static const struct file_operations btmrvl_hscfgcmd_fops = {
.read = btmrvl_hscfgcmd_read,
.write = btmrvl_hscfgcmd_write,
.open = simple_open,
.open = btmrvl_open_generic,
.llseek = default_llseek,
};
@ -104,8 +108,6 @@ static ssize_t btmrvl_psmode_write(struct file *file, const char __user *ubuf,
return -EFAULT;
ret = strict_strtol(buf, 10, &result);
if (ret)
return ret;
priv->btmrvl_dev.psmode = result;
@ -128,7 +130,7 @@ static ssize_t btmrvl_psmode_read(struct file *file, char __user *userbuf,
static const struct file_operations btmrvl_psmode_fops = {
.read = btmrvl_psmode_read,
.write = btmrvl_psmode_write,
.open = simple_open,
.open = btmrvl_open_generic,
.llseek = default_llseek,
};
@ -145,8 +147,6 @@ static ssize_t btmrvl_pscmd_write(struct file *file, const char __user *ubuf,
return -EFAULT;
ret = strict_strtol(buf, 10, &result);
if (ret)
return ret;
priv->btmrvl_dev.pscmd = result;
@ -174,7 +174,7 @@ static ssize_t btmrvl_pscmd_read(struct file *file, char __user *userbuf,
static const struct file_operations btmrvl_pscmd_fops = {
.read = btmrvl_pscmd_read,
.write = btmrvl_pscmd_write,
.open = simple_open,
.open = btmrvl_open_generic,
.llseek = default_llseek,
};
@ -191,8 +191,6 @@ static ssize_t btmrvl_gpiogap_write(struct file *file, const char __user *ubuf,
return -EFAULT;
ret = strict_strtol(buf, 16, &result);
if (ret)
return ret;
priv->btmrvl_dev.gpio_gap = result;
@ -215,7 +213,7 @@ static ssize_t btmrvl_gpiogap_read(struct file *file, char __user *userbuf,
static const struct file_operations btmrvl_gpiogap_fops = {
.read = btmrvl_gpiogap_read,
.write = btmrvl_gpiogap_write,
.open = simple_open,
.open = btmrvl_open_generic,
.llseek = default_llseek,
};
@ -232,8 +230,6 @@ static ssize_t btmrvl_hscmd_write(struct file *file, const char __user *ubuf,
return -EFAULT;
ret = strict_strtol(buf, 10, &result);
if (ret)
return ret;
priv->btmrvl_dev.hscmd = result;
if (priv->btmrvl_dev.hscmd) {
@ -259,7 +255,7 @@ static ssize_t btmrvl_hscmd_read(struct file *file, char __user *userbuf,
static const struct file_operations btmrvl_hscmd_fops = {
.read = btmrvl_hscmd_read,
.write = btmrvl_hscmd_write,
.open = simple_open,
.open = btmrvl_open_generic,
.llseek = default_llseek,
};
@ -276,8 +272,6 @@ static ssize_t btmrvl_hsmode_write(struct file *file, const char __user *ubuf,
return -EFAULT;
ret = strict_strtol(buf, 10, &result);
if (ret)
return ret;
priv->btmrvl_dev.hsmode = result;
@ -299,7 +293,7 @@ static ssize_t btmrvl_hsmode_read(struct file *file, char __user * userbuf,
static const struct file_operations btmrvl_hsmode_fops = {
.read = btmrvl_hsmode_read,
.write = btmrvl_hsmode_write,
.open = simple_open,
.open = btmrvl_open_generic,
.llseek = default_llseek,
};
@ -317,7 +311,7 @@ static ssize_t btmrvl_curpsmode_read(struct file *file, char __user *userbuf,
static const struct file_operations btmrvl_curpsmode_fops = {
.read = btmrvl_curpsmode_read,
.open = simple_open,
.open = btmrvl_open_generic,
.llseek = default_llseek,
};
@ -335,7 +329,7 @@ static ssize_t btmrvl_psstate_read(struct file *file, char __user * userbuf,
static const struct file_operations btmrvl_psstate_fops = {
.read = btmrvl_psstate_read,
.open = simple_open,
.open = btmrvl_open_generic,
.llseek = default_llseek,
};
@ -353,7 +347,7 @@ static ssize_t btmrvl_hsstate_read(struct file *file, char __user *userbuf,
static const struct file_operations btmrvl_hsstate_fops = {
.read = btmrvl_hsstate_read,
.open = simple_open,
.open = btmrvl_open_generic,
.llseek = default_llseek,
};
@ -372,13 +366,13 @@ static ssize_t btmrvl_txdnldready_read(struct file *file, char __user *userbuf,
static const struct file_operations btmrvl_txdnldready_fops = {
.read = btmrvl_txdnldready_read,
.open = simple_open,
.open = btmrvl_open_generic,
.llseek = default_llseek,
};
void btmrvl_debugfs_init(struct hci_dev *hdev)
{
struct btmrvl_private *priv = hci_get_drvdata(hdev);
struct btmrvl_private *priv = hdev->driver_data;
struct btmrvl_debugfs_data *dbg;
if (!hdev->debugfs)
@ -395,34 +389,36 @@ void btmrvl_debugfs_init(struct hci_dev *hdev)
dbg->config_dir = debugfs_create_dir("config", hdev->debugfs);
dbg->psmode = debugfs_create_file("psmode", 0644, dbg->config_dir,
priv, &btmrvl_psmode_fops);
hdev->driver_data, &btmrvl_psmode_fops);
dbg->pscmd = debugfs_create_file("pscmd", 0644, dbg->config_dir,
priv, &btmrvl_pscmd_fops);
hdev->driver_data, &btmrvl_pscmd_fops);
dbg->gpiogap = debugfs_create_file("gpiogap", 0644, dbg->config_dir,
priv, &btmrvl_gpiogap_fops);
hdev->driver_data, &btmrvl_gpiogap_fops);
dbg->hsmode = debugfs_create_file("hsmode", 0644, dbg->config_dir,
priv, &btmrvl_hsmode_fops);
hdev->driver_data, &btmrvl_hsmode_fops);
dbg->hscmd = debugfs_create_file("hscmd", 0644, dbg->config_dir,
priv, &btmrvl_hscmd_fops);
hdev->driver_data, &btmrvl_hscmd_fops);
dbg->hscfgcmd = debugfs_create_file("hscfgcmd", 0644, dbg->config_dir,
priv, &btmrvl_hscfgcmd_fops);
hdev->driver_data, &btmrvl_hscfgcmd_fops);
dbg->status_dir = debugfs_create_dir("status", hdev->debugfs);
dbg->curpsmode = debugfs_create_file("curpsmode", 0444,
dbg->status_dir, priv,
&btmrvl_curpsmode_fops);
dbg->status_dir,
hdev->driver_data,
&btmrvl_curpsmode_fops);
dbg->psstate = debugfs_create_file("psstate", 0444, dbg->status_dir,
priv, &btmrvl_psstate_fops);
hdev->driver_data, &btmrvl_psstate_fops);
dbg->hsstate = debugfs_create_file("hsstate", 0444, dbg->status_dir,
priv, &btmrvl_hsstate_fops);
hdev->driver_data, &btmrvl_hsstate_fops);
dbg->txdnldready = debugfs_create_file("txdnldready", 0444,
dbg->status_dir, priv,
&btmrvl_txdnldready_fops);
dbg->status_dir,
hdev->driver_data,
&btmrvl_txdnldready_fops);
}
void btmrvl_debugfs_remove(struct hci_dev *hdev)
{
struct btmrvl_private *priv = hci_get_drvdata(hdev);
struct btmrvl_private *priv = hdev->driver_data;
struct btmrvl_debugfs_data *dbg = priv->debugfs_data;
if (!dbg)

View file

@ -18,8 +18,6 @@
* this warranty disclaimer.
**/
#include <linux/module.h>
#include <net/bluetooth/bluetooth.h>
#include <net/bluetooth/hci_core.h>
@ -387,6 +385,10 @@ static int btmrvl_ioctl(struct hci_dev *hdev,
return -ENOIOCTLCMD;
}
static void btmrvl_destruct(struct hci_dev *hdev)
{
}
static int btmrvl_send_frame(struct sk_buff *skb)
{
struct hci_dev *hdev = (struct hci_dev *) skb->dev;
@ -394,13 +396,12 @@ static int btmrvl_send_frame(struct sk_buff *skb)
BT_DBG("type=%d, len=%d", skb->pkt_type, skb->len);
if (!hdev) {
if (!hdev || !hdev->driver_data) {
BT_ERR("Frame for unknown HCI device");
return -ENODEV;
}
priv = hci_get_drvdata(hdev);
priv = (struct btmrvl_private *) hdev->driver_data;
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,
@ -431,7 +432,7 @@ static int btmrvl_send_frame(struct sk_buff *skb)
static int btmrvl_flush(struct hci_dev *hdev)
{
struct btmrvl_private *priv = hci_get_drvdata(hdev);
struct btmrvl_private *priv = hdev->driver_data;
skb_queue_purge(&priv->adapter->tx_queue);
@ -440,7 +441,7 @@ static int btmrvl_flush(struct hci_dev *hdev)
static int btmrvl_close(struct hci_dev *hdev)
{
struct btmrvl_private *priv = hci_get_drvdata(hdev);
struct btmrvl_private *priv = hdev->driver_data;
if (!test_and_clear_bit(HCI_RUNNING, &hdev->flags))
return 0;
@ -472,6 +473,8 @@ static int btmrvl_service_main_thread(void *data)
init_waitqueue_entry(&wait, current);
current->flags |= PF_NOFREEZE;
for (;;) {
add_wait_queue(&thread->wait_q, &wait);
@ -543,14 +546,16 @@ int btmrvl_register_hdev(struct btmrvl_private *priv)
}
priv->btmrvl_dev.hcidev = hdev;
hci_set_drvdata(hdev, priv);
hdev->driver_data = priv;
hdev->bus = HCI_SDIO;
hdev->open = btmrvl_open;
hdev->close = btmrvl_close;
hdev->flush = btmrvl_flush;
hdev->send = btmrvl_send_frame;
hdev->destruct = btmrvl_destruct;
hdev->ioctl = btmrvl_ioctl;
hdev->owner = THIS_MODULE;
btmrvl_send_module_cfg_cmd(priv, MODULE_BRINGUP_REQ);

View file

@ -23,7 +23,6 @@
#include <linux/mmc/sdio_ids.h>
#include <linux/mmc/sdio_func.h>
#include <linux/module.h>
#include <net/bluetooth/bluetooth.h>
#include <net/bluetooth/hci_core.h>
@ -65,7 +64,7 @@ static const struct btmrvl_sdio_card_reg btmrvl_reg_8688 = {
.io_port_1 = 0x01,
.io_port_2 = 0x02,
};
static const struct btmrvl_sdio_card_reg btmrvl_reg_87xx = {
static const struct btmrvl_sdio_card_reg btmrvl_reg_8787 = {
.cfg = 0x00,
.host_int_mask = 0x02,
.host_intstatus = 0x03,
@ -82,7 +81,7 @@ static const struct btmrvl_sdio_card_reg btmrvl_reg_87xx = {
.io_port_2 = 0x7a,
};
static const struct btmrvl_sdio_device btmrvl_sdio_sd8688 = {
static const struct btmrvl_sdio_device btmrvl_sdio_sd6888 = {
.helper = "sd8688_helper.bin",
.firmware = "sd8688.bin",
.reg = &btmrvl_reg_8688,
@ -92,27 +91,17 @@ 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",
.reg = &btmrvl_reg_87xx,
.sd_blksz_fw_dl = 256,
};
static const struct btmrvl_sdio_device btmrvl_sdio_sd8797 = {
.helper = NULL,
.firmware = "mrvl/sd8797_uapsta.bin",
.reg = &btmrvl_reg_87xx,
.reg = &btmrvl_reg_8787,
.sd_blksz_fw_dl = 256,
};
static const struct sdio_device_id btmrvl_sdio_ids[] = {
/* Marvell SD8688 Bluetooth device */
{ SDIO_DEVICE(SDIO_VENDOR_ID_MARVELL, 0x9105),
.driver_data = (unsigned long) &btmrvl_sdio_sd8688 },
.driver_data = (unsigned long) &btmrvl_sdio_sd6888 },
/* Marvell SD8787 Bluetooth device */
{ SDIO_DEVICE(SDIO_VENDOR_ID_MARVELL, 0x911A),
.driver_data = (unsigned long) &btmrvl_sdio_sd8787 },
/* Marvell SD8797 Bluetooth device */
{ SDIO_DEVICE(SDIO_VENDOR_ID_MARVELL, 0x912A),
.driver_data = (unsigned long) &btmrvl_sdio_sd8797 },
{ } /* Terminating entry */
};
@ -1086,4 +1075,3 @@ MODULE_LICENSE("GPL v2");
MODULE_FIRMWARE("sd8688_helper.bin");
MODULE_FIRMWARE("sd8688.bin");
MODULE_FIRMWARE("mrvl/sd8787_uapsta.bin");
MODULE_FIRMWARE("mrvl/sd8797_uapsta.bin");

View file

@ -189,7 +189,7 @@ static void btsdio_interrupt(struct sdio_func *func)
static int btsdio_open(struct hci_dev *hdev)
{
struct btsdio_data *data = hci_get_drvdata(hdev);
struct btsdio_data *data = hdev->driver_data;
int err;
BT_DBG("%s", hdev->name);
@ -225,7 +225,7 @@ release:
static int btsdio_close(struct hci_dev *hdev)
{
struct btsdio_data *data = hci_get_drvdata(hdev);
struct btsdio_data *data = hdev->driver_data;
BT_DBG("%s", hdev->name);
@ -246,7 +246,7 @@ static int btsdio_close(struct hci_dev *hdev)
static int btsdio_flush(struct hci_dev *hdev)
{
struct btsdio_data *data = hci_get_drvdata(hdev);
struct btsdio_data *data = hdev->driver_data;
BT_DBG("%s", hdev->name);
@ -258,7 +258,7 @@ static int btsdio_flush(struct hci_dev *hdev)
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);
struct btsdio_data *data = hdev->driver_data;
BT_DBG("%s", hdev->name);
@ -289,6 +289,15 @@ static int btsdio_send_frame(struct sk_buff *skb)
return 0;
}
static void btsdio_destruct(struct hci_dev *hdev)
{
struct btsdio_data *data = hdev->driver_data;
BT_DBG("%s", hdev->name);
kfree(data);
}
static int btsdio_probe(struct sdio_func *func,
const struct sdio_device_id *id)
{
@ -321,7 +330,7 @@ static int btsdio_probe(struct sdio_func *func,
}
hdev->bus = HCI_SDIO;
hci_set_drvdata(hdev, data);
hdev->driver_data = data;
if (id->class == SDIO_CLASS_BT_AMP)
hdev->dev_type = HCI_AMP;
@ -336,6 +345,9 @@ static int btsdio_probe(struct sdio_func *func,
hdev->close = btsdio_close;
hdev->flush = btsdio_flush;
hdev->send = btsdio_send_frame;
hdev->destruct = btsdio_destruct;
hdev->owner = THIS_MODULE;
err = hci_register_dev(hdev);
if (err < 0) {
@ -366,7 +378,6 @@ static void btsdio_remove(struct sdio_func *func)
hci_unregister_dev(hdev);
hci_free_dev(hdev);
kfree(data);
}
static struct sdio_driver btsdio_driver = {

View file

@ -38,6 +38,7 @@
#include <linux/serial.h>
#include <linux/serial_reg.h>
#include <linux/bitops.h>
#include <asm/system.h>
#include <asm/io.h>
#include <pcmcia/cistpl.h>
@ -396,7 +397,7 @@ static void btuart_change_speed(btuart_info_t *info, unsigned int speed)
static int btuart_hci_flush(struct hci_dev *hdev)
{
btuart_info_t *info = hci_get_drvdata(hdev);
btuart_info_t *info = (btuart_info_t *)(hdev->driver_data);
/* Drop TX queue */
skb_queue_purge(&(info->txq));
@ -434,7 +435,7 @@ static int btuart_hci_send_frame(struct sk_buff *skb)
return -ENODEV;
}
info = hci_get_drvdata(hdev);
info = (btuart_info_t *)(hdev->driver_data);
switch (bt_cb(skb)->pkt_type) {
case HCI_COMMAND_PKT:
@ -458,6 +459,11 @@ static int btuart_hci_send_frame(struct sk_buff *skb)
}
static void btuart_hci_destruct(struct hci_dev *hdev)
{
}
static int btuart_hci_ioctl(struct hci_dev *hdev, unsigned int cmd, unsigned long arg)
{
return -ENOIOCTLCMD;
@ -492,15 +498,18 @@ static int btuart_open(btuart_info_t *info)
info->hdev = hdev;
hdev->bus = HCI_PCCARD;
hci_set_drvdata(hdev, info);
hdev->driver_data = 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->destruct = btuart_hci_destruct;
hdev->ioctl = btuart_hci_ioctl;
hdev->owner = THIS_MODULE;
spin_lock_irqsave(&(info->lock), flags);
/* Reset UART */
@ -556,7 +565,9 @@ static int btuart_close(btuart_info_t *info)
spin_unlock_irqrestore(&(info->lock), flags);
hci_unregister_dev(hdev);
if (hci_unregister_dev(hdev) < 0)
BT_ERR("Can't unregister HCI device %s", hdev->name);
hci_free_dev(hdev);
return 0;
@ -678,7 +689,7 @@ static void btuart_release(struct pcmcia_device *link)
pcmcia_disable_device(link);
}
static const struct pcmcia_device_id btuart_ids[] = {
static struct pcmcia_device_id btuart_ids[] = {
/* don't use this driver. Use serial_cs + hci_uart instead */
PCMCIA_DEVICE_NULL
};

View file

@ -37,13 +37,13 @@
#define VERSION "0.6"
static bool ignore_dga;
static bool ignore_csr;
static bool ignore_sniffer;
static bool disable_scofix;
static bool force_scofix;
static int ignore_dga;
static int ignore_csr;
static int ignore_sniffer;
static int disable_scofix;
static int force_scofix;
static bool reset = 1;
static int reset = 1;
static struct usb_driver btusb_driver;
@ -61,7 +61,7 @@ static struct usb_device_id btusb_table[] = {
{ USB_DEVICE_INFO(0xe0, 0x01, 0x01) },
/* Broadcom SoftSailing reporting vendor specific */
{ USB_DEVICE(0x0a5c, 0x21e1) },
{ USB_DEVICE(0x05ac, 0x21e1) },
/* Apple MacBookPro 7,1 */
{ USB_DEVICE(0x05ac, 0x8213) },
@ -100,17 +100,6 @@ static struct usb_device_id btusb_table[] = {
/* Canyon CN-BTU1 with HID interfaces */
{ USB_DEVICE(0x0c10, 0x0000) },
/* Broadcom BCM20702A0 */
{ USB_DEVICE(0x0489, 0xe042) },
{ USB_DEVICE(0x0a5c, 0x21e3) },
{ USB_DEVICE(0x0a5c, 0x21e6) },
{ USB_DEVICE(0x0a5c, 0x21e8) },
{ USB_DEVICE(0x0a5c, 0x21f3) },
{ USB_DEVICE(0x413c, 0x8197) },
/* Foxconn - Hon Hai */
{ USB_DEVICE(0x0489, 0xe033) },
{ } /* Terminating entry */
};
@ -125,20 +114,12 @@ static struct usb_device_id blacklist_table[] = {
/* Atheros 3011 with sflash firmware */
{ USB_DEVICE(0x0cf3, 0x3002), .driver_info = BTUSB_IGNORE },
{ USB_DEVICE(0x13d3, 0x3304), .driver_info = BTUSB_IGNORE },
{ USB_DEVICE(0x0930, 0x0215), .driver_info = BTUSB_IGNORE },
{ USB_DEVICE(0x0489, 0xe03d), .driver_info = BTUSB_IGNORE },
/* Atheros AR9285 Malbec with sflash firmware */
{ USB_DEVICE(0x03f0, 0x311d), .driver_info = BTUSB_IGNORE },
/* Atheros 3012 with sflash firmware */
{ USB_DEVICE(0x0cf3, 0x3004), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x0cf3, 0x311d), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x13d3, 0x3375), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x04ca, 0x3005), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x13d3, 0x3362), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x0cf3, 0xe004), .driver_info = BTUSB_ATH3012 },
/* Atheros AR5BBU12 with sflash firmware */
{ USB_DEVICE(0x0489, 0xe02c), .driver_info = BTUSB_IGNORE },
@ -255,7 +236,7 @@ static int inc_tx(struct btusb_data *data)
static void btusb_intr_complete(struct urb *urb)
{
struct hci_dev *hdev = urb->context;
struct btusb_data *data = hci_get_drvdata(hdev);
struct btusb_data *data = hdev->driver_data;
int err;
BT_DBG("%s urb %p status %d count %d", hdev->name,
@ -283,9 +264,7 @@ static void btusb_intr_complete(struct urb *urb)
err = usb_submit_urb(urb, GFP_ATOMIC);
if (err < 0) {
/* -EPERM: urb is being killed;
* -ENODEV: device got disconnected */
if (err != -EPERM && err != -ENODEV)
if (err != -EPERM)
BT_ERR("%s urb %p failed to resubmit (%d)",
hdev->name, urb, -err);
usb_unanchor_urb(urb);
@ -294,7 +273,7 @@ static void btusb_intr_complete(struct urb *urb)
static int btusb_submit_intr_urb(struct hci_dev *hdev, gfp_t mem_flags)
{
struct btusb_data *data = hci_get_drvdata(hdev);
struct btusb_data *data = hdev->driver_data;
struct urb *urb;
unsigned char *buf;
unsigned int pipe;
@ -329,8 +308,7 @@ static int btusb_submit_intr_urb(struct hci_dev *hdev, gfp_t mem_flags)
err = usb_submit_urb(urb, mem_flags);
if (err < 0) {
if (err != -EPERM && err != -ENODEV)
BT_ERR("%s urb %p submission failed (%d)",
BT_ERR("%s urb %p submission failed (%d)",
hdev->name, urb, -err);
usb_unanchor_urb(urb);
}
@ -343,7 +321,7 @@ static int btusb_submit_intr_urb(struct hci_dev *hdev, gfp_t mem_flags)
static void btusb_bulk_complete(struct urb *urb)
{
struct hci_dev *hdev = urb->context;
struct btusb_data *data = hci_get_drvdata(hdev);
struct btusb_data *data = hdev->driver_data;
int err;
BT_DBG("%s urb %p status %d count %d", hdev->name,
@ -371,9 +349,7 @@ static void btusb_bulk_complete(struct urb *urb)
err = usb_submit_urb(urb, GFP_ATOMIC);
if (err < 0) {
/* -EPERM: urb is being killed;
* -ENODEV: device got disconnected */
if (err != -EPERM && err != -ENODEV)
if (err != -EPERM)
BT_ERR("%s urb %p failed to resubmit (%d)",
hdev->name, urb, -err);
usb_unanchor_urb(urb);
@ -382,7 +358,7 @@ static void btusb_bulk_complete(struct urb *urb)
static int btusb_submit_bulk_urb(struct hci_dev *hdev, gfp_t mem_flags)
{
struct btusb_data *data = hci_get_drvdata(hdev);
struct btusb_data *data = hdev->driver_data;
struct urb *urb;
unsigned char *buf;
unsigned int pipe;
@ -415,8 +391,7 @@ static int btusb_submit_bulk_urb(struct hci_dev *hdev, gfp_t mem_flags)
err = usb_submit_urb(urb, mem_flags);
if (err < 0) {
if (err != -EPERM && err != -ENODEV)
BT_ERR("%s urb %p submission failed (%d)",
BT_ERR("%s urb %p submission failed (%d)",
hdev->name, urb, -err);
usb_unanchor_urb(urb);
}
@ -429,7 +404,7 @@ static int btusb_submit_bulk_urb(struct hci_dev *hdev, gfp_t mem_flags)
static void btusb_isoc_complete(struct urb *urb)
{
struct hci_dev *hdev = urb->context;
struct btusb_data *data = hci_get_drvdata(hdev);
struct btusb_data *data = hdev->driver_data;
int i, err;
BT_DBG("%s urb %p status %d count %d", hdev->name,
@ -464,16 +439,14 @@ static void btusb_isoc_complete(struct urb *urb)
err = usb_submit_urb(urb, GFP_ATOMIC);
if (err < 0) {
/* -EPERM: urb is being killed;
* -ENODEV: device got disconnected */
if (err != -EPERM && err != -ENODEV)
if (err != -EPERM)
BT_ERR("%s urb %p failed to resubmit (%d)",
hdev->name, urb, -err);
usb_unanchor_urb(urb);
}
}
static inline void __fill_isoc_descriptor(struct urb *urb, int len, int mtu)
static void inline __fill_isoc_descriptor(struct urb *urb, int len, int mtu)
{
int i, offset = 0;
@ -496,7 +469,7 @@ static inline void __fill_isoc_descriptor(struct urb *urb, int len, int mtu)
static int btusb_submit_isoc_urb(struct hci_dev *hdev, gfp_t mem_flags)
{
struct btusb_data *data = hci_get_drvdata(hdev);
struct btusb_data *data = hdev->driver_data;
struct urb *urb;
unsigned char *buf;
unsigned int pipe;
@ -522,10 +495,15 @@ static int btusb_submit_isoc_urb(struct hci_dev *hdev, gfp_t mem_flags)
pipe = usb_rcvisocpipe(data->udev, data->isoc_rx_ep->bEndpointAddress);
usb_fill_int_urb(urb, data->udev, pipe, buf, size, btusb_isoc_complete,
hdev, data->isoc_rx_ep->bInterval);
urb->dev = data->udev;
urb->pipe = pipe;
urb->context = hdev;
urb->complete = btusb_isoc_complete;
urb->interval = data->isoc_rx_ep->bInterval;
urb->transfer_flags = URB_FREE_BUFFER | URB_ISO_ASAP;
urb->transfer_buffer = buf;
urb->transfer_buffer_length = size;
__fill_isoc_descriptor(urb, size,
le16_to_cpu(data->isoc_rx_ep->wMaxPacketSize));
@ -534,8 +512,7 @@ static int btusb_submit_isoc_urb(struct hci_dev *hdev, gfp_t mem_flags)
err = usb_submit_urb(urb, mem_flags);
if (err < 0) {
if (err != -EPERM && err != -ENODEV)
BT_ERR("%s urb %p submission failed (%d)",
BT_ERR("%s urb %p submission failed (%d)",
hdev->name, urb, -err);
usb_unanchor_urb(urb);
}
@ -549,7 +526,7 @@ static void btusb_tx_complete(struct urb *urb)
{
struct sk_buff *skb = urb->context;
struct hci_dev *hdev = (struct hci_dev *) skb->dev;
struct btusb_data *data = hci_get_drvdata(hdev);
struct btusb_data *data = hdev->driver_data;
BT_DBG("%s urb %p status %d count %d", hdev->name,
urb, urb->status, urb->actual_length);
@ -596,7 +573,7 @@ done:
static int btusb_open(struct hci_dev *hdev)
{
struct btusb_data *data = hci_get_drvdata(hdev);
struct btusb_data *data = hdev->driver_data;
int err;
BT_DBG("%s", hdev->name);
@ -646,7 +623,7 @@ static void btusb_stop_traffic(struct btusb_data *data)
static int btusb_close(struct hci_dev *hdev)
{
struct btusb_data *data = hci_get_drvdata(hdev);
struct btusb_data *data = hdev->driver_data;
int err;
BT_DBG("%s", hdev->name);
@ -676,7 +653,7 @@ failed:
static int btusb_flush(struct hci_dev *hdev)
{
struct btusb_data *data = hci_get_drvdata(hdev);
struct btusb_data *data = hdev->driver_data;
BT_DBG("%s", hdev->name);
@ -688,7 +665,7 @@ static int btusb_flush(struct hci_dev *hdev)
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 btusb_data *data = hdev->driver_data;
struct usb_ctrlrequest *dr;
struct urb *urb;
unsigned int pipe;
@ -782,23 +759,31 @@ skip_waking:
err = usb_submit_urb(urb, GFP_ATOMIC);
if (err < 0) {
if (err != -EPERM && err != -ENODEV)
BT_ERR("%s urb %p submission failed (%d)",
hdev->name, urb, -err);
BT_ERR("%s urb %p submission failed", hdev->name, urb);
kfree(urb->setup_packet);
usb_unanchor_urb(urb);
} else {
usb_mark_last_busy(data->udev);
}
done:
usb_free_urb(urb);
done:
return err;
}
static void btusb_destruct(struct hci_dev *hdev)
{
struct btusb_data *data = hdev->driver_data;
BT_DBG("%s", hdev->name);
kfree(data);
}
static void btusb_notify(struct hci_dev *hdev, unsigned int evt)
{
struct btusb_data *data = hci_get_drvdata(hdev);
struct btusb_data *data = hdev->driver_data;
BT_DBG("%s evt %d", hdev->name, evt);
@ -808,9 +793,9 @@ static void btusb_notify(struct hci_dev *hdev, unsigned int evt)
}
}
static inline int __set_isoc_interface(struct hci_dev *hdev, int altsetting)
static int inline __set_isoc_interface(struct hci_dev *hdev, int altsetting)
{
struct btusb_data *data = hci_get_drvdata(hdev);
struct btusb_data *data = hdev->driver_data;
struct usb_interface *intf = data->isoc;
struct usb_endpoint_descriptor *ep_desc;
int i, err;
@ -998,7 +983,7 @@ static int btusb_probe(struct usb_interface *intf,
}
hdev->bus = HCI_USB;
hci_set_drvdata(hdev, data);
hdev->driver_data = data;
data->hdev = hdev;
@ -1008,8 +993,11 @@ static int btusb_probe(struct usb_interface *intf,
hdev->close = btusb_close;
hdev->flush = btusb_flush;
hdev->send = btusb_send_frame;
hdev->destruct = btusb_destruct;
hdev->notify = btusb_notify;
hdev->owner = THIS_MODULE;
/* Interface numbers are hardcoded in the specification */
data->isoc = usb_ifnum_to_if(data->udev, 1);
@ -1091,6 +1079,9 @@ static void btusb_disconnect(struct usb_interface *intf)
return;
hdev = data->hdev;
__hci_dev_hold(hdev);
usb_set_intfdata(data->intf, NULL);
if (data->isoc)
@ -1103,8 +1094,9 @@ static void btusb_disconnect(struct usb_interface *intf)
else if (data->isoc)
usb_driver_release_interface(&btusb_driver, data->isoc);
__hci_dev_put(hdev);
hci_free_dev(hdev);
kfree(data);
}
#ifdef CONFIG_PM
@ -1118,7 +1110,7 @@ static int btusb_suspend(struct usb_interface *intf, pm_message_t message)
return 0;
spin_lock_irq(&data->txlock);
if (!(PMSG_IS_AUTO(message) && data->tx_in_flight)) {
if (!((message.event & PM_EVENT_AUTO) && data->tx_in_flight)) {
set_bit(BTUSB_SUSPENDING, &data->flags);
spin_unlock_irq(&data->txlock);
} else {
@ -1220,7 +1212,20 @@ static struct usb_driver btusb_driver = {
.supports_autosuspend = 1,
};
module_usb_driver(btusb_driver);
static int __init btusb_init(void)
{
BT_INFO("Generic Bluetooth USB driver ver %s", VERSION);
return usb_register(&btusb_driver);
}
static void __exit btusb_exit(void)
{
usb_deregister(&btusb_driver);
}
module_init(btusb_init);
module_exit(btusb_exit);
module_param(ignore_dga, bool, 0644);
MODULE_PARM_DESC(ignore_dga, "Ignore devices with id 08fd:0001");

View file

@ -29,7 +29,6 @@
#include <net/bluetooth/hci.h>
#include <linux/ti_wilink_st.h>
#include <linux/module.h>
/* Bluetooth Driver Version */
#define VERSION "1.0"
@ -125,13 +124,6 @@ static long st_receive(void *priv_data, struct sk_buff *skb)
/* ------- Interfaces to HCI layer ------ */
/* protocol structure registered with shared transport */
static struct st_proto_s ti_st_proto[MAX_BT_CHNL_IDS] = {
{
.chnl_id = HCI_EVENT_PKT, /* HCI Events */
.hdr_len = sizeof(struct hci_event_hdr),
.offset_len_in_hdr = offsetof(struct hci_event_hdr, plen),
.len_size = 1, /* sizeof(plen) in struct hci_event_hdr */
.reserve = 8,
},
{
.chnl_id = HCI_ACLDATA_PKT, /* ACL */
.hdr_len = sizeof(struct hci_acl_hdr),
@ -146,6 +138,13 @@ static struct st_proto_s ti_st_proto[MAX_BT_CHNL_IDS] = {
.len_size = 1, /* sizeof(dlen) in struct hci_sco_hdr */
.reserve = 8,
},
{
.chnl_id = HCI_EVENT_PKT, /* HCI Events */
.hdr_len = sizeof(struct hci_event_hdr),
.offset_len_in_hdr = offsetof(struct hci_event_hdr, plen),
.len_size = 1, /* sizeof(plen) in struct hci_event_hdr */
.reserve = 8,
},
};
/* Called from HCI core to initialize the device */
@ -161,7 +160,7 @@ static int ti_st_open(struct hci_dev *hdev)
return -EBUSY;
/* provide contexts for callbacks from ST */
hst = hci_get_drvdata(hdev);
hst = hdev->driver_data;
for (i = 0; i < MAX_BT_CHNL_IDS; i++) {
ti_st_proto[i].priv_data = hst;
@ -236,12 +235,12 @@ done:
static int ti_st_close(struct hci_dev *hdev)
{
int err, i;
struct ti_st *hst = hci_get_drvdata(hdev);
struct ti_st *hst = hdev->driver_data;
if (!test_and_clear_bit(HCI_RUNNING, &hdev->flags))
return 0;
for (i = MAX_BT_CHNL_IDS-1; i >= 0; i--) {
for (i = 0; i < MAX_BT_CHNL_IDS; i++) {
err = st_unregister(&ti_st_proto[i]);
if (err)
BT_ERR("st_unregister(%d) failed with error %d",
@ -264,7 +263,7 @@ static int ti_st_send_frame(struct sk_buff *skb)
if (!test_bit(HCI_RUNNING, &hdev->flags))
return -EBUSY;
hst = hci_get_drvdata(hdev);
hst = hdev->driver_data;
/* Prepend skb with frame type */
memcpy(skb_push(skb, 1), &bt_cb(skb)->pkt_type, 1);
@ -291,6 +290,14 @@ static int ti_st_send_frame(struct sk_buff *skb)
return 0;
}
static void ti_st_destruct(struct hci_dev *hdev)
{
BT_DBG("%s", hdev->name);
/* do nothing here, since platform remove
* would free the hdev->driver_data
*/
}
static int bt_ti_probe(struct platform_device *pdev)
{
static struct ti_st *hst;
@ -312,11 +319,13 @@ static int bt_ti_probe(struct platform_device *pdev)
hst->hdev = hdev;
hdev->bus = HCI_UART;
hci_set_drvdata(hdev, hst);
hdev->driver_data = hst;
hdev->open = ti_st_open;
hdev->close = ti_st_close;
hdev->flush = NULL;
hdev->send = ti_st_send_frame;
hdev->destruct = ti_st_destruct;
hdev->owner = THIS_MODULE;
err = hci_register_dev(hdev);
if (err < 0) {

View file

@ -38,6 +38,7 @@
#include <linux/serial.h>
#include <linux/serial_reg.h>
#include <linux/bitops.h>
#include <asm/system.h>
#include <asm/io.h>
#include <pcmcia/cistpl.h>
@ -82,6 +83,9 @@ typedef struct dtl1_info_t {
static int dtl1_config(struct pcmcia_device *link);
static void dtl1_release(struct pcmcia_device *link);
static void dtl1_detach(struct pcmcia_device *p_dev);
/* Transmit states */
@ -363,7 +367,7 @@ static int dtl1_hci_open(struct hci_dev *hdev)
static int dtl1_hci_flush(struct hci_dev *hdev)
{
dtl1_info_t *info = hci_get_drvdata(hdev);
dtl1_info_t *info = (dtl1_info_t *)(hdev->driver_data);
/* Drop TX queue */
skb_queue_purge(&(info->txq));
@ -395,7 +399,7 @@ static int dtl1_hci_send_frame(struct sk_buff *skb)
return -ENODEV;
}
info = hci_get_drvdata(hdev);
info = (dtl1_info_t *)(hdev->driver_data);
switch (bt_cb(skb)->pkt_type) {
case HCI_COMMAND_PKT:
@ -438,6 +442,11 @@ static int dtl1_hci_send_frame(struct sk_buff *skb)
}
static void dtl1_hci_destruct(struct hci_dev *hdev)
{
}
static int dtl1_hci_ioctl(struct hci_dev *hdev, unsigned int cmd, unsigned long arg)
{
return -ENOIOCTLCMD;
@ -474,15 +483,18 @@ static int dtl1_open(dtl1_info_t *info)
info->hdev = hdev;
hdev->bus = HCI_PCCARD;
hci_set_drvdata(hdev, info);
hdev->driver_data = 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->destruct = dtl1_hci_destruct;
hdev->ioctl = dtl1_hci_ioctl;
hdev->owner = THIS_MODULE;
spin_lock_irqsave(&(info->lock), flags);
/* Reset UART */
@ -539,7 +551,9 @@ static int dtl1_close(dtl1_info_t *info)
spin_unlock_irqrestore(&(info->lock), flags);
hci_unregister_dev(hdev);
if (hci_unregister_dev(hdev) < 0)
BT_ERR("Can't unregister HCI device %s", hdev->name);
hci_free_dev(hdev);
return 0;
@ -567,8 +581,8 @@ static void dtl1_detach(struct pcmcia_device *link)
{
dtl1_info_t *info = link->priv;
dtl1_close(info);
pcmcia_disable_device(link);
dtl1_release(link);
kfree(info);
}
@ -607,11 +621,22 @@ static int dtl1_config(struct pcmcia_device *link)
return 0;
failed:
dtl1_detach(link);
dtl1_release(link);
return -ENODEV;
}
static const struct pcmcia_device_id dtl1_ids[] = {
static void dtl1_release(struct pcmcia_device *link)
{
dtl1_info_t *info = link->priv;
dtl1_close(info);
pcmcia_disable_device(link);
}
static struct pcmcia_device_id dtl1_ids[] = {
PCMCIA_DEVICE_PROD_ID12("Nokia Mobile Phones", "DTL-1", 0xe1bfdd64, 0xe168480d),
PCMCIA_DEVICE_PROD_ID12("Nokia Mobile Phones", "DTL-4", 0xe1bfdd64, 0x9102bc82),
PCMCIA_DEVICE_PROD_ID12("Socket", "CF", 0xb38bcc2e, 0x44ebf863),

View file

@ -112,7 +112,7 @@ static int ath_open(struct hci_uart *hu)
BT_DBG("hu %p", hu);
ath = kzalloc(sizeof(*ath), GFP_KERNEL);
ath = kzalloc(sizeof(*ath), GFP_ATOMIC);
if (!ath)
return -ENOMEM;

View file

@ -49,8 +49,8 @@
#define VERSION "0.3"
static bool txcrc = 1;
static bool hciextn = 1;
static int txcrc = 1;
static int hciextn = 1;
#define BCSP_TXWINSIZE 4
@ -692,7 +692,7 @@ static int bcsp_open(struct hci_uart *hu)
BT_DBG("hu %p", hu);
bcsp = kzalloc(sizeof(*bcsp), GFP_KERNEL);
bcsp = kzalloc(sizeof(*bcsp), GFP_ATOMIC);
if (!bcsp)
return -ENOMEM;

View file

@ -69,7 +69,7 @@ static int h4_open(struct hci_uart *hu)
BT_DBG("hu %p", hu);
h4 = kzalloc(sizeof(*h4), GFP_KERNEL);
h4 = kzalloc(sizeof(*h4), GFP_ATOMIC);
if (!h4)
return -ENOMEM;

View file

@ -48,6 +48,8 @@
#define VERSION "2.2"
static bool reset = 0;
static struct hci_uart_proto *hup[HCI_UART_MAX_PROTO];
int hci_uart_register_proto(struct hci_uart_proto *p)
@ -172,7 +174,7 @@ static int hci_uart_open(struct hci_dev *hdev)
/* Reset device */
static int hci_uart_flush(struct hci_dev *hdev)
{
struct hci_uart *hu = hci_get_drvdata(hdev);
struct hci_uart *hu = (struct hci_uart *) hdev->driver_data;
struct tty_struct *tty = hu->tty;
BT_DBG("hdev %p tty %p", hdev, tty);
@ -218,7 +220,7 @@ static int hci_uart_send_frame(struct sk_buff *skb)
if (!test_bit(HCI_RUNNING, &hdev->flags))
return -EBUSY;
hu = hci_get_drvdata(hdev);
hu = (struct hci_uart *) hdev->driver_data;
BT_DBG("%s: type %d len %d", hdev->name, bt_cb(skb)->pkt_type, skb->len);
@ -229,6 +231,15 @@ static int hci_uart_send_frame(struct sk_buff *skb)
return 0;
}
static void hci_uart_destruct(struct hci_dev *hdev)
{
if (!hdev)
return;
BT_DBG("%s", hdev->name);
kfree(hdev->driver_data);
}
/* ------ LDISC part ------ */
/* hci_uart_tty_open
*
@ -299,14 +310,12 @@ static void hci_uart_tty_close(struct tty_struct *tty)
hci_uart_close(hdev);
if (test_and_clear_bit(HCI_UART_PROTO_SET, &hu->flags)) {
hu->proto->close(hu);
if (hdev) {
hci_unregister_dev(hdev);
hci_free_dev(hdev);
}
hu->proto->close(hu);
}
kfree(hu);
}
}
@ -350,6 +359,7 @@ static void hci_uart_tty_wakeup(struct tty_struct *tty)
*/
static void hci_uart_tty_receive(struct tty_struct *tty, const u8 *data, char *flags, int count)
{
int ret;
struct hci_uart *hu = (void *)tty->disc_data;
if (!hu || tty != hu->tty)
@ -359,8 +369,9 @@ static void hci_uart_tty_receive(struct tty_struct *tty, const u8 *data, char *f
return;
spin_lock(&hu->rx_lock);
hu->proto->recv(hu, (void *) data, count);
hu->hdev->stat.byte_rx += count;
ret = hu->proto->recv(hu, (void *) data, count);
if (ret > 0)
hu->hdev->stat.byte_rx += count;
spin_unlock(&hu->rx_lock);
tty_unthrottle(tty);
@ -382,25 +393,23 @@ static int hci_uart_register_dev(struct hci_uart *hu)
hu->hdev = hdev;
hdev->bus = HCI_UART;
hci_set_drvdata(hdev, hu);
hdev->driver_data = hu;
hdev->open = hci_uart_open;
hdev->close = hci_uart_close;
hdev->flush = hci_uart_flush;
hdev->send = hci_uart_send_frame;
hdev->destruct = hci_uart_destruct;
hdev->parent = hu->tty->dev;
hdev->owner = THIS_MODULE;
if (!reset)
set_bit(HCI_QUIRK_NO_RESET, &hdev->quirks);
if (test_bit(HCI_UART_RAW_DEVICE, &hu->hdev_flags))
set_bit(HCI_QUIRK_RAW_DEVICE, &hdev->quirks);
if (!test_bit(HCI_UART_RESET_ON_INIT, &hu->hdev_flags))
set_bit(HCI_QUIRK_NO_RESET, &hdev->quirks);
if (test_bit(HCI_UART_CREATE_AMP, &hu->hdev_flags))
hdev->dev_type = HCI_AMP;
else
hdev->dev_type = HCI_BREDR;
if (hci_register_dev(hdev) < 0) {
BT_ERR("Can't register HCI device");
hci_free_dev(hdev);
@ -587,6 +596,9 @@ static void __exit hci_uart_exit(void)
module_init(hci_uart_init);
module_exit(hci_uart_exit);
module_param(reset, bool, 0644);
MODULE_PARM_DESC(reset, "Send HCI reset command on initialization");
MODULE_AUTHOR("Marcel Holtmann <marcel@holtmann.org>");
MODULE_DESCRIPTION("Bluetooth HCI UART driver ver " VERSION);
MODULE_VERSION(VERSION);

View file

@ -125,7 +125,7 @@ static int ll_open(struct hci_uart *hu)
BT_DBG("hu %p", hu);
ll = kzalloc(sizeof(*ll), GFP_KERNEL);
ll = kzalloc(sizeof(*ll), GFP_ATOMIC);
if (!ll)
return -ENOMEM;
@ -207,7 +207,7 @@ static void ll_device_want_to_wakeup(struct hci_uart *hu)
/*
* This state means that both the host and the BRF chip
* have simultaneously sent a wake-up-indication packet.
* Traditionally, in this case, receiving a wake-up-indication
* Traditionaly, in this case, receiving a wake-up-indication
* was enough and an additional wake-up-ack wasn't needed.
* This has changed with the BRF6350, which does require an
* explicit wake-up-ack. Other BRF versions, which do not

View file

@ -45,8 +45,6 @@
#define HCI_UART_ATH3K 5
#define HCI_UART_RAW_DEVICE 0
#define HCI_UART_RESET_ON_INIT 1
#define HCI_UART_CREATE_AMP 2
struct hci_uart;

View file

@ -41,8 +41,6 @@
#define VERSION "1.3"
static bool amp;
struct vhci_data {
struct hci_dev *hdev;
@ -61,7 +59,7 @@ static int vhci_open_dev(struct hci_dev *hdev)
static int vhci_close_dev(struct hci_dev *hdev)
{
struct vhci_data *data = hci_get_drvdata(hdev);
struct vhci_data *data = hdev->driver_data;
if (!test_and_clear_bit(HCI_RUNNING, &hdev->flags))
return 0;
@ -73,7 +71,7 @@ static int vhci_close_dev(struct hci_dev *hdev)
static int vhci_flush(struct hci_dev *hdev)
{
struct vhci_data *data = hci_get_drvdata(hdev);
struct vhci_data *data = hdev->driver_data;
skb_queue_purge(&data->readq);
@ -93,7 +91,7 @@ static int vhci_send_frame(struct sk_buff *skb)
if (!test_bit(HCI_RUNNING, &hdev->flags))
return -EBUSY;
data = hci_get_drvdata(hdev);
data = hdev->driver_data;
memcpy(skb_push(skb, 1), &bt_cb(skb)->pkt_type, 1);
skb_queue_tail(&data->readq, skb);
@ -103,6 +101,11 @@ static int vhci_send_frame(struct sk_buff *skb)
return 0;
}
static void vhci_destruct(struct hci_dev *hdev)
{
kfree(hdev->driver_data);
}
static inline ssize_t vhci_get_user(struct vhci_data *data,
const char __user *buf, size_t count)
{
@ -234,15 +237,15 @@ static int vhci_open(struct inode *inode, struct file *file)
data->hdev = hdev;
hdev->bus = HCI_VIRTUAL;
hci_set_drvdata(hdev, data);
if (amp)
hdev->dev_type = HCI_AMP;
hdev->driver_data = data;
hdev->open = vhci_open_dev;
hdev->close = vhci_close_dev;
hdev->flush = vhci_flush;
hdev->send = vhci_send_frame;
hdev->destruct = vhci_destruct;
hdev->owner = THIS_MODULE;
if (hci_register_dev(hdev) < 0) {
BT_ERR("Can't register HCI device");
@ -261,11 +264,13 @@ static int vhci_release(struct inode *inode, struct file *file)
struct vhci_data *data = file->private_data;
struct hci_dev *hdev = data->hdev;
hci_unregister_dev(hdev);
if (hci_unregister_dev(hdev) < 0) {
BT_ERR("Can't unregister HCI device %s", hdev->name);
}
hci_free_dev(hdev);
file->private_data = NULL;
kfree(data);
return 0;
}
@ -301,9 +306,6 @@ static void __exit vhci_exit(void)
module_init(vhci_init);
module_exit(vhci_exit);
module_param(amp, bool, 0644);
MODULE_PARM_DESC(amp, "Create AMP controller device");
MODULE_AUTHOR("Marcel Holtmann <marcel@holtmann.org>");
MODULE_DESCRIPTION("Bluetooth virtual HCI driver ver " VERSION);
MODULE_VERSION(VERSION);