diff options
Diffstat (limited to 'drivers/bluetooth/hci_vhci.c')
-rw-r--r-- | drivers/bluetooth/hci_vhci.c | 101 |
1 files changed, 50 insertions, 51 deletions
diff --git a/drivers/bluetooth/hci_vhci.c b/drivers/bluetooth/hci_vhci.c index 85738223ff0c..a278d98a9151 100644 --- a/drivers/bluetooth/hci_vhci.c +++ b/drivers/bluetooth/hci_vhci.c | |||
@@ -2,9 +2,9 @@ | |||
2 | * | 2 | * |
3 | * Bluetooth virtual HCI driver | 3 | * Bluetooth virtual HCI driver |
4 | * | 4 | * |
5 | * Copyright (C) 2000-2001 Qualcomm Incorporated | 5 | * Copyright (C) 2000-2001 Qualcomm Incorporated |
6 | * Copyright (C) 2002-2003 Maxim Krasnyansky <maxk@qualcomm.com> | 6 | * Copyright (C) 2002-2003 Maxim Krasnyansky <maxk@qualcomm.com> |
7 | * Copyright (C) 2004-2005 Marcel Holtmann <marcel@holtmann.org> | 7 | * Copyright (C) 2004-2006 Marcel Holtmann <marcel@holtmann.org> |
8 | * | 8 | * |
9 | * | 9 | * |
10 | * This program is free software; you can redistribute it and/or modify | 10 | * This program is free software; you can redistribute it and/or modify |
@@ -23,7 +23,6 @@ | |||
23 | * | 23 | * |
24 | */ | 24 | */ |
25 | 25 | ||
26 | #include <linux/config.h> | ||
27 | #include <linux/module.h> | 26 | #include <linux/module.h> |
28 | 27 | ||
29 | #include <linux/kernel.h> | 28 | #include <linux/kernel.h> |
@@ -73,21 +72,21 @@ static int vhci_open_dev(struct hci_dev *hdev) | |||
73 | 72 | ||
74 | static int vhci_close_dev(struct hci_dev *hdev) | 73 | static int vhci_close_dev(struct hci_dev *hdev) |
75 | { | 74 | { |
76 | struct vhci_data *vhci = hdev->driver_data; | 75 | struct vhci_data *data = hdev->driver_data; |
77 | 76 | ||
78 | if (!test_and_clear_bit(HCI_RUNNING, &hdev->flags)) | 77 | if (!test_and_clear_bit(HCI_RUNNING, &hdev->flags)) |
79 | return 0; | 78 | return 0; |
80 | 79 | ||
81 | skb_queue_purge(&vhci->readq); | 80 | skb_queue_purge(&data->readq); |
82 | 81 | ||
83 | return 0; | 82 | return 0; |
84 | } | 83 | } |
85 | 84 | ||
86 | static int vhci_flush(struct hci_dev *hdev) | 85 | static int vhci_flush(struct hci_dev *hdev) |
87 | { | 86 | { |
88 | struct vhci_data *vhci = hdev->driver_data; | 87 | struct vhci_data *data = hdev->driver_data; |
89 | 88 | ||
90 | skb_queue_purge(&vhci->readq); | 89 | skb_queue_purge(&data->readq); |
91 | 90 | ||
92 | return 0; | 91 | return 0; |
93 | } | 92 | } |
@@ -95,7 +94,7 @@ static int vhci_flush(struct hci_dev *hdev) | |||
95 | static int vhci_send_frame(struct sk_buff *skb) | 94 | static int vhci_send_frame(struct sk_buff *skb) |
96 | { | 95 | { |
97 | struct hci_dev* hdev = (struct hci_dev *) skb->dev; | 96 | struct hci_dev* hdev = (struct hci_dev *) skb->dev; |
98 | struct vhci_data *vhci; | 97 | struct vhci_data *data; |
99 | 98 | ||
100 | if (!hdev) { | 99 | if (!hdev) { |
101 | BT_ERR("Frame for unknown HCI device (hdev=NULL)"); | 100 | BT_ERR("Frame for unknown HCI device (hdev=NULL)"); |
@@ -105,15 +104,15 @@ static int vhci_send_frame(struct sk_buff *skb) | |||
105 | if (!test_bit(HCI_RUNNING, &hdev->flags)) | 104 | if (!test_bit(HCI_RUNNING, &hdev->flags)) |
106 | return -EBUSY; | 105 | return -EBUSY; |
107 | 106 | ||
108 | vhci = hdev->driver_data; | 107 | data = hdev->driver_data; |
109 | 108 | ||
110 | memcpy(skb_push(skb, 1), &bt_cb(skb)->pkt_type, 1); | 109 | memcpy(skb_push(skb, 1), &bt_cb(skb)->pkt_type, 1); |
111 | skb_queue_tail(&vhci->readq, skb); | 110 | skb_queue_tail(&data->readq, skb); |
112 | 111 | ||
113 | if (vhci->flags & VHCI_FASYNC) | 112 | if (data->flags & VHCI_FASYNC) |
114 | kill_fasync(&vhci->fasync, SIGIO, POLL_IN); | 113 | kill_fasync(&data->fasync, SIGIO, POLL_IN); |
115 | 114 | ||
116 | wake_up_interruptible(&vhci->read_wait); | 115 | wake_up_interruptible(&data->read_wait); |
117 | 116 | ||
118 | return 0; | 117 | return 0; |
119 | } | 118 | } |
@@ -123,7 +122,7 @@ static void vhci_destruct(struct hci_dev *hdev) | |||
123 | kfree(hdev->driver_data); | 122 | kfree(hdev->driver_data); |
124 | } | 123 | } |
125 | 124 | ||
126 | static inline ssize_t vhci_get_user(struct vhci_data *vhci, | 125 | static inline ssize_t vhci_get_user(struct vhci_data *data, |
127 | const char __user *buf, size_t count) | 126 | const char __user *buf, size_t count) |
128 | { | 127 | { |
129 | struct sk_buff *skb; | 128 | struct sk_buff *skb; |
@@ -140,7 +139,7 @@ static inline ssize_t vhci_get_user(struct vhci_data *vhci, | |||
140 | return -EFAULT; | 139 | return -EFAULT; |
141 | } | 140 | } |
142 | 141 | ||
143 | skb->dev = (void *) vhci->hdev; | 142 | skb->dev = (void *) data->hdev; |
144 | bt_cb(skb)->pkt_type = *((__u8 *) skb->data); | 143 | bt_cb(skb)->pkt_type = *((__u8 *) skb->data); |
145 | skb_pull(skb, 1); | 144 | skb_pull(skb, 1); |
146 | 145 | ||
@@ -149,7 +148,7 @@ static inline ssize_t vhci_get_user(struct vhci_data *vhci, | |||
149 | return count; | 148 | return count; |
150 | } | 149 | } |
151 | 150 | ||
152 | static inline ssize_t vhci_put_user(struct vhci_data *vhci, | 151 | static inline ssize_t vhci_put_user(struct vhci_data *data, |
153 | struct sk_buff *skb, char __user *buf, int count) | 152 | struct sk_buff *skb, char __user *buf, int count) |
154 | { | 153 | { |
155 | char __user *ptr = buf; | 154 | char __user *ptr = buf; |
@@ -162,42 +161,43 @@ static inline ssize_t vhci_put_user(struct vhci_data *vhci, | |||
162 | 161 | ||
163 | total += len; | 162 | total += len; |
164 | 163 | ||
165 | vhci->hdev->stat.byte_tx += len; | 164 | data->hdev->stat.byte_tx += len; |
166 | 165 | ||
167 | switch (bt_cb(skb)->pkt_type) { | 166 | switch (bt_cb(skb)->pkt_type) { |
168 | case HCI_COMMAND_PKT: | 167 | case HCI_COMMAND_PKT: |
169 | vhci->hdev->stat.cmd_tx++; | 168 | data->hdev->stat.cmd_tx++; |
170 | break; | 169 | break; |
171 | 170 | ||
172 | case HCI_ACLDATA_PKT: | 171 | case HCI_ACLDATA_PKT: |
173 | vhci->hdev->stat.acl_tx++; | 172 | data->hdev->stat.acl_tx++; |
174 | break; | 173 | break; |
175 | 174 | ||
176 | case HCI_SCODATA_PKT: | 175 | case HCI_SCODATA_PKT: |
177 | vhci->hdev->stat.cmd_tx++; | 176 | data->hdev->stat.cmd_tx++; |
178 | break; | 177 | break; |
179 | }; | 178 | }; |
180 | 179 | ||
181 | return total; | 180 | return total; |
182 | } | 181 | } |
183 | 182 | ||
184 | static loff_t vhci_llseek(struct file * file, loff_t offset, int origin) | 183 | static loff_t vhci_llseek(struct file *file, loff_t offset, int origin) |
185 | { | 184 | { |
186 | return -ESPIPE; | 185 | return -ESPIPE; |
187 | } | 186 | } |
188 | 187 | ||
189 | static ssize_t vhci_read(struct file * file, char __user * buf, size_t count, loff_t *pos) | 188 | static ssize_t vhci_read(struct file *file, |
189 | char __user *buf, size_t count, loff_t *pos) | ||
190 | { | 190 | { |
191 | DECLARE_WAITQUEUE(wait, current); | 191 | DECLARE_WAITQUEUE(wait, current); |
192 | struct vhci_data *vhci = file->private_data; | 192 | struct vhci_data *data = file->private_data; |
193 | struct sk_buff *skb; | 193 | struct sk_buff *skb; |
194 | ssize_t ret = 0; | 194 | ssize_t ret = 0; |
195 | 195 | ||
196 | add_wait_queue(&vhci->read_wait, &wait); | 196 | add_wait_queue(&data->read_wait, &wait); |
197 | while (count) { | 197 | while (count) { |
198 | set_current_state(TASK_INTERRUPTIBLE); | 198 | set_current_state(TASK_INTERRUPTIBLE); |
199 | 199 | ||
200 | skb = skb_dequeue(&vhci->readq); | 200 | skb = skb_dequeue(&data->readq); |
201 | if (!skb) { | 201 | if (!skb) { |
202 | if (file->f_flags & O_NONBLOCK) { | 202 | if (file->f_flags & O_NONBLOCK) { |
203 | ret = -EAGAIN; | 203 | ret = -EAGAIN; |
@@ -214,7 +214,7 @@ static ssize_t vhci_read(struct file * file, char __user * buf, size_t count, lo | |||
214 | } | 214 | } |
215 | 215 | ||
216 | if (access_ok(VERIFY_WRITE, buf, count)) | 216 | if (access_ok(VERIFY_WRITE, buf, count)) |
217 | ret = vhci_put_user(vhci, skb, buf, count); | 217 | ret = vhci_put_user(data, skb, buf, count); |
218 | else | 218 | else |
219 | ret = -EFAULT; | 219 | ret = -EFAULT; |
220 | 220 | ||
@@ -222,7 +222,7 @@ static ssize_t vhci_read(struct file * file, char __user * buf, size_t count, lo | |||
222 | break; | 222 | break; |
223 | } | 223 | } |
224 | set_current_state(TASK_RUNNING); | 224 | set_current_state(TASK_RUNNING); |
225 | remove_wait_queue(&vhci->read_wait, &wait); | 225 | remove_wait_queue(&data->read_wait, &wait); |
226 | 226 | ||
227 | return ret; | 227 | return ret; |
228 | } | 228 | } |
@@ -230,21 +230,21 @@ static ssize_t vhci_read(struct file * file, char __user * buf, size_t count, lo | |||
230 | static ssize_t vhci_write(struct file *file, | 230 | static ssize_t vhci_write(struct file *file, |
231 | const char __user *buf, size_t count, loff_t *pos) | 231 | const char __user *buf, size_t count, loff_t *pos) |
232 | { | 232 | { |
233 | struct vhci_data *vhci = file->private_data; | 233 | struct vhci_data *data = file->private_data; |
234 | 234 | ||
235 | if (!access_ok(VERIFY_READ, buf, count)) | 235 | if (!access_ok(VERIFY_READ, buf, count)) |
236 | return -EFAULT; | 236 | return -EFAULT; |
237 | 237 | ||
238 | return vhci_get_user(vhci, buf, count); | 238 | return vhci_get_user(data, buf, count); |
239 | } | 239 | } |
240 | 240 | ||
241 | static unsigned int vhci_poll(struct file *file, poll_table *wait) | 241 | static unsigned int vhci_poll(struct file *file, poll_table *wait) |
242 | { | 242 | { |
243 | struct vhci_data *vhci = file->private_data; | 243 | struct vhci_data *data = file->private_data; |
244 | 244 | ||
245 | poll_wait(file, &vhci->read_wait, wait); | 245 | poll_wait(file, &data->read_wait, wait); |
246 | 246 | ||
247 | if (!skb_queue_empty(&vhci->readq)) | 247 | if (!skb_queue_empty(&data->readq)) |
248 | return POLLIN | POLLRDNORM; | 248 | return POLLIN | POLLRDNORM; |
249 | 249 | ||
250 | return POLLOUT | POLLWRNORM; | 250 | return POLLOUT | POLLWRNORM; |
@@ -258,27 +258,26 @@ static int vhci_ioctl(struct inode *inode, struct file *file, | |||
258 | 258 | ||
259 | static int vhci_open(struct inode *inode, struct file *file) | 259 | static int vhci_open(struct inode *inode, struct file *file) |
260 | { | 260 | { |
261 | struct vhci_data *vhci; | 261 | struct vhci_data *data; |
262 | struct hci_dev *hdev; | 262 | struct hci_dev *hdev; |
263 | 263 | ||
264 | vhci = kzalloc(sizeof(struct vhci_data), GFP_KERNEL); | 264 | data = kzalloc(sizeof(struct vhci_data), GFP_KERNEL); |
265 | if (!vhci) | 265 | if (!data) |
266 | return -ENOMEM; | 266 | return -ENOMEM; |
267 | 267 | ||
268 | skb_queue_head_init(&vhci->readq); | 268 | skb_queue_head_init(&data->readq); |
269 | init_waitqueue_head(&vhci->read_wait); | 269 | init_waitqueue_head(&data->read_wait); |
270 | 270 | ||
271 | hdev = hci_alloc_dev(); | 271 | hdev = hci_alloc_dev(); |
272 | if (!hdev) { | 272 | if (!hdev) { |
273 | kfree(vhci); | 273 | kfree(data); |
274 | return -ENOMEM; | 274 | return -ENOMEM; |
275 | } | 275 | } |
276 | 276 | ||
277 | vhci->hdev = hdev; | 277 | data->hdev = hdev; |
278 | 278 | ||
279 | hdev->type = HCI_VHCI; | 279 | hdev->type = HCI_VIRTUAL; |
280 | hdev->driver_data = vhci; | 280 | hdev->driver_data = data; |
281 | SET_HCIDEV_DEV(hdev, vhci_miscdev.dev); | ||
282 | 281 | ||
283 | hdev->open = vhci_open_dev; | 282 | hdev->open = vhci_open_dev; |
284 | hdev->close = vhci_close_dev; | 283 | hdev->close = vhci_close_dev; |
@@ -290,20 +289,20 @@ static int vhci_open(struct inode *inode, struct file *file) | |||
290 | 289 | ||
291 | if (hci_register_dev(hdev) < 0) { | 290 | if (hci_register_dev(hdev) < 0) { |
292 | BT_ERR("Can't register HCI device"); | 291 | BT_ERR("Can't register HCI device"); |
293 | kfree(vhci); | 292 | kfree(data); |
294 | hci_free_dev(hdev); | 293 | hci_free_dev(hdev); |
295 | return -EBUSY; | 294 | return -EBUSY; |
296 | } | 295 | } |
297 | 296 | ||
298 | file->private_data = vhci; | 297 | file->private_data = data; |
299 | 298 | ||
300 | return nonseekable_open(inode, file); | 299 | return nonseekable_open(inode, file); |
301 | } | 300 | } |
302 | 301 | ||
303 | static int vhci_release(struct inode *inode, struct file *file) | 302 | static int vhci_release(struct inode *inode, struct file *file) |
304 | { | 303 | { |
305 | struct vhci_data *vhci = file->private_data; | 304 | struct vhci_data *data = file->private_data; |
306 | struct hci_dev *hdev = vhci->hdev; | 305 | struct hci_dev *hdev = data->hdev; |
307 | 306 | ||
308 | if (hci_unregister_dev(hdev) < 0) { | 307 | if (hci_unregister_dev(hdev) < 0) { |
309 | BT_ERR("Can't unregister HCI device %s", hdev->name); | 308 | BT_ERR("Can't unregister HCI device %s", hdev->name); |
@@ -318,17 +317,17 @@ static int vhci_release(struct inode *inode, struct file *file) | |||
318 | 317 | ||
319 | static int vhci_fasync(int fd, struct file *file, int on) | 318 | static int vhci_fasync(int fd, struct file *file, int on) |
320 | { | 319 | { |
321 | struct vhci_data *vhci = file->private_data; | 320 | struct vhci_data *data = file->private_data; |
322 | int err; | 321 | int err; |
323 | 322 | ||
324 | err = fasync_helper(fd, file, on, &vhci->fasync); | 323 | err = fasync_helper(fd, file, on, &data->fasync); |
325 | if (err < 0) | 324 | if (err < 0) |
326 | return err; | 325 | return err; |
327 | 326 | ||
328 | if (on) | 327 | if (on) |
329 | vhci->flags |= VHCI_FASYNC; | 328 | data->flags |= VHCI_FASYNC; |
330 | else | 329 | else |
331 | vhci->flags &= ~VHCI_FASYNC; | 330 | data->flags &= ~VHCI_FASYNC; |
332 | 331 | ||
333 | return 0; | 332 | return 0; |
334 | } | 333 | } |