aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/bluetooth/hci_vhci.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/bluetooth/hci_vhci.c')
-rw-r--r--drivers/bluetooth/hci_vhci.c101
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
74static int vhci_close_dev(struct hci_dev *hdev) 73static 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
86static int vhci_flush(struct hci_dev *hdev) 85static 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)
95static int vhci_send_frame(struct sk_buff *skb) 94static 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
126static inline ssize_t vhci_get_user(struct vhci_data *vhci, 125static 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
152static inline ssize_t vhci_put_user(struct vhci_data *vhci, 151static 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
184static loff_t vhci_llseek(struct file * file, loff_t offset, int origin) 183static loff_t vhci_llseek(struct file *file, loff_t offset, int origin)
185{ 184{
186 return -ESPIPE; 185 return -ESPIPE;
187} 186}
188 187
189static ssize_t vhci_read(struct file * file, char __user * buf, size_t count, loff_t *pos) 188static 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
230static ssize_t vhci_write(struct file *file, 230static 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
241static unsigned int vhci_poll(struct file *file, poll_table *wait) 241static 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
259static int vhci_open(struct inode *inode, struct file *file) 259static 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
303static int vhci_release(struct inode *inode, struct file *file) 302static 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
319static int vhci_fasync(int fd, struct file *file, int on) 318static 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}