Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
hci_vhci.c
Go to the documentation of this file.
1 /*
2  *
3  * Bluetooth virtual HCI driver
4  *
5  * Copyright (C) 2000-2001 Qualcomm Incorporated
6  * Copyright (C) 2002-2003 Maxim Krasnyansky <[email protected]>
7  * Copyright (C) 2004-2006 Marcel Holtmann <[email protected]>
8  *
9  *
10  * This program is free software; you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License as published by
12  * the Free Software Foundation; either version 2 of the License, or
13  * (at your option) any later version.
14  *
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18  * GNU General Public License for more details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with this program; if not, write to the Free Software
22  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23  *
24  */
25 
26 #include <linux/module.h>
27 
28 #include <linux/kernel.h>
29 #include <linux/init.h>
30 #include <linux/slab.h>
31 #include <linux/types.h>
32 #include <linux/errno.h>
33 #include <linux/sched.h>
34 #include <linux/poll.h>
35 
36 #include <linux/skbuff.h>
37 #include <linux/miscdevice.h>
38 
40 #include <net/bluetooth/hci_core.h>
41 
42 #define VERSION "1.3"
43 
44 static bool amp;
45 
46 struct vhci_data {
47  struct hci_dev *hdev;
48 
49  unsigned long flags;
50 
53 };
54 
55 static int vhci_open_dev(struct hci_dev *hdev)
56 {
57  set_bit(HCI_RUNNING, &hdev->flags);
58 
59  return 0;
60 }
61 
62 static int vhci_close_dev(struct hci_dev *hdev)
63 {
64  struct vhci_data *data = hci_get_drvdata(hdev);
65 
66  if (!test_and_clear_bit(HCI_RUNNING, &hdev->flags))
67  return 0;
68 
69  skb_queue_purge(&data->readq);
70 
71  return 0;
72 }
73 
74 static int vhci_flush(struct hci_dev *hdev)
75 {
76  struct vhci_data *data = hci_get_drvdata(hdev);
77 
78  skb_queue_purge(&data->readq);
79 
80  return 0;
81 }
82 
83 static int vhci_send_frame(struct sk_buff *skb)
84 {
85  struct hci_dev* hdev = (struct hci_dev *) skb->dev;
86  struct vhci_data *data;
87 
88  if (!hdev) {
89  BT_ERR("Frame for unknown HCI device (hdev=NULL)");
90  return -ENODEV;
91  }
92 
93  if (!test_bit(HCI_RUNNING, &hdev->flags))
94  return -EBUSY;
95 
96  data = hci_get_drvdata(hdev);
97 
98  memcpy(skb_push(skb, 1), &bt_cb(skb)->pkt_type, 1);
99  skb_queue_tail(&data->readq, skb);
100 
102 
103  return 0;
104 }
105 
106 static inline ssize_t vhci_get_user(struct vhci_data *data,
107  const char __user *buf, size_t count)
108 {
109  struct sk_buff *skb;
110 
111  if (count > HCI_MAX_FRAME_SIZE)
112  return -EINVAL;
113 
114  skb = bt_skb_alloc(count, GFP_KERNEL);
115  if (!skb)
116  return -ENOMEM;
117 
118  if (copy_from_user(skb_put(skb, count), buf, count)) {
119  kfree_skb(skb);
120  return -EFAULT;
121  }
122 
123  skb->dev = (void *) data->hdev;
124  bt_cb(skb)->pkt_type = *((__u8 *) skb->data);
125  skb_pull(skb, 1);
126 
127  hci_recv_frame(skb);
128 
129  return count;
130 }
131 
132 static inline ssize_t vhci_put_user(struct vhci_data *data,
133  struct sk_buff *skb, char __user *buf, int count)
134 {
135  char __user *ptr = buf;
136  int len, total = 0;
137 
138  len = min_t(unsigned int, skb->len, count);
139 
140  if (copy_to_user(ptr, skb->data, len))
141  return -EFAULT;
142 
143  total += len;
144 
145  data->hdev->stat.byte_tx += len;
146 
147  switch (bt_cb(skb)->pkt_type) {
148  case HCI_COMMAND_PKT:
149  data->hdev->stat.cmd_tx++;
150  break;
151 
152  case HCI_ACLDATA_PKT:
153  data->hdev->stat.acl_tx++;
154  break;
155 
156  case HCI_SCODATA_PKT:
157  data->hdev->stat.sco_tx++;
158  break;
159  }
160 
161  return total;
162 }
163 
164 static ssize_t vhci_read(struct file *file,
165  char __user *buf, size_t count, loff_t *pos)
166 {
167  struct vhci_data *data = file->private_data;
168  struct sk_buff *skb;
169  ssize_t ret = 0;
170 
171  while (count) {
172  skb = skb_dequeue(&data->readq);
173  if (skb) {
174  ret = vhci_put_user(data, skb, buf, count);
175  if (ret < 0)
176  skb_queue_head(&data->readq, skb);
177  else
178  kfree_skb(skb);
179  break;
180  }
181 
182  if (file->f_flags & O_NONBLOCK) {
183  ret = -EAGAIN;
184  break;
185  }
186 
188  !skb_queue_empty(&data->readq));
189  if (ret < 0)
190  break;
191  }
192 
193  return ret;
194 }
195 
196 static ssize_t vhci_write(struct file *file,
197  const char __user *buf, size_t count, loff_t *pos)
198 {
199  struct vhci_data *data = file->private_data;
200 
201  return vhci_get_user(data, buf, count);
202 }
203 
204 static unsigned int vhci_poll(struct file *file, poll_table *wait)
205 {
206  struct vhci_data *data = file->private_data;
207 
208  poll_wait(file, &data->read_wait, wait);
209 
210  if (!skb_queue_empty(&data->readq))
211  return POLLIN | POLLRDNORM;
212 
213  return POLLOUT | POLLWRNORM;
214 }
215 
216 static int vhci_open(struct inode *inode, struct file *file)
217 {
218  struct vhci_data *data;
219  struct hci_dev *hdev;
220 
221  data = kzalloc(sizeof(struct vhci_data), GFP_KERNEL);
222  if (!data)
223  return -ENOMEM;
224 
225  skb_queue_head_init(&data->readq);
227 
228  hdev = hci_alloc_dev();
229  if (!hdev) {
230  kfree(data);
231  return -ENOMEM;
232  }
233 
234  data->hdev = hdev;
235 
236  hdev->bus = HCI_VIRTUAL;
237  hci_set_drvdata(hdev, data);
238 
239  if (amp)
240  hdev->dev_type = HCI_AMP;
241 
242  hdev->open = vhci_open_dev;
243  hdev->close = vhci_close_dev;
244  hdev->flush = vhci_flush;
245  hdev->send = vhci_send_frame;
246 
247  if (hci_register_dev(hdev) < 0) {
248  BT_ERR("Can't register HCI device");
249  kfree(data);
250  hci_free_dev(hdev);
251  return -EBUSY;
252  }
253 
254  file->private_data = data;
255  nonseekable_open(inode, file);
256 
257  return 0;
258 }
259 
260 static int vhci_release(struct inode *inode, struct file *file)
261 {
262  struct vhci_data *data = file->private_data;
263  struct hci_dev *hdev = data->hdev;
264 
265  hci_unregister_dev(hdev);
266  hci_free_dev(hdev);
267 
268  file->private_data = NULL;
269  kfree(data);
270 
271  return 0;
272 }
273 
274 static const struct file_operations vhci_fops = {
275  .owner = THIS_MODULE,
276  .read = vhci_read,
277  .write = vhci_write,
278  .poll = vhci_poll,
279  .open = vhci_open,
280  .release = vhci_release,
281  .llseek = no_llseek,
282 };
283 
284 static struct miscdevice vhci_miscdev= {
285  .name = "vhci",
286  .fops = &vhci_fops,
287  .minor = MISC_DYNAMIC_MINOR,
288 };
289 
290 static int __init vhci_init(void)
291 {
292  BT_INFO("Virtual HCI driver ver %s", VERSION);
293 
294  return misc_register(&vhci_miscdev);
295 }
296 
297 static void __exit vhci_exit(void)
298 {
299  misc_deregister(&vhci_miscdev);
300 }
301 
302 module_init(vhci_init);
303 module_exit(vhci_exit);
304 
305 module_param(amp, bool, 0644);
306 MODULE_PARM_DESC(amp, "Create AMP controller device");
307 
308 MODULE_AUTHOR("Marcel Holtmann <[email protected]>");
309 MODULE_DESCRIPTION("Bluetooth virtual HCI driver ver " VERSION);
311 MODULE_LICENSE("GPL");