diff options
Diffstat (limited to 'net/bluetooth/sco.c')
-rw-r--r-- | net/bluetooth/sco.c | 44 |
1 files changed, 31 insertions, 13 deletions
diff --git a/net/bluetooth/sco.c b/net/bluetooth/sco.c index 77f4153bdb5e..ca6b2ad1c3fc 100644 --- a/net/bluetooth/sco.c +++ b/net/bluetooth/sco.c | |||
@@ -38,6 +38,8 @@ | |||
38 | #include <linux/socket.h> | 38 | #include <linux/socket.h> |
39 | #include <linux/skbuff.h> | 39 | #include <linux/skbuff.h> |
40 | #include <linux/device.h> | 40 | #include <linux/device.h> |
41 | #include <linux/debugfs.h> | ||
42 | #include <linux/seq_file.h> | ||
41 | #include <linux/list.h> | 43 | #include <linux/list.h> |
42 | #include <net/sock.h> | 44 | #include <net/sock.h> |
43 | 45 | ||
@@ -430,7 +432,8 @@ static struct sock *sco_sock_alloc(struct net *net, struct socket *sock, int pro | |||
430 | return sk; | 432 | return sk; |
431 | } | 433 | } |
432 | 434 | ||
433 | static int sco_sock_create(struct net *net, struct socket *sock, int protocol) | 435 | static int sco_sock_create(struct net *net, struct socket *sock, int protocol, |
436 | int kern) | ||
434 | { | 437 | { |
435 | struct sock *sk; | 438 | struct sock *sk; |
436 | 439 | ||
@@ -496,7 +499,8 @@ static int sco_sock_connect(struct socket *sock, struct sockaddr *addr, int alen | |||
496 | 499 | ||
497 | BT_DBG("sk %p", sk); | 500 | BT_DBG("sk %p", sk); |
498 | 501 | ||
499 | if (addr->sa_family != AF_BLUETOOTH || alen < sizeof(struct sockaddr_sco)) | 502 | if (alen < sizeof(struct sockaddr_sco) || |
503 | addr->sa_family != AF_BLUETOOTH) | ||
500 | return -EINVAL; | 504 | return -EINVAL; |
501 | 505 | ||
502 | if (sk->sk_state != BT_OPEN && sk->sk_state != BT_BOUND) | 506 | if (sk->sk_state != BT_OPEN && sk->sk_state != BT_BOUND) |
@@ -952,26 +956,36 @@ drop: | |||
952 | return 0; | 956 | return 0; |
953 | } | 957 | } |
954 | 958 | ||
955 | static ssize_t sco_sysfs_show(struct class *dev, char *buf) | 959 | static int sco_debugfs_show(struct seq_file *f, void *p) |
956 | { | 960 | { |
957 | struct sock *sk; | 961 | struct sock *sk; |
958 | struct hlist_node *node; | 962 | struct hlist_node *node; |
959 | char *str = buf; | ||
960 | 963 | ||
961 | read_lock_bh(&sco_sk_list.lock); | 964 | read_lock_bh(&sco_sk_list.lock); |
962 | 965 | ||
963 | sk_for_each(sk, node, &sco_sk_list.head) { | 966 | sk_for_each(sk, node, &sco_sk_list.head) { |
964 | str += sprintf(str, "%s %s %d\n", | 967 | seq_printf(f, "%s %s %d\n", batostr(&bt_sk(sk)->src), |
965 | batostr(&bt_sk(sk)->src), batostr(&bt_sk(sk)->dst), | 968 | batostr(&bt_sk(sk)->dst), sk->sk_state); |
966 | sk->sk_state); | ||
967 | } | 969 | } |
968 | 970 | ||
969 | read_unlock_bh(&sco_sk_list.lock); | 971 | read_unlock_bh(&sco_sk_list.lock); |
970 | 972 | ||
971 | return (str - buf); | 973 | return 0; |
972 | } | 974 | } |
973 | 975 | ||
974 | static CLASS_ATTR(sco, S_IRUGO, sco_sysfs_show, NULL); | 976 | static int sco_debugfs_open(struct inode *inode, struct file *file) |
977 | { | ||
978 | return single_open(file, sco_debugfs_show, inode->i_private); | ||
979 | } | ||
980 | |||
981 | static const struct file_operations sco_debugfs_fops = { | ||
982 | .open = sco_debugfs_open, | ||
983 | .read = seq_read, | ||
984 | .llseek = seq_lseek, | ||
985 | .release = single_release, | ||
986 | }; | ||
987 | |||
988 | static struct dentry *sco_debugfs; | ||
975 | 989 | ||
976 | static const struct proto_ops sco_sock_ops = { | 990 | static const struct proto_ops sco_sock_ops = { |
977 | .family = PF_BLUETOOTH, | 991 | .family = PF_BLUETOOTH, |
@@ -993,7 +1007,7 @@ static const struct proto_ops sco_sock_ops = { | |||
993 | .getsockopt = sco_sock_getsockopt | 1007 | .getsockopt = sco_sock_getsockopt |
994 | }; | 1008 | }; |
995 | 1009 | ||
996 | static struct net_proto_family sco_sock_family_ops = { | 1010 | static const struct net_proto_family sco_sock_family_ops = { |
997 | .family = PF_BLUETOOTH, | 1011 | .family = PF_BLUETOOTH, |
998 | .owner = THIS_MODULE, | 1012 | .owner = THIS_MODULE, |
999 | .create = sco_sock_create, | 1013 | .create = sco_sock_create, |
@@ -1029,8 +1043,12 @@ static int __init sco_init(void) | |||
1029 | goto error; | 1043 | goto error; |
1030 | } | 1044 | } |
1031 | 1045 | ||
1032 | if (class_create_file(bt_class, &class_attr_sco) < 0) | 1046 | if (bt_debugfs) { |
1033 | BT_ERR("Failed to create SCO info file"); | 1047 | sco_debugfs = debugfs_create_file("sco", 0444, |
1048 | bt_debugfs, NULL, &sco_debugfs_fops); | ||
1049 | if (!sco_debugfs) | ||
1050 | BT_ERR("Failed to create SCO debug file"); | ||
1051 | } | ||
1034 | 1052 | ||
1035 | BT_INFO("SCO (Voice Link) ver %s", VERSION); | 1053 | BT_INFO("SCO (Voice Link) ver %s", VERSION); |
1036 | BT_INFO("SCO socket layer initialized"); | 1054 | BT_INFO("SCO socket layer initialized"); |
@@ -1044,7 +1062,7 @@ error: | |||
1044 | 1062 | ||
1045 | static void __exit sco_exit(void) | 1063 | static void __exit sco_exit(void) |
1046 | { | 1064 | { |
1047 | class_remove_file(bt_class, &class_attr_sco); | 1065 | debugfs_remove(sco_debugfs); |
1048 | 1066 | ||
1049 | if (bt_sock_unregister(BTPROTO_SCO) < 0) | 1067 | if (bt_sock_unregister(BTPROTO_SCO) < 0) |
1050 | BT_ERR("SCO socket unregistration failed"); | 1068 | BT_ERR("SCO socket unregistration failed"); |