Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/holtmann/bluetooth-2.6
This commit is contained in:
Коммит
e3a61d47cc
|
@ -176,6 +176,6 @@ extern void hci_sock_cleanup(void);
|
||||||
extern int bt_sysfs_init(void);
|
extern int bt_sysfs_init(void);
|
||||||
extern void bt_sysfs_cleanup(void);
|
extern void bt_sysfs_cleanup(void);
|
||||||
|
|
||||||
extern struct class *bt_class;
|
extern struct dentry *bt_debugfs;
|
||||||
|
|
||||||
#endif /* __BLUETOOTH_H */
|
#endif /* __BLUETOOTH_H */
|
||||||
|
|
|
@ -8,8 +8,7 @@
|
||||||
#include <net/bluetooth/bluetooth.h>
|
#include <net/bluetooth/bluetooth.h>
|
||||||
#include <net/bluetooth/hci_core.h>
|
#include <net/bluetooth/hci_core.h>
|
||||||
|
|
||||||
struct class *bt_class = NULL;
|
static struct class *bt_class;
|
||||||
EXPORT_SYMBOL_GPL(bt_class);
|
|
||||||
|
|
||||||
struct dentry *bt_debugfs = NULL;
|
struct dentry *bt_debugfs = NULL;
|
||||||
EXPORT_SYMBOL_GPL(bt_debugfs);
|
EXPORT_SYMBOL_GPL(bt_debugfs);
|
||||||
|
|
|
@ -40,6 +40,8 @@
|
||||||
#include <linux/skbuff.h>
|
#include <linux/skbuff.h>
|
||||||
#include <linux/list.h>
|
#include <linux/list.h>
|
||||||
#include <linux/device.h>
|
#include <linux/device.h>
|
||||||
|
#include <linux/debugfs.h>
|
||||||
|
#include <linux/seq_file.h>
|
||||||
#include <linux/uaccess.h>
|
#include <linux/uaccess.h>
|
||||||
#include <linux/crc16.h>
|
#include <linux/crc16.h>
|
||||||
#include <net/sock.h>
|
#include <net/sock.h>
|
||||||
|
@ -2830,6 +2832,11 @@ static inline int l2cap_config_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr
|
||||||
int len = cmd->len - sizeof(*rsp);
|
int len = cmd->len - sizeof(*rsp);
|
||||||
char req[64];
|
char req[64];
|
||||||
|
|
||||||
|
if (len > sizeof(req) - sizeof(struct l2cap_conf_req)) {
|
||||||
|
l2cap_send_disconn_req(conn, sk);
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
/* throw out any old stored conf requests */
|
/* throw out any old stored conf requests */
|
||||||
result = L2CAP_CONF_SUCCESS;
|
result = L2CAP_CONF_SUCCESS;
|
||||||
len = l2cap_parse_conf_rsp(sk, rsp->data,
|
len = l2cap_parse_conf_rsp(sk, rsp->data,
|
||||||
|
@ -3937,31 +3944,42 @@ drop:
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static ssize_t l2cap_sysfs_show(struct class *dev,
|
static int l2cap_debugfs_show(struct seq_file *f, void *p)
|
||||||
struct class_attribute *attr,
|
|
||||||
char *buf)
|
|
||||||
{
|
{
|
||||||
struct sock *sk;
|
struct sock *sk;
|
||||||
struct hlist_node *node;
|
struct hlist_node *node;
|
||||||
char *str = buf;
|
|
||||||
|
|
||||||
read_lock_bh(&l2cap_sk_list.lock);
|
read_lock_bh(&l2cap_sk_list.lock);
|
||||||
|
|
||||||
sk_for_each(sk, node, &l2cap_sk_list.head) {
|
sk_for_each(sk, node, &l2cap_sk_list.head) {
|
||||||
struct l2cap_pinfo *pi = l2cap_pi(sk);
|
struct l2cap_pinfo *pi = l2cap_pi(sk);
|
||||||
|
|
||||||
str += sprintf(str, "%s %s %d %d 0x%4.4x 0x%4.4x %d %d %d\n",
|
seq_printf(f, "%s %s %d %d 0x%4.4x 0x%4.4x %d %d %d\n",
|
||||||
batostr(&bt_sk(sk)->src), batostr(&bt_sk(sk)->dst),
|
batostr(&bt_sk(sk)->src),
|
||||||
sk->sk_state, __le16_to_cpu(pi->psm), pi->scid,
|
batostr(&bt_sk(sk)->dst),
|
||||||
pi->dcid, pi->imtu, pi->omtu, pi->sec_level);
|
sk->sk_state, __le16_to_cpu(pi->psm),
|
||||||
|
pi->scid, pi->dcid,
|
||||||
|
pi->imtu, pi->omtu, pi->sec_level);
|
||||||
}
|
}
|
||||||
|
|
||||||
read_unlock_bh(&l2cap_sk_list.lock);
|
read_unlock_bh(&l2cap_sk_list.lock);
|
||||||
|
|
||||||
return str - buf;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static CLASS_ATTR(l2cap, S_IRUGO, l2cap_sysfs_show, NULL);
|
static int l2cap_debugfs_open(struct inode *inode, struct file *file)
|
||||||
|
{
|
||||||
|
return single_open(file, l2cap_debugfs_show, inode->i_private);
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct file_operations l2cap_debugfs_fops = {
|
||||||
|
.open = l2cap_debugfs_open,
|
||||||
|
.read = seq_read,
|
||||||
|
.llseek = seq_lseek,
|
||||||
|
.release = single_release,
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct dentry *l2cap_debugfs;
|
||||||
|
|
||||||
static const struct proto_ops l2cap_sock_ops = {
|
static const struct proto_ops l2cap_sock_ops = {
|
||||||
.family = PF_BLUETOOTH,
|
.family = PF_BLUETOOTH,
|
||||||
|
@ -4021,8 +4039,12 @@ static int __init l2cap_init(void)
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (class_create_file(bt_class, &class_attr_l2cap) < 0)
|
if (bt_debugfs) {
|
||||||
BT_ERR("Failed to create L2CAP info file");
|
l2cap_debugfs = debugfs_create_file("l2cap", 0444,
|
||||||
|
bt_debugfs, NULL, &l2cap_debugfs_fops);
|
||||||
|
if (!l2cap_debugfs)
|
||||||
|
BT_ERR("Failed to create L2CAP debug file");
|
||||||
|
}
|
||||||
|
|
||||||
BT_INFO("L2CAP ver %s", VERSION);
|
BT_INFO("L2CAP ver %s", VERSION);
|
||||||
BT_INFO("L2CAP socket layer initialized");
|
BT_INFO("L2CAP socket layer initialized");
|
||||||
|
@ -4036,7 +4058,7 @@ error:
|
||||||
|
|
||||||
static void __exit l2cap_exit(void)
|
static void __exit l2cap_exit(void)
|
||||||
{
|
{
|
||||||
class_remove_file(bt_class, &class_attr_l2cap);
|
debugfs_remove(l2cap_debugfs);
|
||||||
|
|
||||||
if (bt_sock_unregister(BTPROTO_L2CAP) < 0)
|
if (bt_sock_unregister(BTPROTO_L2CAP) < 0)
|
||||||
BT_ERR("L2CAP socket unregistration failed");
|
BT_ERR("L2CAP socket unregistration failed");
|
||||||
|
|
|
@ -33,6 +33,8 @@
|
||||||
#include <linux/init.h>
|
#include <linux/init.h>
|
||||||
#include <linux/wait.h>
|
#include <linux/wait.h>
|
||||||
#include <linux/device.h>
|
#include <linux/device.h>
|
||||||
|
#include <linux/debugfs.h>
|
||||||
|
#include <linux/seq_file.h>
|
||||||
#include <linux/net.h>
|
#include <linux/net.h>
|
||||||
#include <linux/mutex.h>
|
#include <linux/mutex.h>
|
||||||
#include <linux/kthread.h>
|
#include <linux/kthread.h>
|
||||||
|
@ -2098,13 +2100,10 @@ static struct hci_cb rfcomm_cb = {
|
||||||
.security_cfm = rfcomm_security_cfm
|
.security_cfm = rfcomm_security_cfm
|
||||||
};
|
};
|
||||||
|
|
||||||
static ssize_t rfcomm_dlc_sysfs_show(struct class *dev,
|
static int rfcomm_dlc_debugfs_show(struct seq_file *f, void *x)
|
||||||
struct class_attribute *attr,
|
|
||||||
char *buf)
|
|
||||||
{
|
{
|
||||||
struct rfcomm_session *s;
|
struct rfcomm_session *s;
|
||||||
struct list_head *pp, *p;
|
struct list_head *pp, *p;
|
||||||
char *str = buf;
|
|
||||||
|
|
||||||
rfcomm_lock();
|
rfcomm_lock();
|
||||||
|
|
||||||
|
@ -2114,18 +2113,32 @@ static ssize_t rfcomm_dlc_sysfs_show(struct class *dev,
|
||||||
struct sock *sk = s->sock->sk;
|
struct sock *sk = s->sock->sk;
|
||||||
struct rfcomm_dlc *d = list_entry(pp, struct rfcomm_dlc, list);
|
struct rfcomm_dlc *d = list_entry(pp, struct rfcomm_dlc, list);
|
||||||
|
|
||||||
str += sprintf(str, "%s %s %ld %d %d %d %d\n",
|
seq_printf(f, "%s %s %ld %d %d %d %d\n",
|
||||||
batostr(&bt_sk(sk)->src), batostr(&bt_sk(sk)->dst),
|
batostr(&bt_sk(sk)->src),
|
||||||
d->state, d->dlci, d->mtu, d->rx_credits, d->tx_credits);
|
batostr(&bt_sk(sk)->dst),
|
||||||
|
d->state, d->dlci, d->mtu,
|
||||||
|
d->rx_credits, d->tx_credits);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
rfcomm_unlock();
|
rfcomm_unlock();
|
||||||
|
|
||||||
return (str - buf);
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static CLASS_ATTR(rfcomm_dlc, S_IRUGO, rfcomm_dlc_sysfs_show, NULL);
|
static int rfcomm_dlc_debugfs_open(struct inode *inode, struct file *file)
|
||||||
|
{
|
||||||
|
return single_open(file, rfcomm_dlc_debugfs_show, inode->i_private);
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct file_operations rfcomm_dlc_debugfs_fops = {
|
||||||
|
.open = rfcomm_dlc_debugfs_open,
|
||||||
|
.read = seq_read,
|
||||||
|
.llseek = seq_lseek,
|
||||||
|
.release = single_release,
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct dentry *rfcomm_dlc_debugfs;
|
||||||
|
|
||||||
/* ---- Initialization ---- */
|
/* ---- Initialization ---- */
|
||||||
static int __init rfcomm_init(void)
|
static int __init rfcomm_init(void)
|
||||||
|
@ -2142,8 +2155,12 @@ static int __init rfcomm_init(void)
|
||||||
goto unregister;
|
goto unregister;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (class_create_file(bt_class, &class_attr_rfcomm_dlc) < 0)
|
if (bt_debugfs) {
|
||||||
BT_ERR("Failed to create RFCOMM info file");
|
rfcomm_dlc_debugfs = debugfs_create_file("rfcomm_dlc", 0444,
|
||||||
|
bt_debugfs, NULL, &rfcomm_dlc_debugfs_fops);
|
||||||
|
if (!rfcomm_dlc_debugfs)
|
||||||
|
BT_ERR("Failed to create RFCOMM debug file");
|
||||||
|
}
|
||||||
|
|
||||||
err = rfcomm_init_ttys();
|
err = rfcomm_init_ttys();
|
||||||
if (err < 0)
|
if (err < 0)
|
||||||
|
@ -2171,7 +2188,7 @@ unregister:
|
||||||
|
|
||||||
static void __exit rfcomm_exit(void)
|
static void __exit rfcomm_exit(void)
|
||||||
{
|
{
|
||||||
class_remove_file(bt_class, &class_attr_rfcomm_dlc);
|
debugfs_remove(rfcomm_dlc_debugfs);
|
||||||
|
|
||||||
hci_unregister_cb(&rfcomm_cb);
|
hci_unregister_cb(&rfcomm_cb);
|
||||||
|
|
||||||
|
|
|
@ -40,6 +40,8 @@
|
||||||
#include <linux/skbuff.h>
|
#include <linux/skbuff.h>
|
||||||
#include <linux/list.h>
|
#include <linux/list.h>
|
||||||
#include <linux/device.h>
|
#include <linux/device.h>
|
||||||
|
#include <linux/debugfs.h>
|
||||||
|
#include <linux/seq_file.h>
|
||||||
#include <net/sock.h>
|
#include <net/sock.h>
|
||||||
|
|
||||||
#include <asm/system.h>
|
#include <asm/system.h>
|
||||||
|
@ -1061,28 +1063,38 @@ done:
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
static ssize_t rfcomm_sock_sysfs_show(struct class *dev,
|
static int rfcomm_sock_debugfs_show(struct seq_file *f, void *p)
|
||||||
struct class_attribute *attr,
|
|
||||||
char *buf)
|
|
||||||
{
|
{
|
||||||
struct sock *sk;
|
struct sock *sk;
|
||||||
struct hlist_node *node;
|
struct hlist_node *node;
|
||||||
char *str = buf;
|
|
||||||
|
|
||||||
read_lock_bh(&rfcomm_sk_list.lock);
|
read_lock_bh(&rfcomm_sk_list.lock);
|
||||||
|
|
||||||
sk_for_each(sk, node, &rfcomm_sk_list.head) {
|
sk_for_each(sk, node, &rfcomm_sk_list.head) {
|
||||||
str += sprintf(str, "%s %s %d %d\n",
|
seq_printf(f, "%s %s %d %d\n",
|
||||||
batostr(&bt_sk(sk)->src), batostr(&bt_sk(sk)->dst),
|
batostr(&bt_sk(sk)->src),
|
||||||
|
batostr(&bt_sk(sk)->dst),
|
||||||
sk->sk_state, rfcomm_pi(sk)->channel);
|
sk->sk_state, rfcomm_pi(sk)->channel);
|
||||||
}
|
}
|
||||||
|
|
||||||
read_unlock_bh(&rfcomm_sk_list.lock);
|
read_unlock_bh(&rfcomm_sk_list.lock);
|
||||||
|
|
||||||
return (str - buf);
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static CLASS_ATTR(rfcomm, S_IRUGO, rfcomm_sock_sysfs_show, NULL);
|
static int rfcomm_sock_debugfs_open(struct inode *inode, struct file *file)
|
||||||
|
{
|
||||||
|
return single_open(file, rfcomm_sock_debugfs_show, inode->i_private);
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct file_operations rfcomm_sock_debugfs_fops = {
|
||||||
|
.open = rfcomm_sock_debugfs_open,
|
||||||
|
.read = seq_read,
|
||||||
|
.llseek = seq_lseek,
|
||||||
|
.release = single_release,
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct dentry *rfcomm_sock_debugfs;
|
||||||
|
|
||||||
static const struct proto_ops rfcomm_sock_ops = {
|
static const struct proto_ops rfcomm_sock_ops = {
|
||||||
.family = PF_BLUETOOTH,
|
.family = PF_BLUETOOTH,
|
||||||
|
@ -1122,8 +1134,12 @@ int __init rfcomm_init_sockets(void)
|
||||||
if (err < 0)
|
if (err < 0)
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
if (class_create_file(bt_class, &class_attr_rfcomm) < 0)
|
if (bt_debugfs) {
|
||||||
BT_ERR("Failed to create RFCOMM info file");
|
rfcomm_sock_debugfs = debugfs_create_file("rfcomm", 0444,
|
||||||
|
bt_debugfs, NULL, &rfcomm_sock_debugfs_fops);
|
||||||
|
if (!rfcomm_sock_debugfs)
|
||||||
|
BT_ERR("Failed to create RFCOMM debug file");
|
||||||
|
}
|
||||||
|
|
||||||
BT_INFO("RFCOMM socket layer initialized");
|
BT_INFO("RFCOMM socket layer initialized");
|
||||||
|
|
||||||
|
@ -1137,7 +1153,7 @@ error:
|
||||||
|
|
||||||
void rfcomm_cleanup_sockets(void)
|
void rfcomm_cleanup_sockets(void)
|
||||||
{
|
{
|
||||||
class_remove_file(bt_class, &class_attr_rfcomm);
|
debugfs_remove(rfcomm_sock_debugfs);
|
||||||
|
|
||||||
if (bt_sock_unregister(BTPROTO_RFCOMM) < 0)
|
if (bt_sock_unregister(BTPROTO_RFCOMM) < 0)
|
||||||
BT_ERR("RFCOMM socket layer unregistration failed");
|
BT_ERR("RFCOMM socket layer unregistration failed");
|
||||||
|
|
|
@ -38,6 +38,8 @@
|
||||||
#include <linux/socket.h>
|
#include <linux/socket.h>
|
||||||
#include <linux/skbuff.h>
|
#include <linux/skbuff.h>
|
||||||
#include <linux/device.h>
|
#include <linux/device.h>
|
||||||
|
#include <linux/debugfs.h>
|
||||||
|
#include <linux/seq_file.h>
|
||||||
#include <linux/list.h>
|
#include <linux/list.h>
|
||||||
#include <net/sock.h>
|
#include <net/sock.h>
|
||||||
|
|
||||||
|
@ -953,28 +955,36 @@ drop:
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static ssize_t sco_sysfs_show(struct class *dev,
|
static int sco_debugfs_show(struct seq_file *f, void *p)
|
||||||
struct class_attribute *attr,
|
|
||||||
char *buf)
|
|
||||||
{
|
{
|
||||||
struct sock *sk;
|
struct sock *sk;
|
||||||
struct hlist_node *node;
|
struct hlist_node *node;
|
||||||
char *str = buf;
|
|
||||||
|
|
||||||
read_lock_bh(&sco_sk_list.lock);
|
read_lock_bh(&sco_sk_list.lock);
|
||||||
|
|
||||||
sk_for_each(sk, node, &sco_sk_list.head) {
|
sk_for_each(sk, node, &sco_sk_list.head) {
|
||||||
str += sprintf(str, "%s %s %d\n",
|
seq_printf(f, "%s %s %d\n", batostr(&bt_sk(sk)->src),
|
||||||
batostr(&bt_sk(sk)->src), batostr(&bt_sk(sk)->dst),
|
batostr(&bt_sk(sk)->dst), sk->sk_state);
|
||||||
sk->sk_state);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
read_unlock_bh(&sco_sk_list.lock);
|
read_unlock_bh(&sco_sk_list.lock);
|
||||||
|
|
||||||
return (str - buf);
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static CLASS_ATTR(sco, S_IRUGO, sco_sysfs_show, NULL);
|
static int sco_debugfs_open(struct inode *inode, struct file *file)
|
||||||
|
{
|
||||||
|
return single_open(file, sco_debugfs_show, inode->i_private);
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct file_operations sco_debugfs_fops = {
|
||||||
|
.open = sco_debugfs_open,
|
||||||
|
.read = seq_read,
|
||||||
|
.llseek = seq_lseek,
|
||||||
|
.release = single_release,
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct dentry *sco_debugfs;
|
||||||
|
|
||||||
static const struct proto_ops sco_sock_ops = {
|
static const struct proto_ops sco_sock_ops = {
|
||||||
.family = PF_BLUETOOTH,
|
.family = PF_BLUETOOTH,
|
||||||
|
@ -1032,8 +1042,12 @@ static int __init sco_init(void)
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (class_create_file(bt_class, &class_attr_sco) < 0)
|
if (bt_debugfs) {
|
||||||
BT_ERR("Failed to create SCO info file");
|
sco_debugfs = debugfs_create_file("sco", 0444,
|
||||||
|
bt_debugfs, NULL, &sco_debugfs_fops);
|
||||||
|
if (!sco_debugfs)
|
||||||
|
BT_ERR("Failed to create SCO debug file");
|
||||||
|
}
|
||||||
|
|
||||||
BT_INFO("SCO (Voice Link) ver %s", VERSION);
|
BT_INFO("SCO (Voice Link) ver %s", VERSION);
|
||||||
BT_INFO("SCO socket layer initialized");
|
BT_INFO("SCO socket layer initialized");
|
||||||
|
@ -1047,7 +1061,7 @@ error:
|
||||||
|
|
||||||
static void __exit sco_exit(void)
|
static void __exit sco_exit(void)
|
||||||
{
|
{
|
||||||
class_remove_file(bt_class, &class_attr_sco);
|
debugfs_remove(sco_debugfs);
|
||||||
|
|
||||||
if (bt_sock_unregister(BTPROTO_SCO) < 0)
|
if (bt_sock_unregister(BTPROTO_SCO) < 0)
|
||||||
BT_ERR("SCO socket unregistration failed");
|
BT_ERR("SCO socket unregistration failed");
|
||||||
|
|
Загрузка…
Ссылка в новой задаче