aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/bluetooth/hci_vhci.c30
1 files changed, 21 insertions, 9 deletions
diff --git a/drivers/bluetooth/hci_vhci.c b/drivers/bluetooth/hci_vhci.c
index add1c6a72063..aa446c7eb7e5 100644
--- a/drivers/bluetooth/hci_vhci.c
+++ b/drivers/bluetooth/hci_vhci.c
@@ -40,7 +40,7 @@
40#include <net/bluetooth/bluetooth.h> 40#include <net/bluetooth/bluetooth.h>
41#include <net/bluetooth/hci_core.h> 41#include <net/bluetooth/hci_core.h>
42 42
43#define VERSION "1.4" 43#define VERSION "1.5"
44 44
45static bool amp; 45static bool amp;
46 46
@@ -95,10 +95,21 @@ static int vhci_send_frame(struct hci_dev *hdev, struct sk_buff *skb)
95 return 0; 95 return 0;
96} 96}
97 97
98static int vhci_create_device(struct vhci_data *data, __u8 dev_type) 98static int vhci_create_device(struct vhci_data *data, __u8 opcode)
99{ 99{
100 struct hci_dev *hdev; 100 struct hci_dev *hdev;
101 struct sk_buff *skb; 101 struct sk_buff *skb;
102 __u8 dev_type;
103
104 /* bits 0-1 are dev_type (BR/EDR or AMP) */
105 dev_type = opcode & 0x03;
106
107 if (dev_type != HCI_BREDR && dev_type != HCI_AMP)
108 return -EINVAL;
109
110 /* bits 2-6 are reserved (must be zero) */
111 if (opcode & 0x7c)
112 return -EINVAL;
102 113
103 skb = bt_skb_alloc(4, GFP_KERNEL); 114 skb = bt_skb_alloc(4, GFP_KERNEL);
104 if (!skb) 115 if (!skb)
@@ -121,6 +132,10 @@ static int vhci_create_device(struct vhci_data *data, __u8 dev_type)
121 hdev->flush = vhci_flush; 132 hdev->flush = vhci_flush;
122 hdev->send = vhci_send_frame; 133 hdev->send = vhci_send_frame;
123 134
135 /* bit 7 is for raw device */
136 if (opcode & 0x80)
137 set_bit(HCI_QUIRK_RAW_DEVICE, &hdev->quirks);
138
124 if (hci_register_dev(hdev) < 0) { 139 if (hci_register_dev(hdev) < 0) {
125 BT_ERR("Can't register HCI device"); 140 BT_ERR("Can't register HCI device");
126 hci_free_dev(hdev); 141 hci_free_dev(hdev);
@@ -132,7 +147,7 @@ static int vhci_create_device(struct vhci_data *data, __u8 dev_type)
132 bt_cb(skb)->pkt_type = HCI_VENDOR_PKT; 147 bt_cb(skb)->pkt_type = HCI_VENDOR_PKT;
133 148
134 *skb_put(skb, 1) = 0xff; 149 *skb_put(skb, 1) = 0xff;
135 *skb_put(skb, 1) = dev_type; 150 *skb_put(skb, 1) = opcode;
136 put_unaligned_le16(hdev->id, skb_put(skb, 2)); 151 put_unaligned_le16(hdev->id, skb_put(skb, 2));
137 skb_queue_tail(&data->readq, skb); 152 skb_queue_tail(&data->readq, skb);
138 153
@@ -146,7 +161,7 @@ static inline ssize_t vhci_get_user(struct vhci_data *data,
146{ 161{
147 size_t len = iov_length(iov, count); 162 size_t len = iov_length(iov, count);
148 struct sk_buff *skb; 163 struct sk_buff *skb;
149 __u8 pkt_type, dev_type; 164 __u8 pkt_type, opcode;
150 unsigned long i; 165 unsigned long i;
151 int ret; 166 int ret;
152 167
@@ -190,7 +205,7 @@ static inline ssize_t vhci_get_user(struct vhci_data *data,
190 205
191 cancel_delayed_work_sync(&data->open_timeout); 206 cancel_delayed_work_sync(&data->open_timeout);
192 207
193 dev_type = *((__u8 *) skb->data); 208 opcode = *((__u8 *) skb->data);
194 skb_pull(skb, 1); 209 skb_pull(skb, 1);
195 210
196 if (skb->len > 0) { 211 if (skb->len > 0) {
@@ -200,10 +215,7 @@ static inline ssize_t vhci_get_user(struct vhci_data *data,
200 215
201 kfree_skb(skb); 216 kfree_skb(skb);
202 217
203 if (dev_type != HCI_BREDR && dev_type != HCI_AMP) 218 ret = vhci_create_device(data, opcode);
204 return -EINVAL;
205
206 ret = vhci_create_device(data, dev_type);
207 break; 219 break;
208 220
209 default: 221 default: