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. The core driver to support Marvell Bluetooth devices.
This driver is required if you want to support 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 Say Y here to compile Marvell Bluetooth driver
into the kernel or say M to compile it as module. into the kernel or say M to compile it as module.

View file

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

View file

@ -24,7 +24,6 @@
#include <linux/module.h> #include <linux/module.h>
#include <linux/atomic.h>
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/init.h> #include <linux/init.h>
#include <linux/slab.h> #include <linux/slab.h>
@ -66,7 +65,6 @@ struct bcm203x_data {
unsigned long state; unsigned long state;
struct work_struct work; struct work_struct work;
atomic_t shutdown;
struct urb *urb; struct urb *urb;
unsigned char *buffer; unsigned char *buffer;
@ -99,7 +97,6 @@ static void bcm203x_complete(struct urb *urb)
data->state = BCM203X_SELECT_MEMORY; data->state = BCM203X_SELECT_MEMORY;
/* use workqueue to have a small delay */
schedule_work(&data->work); schedule_work(&data->work);
break; break;
@ -158,10 +155,7 @@ static void bcm203x_work(struct work_struct *work)
struct bcm203x_data *data = struct bcm203x_data *data =
container_of(work, struct bcm203x_data, work); container_of(work, struct bcm203x_data, work);
if (atomic_read(&data->shutdown)) if (usb_submit_urb(data->urb, GFP_ATOMIC) < 0)
return;
if (usb_submit_urb(data->urb, GFP_KERNEL) < 0)
BT_ERR("Can't submit URB"); 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); usb_set_intfdata(intf, data);
/* use workqueue to have a small delay */
schedule_work(&data->work); schedule_work(&data->work);
return 0; return 0;
@ -261,9 +254,6 @@ static void bcm203x_disconnect(struct usb_interface *intf)
BT_DBG("intf %p", intf); BT_DBG("intf %p", intf);
atomic_inc(&data->shutdown);
cancel_work_sync(&data->work);
usb_kill_urb(data->urb); usb_kill_urb(data->urb);
usb_set_intfdata(intf, NULL); usb_set_intfdata(intf, NULL);
@ -281,7 +271,26 @@ static struct usb_driver bcm203x_driver = {
.id_table = bcm203x_table, .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_AUTHOR("Marcel Holtmann <marcel@holtmann.org>");
MODULE_DESCRIPTION("Broadcom Blutonium firmware driver ver " VERSION); MODULE_DESCRIPTION("Broadcom Blutonium firmware driver ver " VERSION);

View file

@ -411,7 +411,7 @@ unlock:
static int bfusb_open(struct hci_dev *hdev) 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; unsigned long flags;
int i, err; int i, err;
@ -437,7 +437,7 @@ static int bfusb_open(struct hci_dev *hdev)
static int bfusb_flush(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); 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) 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; unsigned long flags;
BT_DBG("hdev %p bfusb %p", hdev, data); 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)) if (!test_bit(HCI_RUNNING, &hdev->flags))
return -EBUSY; return -EBUSY;
data = hci_get_drvdata(hdev); data = hdev->driver_data;
switch (bt_cb(skb)->pkt_type) { switch (bt_cb(skb)->pkt_type) {
case HCI_COMMAND_PKT: case HCI_COMMAND_PKT:
@ -544,6 +544,15 @@ static int bfusb_send_frame(struct sk_buff *skb)
return 0; 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) static int bfusb_ioctl(struct hci_dev *hdev, unsigned int cmd, unsigned long arg)
{ {
return -ENOIOCTLCMD; return -ENOIOCTLCMD;
@ -559,23 +568,22 @@ static int bfusb_load_firmware(struct bfusb_data *data,
BT_INFO("BlueFRITZ! USB loading firmware"); 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); pipe = usb_sndctrlpipe(data->udev, 0);
if (usb_control_msg(data->udev, pipe, USB_REQ_SET_CONFIGURATION, if (usb_control_msg(data->udev, pipe, USB_REQ_SET_CONFIGURATION,
0, 1, 0, NULL, 0, USB_CTRL_SET_TIMEOUT) < 0) { 0, 1, 0, NULL, 0, USB_CTRL_SET_TIMEOUT) < 0) {
BT_ERR("Can't change to loading configuration"); BT_ERR("Can't change to loading configuration");
kfree(buf);
return -EBUSY; return -EBUSY;
} }
data->udev->toggle[0] = data->udev->toggle[1] = 0; 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); pipe = usb_sndbulkpipe(data->udev, data->bulk_out_ep);
while (count) { while (count) {
@ -696,15 +704,18 @@ static int bfusb_probe(struct usb_interface *intf, const struct usb_device_id *i
data->hdev = hdev; data->hdev = hdev;
hdev->bus = HCI_USB; hdev->bus = HCI_USB;
hci_set_drvdata(hdev, data); hdev->driver_data = data;
SET_HCIDEV_DEV(hdev, &intf->dev); SET_HCIDEV_DEV(hdev, &intf->dev);
hdev->open = bfusb_open; hdev->open = bfusb_open;
hdev->close = bfusb_close; hdev->close = bfusb_close;
hdev->flush = bfusb_flush; hdev->flush = bfusb_flush;
hdev->send = bfusb_send_frame; hdev->send = bfusb_send_frame;
hdev->destruct = bfusb_destruct;
hdev->ioctl = bfusb_ioctl; hdev->ioctl = bfusb_ioctl;
hdev->owner = THIS_MODULE;
if (hci_register_dev(hdev) < 0) { if (hci_register_dev(hdev) < 0) {
BT_ERR("Can't register HCI device"); BT_ERR("Can't register HCI device");
hci_free_dev(hdev); hci_free_dev(hdev);
@ -739,9 +750,10 @@ static void bfusb_disconnect(struct usb_interface *intf)
bfusb_close(hdev); 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); hci_free_dev(hdev);
kfree(data);
} }
static struct usb_driver bfusb_driver = { static struct usb_driver bfusb_driver = {
@ -751,7 +763,26 @@ static struct usb_driver bfusb_driver = {
.id_table = bfusb_table, .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_AUTHOR("Marcel Holtmann <marcel@holtmann.org>");
MODULE_DESCRIPTION("BlueFRITZ! USB driver ver " VERSION); 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) 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; struct sk_buff *skb;
/* Ericsson baud rate command */ /* 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) 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 */ /* Drop TX queue */
skb_queue_purge(&(info->txq)); 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) 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; unsigned int iobase = info->p_dev->resource[0]->start;
if (test_bit(CARD_HAS_PCCARD_ID, &(info->hw_state))) 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) 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; unsigned int iobase = info->p_dev->resource[0]->start;
if (!test_and_clear_bit(HCI_RUNNING, &(hdev->flags))) 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; return -ENODEV;
} }
info = hci_get_drvdata(hdev); info = (bluecard_info_t *)(hdev->driver_data);
switch (bt_cb(skb)->pkt_type) { switch (bt_cb(skb)->pkt_type) {
case HCI_COMMAND_PKT: 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) static int bluecard_hci_ioctl(struct hci_dev *hdev, unsigned int cmd, unsigned long arg)
{ {
return -ENOIOCTLCMD; return -ENOIOCTLCMD;
@ -729,15 +734,18 @@ static int bluecard_open(bluecard_info_t *info)
info->hdev = hdev; info->hdev = hdev;
hdev->bus = HCI_PCCARD; hdev->bus = HCI_PCCARD;
hci_set_drvdata(hdev, info); hdev->driver_data = info;
SET_HCIDEV_DEV(hdev, &info->p_dev->dev); SET_HCIDEV_DEV(hdev, &info->p_dev->dev);
hdev->open = bluecard_hci_open; hdev->open = bluecard_hci_open;
hdev->close = bluecard_hci_close; hdev->close = bluecard_hci_close;
hdev->flush = bluecard_hci_flush; hdev->flush = bluecard_hci_flush;
hdev->send = bluecard_hci_send_frame; hdev->send = bluecard_hci_send_frame;
hdev->destruct = bluecard_hci_destruct;
hdev->ioctl = bluecard_hci_ioctl; hdev->ioctl = bluecard_hci_ioctl;
hdev->owner = THIS_MODULE;
id = inb(iobase + 0x30); id = inb(iobase + 0x30);
if ((id & 0x0f) == 0x02) if ((id & 0x0f) == 0x02)
@ -836,7 +844,9 @@ static int bluecard_close(bluecard_info_t *info)
/* Turn FPGA off */ /* Turn FPGA off */
outb(0x80, iobase + 0x30); 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); hci_free_dev(hdev);
return 0; return 0;
@ -920,7 +930,7 @@ static void bluecard_release(struct pcmcia_device *link)
pcmcia_disable_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("BlueCard", "LSE041", 0xbaf16fbf, 0x657cc15e),
PCMCIA_DEVICE_PROD_ID12("BTCFCARD", "LSE139", 0xe3987764, 0x2524b59c), PCMCIA_DEVICE_PROD_ID12("BTCFCARD", "LSE139", 0xe3987764, 0x2524b59c),
PCMCIA_DEVICE_PROD_ID12("WSS", "LSE039", 0x0a0736ec, 0x24e6dfab), 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) 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, BT_DBG("%s queue %d buffer %p count %d", hdev->name,
queue, buf, count); queue, buf, count);
@ -189,7 +189,7 @@ done:
static void bpa10x_rx_complete(struct urb *urb) static void bpa10x_rx_complete(struct urb *urb)
{ {
struct hci_dev *hdev = urb->context; struct hci_dev *hdev = urb->context;
struct bpa10x_data *data = hci_get_drvdata(hdev); struct bpa10x_data *data = hdev->driver_data;
int err; int err;
BT_DBG("%s urb %p status %d count %d", hdev->name, 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) 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; struct urb *urb;
unsigned char *buf; unsigned char *buf;
unsigned int pipe; 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) 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; struct urb *urb;
unsigned char *buf; unsigned char *buf;
unsigned int pipe; 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) 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; int err;
BT_DBG("%s", hdev->name); BT_DBG("%s", hdev->name);
@ -329,7 +329,7 @@ error:
static int bpa10x_close(struct hci_dev *hdev) 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); 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) 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); 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) static int bpa10x_send_frame(struct sk_buff *skb)
{ {
struct hci_dev *hdev = (struct hci_dev *) skb->dev; 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 usb_ctrlrequest *dr;
struct urb *urb; struct urb *urb;
unsigned int pipe; unsigned int pipe;
@ -432,6 +432,17 @@ static int bpa10x_send_frame(struct sk_buff *skb)
return 0; 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) static int bpa10x_probe(struct usb_interface *intf, const struct usb_device_id *id)
{ {
struct bpa10x_data *data; 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; hdev->bus = HCI_USB;
hci_set_drvdata(hdev, data); hdev->driver_data = data;
data->hdev = hdev; 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->close = bpa10x_close;
hdev->flush = bpa10x_flush; hdev->flush = bpa10x_flush;
hdev->send = bpa10x_send_frame; hdev->send = bpa10x_send_frame;
hdev->destruct = bpa10x_destruct;
hdev->owner = THIS_MODULE;
set_bit(HCI_QUIRK_NO_RESET, &hdev->quirks); 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_unregister_dev(data->hdev);
hci_free_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 = { static struct usb_driver bpa10x_driver = {
@ -510,7 +521,20 @@ static struct usb_driver bpa10x_driver = {
.id_table = bpa10x_table, .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_AUTHOR("Marcel Holtmann <marcel@holtmann.org>");
MODULE_DESCRIPTION("Digianswer Bluetooth USB driver ver " VERSION); MODULE_DESCRIPTION("Digianswer Bluetooth USB driver ver " VERSION);

View file

@ -39,6 +39,7 @@
#include <linux/serial.h> #include <linux/serial.h>
#include <linux/serial_reg.h> #include <linux/serial_reg.h>
#include <linux/bitops.h> #include <linux/bitops.h>
#include <asm/system.h>
#include <asm/io.h> #include <asm/io.h>
#include <linux/device.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) 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 */ /* Drop TX queue */
skb_queue_purge(&(info->txq)); skb_queue_purge(&(info->txq));
@ -427,7 +428,7 @@ static int bt3c_hci_send_frame(struct sk_buff *skb)
return -ENODEV; return -ENODEV;
} }
info = hci_get_drvdata(hdev); info = (bt3c_info_t *) (hdev->driver_data);
switch (bt_cb(skb)->pkt_type) { switch (bt_cb(skb)->pkt_type) {
case HCI_COMMAND_PKT: 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) static int bt3c_hci_ioctl(struct hci_dev *hdev, unsigned int cmd, unsigned long arg)
{ {
return -ENOIOCTLCMD; return -ENOIOCTLCMD;
@ -574,15 +580,18 @@ static int bt3c_open(bt3c_info_t *info)
info->hdev = hdev; info->hdev = hdev;
hdev->bus = HCI_PCCARD; hdev->bus = HCI_PCCARD;
hci_set_drvdata(hdev, info); hdev->driver_data = info;
SET_HCIDEV_DEV(hdev, &info->p_dev->dev); SET_HCIDEV_DEV(hdev, &info->p_dev->dev);
hdev->open = bt3c_hci_open; hdev->open = bt3c_hci_open;
hdev->close = bt3c_hci_close; hdev->close = bt3c_hci_close;
hdev->flush = bt3c_hci_flush; hdev->flush = bt3c_hci_flush;
hdev->send = bt3c_hci_send_frame; hdev->send = bt3c_hci_send_frame;
hdev->destruct = bt3c_hci_destruct;
hdev->ioctl = bt3c_hci_ioctl; hdev->ioctl = bt3c_hci_ioctl;
hdev->owner = THIS_MODULE;
/* Load firmware */ /* Load firmware */
err = request_firmware(&firmware, "BT3CPCC.bin", &info->p_dev->dev); err = request_firmware(&firmware, "BT3CPCC.bin", &info->p_dev->dev);
if (err < 0) { if (err < 0) {
@ -627,7 +636,9 @@ static int bt3c_close(bt3c_info_t *info)
bt3c_hci_close(hdev); 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); hci_free_dev(hdev);
return 0; 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_PROD_ID13("3COM", "Bluetooth PC Card", 0xefce0a31, 0xd4ce9b02),
PCMCIA_DEVICE_NULL PCMCIA_DEVICE_NULL
}; };

View file

@ -45,6 +45,12 @@ struct btmrvl_debugfs_data {
struct dentry *txdnldready; 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, static ssize_t btmrvl_hscfgcmd_write(struct file *file,
const char __user *ubuf, size_t count, loff_t *ppos) 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; return -EFAULT;
ret = strict_strtol(buf, 10, &result); ret = strict_strtol(buf, 10, &result);
if (ret)
return ret;
priv->btmrvl_dev.hscfgcmd = result; 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 = { static const struct file_operations btmrvl_hscfgcmd_fops = {
.read = btmrvl_hscfgcmd_read, .read = btmrvl_hscfgcmd_read,
.write = btmrvl_hscfgcmd_write, .write = btmrvl_hscfgcmd_write,
.open = simple_open, .open = btmrvl_open_generic,
.llseek = default_llseek, .llseek = default_llseek,
}; };
@ -104,8 +108,6 @@ static ssize_t btmrvl_psmode_write(struct file *file, const char __user *ubuf,
return -EFAULT; return -EFAULT;
ret = strict_strtol(buf, 10, &result); ret = strict_strtol(buf, 10, &result);
if (ret)
return ret;
priv->btmrvl_dev.psmode = result; 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 = { static const struct file_operations btmrvl_psmode_fops = {
.read = btmrvl_psmode_read, .read = btmrvl_psmode_read,
.write = btmrvl_psmode_write, .write = btmrvl_psmode_write,
.open = simple_open, .open = btmrvl_open_generic,
.llseek = default_llseek, .llseek = default_llseek,
}; };
@ -145,8 +147,6 @@ static ssize_t btmrvl_pscmd_write(struct file *file, const char __user *ubuf,
return -EFAULT; return -EFAULT;
ret = strict_strtol(buf, 10, &result); ret = strict_strtol(buf, 10, &result);
if (ret)
return ret;
priv->btmrvl_dev.pscmd = result; 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 = { static const struct file_operations btmrvl_pscmd_fops = {
.read = btmrvl_pscmd_read, .read = btmrvl_pscmd_read,
.write = btmrvl_pscmd_write, .write = btmrvl_pscmd_write,
.open = simple_open, .open = btmrvl_open_generic,
.llseek = default_llseek, .llseek = default_llseek,
}; };
@ -191,8 +191,6 @@ static ssize_t btmrvl_gpiogap_write(struct file *file, const char __user *ubuf,
return -EFAULT; return -EFAULT;
ret = strict_strtol(buf, 16, &result); ret = strict_strtol(buf, 16, &result);
if (ret)
return ret;
priv->btmrvl_dev.gpio_gap = result; 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 = { static const struct file_operations btmrvl_gpiogap_fops = {
.read = btmrvl_gpiogap_read, .read = btmrvl_gpiogap_read,
.write = btmrvl_gpiogap_write, .write = btmrvl_gpiogap_write,
.open = simple_open, .open = btmrvl_open_generic,
.llseek = default_llseek, .llseek = default_llseek,
}; };
@ -232,8 +230,6 @@ static ssize_t btmrvl_hscmd_write(struct file *file, const char __user *ubuf,
return -EFAULT; return -EFAULT;
ret = strict_strtol(buf, 10, &result); ret = strict_strtol(buf, 10, &result);
if (ret)
return ret;
priv->btmrvl_dev.hscmd = result; priv->btmrvl_dev.hscmd = result;
if (priv->btmrvl_dev.hscmd) { 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 = { static const struct file_operations btmrvl_hscmd_fops = {
.read = btmrvl_hscmd_read, .read = btmrvl_hscmd_read,
.write = btmrvl_hscmd_write, .write = btmrvl_hscmd_write,
.open = simple_open, .open = btmrvl_open_generic,
.llseek = default_llseek, .llseek = default_llseek,
}; };
@ -276,8 +272,6 @@ static ssize_t btmrvl_hsmode_write(struct file *file, const char __user *ubuf,
return -EFAULT; return -EFAULT;
ret = strict_strtol(buf, 10, &result); ret = strict_strtol(buf, 10, &result);
if (ret)
return ret;
priv->btmrvl_dev.hsmode = result; 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 = { static const struct file_operations btmrvl_hsmode_fops = {
.read = btmrvl_hsmode_read, .read = btmrvl_hsmode_read,
.write = btmrvl_hsmode_write, .write = btmrvl_hsmode_write,
.open = simple_open, .open = btmrvl_open_generic,
.llseek = default_llseek, .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 = { static const struct file_operations btmrvl_curpsmode_fops = {
.read = btmrvl_curpsmode_read, .read = btmrvl_curpsmode_read,
.open = simple_open, .open = btmrvl_open_generic,
.llseek = default_llseek, .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 = { static const struct file_operations btmrvl_psstate_fops = {
.read = btmrvl_psstate_read, .read = btmrvl_psstate_read,
.open = simple_open, .open = btmrvl_open_generic,
.llseek = default_llseek, .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 = { static const struct file_operations btmrvl_hsstate_fops = {
.read = btmrvl_hsstate_read, .read = btmrvl_hsstate_read,
.open = simple_open, .open = btmrvl_open_generic,
.llseek = default_llseek, .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 = { static const struct file_operations btmrvl_txdnldready_fops = {
.read = btmrvl_txdnldready_read, .read = btmrvl_txdnldready_read,
.open = simple_open, .open = btmrvl_open_generic,
.llseek = default_llseek, .llseek = default_llseek,
}; };
void btmrvl_debugfs_init(struct hci_dev *hdev) 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; struct btmrvl_debugfs_data *dbg;
if (!hdev->debugfs) 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->config_dir = debugfs_create_dir("config", hdev->debugfs);
dbg->psmode = debugfs_create_file("psmode", 0644, dbg->config_dir, 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, 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, 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, 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, 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, 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->status_dir = debugfs_create_dir("status", hdev->debugfs);
dbg->curpsmode = debugfs_create_file("curpsmode", 0444, dbg->curpsmode = debugfs_create_file("curpsmode", 0444,
dbg->status_dir, priv, dbg->status_dir,
&btmrvl_curpsmode_fops); hdev->driver_data,
&btmrvl_curpsmode_fops);
dbg->psstate = debugfs_create_file("psstate", 0444, dbg->status_dir, 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, 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->txdnldready = debugfs_create_file("txdnldready", 0444,
dbg->status_dir, priv, dbg->status_dir,
&btmrvl_txdnldready_fops); hdev->driver_data,
&btmrvl_txdnldready_fops);
} }
void btmrvl_debugfs_remove(struct hci_dev *hdev) 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; struct btmrvl_debugfs_data *dbg = priv->debugfs_data;
if (!dbg) if (!dbg)

View file

@ -18,8 +18,6 @@
* this warranty disclaimer. * this warranty disclaimer.
**/ **/
#include <linux/module.h>
#include <net/bluetooth/bluetooth.h> #include <net/bluetooth/bluetooth.h>
#include <net/bluetooth/hci_core.h> #include <net/bluetooth/hci_core.h>
@ -387,6 +385,10 @@ static int btmrvl_ioctl(struct hci_dev *hdev,
return -ENOIOCTLCMD; return -ENOIOCTLCMD;
} }
static void btmrvl_destruct(struct hci_dev *hdev)
{
}
static int btmrvl_send_frame(struct sk_buff *skb) static int btmrvl_send_frame(struct sk_buff *skb)
{ {
struct hci_dev *hdev = (struct hci_dev *) skb->dev; 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); 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"); BT_ERR("Frame for unknown HCI device");
return -ENODEV; return -ENODEV;
} }
priv = hci_get_drvdata(hdev); priv = (struct btmrvl_private *) hdev->driver_data;
if (!test_bit(HCI_RUNNING, &hdev->flags)) { if (!test_bit(HCI_RUNNING, &hdev->flags)) {
BT_ERR("Failed testing HCI_RUNING, flags=%lx", hdev->flags); BT_ERR("Failed testing HCI_RUNING, flags=%lx", hdev->flags);
print_hex_dump_bytes("data: ", DUMP_PREFIX_OFFSET, 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) 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); 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) 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)) if (!test_and_clear_bit(HCI_RUNNING, &hdev->flags))
return 0; return 0;
@ -472,6 +473,8 @@ static int btmrvl_service_main_thread(void *data)
init_waitqueue_entry(&wait, current); init_waitqueue_entry(&wait, current);
current->flags |= PF_NOFREEZE;
for (;;) { for (;;) {
add_wait_queue(&thread->wait_q, &wait); add_wait_queue(&thread->wait_q, &wait);
@ -543,14 +546,16 @@ int btmrvl_register_hdev(struct btmrvl_private *priv)
} }
priv->btmrvl_dev.hcidev = hdev; priv->btmrvl_dev.hcidev = hdev;
hci_set_drvdata(hdev, priv); hdev->driver_data = priv;
hdev->bus = HCI_SDIO; hdev->bus = HCI_SDIO;
hdev->open = btmrvl_open; hdev->open = btmrvl_open;
hdev->close = btmrvl_close; hdev->close = btmrvl_close;
hdev->flush = btmrvl_flush; hdev->flush = btmrvl_flush;
hdev->send = btmrvl_send_frame; hdev->send = btmrvl_send_frame;
hdev->destruct = btmrvl_destruct;
hdev->ioctl = btmrvl_ioctl; hdev->ioctl = btmrvl_ioctl;
hdev->owner = THIS_MODULE;
btmrvl_send_module_cfg_cmd(priv, MODULE_BRINGUP_REQ); 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_ids.h>
#include <linux/mmc/sdio_func.h> #include <linux/mmc/sdio_func.h>
#include <linux/module.h>
#include <net/bluetooth/bluetooth.h> #include <net/bluetooth/bluetooth.h>
#include <net/bluetooth/hci_core.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_1 = 0x01,
.io_port_2 = 0x02, .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, .cfg = 0x00,
.host_int_mask = 0x02, .host_int_mask = 0x02,
.host_intstatus = 0x03, .host_intstatus = 0x03,
@ -82,7 +81,7 @@ static const struct btmrvl_sdio_card_reg btmrvl_reg_87xx = {
.io_port_2 = 0x7a, .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", .helper = "sd8688_helper.bin",
.firmware = "sd8688.bin", .firmware = "sd8688.bin",
.reg = &btmrvl_reg_8688, .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 = { static const struct btmrvl_sdio_device btmrvl_sdio_sd8787 = {
.helper = NULL, .helper = NULL,
.firmware = "mrvl/sd8787_uapsta.bin", .firmware = "mrvl/sd8787_uapsta.bin",
.reg = &btmrvl_reg_87xx, .reg = &btmrvl_reg_8787,
.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,
.sd_blksz_fw_dl = 256, .sd_blksz_fw_dl = 256,
}; };
static const struct sdio_device_id btmrvl_sdio_ids[] = { static const struct sdio_device_id btmrvl_sdio_ids[] = {
/* Marvell SD8688 Bluetooth device */ /* Marvell SD8688 Bluetooth device */
{ SDIO_DEVICE(SDIO_VENDOR_ID_MARVELL, 0x9105), { 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 */ /* Marvell SD8787 Bluetooth device */
{ SDIO_DEVICE(SDIO_VENDOR_ID_MARVELL, 0x911A), { SDIO_DEVICE(SDIO_VENDOR_ID_MARVELL, 0x911A),
.driver_data = (unsigned long) &btmrvl_sdio_sd8787 }, .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 */ { } /* Terminating entry */
}; };
@ -1086,4 +1075,3 @@ MODULE_LICENSE("GPL v2");
MODULE_FIRMWARE("sd8688_helper.bin"); MODULE_FIRMWARE("sd8688_helper.bin");
MODULE_FIRMWARE("sd8688.bin"); MODULE_FIRMWARE("sd8688.bin");
MODULE_FIRMWARE("mrvl/sd8787_uapsta.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) 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; int err;
BT_DBG("%s", hdev->name); BT_DBG("%s", hdev->name);
@ -225,7 +225,7 @@ release:
static int btsdio_close(struct hci_dev *hdev) 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); 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) 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); 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) static int btsdio_send_frame(struct sk_buff *skb)
{ {
struct hci_dev *hdev = (struct hci_dev *) skb->dev; 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); BT_DBG("%s", hdev->name);
@ -289,6 +289,15 @@ static int btsdio_send_frame(struct sk_buff *skb)
return 0; 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, static int btsdio_probe(struct sdio_func *func,
const struct sdio_device_id *id) const struct sdio_device_id *id)
{ {
@ -321,7 +330,7 @@ static int btsdio_probe(struct sdio_func *func,
} }
hdev->bus = HCI_SDIO; hdev->bus = HCI_SDIO;
hci_set_drvdata(hdev, data); hdev->driver_data = data;
if (id->class == SDIO_CLASS_BT_AMP) if (id->class == SDIO_CLASS_BT_AMP)
hdev->dev_type = HCI_AMP; hdev->dev_type = HCI_AMP;
@ -336,6 +345,9 @@ static int btsdio_probe(struct sdio_func *func,
hdev->close = btsdio_close; hdev->close = btsdio_close;
hdev->flush = btsdio_flush; hdev->flush = btsdio_flush;
hdev->send = btsdio_send_frame; hdev->send = btsdio_send_frame;
hdev->destruct = btsdio_destruct;
hdev->owner = THIS_MODULE;
err = hci_register_dev(hdev); err = hci_register_dev(hdev);
if (err < 0) { if (err < 0) {
@ -366,7 +378,6 @@ static void btsdio_remove(struct sdio_func *func)
hci_unregister_dev(hdev); hci_unregister_dev(hdev);
hci_free_dev(hdev); hci_free_dev(hdev);
kfree(data);
} }
static struct sdio_driver btsdio_driver = { static struct sdio_driver btsdio_driver = {

View file

@ -38,6 +38,7 @@
#include <linux/serial.h> #include <linux/serial.h>
#include <linux/serial_reg.h> #include <linux/serial_reg.h>
#include <linux/bitops.h> #include <linux/bitops.h>
#include <asm/system.h>
#include <asm/io.h> #include <asm/io.h>
#include <pcmcia/cistpl.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) 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 */ /* Drop TX queue */
skb_queue_purge(&(info->txq)); skb_queue_purge(&(info->txq));
@ -434,7 +435,7 @@ static int btuart_hci_send_frame(struct sk_buff *skb)
return -ENODEV; return -ENODEV;
} }
info = hci_get_drvdata(hdev); info = (btuart_info_t *)(hdev->driver_data);
switch (bt_cb(skb)->pkt_type) { switch (bt_cb(skb)->pkt_type) {
case HCI_COMMAND_PKT: 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) static int btuart_hci_ioctl(struct hci_dev *hdev, unsigned int cmd, unsigned long arg)
{ {
return -ENOIOCTLCMD; return -ENOIOCTLCMD;
@ -492,15 +498,18 @@ static int btuart_open(btuart_info_t *info)
info->hdev = hdev; info->hdev = hdev;
hdev->bus = HCI_PCCARD; hdev->bus = HCI_PCCARD;
hci_set_drvdata(hdev, info); hdev->driver_data = info;
SET_HCIDEV_DEV(hdev, &info->p_dev->dev); SET_HCIDEV_DEV(hdev, &info->p_dev->dev);
hdev->open = btuart_hci_open; hdev->open = btuart_hci_open;
hdev->close = btuart_hci_close; hdev->close = btuart_hci_close;
hdev->flush = btuart_hci_flush; hdev->flush = btuart_hci_flush;
hdev->send = btuart_hci_send_frame; hdev->send = btuart_hci_send_frame;
hdev->destruct = btuart_hci_destruct;
hdev->ioctl = btuart_hci_ioctl; hdev->ioctl = btuart_hci_ioctl;
hdev->owner = THIS_MODULE;
spin_lock_irqsave(&(info->lock), flags); spin_lock_irqsave(&(info->lock), flags);
/* Reset UART */ /* Reset UART */
@ -556,7 +565,9 @@ static int btuart_close(btuart_info_t *info)
spin_unlock_irqrestore(&(info->lock), flags); 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); hci_free_dev(hdev);
return 0; return 0;
@ -678,7 +689,7 @@ static void btuart_release(struct pcmcia_device *link)
pcmcia_disable_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 */ /* don't use this driver. Use serial_cs + hci_uart instead */
PCMCIA_DEVICE_NULL PCMCIA_DEVICE_NULL
}; };

View file

@ -37,13 +37,13 @@
#define VERSION "0.6" #define VERSION "0.6"
static bool ignore_dga; static int ignore_dga;
static bool ignore_csr; static int ignore_csr;
static bool ignore_sniffer; static int ignore_sniffer;
static bool disable_scofix; static int disable_scofix;
static bool force_scofix; static int force_scofix;
static bool reset = 1; static int reset = 1;
static struct usb_driver btusb_driver; static struct usb_driver btusb_driver;
@ -61,7 +61,7 @@ static struct usb_device_id btusb_table[] = {
{ USB_DEVICE_INFO(0xe0, 0x01, 0x01) }, { USB_DEVICE_INFO(0xe0, 0x01, 0x01) },
/* Broadcom SoftSailing reporting vendor specific */ /* Broadcom SoftSailing reporting vendor specific */
{ USB_DEVICE(0x0a5c, 0x21e1) }, { USB_DEVICE(0x05ac, 0x21e1) },
/* Apple MacBookPro 7,1 */ /* Apple MacBookPro 7,1 */
{ USB_DEVICE(0x05ac, 0x8213) }, { USB_DEVICE(0x05ac, 0x8213) },
@ -100,17 +100,6 @@ static struct usb_device_id btusb_table[] = {
/* Canyon CN-BTU1 with HID interfaces */ /* Canyon CN-BTU1 with HID interfaces */
{ USB_DEVICE(0x0c10, 0x0000) }, { 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 */ { } /* Terminating entry */
}; };
@ -125,20 +114,12 @@ static struct usb_device_id blacklist_table[] = {
/* Atheros 3011 with sflash firmware */ /* Atheros 3011 with sflash firmware */
{ USB_DEVICE(0x0cf3, 0x3002), .driver_info = BTUSB_IGNORE }, { 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 */ /* Atheros AR9285 Malbec with sflash firmware */
{ USB_DEVICE(0x03f0, 0x311d), .driver_info = BTUSB_IGNORE }, { USB_DEVICE(0x03f0, 0x311d), .driver_info = BTUSB_IGNORE },
/* Atheros 3012 with sflash firmware */ /* Atheros 3012 with sflash firmware */
{ USB_DEVICE(0x0cf3, 0x3004), .driver_info = BTUSB_ATH3012 }, { 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 */ /* Atheros AR5BBU12 with sflash firmware */
{ USB_DEVICE(0x0489, 0xe02c), .driver_info = BTUSB_IGNORE }, { 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) static void btusb_intr_complete(struct urb *urb)
{ {
struct hci_dev *hdev = urb->context; struct hci_dev *hdev = urb->context;
struct btusb_data *data = hci_get_drvdata(hdev); struct btusb_data *data = hdev->driver_data;
int err; int err;
BT_DBG("%s urb %p status %d count %d", hdev->name, 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); err = usb_submit_urb(urb, GFP_ATOMIC);
if (err < 0) { if (err < 0) {
/* -EPERM: urb is being killed; if (err != -EPERM)
* -ENODEV: device got disconnected */
if (err != -EPERM && err != -ENODEV)
BT_ERR("%s urb %p failed to resubmit (%d)", BT_ERR("%s urb %p failed to resubmit (%d)",
hdev->name, urb, -err); hdev->name, urb, -err);
usb_unanchor_urb(urb); 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) 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; struct urb *urb;
unsigned char *buf; unsigned char *buf;
unsigned int pipe; 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); err = usb_submit_urb(urb, mem_flags);
if (err < 0) { 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); hdev->name, urb, -err);
usb_unanchor_urb(urb); 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) static void btusb_bulk_complete(struct urb *urb)
{ {
struct hci_dev *hdev = urb->context; struct hci_dev *hdev = urb->context;
struct btusb_data *data = hci_get_drvdata(hdev); struct btusb_data *data = hdev->driver_data;
int err; int err;
BT_DBG("%s urb %p status %d count %d", hdev->name, 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); err = usb_submit_urb(urb, GFP_ATOMIC);
if (err < 0) { if (err < 0) {
/* -EPERM: urb is being killed; if (err != -EPERM)
* -ENODEV: device got disconnected */
if (err != -EPERM && err != -ENODEV)
BT_ERR("%s urb %p failed to resubmit (%d)", BT_ERR("%s urb %p failed to resubmit (%d)",
hdev->name, urb, -err); hdev->name, urb, -err);
usb_unanchor_urb(urb); 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) 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; struct urb *urb;
unsigned char *buf; unsigned char *buf;
unsigned int pipe; 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); err = usb_submit_urb(urb, mem_flags);
if (err < 0) { 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); hdev->name, urb, -err);
usb_unanchor_urb(urb); 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) static void btusb_isoc_complete(struct urb *urb)
{ {
struct hci_dev *hdev = urb->context; struct hci_dev *hdev = urb->context;
struct btusb_data *data = hci_get_drvdata(hdev); struct btusb_data *data = hdev->driver_data;
int i, err; int i, err;
BT_DBG("%s urb %p status %d count %d", hdev->name, 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); err = usb_submit_urb(urb, GFP_ATOMIC);
if (err < 0) { if (err < 0) {
/* -EPERM: urb is being killed; if (err != -EPERM)
* -ENODEV: device got disconnected */
if (err != -EPERM && err != -ENODEV)
BT_ERR("%s urb %p failed to resubmit (%d)", BT_ERR("%s urb %p failed to resubmit (%d)",
hdev->name, urb, -err); hdev->name, urb, -err);
usb_unanchor_urb(urb); 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; 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) 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; struct urb *urb;
unsigned char *buf; unsigned char *buf;
unsigned int pipe; 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); pipe = usb_rcvisocpipe(data->udev, data->isoc_rx_ep->bEndpointAddress);
usb_fill_int_urb(urb, data->udev, pipe, buf, size, btusb_isoc_complete, urb->dev = data->udev;
hdev, data->isoc_rx_ep->bInterval); 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_flags = URB_FREE_BUFFER | URB_ISO_ASAP;
urb->transfer_buffer = buf;
urb->transfer_buffer_length = size;
__fill_isoc_descriptor(urb, size, __fill_isoc_descriptor(urb, size,
le16_to_cpu(data->isoc_rx_ep->wMaxPacketSize)); 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); err = usb_submit_urb(urb, mem_flags);
if (err < 0) { 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); hdev->name, urb, -err);
usb_unanchor_urb(urb); usb_unanchor_urb(urb);
} }
@ -549,7 +526,7 @@ static void btusb_tx_complete(struct urb *urb)
{ {
struct sk_buff *skb = urb->context; struct sk_buff *skb = urb->context;
struct hci_dev *hdev = (struct hci_dev *) skb->dev; 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, BT_DBG("%s urb %p status %d count %d", hdev->name,
urb, urb->status, urb->actual_length); urb, urb->status, urb->actual_length);
@ -596,7 +573,7 @@ done:
static int btusb_open(struct hci_dev *hdev) 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; int err;
BT_DBG("%s", hdev->name); 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) 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; int err;
BT_DBG("%s", hdev->name); BT_DBG("%s", hdev->name);
@ -676,7 +653,7 @@ failed:
static int btusb_flush(struct hci_dev *hdev) 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); 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) static int btusb_send_frame(struct sk_buff *skb)
{ {
struct hci_dev *hdev = (struct hci_dev *) skb->dev; 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 usb_ctrlrequest *dr;
struct urb *urb; struct urb *urb;
unsigned int pipe; unsigned int pipe;
@ -782,23 +759,31 @@ skip_waking:
err = usb_submit_urb(urb, GFP_ATOMIC); err = usb_submit_urb(urb, GFP_ATOMIC);
if (err < 0) { if (err < 0) {
if (err != -EPERM && err != -ENODEV) BT_ERR("%s urb %p submission failed", hdev->name, urb);
BT_ERR("%s urb %p submission failed (%d)",
hdev->name, urb, -err);
kfree(urb->setup_packet); kfree(urb->setup_packet);
usb_unanchor_urb(urb); usb_unanchor_urb(urb);
} else { } else {
usb_mark_last_busy(data->udev); usb_mark_last_busy(data->udev);
} }
done:
usb_free_urb(urb); usb_free_urb(urb);
done:
return err; 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) 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); 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_interface *intf = data->isoc;
struct usb_endpoint_descriptor *ep_desc; struct usb_endpoint_descriptor *ep_desc;
int i, err; int i, err;
@ -998,7 +983,7 @@ static int btusb_probe(struct usb_interface *intf,
} }
hdev->bus = HCI_USB; hdev->bus = HCI_USB;
hci_set_drvdata(hdev, data); hdev->driver_data = data;
data->hdev = hdev; data->hdev = hdev;
@ -1008,8 +993,11 @@ static int btusb_probe(struct usb_interface *intf,
hdev->close = btusb_close; hdev->close = btusb_close;
hdev->flush = btusb_flush; hdev->flush = btusb_flush;
hdev->send = btusb_send_frame; hdev->send = btusb_send_frame;
hdev->destruct = btusb_destruct;
hdev->notify = btusb_notify; hdev->notify = btusb_notify;
hdev->owner = THIS_MODULE;
/* Interface numbers are hardcoded in the specification */ /* Interface numbers are hardcoded in the specification */
data->isoc = usb_ifnum_to_if(data->udev, 1); data->isoc = usb_ifnum_to_if(data->udev, 1);
@ -1091,6 +1079,9 @@ static void btusb_disconnect(struct usb_interface *intf)
return; return;
hdev = data->hdev; hdev = data->hdev;
__hci_dev_hold(hdev);
usb_set_intfdata(data->intf, NULL); usb_set_intfdata(data->intf, NULL);
if (data->isoc) if (data->isoc)
@ -1103,8 +1094,9 @@ static void btusb_disconnect(struct usb_interface *intf)
else if (data->isoc) else if (data->isoc)
usb_driver_release_interface(&btusb_driver, data->isoc); usb_driver_release_interface(&btusb_driver, data->isoc);
__hci_dev_put(hdev);
hci_free_dev(hdev); hci_free_dev(hdev);
kfree(data);
} }
#ifdef CONFIG_PM #ifdef CONFIG_PM
@ -1118,7 +1110,7 @@ static int btusb_suspend(struct usb_interface *intf, pm_message_t message)
return 0; return 0;
spin_lock_irq(&data->txlock); 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); set_bit(BTUSB_SUSPENDING, &data->flags);
spin_unlock_irq(&data->txlock); spin_unlock_irq(&data->txlock);
} else { } else {
@ -1220,7 +1212,20 @@ static struct usb_driver btusb_driver = {
.supports_autosuspend = 1, .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_param(ignore_dga, bool, 0644);
MODULE_PARM_DESC(ignore_dga, "Ignore devices with id 08fd:0001"); MODULE_PARM_DESC(ignore_dga, "Ignore devices with id 08fd:0001");

View file

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

View file

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

View file

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

View file

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

View file

@ -48,6 +48,8 @@
#define VERSION "2.2" #define VERSION "2.2"
static bool reset = 0;
static struct hci_uart_proto *hup[HCI_UART_MAX_PROTO]; static struct hci_uart_proto *hup[HCI_UART_MAX_PROTO];
int hci_uart_register_proto(struct hci_uart_proto *p) 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 */ /* Reset device */
static int hci_uart_flush(struct hci_dev *hdev) 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; struct tty_struct *tty = hu->tty;
BT_DBG("hdev %p tty %p", hdev, 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)) if (!test_bit(HCI_RUNNING, &hdev->flags))
return -EBUSY; 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); 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; 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 ------ */ /* ------ LDISC part ------ */
/* hci_uart_tty_open /* hci_uart_tty_open
* *
@ -299,14 +310,12 @@ static void hci_uart_tty_close(struct tty_struct *tty)
hci_uart_close(hdev); hci_uart_close(hdev);
if (test_and_clear_bit(HCI_UART_PROTO_SET, &hu->flags)) { if (test_and_clear_bit(HCI_UART_PROTO_SET, &hu->flags)) {
hu->proto->close(hu);
if (hdev) { if (hdev) {
hci_unregister_dev(hdev); hci_unregister_dev(hdev);
hci_free_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) 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; struct hci_uart *hu = (void *)tty->disc_data;
if (!hu || tty != hu->tty) 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; return;
spin_lock(&hu->rx_lock); spin_lock(&hu->rx_lock);
hu->proto->recv(hu, (void *) data, count); ret = hu->proto->recv(hu, (void *) data, count);
hu->hdev->stat.byte_rx += count; if (ret > 0)
hu->hdev->stat.byte_rx += count;
spin_unlock(&hu->rx_lock); spin_unlock(&hu->rx_lock);
tty_unthrottle(tty); tty_unthrottle(tty);
@ -382,25 +393,23 @@ static int hci_uart_register_dev(struct hci_uart *hu)
hu->hdev = hdev; hu->hdev = hdev;
hdev->bus = HCI_UART; hdev->bus = HCI_UART;
hci_set_drvdata(hdev, hu); hdev->driver_data = hu;
hdev->open = hci_uart_open; hdev->open = hci_uart_open;
hdev->close = hci_uart_close; hdev->close = hci_uart_close;
hdev->flush = hci_uart_flush; hdev->flush = hci_uart_flush;
hdev->send = hci_uart_send_frame; hdev->send = hci_uart_send_frame;
hdev->destruct = hci_uart_destruct;
hdev->parent = hu->tty->dev; 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)) if (test_bit(HCI_UART_RAW_DEVICE, &hu->hdev_flags))
set_bit(HCI_QUIRK_RAW_DEVICE, &hdev->quirks); 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) { if (hci_register_dev(hdev) < 0) {
BT_ERR("Can't register HCI device"); BT_ERR("Can't register HCI device");
hci_free_dev(hdev); hci_free_dev(hdev);
@ -587,6 +596,9 @@ static void __exit hci_uart_exit(void)
module_init(hci_uart_init); module_init(hci_uart_init);
module_exit(hci_uart_exit); 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_AUTHOR("Marcel Holtmann <marcel@holtmann.org>");
MODULE_DESCRIPTION("Bluetooth HCI UART driver ver " VERSION); MODULE_DESCRIPTION("Bluetooth HCI UART driver ver " VERSION);
MODULE_VERSION(VERSION); MODULE_VERSION(VERSION);

View file

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

View file

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

View file

@ -41,8 +41,6 @@
#define VERSION "1.3" #define VERSION "1.3"
static bool amp;
struct vhci_data { struct vhci_data {
struct hci_dev *hdev; 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) 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)) if (!test_and_clear_bit(HCI_RUNNING, &hdev->flags))
return 0; return 0;
@ -73,7 +71,7 @@ static int vhci_close_dev(struct hci_dev *hdev)
static int vhci_flush(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); 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)) if (!test_bit(HCI_RUNNING, &hdev->flags))
return -EBUSY; return -EBUSY;
data = hci_get_drvdata(hdev); data = hdev->driver_data;
memcpy(skb_push(skb, 1), &bt_cb(skb)->pkt_type, 1); memcpy(skb_push(skb, 1), &bt_cb(skb)->pkt_type, 1);
skb_queue_tail(&data->readq, skb); skb_queue_tail(&data->readq, skb);
@ -103,6 +101,11 @@ static int vhci_send_frame(struct sk_buff *skb)
return 0; 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, 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)
{ {
@ -234,15 +237,15 @@ static int vhci_open(struct inode *inode, struct file *file)
data->hdev = hdev; data->hdev = hdev;
hdev->bus = HCI_VIRTUAL; hdev->bus = HCI_VIRTUAL;
hci_set_drvdata(hdev, data); hdev->driver_data = data;
if (amp)
hdev->dev_type = HCI_AMP;
hdev->open = vhci_open_dev; hdev->open = vhci_open_dev;
hdev->close = vhci_close_dev; hdev->close = vhci_close_dev;
hdev->flush = vhci_flush; hdev->flush = vhci_flush;
hdev->send = vhci_send_frame; hdev->send = vhci_send_frame;
hdev->destruct = vhci_destruct;
hdev->owner = THIS_MODULE;
if (hci_register_dev(hdev) < 0) { if (hci_register_dev(hdev) < 0) {
BT_ERR("Can't register HCI device"); 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 vhci_data *data = file->private_data;
struct hci_dev *hdev = data->hdev; 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); hci_free_dev(hdev);
file->private_data = NULL; file->private_data = NULL;
kfree(data);
return 0; return 0;
} }
@ -301,9 +306,6 @@ static void __exit vhci_exit(void)
module_init(vhci_init); module_init(vhci_init);
module_exit(vhci_exit); 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_AUTHOR("Marcel Holtmann <marcel@holtmann.org>");
MODULE_DESCRIPTION("Bluetooth virtual HCI driver ver " VERSION); MODULE_DESCRIPTION("Bluetooth virtual HCI driver ver " VERSION);
MODULE_VERSION(VERSION); MODULE_VERSION(VERSION);