Loading drivers/bluetooth/hci_vhci.c +19 −71 Original line number Diff line number Diff line Loading @@ -40,7 +40,7 @@ #include <net/bluetooth/bluetooth.h> #include <net/bluetooth/hci_core.h> #define VERSION "1.2" #define VERSION "1.3" static int minor = MISC_DYNAMIC_MINOR; Loading @@ -51,14 +51,8 @@ struct vhci_data { wait_queue_head_t read_wait; struct sk_buff_head readq; struct fasync_struct *fasync; }; #define VHCI_FASYNC 0x0010 static struct miscdevice vhci_miscdev; static int vhci_open_dev(struct hci_dev *hdev) { set_bit(HCI_RUNNING, &hdev->flags); Loading Loading @@ -105,9 +99,6 @@ static int vhci_send_frame(struct sk_buff *skb) memcpy(skb_push(skb, 1), &bt_cb(skb)->pkt_type, 1); skb_queue_tail(&data->readq, skb); if (data->flags & VHCI_FASYNC) kill_fasync(&data->fasync, SIGIO, POLL_IN); wake_up_interruptible(&data->read_wait); return 0; Loading Loading @@ -179,41 +170,31 @@ static inline ssize_t vhci_put_user(struct vhci_data *data, static ssize_t vhci_read(struct file *file, char __user *buf, size_t count, loff_t *pos) { DECLARE_WAITQUEUE(wait, current); struct vhci_data *data = file->private_data; struct sk_buff *skb; ssize_t ret = 0; add_wait_queue(&data->read_wait, &wait); while (count) { set_current_state(TASK_INTERRUPTIBLE); skb = skb_dequeue(&data->readq); if (!skb) { if (file->f_flags & O_NONBLOCK) { ret = -EAGAIN; if (skb) { ret = vhci_put_user(data, skb, buf, count); if (ret < 0) skb_queue_head(&data->readq, skb); else kfree_skb(skb); break; } if (signal_pending(current)) { ret = -ERESTARTSYS; if (file->f_flags & O_NONBLOCK) { ret = -EAGAIN; break; } schedule(); continue; } if (access_ok(VERIFY_WRITE, buf, count)) ret = vhci_put_user(data, skb, buf, count); else ret = -EFAULT; kfree_skb(skb); ret = wait_event_interruptible(data->read_wait, !skb_queue_empty(&data->readq)); if (ret < 0) break; } set_current_state(TASK_RUNNING); remove_wait_queue(&data->read_wait, &wait); return ret; } Loading @@ -223,9 +204,6 @@ static ssize_t vhci_write(struct file *file, { struct vhci_data *data = file->private_data; if (!access_ok(VERIFY_READ, buf, count)) return -EFAULT; return vhci_get_user(data, buf, count); } Loading Loading @@ -259,11 +237,9 @@ static int vhci_open(struct inode *inode, struct file *file) skb_queue_head_init(&data->readq); init_waitqueue_head(&data->read_wait); lock_kernel(); hdev = hci_alloc_dev(); if (!hdev) { kfree(data); unlock_kernel(); return -ENOMEM; } Loading @@ -284,12 +260,10 @@ static int vhci_open(struct inode *inode, struct file *file) BT_ERR("Can't register HCI device"); kfree(data); hci_free_dev(hdev); unlock_kernel(); return -EBUSY; } file->private_data = data; unlock_kernel(); return nonseekable_open(inode, file); } Loading @@ -310,48 +284,25 @@ static int vhci_release(struct inode *inode, struct file *file) return 0; } static int vhci_fasync(int fd, struct file *file, int on) { struct vhci_data *data = file->private_data; int err = 0; lock_kernel(); err = fasync_helper(fd, file, on, &data->fasync); if (err < 0) goto out; if (on) data->flags |= VHCI_FASYNC; else data->flags &= ~VHCI_FASYNC; out: unlock_kernel(); return err; } static const struct file_operations vhci_fops = { .owner = THIS_MODULE, .read = vhci_read, .write = vhci_write, .poll = vhci_poll, .ioctl = vhci_ioctl, .open = vhci_open, .release = vhci_release, .fasync = vhci_fasync, }; static struct miscdevice vhci_miscdev= { .name = "vhci", .fops = &vhci_fops, .minor = MISC_DYNAMIC_MINOR, }; static int __init vhci_init(void) { BT_INFO("Virtual HCI driver ver %s", VERSION); vhci_miscdev.minor = minor; if (misc_register(&vhci_miscdev) < 0) { BT_ERR("Can't register misc device with minor %d", minor); return -EIO; Loading @@ -369,9 +320,6 @@ static void __exit vhci_exit(void) module_init(vhci_init); module_exit(vhci_exit); module_param(minor, int, 0444); MODULE_PARM_DESC(minor, "Miscellaneous minor device number"); MODULE_AUTHOR("Marcel Holtmann <marcel@holtmann.org>"); MODULE_DESCRIPTION("Bluetooth virtual HCI driver ver " VERSION); MODULE_VERSION(VERSION); Loading include/net/bluetooth/bluetooth.h +0 −6 Original line number Diff line number Diff line Loading @@ -81,12 +81,6 @@ enum { BT_CLOSED }; /* Endianness conversions */ #define htobs(a) __cpu_to_le16(a) #define htobl(a) __cpu_to_le32(a) #define btohs(a) __le16_to_cpu(a) #define btohl(a) __le32_to_cpu(a) /* BD Address */ typedef struct { __u8 b[6]; Loading include/net/bluetooth/hci_core.h +2 −0 Original line number Diff line number Diff line Loading @@ -137,6 +137,8 @@ struct hci_dev { struct device *parent; struct device dev; struct rfkill *rfkill; struct module *owner; int (*open)(struct hci_dev *hdev); Loading include/net/bluetooth/l2cap.h +50 −21 Original line number Diff line number Diff line Loading @@ -27,7 +27,12 @@ /* L2CAP defaults */ #define L2CAP_DEFAULT_MTU 672 #define L2CAP_DEFAULT_FLUSH_TO 0xFFFF #define L2CAP_DEFAULT_FLUSH_TO 0xffff #define L2CAP_DEFAULT_RX_WINDOW 1 #define L2CAP_DEFAULT_MAX_RECEIVE 1 #define L2CAP_DEFAULT_RETRANS_TO 300 /* 300 milliseconds */ #define L2CAP_DEFAULT_MONITOR_TO 1000 /* 1 second */ #define L2CAP_DEFAULT_MAX_RX_APDU 0xfff7 #define L2CAP_CONN_TIMEOUT (40000) /* 40 seconds */ #define L2CAP_INFO_TIMEOUT (4000) /* 4 seconds */ Loading Loading @@ -76,6 +81,18 @@ struct l2cap_conninfo { #define L2CAP_INFO_REQ 0x0a #define L2CAP_INFO_RSP 0x0b /* L2CAP feature mask */ #define L2CAP_FEAT_FLOWCTL 0x00000001 #define L2CAP_FEAT_RETRANS 0x00000002 #define L2CAP_FEAT_ERTM 0x00000008 #define L2CAP_FEAT_STREAMING 0x00000010 #define L2CAP_FEAT_FCS 0x00000020 #define L2CAP_FEAT_FIXED_CHAN 0x00000080 /* L2CAP checksum option */ #define L2CAP_FCS_NONE 0x00 #define L2CAP_FCS_CRC16 0x01 /* L2CAP structures */ struct l2cap_hdr { __le16 len; Loading Loading @@ -106,6 +123,12 @@ struct l2cap_conn_rsp { __le16 status; } __attribute__ ((packed)); /* channel indentifier */ #define L2CAP_CID_SIGNALING 0x0001 #define L2CAP_CID_CONN_LESS 0x0002 #define L2CAP_CID_DYN_START 0x0040 #define L2CAP_CID_DYN_END 0xffff /* connect result */ #define L2CAP_CR_SUCCESS 0x0000 #define L2CAP_CR_PEND 0x0001 Loading Loading @@ -143,10 +166,14 @@ struct l2cap_conf_opt { } __attribute__ ((packed)); #define L2CAP_CONF_OPT_SIZE 2 #define L2CAP_CONF_HINT 0x80 #define L2CAP_CONF_MASK 0x7f #define L2CAP_CONF_MTU 0x01 #define L2CAP_CONF_FLUSH_TO 0x02 #define L2CAP_CONF_QOS 0x03 #define L2CAP_CONF_RFC 0x04 #define L2CAP_CONF_FCS 0x05 #define L2CAP_CONF_MAX_SIZE 22 Loading @@ -162,6 +189,8 @@ struct l2cap_conf_rfc { #define L2CAP_MODE_BASIC 0x00 #define L2CAP_MODE_RETRANS 0x01 #define L2CAP_MODE_FLOWCTL 0x02 #define L2CAP_MODE_ERTM 0x03 #define L2CAP_MODE_STREAM 0x04 struct l2cap_disconn_req { __le16 dcid; Loading net/bluetooth/hci_core.c +40 −1 Original line number Diff line number Diff line Loading @@ -39,6 +39,7 @@ #include <linux/skbuff.h> #include <linux/interrupt.h> #include <linux/notifier.h> #include <linux/rfkill.h> #include <net/sock.h> #include <asm/system.h> Loading Loading @@ -476,6 +477,11 @@ int hci_dev_open(__u16 dev) hci_req_lock(hdev); if (hdev->rfkill && rfkill_blocked(hdev->rfkill)) { ret = -ERFKILL; goto done; } if (test_bit(HCI_UP, &hdev->flags)) { ret = -EALREADY; goto done; Loading Loading @@ -813,6 +819,24 @@ int hci_get_dev_info(void __user *arg) /* ---- Interface to HCI drivers ---- */ static int hci_rfkill_set_block(void *data, bool blocked) { struct hci_dev *hdev = data; BT_DBG("%p name %s blocked %d", hdev, hdev->name, blocked); if (!blocked) return 0; hci_dev_do_close(hdev); return 0; } static const struct rfkill_ops hci_rfkill_ops = { .set_block = hci_rfkill_set_block, }; /* Alloc HCI device */ struct hci_dev *hci_alloc_dev(void) { Loading Loading @@ -844,7 +868,8 @@ int hci_register_dev(struct hci_dev *hdev) struct list_head *head = &hci_dev_list, *p; int i, id = 0; BT_DBG("%p name %s type %d owner %p", hdev, hdev->name, hdev->type, hdev->owner); BT_DBG("%p name %s type %d owner %p", hdev, hdev->name, hdev->type, hdev->owner); if (!hdev->open || !hdev->close || !hdev->destruct) return -EINVAL; Loading Loading @@ -900,6 +925,15 @@ int hci_register_dev(struct hci_dev *hdev) hci_register_sysfs(hdev); hdev->rfkill = rfkill_alloc(hdev->name, &hdev->dev, RFKILL_TYPE_BLUETOOTH, &hci_rfkill_ops, hdev); if (hdev->rfkill) { if (rfkill_register(hdev->rfkill) < 0) { rfkill_destroy(hdev->rfkill); hdev->rfkill = NULL; } } hci_notify(hdev, HCI_DEV_REG); return id; Loading @@ -924,6 +958,11 @@ int hci_unregister_dev(struct hci_dev *hdev) hci_notify(hdev, HCI_DEV_UNREG); if (hdev->rfkill) { rfkill_unregister(hdev->rfkill); rfkill_destroy(hdev->rfkill); } hci_unregister_sysfs(hdev); __hci_dev_put(hdev); Loading Loading
drivers/bluetooth/hci_vhci.c +19 −71 Original line number Diff line number Diff line Loading @@ -40,7 +40,7 @@ #include <net/bluetooth/bluetooth.h> #include <net/bluetooth/hci_core.h> #define VERSION "1.2" #define VERSION "1.3" static int minor = MISC_DYNAMIC_MINOR; Loading @@ -51,14 +51,8 @@ struct vhci_data { wait_queue_head_t read_wait; struct sk_buff_head readq; struct fasync_struct *fasync; }; #define VHCI_FASYNC 0x0010 static struct miscdevice vhci_miscdev; static int vhci_open_dev(struct hci_dev *hdev) { set_bit(HCI_RUNNING, &hdev->flags); Loading Loading @@ -105,9 +99,6 @@ static int vhci_send_frame(struct sk_buff *skb) memcpy(skb_push(skb, 1), &bt_cb(skb)->pkt_type, 1); skb_queue_tail(&data->readq, skb); if (data->flags & VHCI_FASYNC) kill_fasync(&data->fasync, SIGIO, POLL_IN); wake_up_interruptible(&data->read_wait); return 0; Loading Loading @@ -179,41 +170,31 @@ static inline ssize_t vhci_put_user(struct vhci_data *data, static ssize_t vhci_read(struct file *file, char __user *buf, size_t count, loff_t *pos) { DECLARE_WAITQUEUE(wait, current); struct vhci_data *data = file->private_data; struct sk_buff *skb; ssize_t ret = 0; add_wait_queue(&data->read_wait, &wait); while (count) { set_current_state(TASK_INTERRUPTIBLE); skb = skb_dequeue(&data->readq); if (!skb) { if (file->f_flags & O_NONBLOCK) { ret = -EAGAIN; if (skb) { ret = vhci_put_user(data, skb, buf, count); if (ret < 0) skb_queue_head(&data->readq, skb); else kfree_skb(skb); break; } if (signal_pending(current)) { ret = -ERESTARTSYS; if (file->f_flags & O_NONBLOCK) { ret = -EAGAIN; break; } schedule(); continue; } if (access_ok(VERIFY_WRITE, buf, count)) ret = vhci_put_user(data, skb, buf, count); else ret = -EFAULT; kfree_skb(skb); ret = wait_event_interruptible(data->read_wait, !skb_queue_empty(&data->readq)); if (ret < 0) break; } set_current_state(TASK_RUNNING); remove_wait_queue(&data->read_wait, &wait); return ret; } Loading @@ -223,9 +204,6 @@ static ssize_t vhci_write(struct file *file, { struct vhci_data *data = file->private_data; if (!access_ok(VERIFY_READ, buf, count)) return -EFAULT; return vhci_get_user(data, buf, count); } Loading Loading @@ -259,11 +237,9 @@ static int vhci_open(struct inode *inode, struct file *file) skb_queue_head_init(&data->readq); init_waitqueue_head(&data->read_wait); lock_kernel(); hdev = hci_alloc_dev(); if (!hdev) { kfree(data); unlock_kernel(); return -ENOMEM; } Loading @@ -284,12 +260,10 @@ static int vhci_open(struct inode *inode, struct file *file) BT_ERR("Can't register HCI device"); kfree(data); hci_free_dev(hdev); unlock_kernel(); return -EBUSY; } file->private_data = data; unlock_kernel(); return nonseekable_open(inode, file); } Loading @@ -310,48 +284,25 @@ static int vhci_release(struct inode *inode, struct file *file) return 0; } static int vhci_fasync(int fd, struct file *file, int on) { struct vhci_data *data = file->private_data; int err = 0; lock_kernel(); err = fasync_helper(fd, file, on, &data->fasync); if (err < 0) goto out; if (on) data->flags |= VHCI_FASYNC; else data->flags &= ~VHCI_FASYNC; out: unlock_kernel(); return err; } static const struct file_operations vhci_fops = { .owner = THIS_MODULE, .read = vhci_read, .write = vhci_write, .poll = vhci_poll, .ioctl = vhci_ioctl, .open = vhci_open, .release = vhci_release, .fasync = vhci_fasync, }; static struct miscdevice vhci_miscdev= { .name = "vhci", .fops = &vhci_fops, .minor = MISC_DYNAMIC_MINOR, }; static int __init vhci_init(void) { BT_INFO("Virtual HCI driver ver %s", VERSION); vhci_miscdev.minor = minor; if (misc_register(&vhci_miscdev) < 0) { BT_ERR("Can't register misc device with minor %d", minor); return -EIO; Loading @@ -369,9 +320,6 @@ static void __exit vhci_exit(void) module_init(vhci_init); module_exit(vhci_exit); module_param(minor, int, 0444); MODULE_PARM_DESC(minor, "Miscellaneous minor device number"); MODULE_AUTHOR("Marcel Holtmann <marcel@holtmann.org>"); MODULE_DESCRIPTION("Bluetooth virtual HCI driver ver " VERSION); MODULE_VERSION(VERSION); Loading
include/net/bluetooth/bluetooth.h +0 −6 Original line number Diff line number Diff line Loading @@ -81,12 +81,6 @@ enum { BT_CLOSED }; /* Endianness conversions */ #define htobs(a) __cpu_to_le16(a) #define htobl(a) __cpu_to_le32(a) #define btohs(a) __le16_to_cpu(a) #define btohl(a) __le32_to_cpu(a) /* BD Address */ typedef struct { __u8 b[6]; Loading
include/net/bluetooth/hci_core.h +2 −0 Original line number Diff line number Diff line Loading @@ -137,6 +137,8 @@ struct hci_dev { struct device *parent; struct device dev; struct rfkill *rfkill; struct module *owner; int (*open)(struct hci_dev *hdev); Loading
include/net/bluetooth/l2cap.h +50 −21 Original line number Diff line number Diff line Loading @@ -27,7 +27,12 @@ /* L2CAP defaults */ #define L2CAP_DEFAULT_MTU 672 #define L2CAP_DEFAULT_FLUSH_TO 0xFFFF #define L2CAP_DEFAULT_FLUSH_TO 0xffff #define L2CAP_DEFAULT_RX_WINDOW 1 #define L2CAP_DEFAULT_MAX_RECEIVE 1 #define L2CAP_DEFAULT_RETRANS_TO 300 /* 300 milliseconds */ #define L2CAP_DEFAULT_MONITOR_TO 1000 /* 1 second */ #define L2CAP_DEFAULT_MAX_RX_APDU 0xfff7 #define L2CAP_CONN_TIMEOUT (40000) /* 40 seconds */ #define L2CAP_INFO_TIMEOUT (4000) /* 4 seconds */ Loading Loading @@ -76,6 +81,18 @@ struct l2cap_conninfo { #define L2CAP_INFO_REQ 0x0a #define L2CAP_INFO_RSP 0x0b /* L2CAP feature mask */ #define L2CAP_FEAT_FLOWCTL 0x00000001 #define L2CAP_FEAT_RETRANS 0x00000002 #define L2CAP_FEAT_ERTM 0x00000008 #define L2CAP_FEAT_STREAMING 0x00000010 #define L2CAP_FEAT_FCS 0x00000020 #define L2CAP_FEAT_FIXED_CHAN 0x00000080 /* L2CAP checksum option */ #define L2CAP_FCS_NONE 0x00 #define L2CAP_FCS_CRC16 0x01 /* L2CAP structures */ struct l2cap_hdr { __le16 len; Loading Loading @@ -106,6 +123,12 @@ struct l2cap_conn_rsp { __le16 status; } __attribute__ ((packed)); /* channel indentifier */ #define L2CAP_CID_SIGNALING 0x0001 #define L2CAP_CID_CONN_LESS 0x0002 #define L2CAP_CID_DYN_START 0x0040 #define L2CAP_CID_DYN_END 0xffff /* connect result */ #define L2CAP_CR_SUCCESS 0x0000 #define L2CAP_CR_PEND 0x0001 Loading Loading @@ -143,10 +166,14 @@ struct l2cap_conf_opt { } __attribute__ ((packed)); #define L2CAP_CONF_OPT_SIZE 2 #define L2CAP_CONF_HINT 0x80 #define L2CAP_CONF_MASK 0x7f #define L2CAP_CONF_MTU 0x01 #define L2CAP_CONF_FLUSH_TO 0x02 #define L2CAP_CONF_QOS 0x03 #define L2CAP_CONF_RFC 0x04 #define L2CAP_CONF_FCS 0x05 #define L2CAP_CONF_MAX_SIZE 22 Loading @@ -162,6 +189,8 @@ struct l2cap_conf_rfc { #define L2CAP_MODE_BASIC 0x00 #define L2CAP_MODE_RETRANS 0x01 #define L2CAP_MODE_FLOWCTL 0x02 #define L2CAP_MODE_ERTM 0x03 #define L2CAP_MODE_STREAM 0x04 struct l2cap_disconn_req { __le16 dcid; Loading
net/bluetooth/hci_core.c +40 −1 Original line number Diff line number Diff line Loading @@ -39,6 +39,7 @@ #include <linux/skbuff.h> #include <linux/interrupt.h> #include <linux/notifier.h> #include <linux/rfkill.h> #include <net/sock.h> #include <asm/system.h> Loading Loading @@ -476,6 +477,11 @@ int hci_dev_open(__u16 dev) hci_req_lock(hdev); if (hdev->rfkill && rfkill_blocked(hdev->rfkill)) { ret = -ERFKILL; goto done; } if (test_bit(HCI_UP, &hdev->flags)) { ret = -EALREADY; goto done; Loading Loading @@ -813,6 +819,24 @@ int hci_get_dev_info(void __user *arg) /* ---- Interface to HCI drivers ---- */ static int hci_rfkill_set_block(void *data, bool blocked) { struct hci_dev *hdev = data; BT_DBG("%p name %s blocked %d", hdev, hdev->name, blocked); if (!blocked) return 0; hci_dev_do_close(hdev); return 0; } static const struct rfkill_ops hci_rfkill_ops = { .set_block = hci_rfkill_set_block, }; /* Alloc HCI device */ struct hci_dev *hci_alloc_dev(void) { Loading Loading @@ -844,7 +868,8 @@ int hci_register_dev(struct hci_dev *hdev) struct list_head *head = &hci_dev_list, *p; int i, id = 0; BT_DBG("%p name %s type %d owner %p", hdev, hdev->name, hdev->type, hdev->owner); BT_DBG("%p name %s type %d owner %p", hdev, hdev->name, hdev->type, hdev->owner); if (!hdev->open || !hdev->close || !hdev->destruct) return -EINVAL; Loading Loading @@ -900,6 +925,15 @@ int hci_register_dev(struct hci_dev *hdev) hci_register_sysfs(hdev); hdev->rfkill = rfkill_alloc(hdev->name, &hdev->dev, RFKILL_TYPE_BLUETOOTH, &hci_rfkill_ops, hdev); if (hdev->rfkill) { if (rfkill_register(hdev->rfkill) < 0) { rfkill_destroy(hdev->rfkill); hdev->rfkill = NULL; } } hci_notify(hdev, HCI_DEV_REG); return id; Loading @@ -924,6 +958,11 @@ int hci_unregister_dev(struct hci_dev *hdev) hci_notify(hdev, HCI_DEV_UNREG); if (hdev->rfkill) { rfkill_unregister(hdev->rfkill); rfkill_destroy(hdev->rfkill); } hci_unregister_sysfs(hdev); __hci_dev_put(hdev); Loading