diff options
-rw-r--r-- | drivers/bluetooth/hci_vhci.c | 30 |
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 | ||
45 | static bool amp; | 45 | static 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 | ||
98 | static int vhci_create_device(struct vhci_data *data, __u8 dev_type) | 98 | static 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: |