diff options
author | David S. Miller <davem@davemloft.net> | 2010-02-28 03:57:28 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2010-02-28 03:57:28 -0500 |
commit | 46976c042ba1ff59253f2f7a513099175c24794e (patch) | |
tree | a7af3f1c3ef2a2d430c49fb774ab744c296a2285 /net | |
parent | 024c378f0b719d43b01b875caefa19f2612e103a (diff) | |
parent | f6e623a65cb301088bd04794043e82bfc996c512 (diff) |
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/holtmann/bluetooth-next-2.6
Diffstat (limited to 'net')
-rw-r--r-- | net/bluetooth/hci_core.c | 12 | ||||
-rw-r--r-- | net/bluetooth/hci_event.c | 1 | ||||
-rw-r--r-- | net/bluetooth/hci_sock.c | 4 | ||||
-rw-r--r-- | net/bluetooth/hci_sysfs.c | 122 |
4 files changed, 99 insertions, 40 deletions
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c index 94ba34982021..4ad23192c7a5 100644 --- a/net/bluetooth/hci_core.c +++ b/net/bluetooth/hci_core.c | |||
@@ -491,6 +491,10 @@ int hci_dev_open(__u16 dev) | |||
491 | if (test_bit(HCI_QUIRK_RAW_DEVICE, &hdev->quirks)) | 491 | if (test_bit(HCI_QUIRK_RAW_DEVICE, &hdev->quirks)) |
492 | set_bit(HCI_RAW, &hdev->flags); | 492 | set_bit(HCI_RAW, &hdev->flags); |
493 | 493 | ||
494 | /* Treat all non BR/EDR controllers as raw devices for now */ | ||
495 | if (hdev->dev_type != HCI_BREDR) | ||
496 | set_bit(HCI_RAW, &hdev->flags); | ||
497 | |||
494 | if (hdev->open(hdev)) { | 498 | if (hdev->open(hdev)) { |
495 | ret = -EIO; | 499 | ret = -EIO; |
496 | goto done; | 500 | goto done; |
@@ -797,7 +801,7 @@ int hci_get_dev_info(void __user *arg) | |||
797 | 801 | ||
798 | strcpy(di.name, hdev->name); | 802 | strcpy(di.name, hdev->name); |
799 | di.bdaddr = hdev->bdaddr; | 803 | di.bdaddr = hdev->bdaddr; |
800 | di.type = hdev->type; | 804 | di.type = (hdev->bus & 0x0f) | (hdev->dev_type << 4); |
801 | di.flags = hdev->flags; | 805 | di.flags = hdev->flags; |
802 | di.pkt_type = hdev->pkt_type; | 806 | di.pkt_type = hdev->pkt_type; |
803 | di.acl_mtu = hdev->acl_mtu; | 807 | di.acl_mtu = hdev->acl_mtu; |
@@ -869,8 +873,8 @@ int hci_register_dev(struct hci_dev *hdev) | |||
869 | struct list_head *head = &hci_dev_list, *p; | 873 | struct list_head *head = &hci_dev_list, *p; |
870 | int i, id = 0; | 874 | int i, id = 0; |
871 | 875 | ||
872 | BT_DBG("%p name %s type %d owner %p", hdev, hdev->name, | 876 | BT_DBG("%p name %s bus %d owner %p", hdev, hdev->name, |
873 | hdev->type, hdev->owner); | 877 | hdev->bus, hdev->owner); |
874 | 878 | ||
875 | if (!hdev->open || !hdev->close || !hdev->destruct) | 879 | if (!hdev->open || !hdev->close || !hdev->destruct) |
876 | return -EINVAL; | 880 | return -EINVAL; |
@@ -946,7 +950,7 @@ int hci_unregister_dev(struct hci_dev *hdev) | |||
946 | { | 950 | { |
947 | int i; | 951 | int i; |
948 | 952 | ||
949 | BT_DBG("%p name %s type %d", hdev, hdev->name, hdev->type); | 953 | BT_DBG("%p name %s bus %d", hdev, hdev->name, hdev->bus); |
950 | 954 | ||
951 | write_lock_bh(&hci_dev_list_lock); | 955 | write_lock_bh(&hci_dev_list_lock); |
952 | list_del(&hdev->list); | 956 | list_del(&hdev->list); |
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c index 592da5c909c1..6c57fc71c7e2 100644 --- a/net/bluetooth/hci_event.c +++ b/net/bluetooth/hci_event.c | |||
@@ -1698,6 +1698,7 @@ static inline void hci_sync_conn_complete_evt(struct hci_dev *hdev, struct sk_bu | |||
1698 | hci_conn_add_sysfs(conn); | 1698 | hci_conn_add_sysfs(conn); |
1699 | break; | 1699 | break; |
1700 | 1700 | ||
1701 | case 0x11: /* Unsupported Feature or Parameter Value */ | ||
1701 | case 0x1c: /* SCO interval rejected */ | 1702 | case 0x1c: /* SCO interval rejected */ |
1702 | case 0x1a: /* Unsupported Remote Feature */ | 1703 | case 0x1a: /* Unsupported Remote Feature */ |
1703 | case 0x1f: /* Unspecified error */ | 1704 | case 0x1f: /* Unspecified error */ |
diff --git a/net/bluetooth/hci_sock.c b/net/bluetooth/hci_sock.c index 688cfebfbee0..38f08f6b86f6 100644 --- a/net/bluetooth/hci_sock.c +++ b/net/bluetooth/hci_sock.c | |||
@@ -329,6 +329,9 @@ static inline void hci_sock_cmsg(struct sock *sk, struct msghdr *msg, struct sk_ | |||
329 | } | 329 | } |
330 | 330 | ||
331 | if (mask & HCI_CMSG_TSTAMP) { | 331 | if (mask & HCI_CMSG_TSTAMP) { |
332 | #ifdef CONFIG_COMPAT | ||
333 | struct compat_timeval ctv; | ||
334 | #endif | ||
332 | struct timeval tv; | 335 | struct timeval tv; |
333 | void *data; | 336 | void *data; |
334 | int len; | 337 | int len; |
@@ -339,7 +342,6 @@ static inline void hci_sock_cmsg(struct sock *sk, struct msghdr *msg, struct sk_ | |||
339 | len = sizeof(tv); | 342 | len = sizeof(tv); |
340 | #ifdef CONFIG_COMPAT | 343 | #ifdef CONFIG_COMPAT |
341 | if (msg->msg_flags & MSG_CMSG_COMPAT) { | 344 | if (msg->msg_flags & MSG_CMSG_COMPAT) { |
342 | struct compat_timeval ctv; | ||
343 | ctv.tv_sec = tv.tv_sec; | 345 | ctv.tv_sec = tv.tv_sec; |
344 | ctv.tv_usec = tv.tv_usec; | 346 | ctv.tv_usec = tv.tv_usec; |
345 | data = &ctv; | 347 | data = &ctv; |
diff --git a/net/bluetooth/hci_sysfs.c b/net/bluetooth/hci_sysfs.c index 2bc6f6a8de68..1a79a6c7e30e 100644 --- a/net/bluetooth/hci_sysfs.c +++ b/net/bluetooth/hci_sysfs.c | |||
@@ -2,6 +2,7 @@ | |||
2 | 2 | ||
3 | #include <linux/kernel.h> | 3 | #include <linux/kernel.h> |
4 | #include <linux/init.h> | 4 | #include <linux/init.h> |
5 | #include <linux/debugfs.h> | ||
5 | 6 | ||
6 | #include <net/bluetooth/bluetooth.h> | 7 | #include <net/bluetooth/bluetooth.h> |
7 | #include <net/bluetooth/hci_core.h> | 8 | #include <net/bluetooth/hci_core.h> |
@@ -9,6 +10,9 @@ | |||
9 | struct class *bt_class = NULL; | 10 | struct class *bt_class = NULL; |
10 | EXPORT_SYMBOL_GPL(bt_class); | 11 | EXPORT_SYMBOL_GPL(bt_class); |
11 | 12 | ||
13 | struct dentry *bt_debugfs = NULL; | ||
14 | EXPORT_SYMBOL_GPL(bt_debugfs); | ||
15 | |||
12 | static struct workqueue_struct *bt_workq; | 16 | static struct workqueue_struct *bt_workq; |
13 | 17 | ||
14 | static inline char *link_typetostr(int type) | 18 | static inline char *link_typetostr(int type) |
@@ -166,9 +170,9 @@ void hci_conn_del_sysfs(struct hci_conn *conn) | |||
166 | queue_work(bt_workq, &conn->work_del); | 170 | queue_work(bt_workq, &conn->work_del); |
167 | } | 171 | } |
168 | 172 | ||
169 | static inline char *host_typetostr(int type) | 173 | static inline char *host_bustostr(int bus) |
170 | { | 174 | { |
171 | switch (type) { | 175 | switch (bus) { |
172 | case HCI_VIRTUAL: | 176 | case HCI_VIRTUAL: |
173 | return "VIRTUAL"; | 177 | return "VIRTUAL"; |
174 | case HCI_USB: | 178 | case HCI_USB: |
@@ -188,10 +192,28 @@ static inline char *host_typetostr(int type) | |||
188 | } | 192 | } |
189 | } | 193 | } |
190 | 194 | ||
195 | static inline char *host_typetostr(int type) | ||
196 | { | ||
197 | switch (type) { | ||
198 | case HCI_BREDR: | ||
199 | return "BR/EDR"; | ||
200 | case HCI_80211: | ||
201 | return "802.11"; | ||
202 | default: | ||
203 | return "UNKNOWN"; | ||
204 | } | ||
205 | } | ||
206 | |||
207 | static ssize_t show_bus(struct device *dev, struct device_attribute *attr, char *buf) | ||
208 | { | ||
209 | struct hci_dev *hdev = dev_get_drvdata(dev); | ||
210 | return sprintf(buf, "%s\n", host_bustostr(hdev->bus)); | ||
211 | } | ||
212 | |||
191 | static ssize_t show_type(struct device *dev, struct device_attribute *attr, char *buf) | 213 | static ssize_t show_type(struct device *dev, struct device_attribute *attr, char *buf) |
192 | { | 214 | { |
193 | struct hci_dev *hdev = dev_get_drvdata(dev); | 215 | struct hci_dev *hdev = dev_get_drvdata(dev); |
194 | return sprintf(buf, "%s\n", host_typetostr(hdev->type)); | 216 | return sprintf(buf, "%s\n", host_typetostr(hdev->dev_type)); |
195 | } | 217 | } |
196 | 218 | ||
197 | static ssize_t show_name(struct device *dev, struct device_attribute *attr, char *buf) | 219 | static ssize_t show_name(struct device *dev, struct device_attribute *attr, char *buf) |
@@ -251,32 +273,6 @@ static ssize_t show_hci_revision(struct device *dev, struct device_attribute *at | |||
251 | return sprintf(buf, "%d\n", hdev->hci_rev); | 273 | return sprintf(buf, "%d\n", hdev->hci_rev); |
252 | } | 274 | } |
253 | 275 | ||
254 | static ssize_t show_inquiry_cache(struct device *dev, struct device_attribute *attr, char *buf) | ||
255 | { | ||
256 | struct hci_dev *hdev = dev_get_drvdata(dev); | ||
257 | struct inquiry_cache *cache = &hdev->inq_cache; | ||
258 | struct inquiry_entry *e; | ||
259 | int n = 0; | ||
260 | |||
261 | hci_dev_lock_bh(hdev); | ||
262 | |||
263 | for (e = cache->list; e; e = e->next) { | ||
264 | struct inquiry_data *data = &e->data; | ||
265 | bdaddr_t bdaddr; | ||
266 | baswap(&bdaddr, &data->bdaddr); | ||
267 | n += sprintf(buf + n, "%s %d %d %d 0x%.2x%.2x%.2x 0x%.4x %d %d %u\n", | ||
268 | batostr(&bdaddr), | ||
269 | data->pscan_rep_mode, data->pscan_period_mode, | ||
270 | data->pscan_mode, data->dev_class[2], | ||
271 | data->dev_class[1], data->dev_class[0], | ||
272 | __le16_to_cpu(data->clock_offset), | ||
273 | data->rssi, data->ssp_mode, e->timestamp); | ||
274 | } | ||
275 | |||
276 | hci_dev_unlock_bh(hdev); | ||
277 | return n; | ||
278 | } | ||
279 | |||
280 | static ssize_t show_idle_timeout(struct device *dev, struct device_attribute *attr, char *buf) | 276 | static ssize_t show_idle_timeout(struct device *dev, struct device_attribute *attr, char *buf) |
281 | { | 277 | { |
282 | struct hci_dev *hdev = dev_get_drvdata(dev); | 278 | struct hci_dev *hdev = dev_get_drvdata(dev); |
@@ -355,6 +351,7 @@ static ssize_t store_sniff_min_interval(struct device *dev, struct device_attrib | |||
355 | return count; | 351 | return count; |
356 | } | 352 | } |
357 | 353 | ||
354 | static DEVICE_ATTR(bus, S_IRUGO, show_bus, NULL); | ||
358 | static DEVICE_ATTR(type, S_IRUGO, show_type, NULL); | 355 | static DEVICE_ATTR(type, S_IRUGO, show_type, NULL); |
359 | static DEVICE_ATTR(name, S_IRUGO, show_name, NULL); | 356 | static DEVICE_ATTR(name, S_IRUGO, show_name, NULL); |
360 | static DEVICE_ATTR(class, S_IRUGO, show_class, NULL); | 357 | static DEVICE_ATTR(class, S_IRUGO, show_class, NULL); |
@@ -363,7 +360,6 @@ static DEVICE_ATTR(features, S_IRUGO, show_features, NULL); | |||
363 | static DEVICE_ATTR(manufacturer, S_IRUGO, show_manufacturer, NULL); | 360 | static DEVICE_ATTR(manufacturer, S_IRUGO, show_manufacturer, NULL); |
364 | static DEVICE_ATTR(hci_version, S_IRUGO, show_hci_version, NULL); | 361 | static DEVICE_ATTR(hci_version, S_IRUGO, show_hci_version, NULL); |
365 | static DEVICE_ATTR(hci_revision, S_IRUGO, show_hci_revision, NULL); | 362 | static DEVICE_ATTR(hci_revision, S_IRUGO, show_hci_revision, NULL); |
366 | static DEVICE_ATTR(inquiry_cache, S_IRUGO, show_inquiry_cache, NULL); | ||
367 | 363 | ||
368 | static DEVICE_ATTR(idle_timeout, S_IRUGO | S_IWUSR, | 364 | static DEVICE_ATTR(idle_timeout, S_IRUGO | S_IWUSR, |
369 | show_idle_timeout, store_idle_timeout); | 365 | show_idle_timeout, store_idle_timeout); |
@@ -373,6 +369,7 @@ static DEVICE_ATTR(sniff_min_interval, S_IRUGO | S_IWUSR, | |||
373 | show_sniff_min_interval, store_sniff_min_interval); | 369 | show_sniff_min_interval, store_sniff_min_interval); |
374 | 370 | ||
375 | static struct attribute *bt_host_attrs[] = { | 371 | static struct attribute *bt_host_attrs[] = { |
372 | &dev_attr_bus.attr, | ||
376 | &dev_attr_type.attr, | 373 | &dev_attr_type.attr, |
377 | &dev_attr_name.attr, | 374 | &dev_attr_name.attr, |
378 | &dev_attr_class.attr, | 375 | &dev_attr_class.attr, |
@@ -381,7 +378,6 @@ static struct attribute *bt_host_attrs[] = { | |||
381 | &dev_attr_manufacturer.attr, | 378 | &dev_attr_manufacturer.attr, |
382 | &dev_attr_hci_version.attr, | 379 | &dev_attr_hci_version.attr, |
383 | &dev_attr_hci_revision.attr, | 380 | &dev_attr_hci_revision.attr, |
384 | &dev_attr_inquiry_cache.attr, | ||
385 | &dev_attr_idle_timeout.attr, | 381 | &dev_attr_idle_timeout.attr, |
386 | &dev_attr_sniff_max_interval.attr, | 382 | &dev_attr_sniff_max_interval.attr, |
387 | &dev_attr_sniff_min_interval.attr, | 383 | &dev_attr_sniff_min_interval.attr, |
@@ -409,12 +405,52 @@ static struct device_type bt_host = { | |||
409 | .release = bt_host_release, | 405 | .release = bt_host_release, |
410 | }; | 406 | }; |
411 | 407 | ||
408 | static int inquiry_cache_open(struct inode *inode, struct file *file) | ||
409 | { | ||
410 | file->private_data = inode->i_private; | ||
411 | return 0; | ||
412 | } | ||
413 | |||
414 | static ssize_t inquiry_cache_read(struct file *file, char __user *userbuf, | ||
415 | size_t count, loff_t *ppos) | ||
416 | { | ||
417 | struct hci_dev *hdev = file->private_data; | ||
418 | struct inquiry_cache *cache = &hdev->inq_cache; | ||
419 | struct inquiry_entry *e; | ||
420 | char buf[4096]; | ||
421 | int n = 0; | ||
422 | |||
423 | hci_dev_lock_bh(hdev); | ||
424 | |||
425 | for (e = cache->list; e; e = e->next) { | ||
426 | struct inquiry_data *data = &e->data; | ||
427 | bdaddr_t bdaddr; | ||
428 | baswap(&bdaddr, &data->bdaddr); | ||
429 | n += sprintf(buf + n, "%s %d %d %d 0x%.2x%.2x%.2x 0x%.4x %d %d %u\n", | ||
430 | batostr(&bdaddr), | ||
431 | data->pscan_rep_mode, data->pscan_period_mode, | ||
432 | data->pscan_mode, data->dev_class[2], | ||
433 | data->dev_class[1], data->dev_class[0], | ||
434 | __le16_to_cpu(data->clock_offset), | ||
435 | data->rssi, data->ssp_mode, e->timestamp); | ||
436 | } | ||
437 | |||
438 | hci_dev_unlock_bh(hdev); | ||
439 | |||
440 | return simple_read_from_buffer(userbuf, count, ppos, buf, n); | ||
441 | } | ||
442 | |||
443 | static const struct file_operations inquiry_cache_fops = { | ||
444 | .open = inquiry_cache_open, | ||
445 | .read = inquiry_cache_read, | ||
446 | }; | ||
447 | |||
412 | int hci_register_sysfs(struct hci_dev *hdev) | 448 | int hci_register_sysfs(struct hci_dev *hdev) |
413 | { | 449 | { |
414 | struct device *dev = &hdev->dev; | 450 | struct device *dev = &hdev->dev; |
415 | int err; | 451 | int err; |
416 | 452 | ||
417 | BT_DBG("%p name %s type %d", hdev, hdev->name, hdev->type); | 453 | BT_DBG("%p name %s bus %d", hdev, hdev->name, hdev->bus); |
418 | 454 | ||
419 | dev->type = &bt_host; | 455 | dev->type = &bt_host; |
420 | dev->class = bt_class; | 456 | dev->class = bt_class; |
@@ -428,12 +464,24 @@ int hci_register_sysfs(struct hci_dev *hdev) | |||
428 | if (err < 0) | 464 | if (err < 0) |
429 | return err; | 465 | return err; |
430 | 466 | ||
467 | if (!bt_debugfs) | ||
468 | return 0; | ||
469 | |||
470 | hdev->debugfs = debugfs_create_dir(hdev->name, bt_debugfs); | ||
471 | if (!hdev->debugfs) | ||
472 | return 0; | ||
473 | |||
474 | debugfs_create_file("inquiry_cache", 0444, hdev->debugfs, | ||
475 | hdev, &inquiry_cache_fops); | ||
476 | |||
431 | return 0; | 477 | return 0; |
432 | } | 478 | } |
433 | 479 | ||
434 | void hci_unregister_sysfs(struct hci_dev *hdev) | 480 | void hci_unregister_sysfs(struct hci_dev *hdev) |
435 | { | 481 | { |
436 | BT_DBG("%p name %s type %d", hdev, hdev->name, hdev->type); | 482 | BT_DBG("%p name %s bus %d", hdev, hdev->name, hdev->bus); |
483 | |||
484 | debugfs_remove_recursive(hdev->debugfs); | ||
437 | 485 | ||
438 | device_del(&hdev->dev); | 486 | device_del(&hdev->dev); |
439 | } | 487 | } |
@@ -444,6 +492,8 @@ int __init bt_sysfs_init(void) | |||
444 | if (!bt_workq) | 492 | if (!bt_workq) |
445 | return -ENOMEM; | 493 | return -ENOMEM; |
446 | 494 | ||
495 | bt_debugfs = debugfs_create_dir("bluetooth", NULL); | ||
496 | |||
447 | bt_class = class_create(THIS_MODULE, "bluetooth"); | 497 | bt_class = class_create(THIS_MODULE, "bluetooth"); |
448 | if (IS_ERR(bt_class)) { | 498 | if (IS_ERR(bt_class)) { |
449 | destroy_workqueue(bt_workq); | 499 | destroy_workqueue(bt_workq); |
@@ -455,7 +505,9 @@ int __init bt_sysfs_init(void) | |||
455 | 505 | ||
456 | void bt_sysfs_cleanup(void) | 506 | void bt_sysfs_cleanup(void) |
457 | { | 507 | { |
458 | destroy_workqueue(bt_workq); | ||
459 | |||
460 | class_destroy(bt_class); | 508 | class_destroy(bt_class); |
509 | |||
510 | debugfs_remove_recursive(bt_debugfs); | ||
511 | |||
512 | destroy_workqueue(bt_workq); | ||
461 | } | 513 | } |