[Bluetooth]: Remove the usage of /proc completely
This patch removes all relics of the /proc usage from the Bluetooth subsystem core and its upper layers. All the previous information are now available via /sys/class/bluetooth through appropriate functions. Signed-off-by: Marcel Holtmann <marcel@holtmann.org> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
1ebb92521d
commit
be9d122730
9 changed files with 69 additions and 372 deletions
|
@ -57,8 +57,6 @@
|
|||
#define BT_DBG(fmt, arg...) printk(KERN_INFO "%s: " fmt "\n" , __FUNCTION__ , ## arg)
|
||||
#define BT_ERR(fmt, arg...) printk(KERN_ERR "%s: " fmt "\n" , __FUNCTION__ , ## arg)
|
||||
|
||||
extern struct proc_dir_entry *proc_bt;
|
||||
|
||||
/* Connection and socket states */
|
||||
enum {
|
||||
BT_CONNECTED = 1, /* Equal to TCP_ESTABLISHED to make net code happy */
|
||||
|
@ -177,4 +175,6 @@ extern int hci_sock_cleanup(void);
|
|||
extern int bt_sysfs_init(void);
|
||||
extern void bt_sysfs_cleanup(void);
|
||||
|
||||
extern struct class bt_class;
|
||||
|
||||
#endif /* __BLUETOOTH_H */
|
||||
|
|
|
@ -25,7 +25,6 @@
|
|||
#ifndef __HCI_CORE_H
|
||||
#define __HCI_CORE_H
|
||||
|
||||
#include <linux/proc_fs.h>
|
||||
#include <net/bluetooth/hci.h>
|
||||
|
||||
/* HCI upper protocols */
|
||||
|
@ -34,8 +33,6 @@
|
|||
|
||||
#define HCI_INIT_TIMEOUT (HZ * 10)
|
||||
|
||||
extern struct proc_dir_entry *proc_bt_hci;
|
||||
|
||||
/* HCI Core structures */
|
||||
|
||||
struct inquiry_data {
|
||||
|
@ -126,10 +123,6 @@ struct hci_dev {
|
|||
|
||||
atomic_t promisc;
|
||||
|
||||
#ifdef CONFIG_PROC_FS
|
||||
struct proc_dir_entry *proc;
|
||||
#endif
|
||||
|
||||
struct class_device class_dev;
|
||||
|
||||
struct module *owner;
|
||||
|
|
|
@ -351,6 +351,4 @@ int rfcomm_dev_ioctl(struct sock *sk, unsigned int cmd, void __user *arg);
|
|||
int rfcomm_init_ttys(void);
|
||||
void rfcomm_cleanup_ttys(void);
|
||||
|
||||
extern struct proc_dir_entry *proc_bt_rfcomm;
|
||||
|
||||
#endif /* __RFCOMM_H */
|
||||
|
|
|
@ -36,7 +36,6 @@
|
|||
#include <linux/skbuff.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/poll.h>
|
||||
#include <linux/proc_fs.h>
|
||||
#include <net/sock.h>
|
||||
|
||||
#if defined(CONFIG_KMOD)
|
||||
|
@ -50,10 +49,7 @@
|
|||
#define BT_DBG(D...)
|
||||
#endif
|
||||
|
||||
#define VERSION "2.7"
|
||||
|
||||
struct proc_dir_entry *proc_bt;
|
||||
EXPORT_SYMBOL(proc_bt);
|
||||
#define VERSION "2.8"
|
||||
|
||||
/* Bluetooth sockets */
|
||||
#define BT_MAX_PROTO 8
|
||||
|
@ -312,10 +308,6 @@ static int __init bt_init(void)
|
|||
{
|
||||
BT_INFO("Core ver %s", VERSION);
|
||||
|
||||
proc_bt = proc_mkdir("bluetooth", NULL);
|
||||
if (proc_bt)
|
||||
proc_bt->owner = THIS_MODULE;
|
||||
|
||||
sock_register(&bt_sock_family_ops);
|
||||
|
||||
BT_INFO("HCI device and connection manager initialized");
|
||||
|
@ -334,8 +326,6 @@ static void __exit bt_exit(void)
|
|||
bt_sysfs_cleanup();
|
||||
|
||||
sock_unregister(PF_BLUETOOTH);
|
||||
|
||||
remove_proc_entry("bluetooth", NULL);
|
||||
}
|
||||
|
||||
subsys_initcall(bt_init);
|
||||
|
|
|
@ -103,7 +103,7 @@ static void bt_release(struct class_device *cdev)
|
|||
kfree(hdev);
|
||||
}
|
||||
|
||||
static struct class bt_class = {
|
||||
struct class bt_class = {
|
||||
.name = "bluetooth",
|
||||
.release = bt_release,
|
||||
#ifdef CONFIG_HOTPLUG
|
||||
|
@ -111,6 +111,8 @@ static struct class bt_class = {
|
|||
#endif
|
||||
};
|
||||
|
||||
EXPORT_SYMBOL_GPL(bt_class);
|
||||
|
||||
int hci_register_sysfs(struct hci_dev *hdev)
|
||||
{
|
||||
struct class_device *cdev = &hdev->class_dev;
|
||||
|
|
|
@ -38,9 +38,8 @@
|
|||
#include <linux/interrupt.h>
|
||||
#include <linux/socket.h>
|
||||
#include <linux/skbuff.h>
|
||||
#include <linux/proc_fs.h>
|
||||
#include <linux/seq_file.h>
|
||||
#include <linux/list.h>
|
||||
#include <linux/device.h>
|
||||
#include <net/sock.h>
|
||||
|
||||
#include <asm/system.h>
|
||||
|
@ -56,7 +55,7 @@
|
|||
#define BT_DBG(D...)
|
||||
#endif
|
||||
|
||||
#define VERSION "2.7"
|
||||
#define VERSION "2.8"
|
||||
|
||||
static struct proto_ops l2cap_sock_ops;
|
||||
|
||||
|
@ -2137,94 +2136,29 @@ static int l2cap_recv_acldata(struct hci_conn *hcon, struct sk_buff *skb, u16 fl
|
|||
return 0;
|
||||
}
|
||||
|
||||
/* ---- Proc fs support ---- */
|
||||
#ifdef CONFIG_PROC_FS
|
||||
static void *l2cap_seq_start(struct seq_file *seq, loff_t *pos)
|
||||
static ssize_t l2cap_sysfs_show(struct class *dev, char *buf)
|
||||
{
|
||||
struct sock *sk;
|
||||
struct hlist_node *node;
|
||||
loff_t l = *pos;
|
||||
char *str = buf;
|
||||
|
||||
read_lock_bh(&l2cap_sk_list.lock);
|
||||
|
||||
sk_for_each(sk, node, &l2cap_sk_list.head)
|
||||
if (!l--)
|
||||
goto found;
|
||||
sk = NULL;
|
||||
found:
|
||||
return sk;
|
||||
}
|
||||
sk_for_each(sk, node, &l2cap_sk_list.head) {
|
||||
struct l2cap_pinfo *pi = l2cap_pi(sk);
|
||||
|
||||
static void *l2cap_seq_next(struct seq_file *seq, void *e, loff_t *pos)
|
||||
{
|
||||
(*pos)++;
|
||||
return sk_next(e);
|
||||
}
|
||||
str += sprintf(str, "%s %s %d %d 0x%4.4x 0x%4.4x %d %d 0x%x\n",
|
||||
batostr(&bt_sk(sk)->src), batostr(&bt_sk(sk)->dst),
|
||||
sk->sk_state, pi->psm, pi->scid, pi->dcid, pi->imtu,
|
||||
pi->omtu, pi->link_mode);
|
||||
}
|
||||
|
||||
static void l2cap_seq_stop(struct seq_file *seq, void *e)
|
||||
{
|
||||
read_unlock_bh(&l2cap_sk_list.lock);
|
||||
|
||||
return (str - buf);
|
||||
}
|
||||
|
||||
static int l2cap_seq_show(struct seq_file *seq, void *e)
|
||||
{
|
||||
struct sock *sk = e;
|
||||
struct l2cap_pinfo *pi = l2cap_pi(sk);
|
||||
|
||||
seq_printf(seq, "%s %s %d %d 0x%4.4x 0x%4.4x %d %d 0x%x\n",
|
||||
batostr(&bt_sk(sk)->src), batostr(&bt_sk(sk)->dst),
|
||||
sk->sk_state, pi->psm, pi->scid, pi->dcid, pi->imtu,
|
||||
pi->omtu, pi->link_mode);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct seq_operations l2cap_seq_ops = {
|
||||
.start = l2cap_seq_start,
|
||||
.next = l2cap_seq_next,
|
||||
.stop = l2cap_seq_stop,
|
||||
.show = l2cap_seq_show
|
||||
};
|
||||
|
||||
static int l2cap_seq_open(struct inode *inode, struct file *file)
|
||||
{
|
||||
return seq_open(file, &l2cap_seq_ops);
|
||||
}
|
||||
|
||||
static struct file_operations l2cap_seq_fops = {
|
||||
.owner = THIS_MODULE,
|
||||
.open = l2cap_seq_open,
|
||||
.read = seq_read,
|
||||
.llseek = seq_lseek,
|
||||
.release = seq_release,
|
||||
};
|
||||
|
||||
static int __init l2cap_proc_init(void)
|
||||
{
|
||||
struct proc_dir_entry *p = create_proc_entry("l2cap", S_IRUGO, proc_bt);
|
||||
if (!p)
|
||||
return -ENOMEM;
|
||||
p->owner = THIS_MODULE;
|
||||
p->proc_fops = &l2cap_seq_fops;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void __exit l2cap_proc_cleanup(void)
|
||||
{
|
||||
remove_proc_entry("l2cap", proc_bt);
|
||||
}
|
||||
|
||||
#else /* CONFIG_PROC_FS */
|
||||
|
||||
static int __init l2cap_proc_init(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void __exit l2cap_proc_cleanup(void)
|
||||
{
|
||||
return;
|
||||
}
|
||||
#endif /* CONFIG_PROC_FS */
|
||||
static CLASS_ATTR(l2cap, S_IRUGO, l2cap_sysfs_show, NULL);
|
||||
|
||||
static struct proto_ops l2cap_sock_ops = {
|
||||
.family = PF_BLUETOOTH,
|
||||
|
@ -2266,7 +2200,7 @@ static struct hci_proto l2cap_hci_proto = {
|
|||
static int __init l2cap_init(void)
|
||||
{
|
||||
int err;
|
||||
|
||||
|
||||
err = proto_register(&l2cap_proto, 0);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
@ -2284,7 +2218,7 @@ static int __init l2cap_init(void)
|
|||
goto error;
|
||||
}
|
||||
|
||||
l2cap_proc_init();
|
||||
class_create_file(&bt_class, &class_attr_l2cap);
|
||||
|
||||
BT_INFO("L2CAP ver %s", VERSION);
|
||||
BT_INFO("L2CAP socket layer initialized");
|
||||
|
@ -2298,7 +2232,7 @@ static int __init l2cap_init(void)
|
|||
|
||||
static void __exit l2cap_exit(void)
|
||||
{
|
||||
l2cap_proc_cleanup();
|
||||
class_remove_file(&bt_class, &class_attr_l2cap);
|
||||
|
||||
if (bt_sock_unregister(BTPROTO_L2CAP) < 0)
|
||||
BT_ERR("L2CAP socket unregistration failed");
|
||||
|
|
|
@ -35,9 +35,8 @@
|
|||
#include <linux/signal.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/wait.h>
|
||||
#include <linux/device.h>
|
||||
#include <linux/net.h>
|
||||
#include <linux/proc_fs.h>
|
||||
#include <linux/seq_file.h>
|
||||
#include <net/sock.h>
|
||||
#include <asm/uaccess.h>
|
||||
#include <asm/unaligned.h>
|
||||
|
@ -47,17 +46,13 @@
|
|||
#include <net/bluetooth/l2cap.h>
|
||||
#include <net/bluetooth/rfcomm.h>
|
||||
|
||||
#define VERSION "1.5"
|
||||
#define VERSION "1.6"
|
||||
|
||||
#ifndef CONFIG_BT_RFCOMM_DEBUG
|
||||
#undef BT_DBG
|
||||
#define BT_DBG(D...)
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_PROC_FS
|
||||
struct proc_dir_entry *proc_bt_rfcomm;
|
||||
#endif
|
||||
|
||||
static struct task_struct *rfcomm_thread;
|
||||
|
||||
static DECLARE_MUTEX(rfcomm_sem);
|
||||
|
@ -2001,117 +1996,32 @@ static struct hci_cb rfcomm_cb = {
|
|||
.encrypt_cfm = rfcomm_encrypt_cfm
|
||||
};
|
||||
|
||||
/* ---- Proc fs support ---- */
|
||||
#ifdef CONFIG_PROC_FS
|
||||
static void *rfcomm_seq_start(struct seq_file *seq, loff_t *pos)
|
||||
static ssize_t rfcomm_dlc_sysfs_show(struct class *dev, char *buf)
|
||||
{
|
||||
struct rfcomm_session *s;
|
||||
struct list_head *pp, *p;
|
||||
loff_t l = *pos;
|
||||
char *str = buf;
|
||||
|
||||
rfcomm_lock();
|
||||
|
||||
list_for_each(p, &session_list) {
|
||||
s = list_entry(p, struct rfcomm_session, list);
|
||||
list_for_each(pp, &s->dlcs)
|
||||
if (!l--) {
|
||||
seq->private = s;
|
||||
return pp;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
list_for_each(pp, &s->dlcs) {
|
||||
struct sock *sk = s->sock->sk;
|
||||
struct rfcomm_dlc *d = list_entry(pp, struct rfcomm_dlc, list);
|
||||
|
||||
static void *rfcomm_seq_next(struct seq_file *seq, void *e, loff_t *pos)
|
||||
{
|
||||
struct rfcomm_session *s = seq->private;
|
||||
struct list_head *pp, *p = e;
|
||||
(*pos)++;
|
||||
|
||||
if (p->next != &s->dlcs)
|
||||
return p->next;
|
||||
|
||||
list_for_each(p, &session_list) {
|
||||
s = list_entry(p, struct rfcomm_session, list);
|
||||
__list_for_each(pp, &s->dlcs) {
|
||||
seq->private = s;
|
||||
return pp;
|
||||
str += sprintf(str, "%s %s %ld %d %d %d %d\n",
|
||||
batostr(&bt_sk(sk)->src), batostr(&bt_sk(sk)->dst),
|
||||
d->state, d->dlci, d->mtu, d->rx_credits, d->tx_credits);
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void rfcomm_seq_stop(struct seq_file *seq, void *e)
|
||||
{
|
||||
rfcomm_unlock();
|
||||
|
||||
return (str - buf);
|
||||
}
|
||||
|
||||
static int rfcomm_seq_show(struct seq_file *seq, void *e)
|
||||
{
|
||||
struct rfcomm_session *s = seq->private;
|
||||
struct sock *sk = s->sock->sk;
|
||||
struct rfcomm_dlc *d = list_entry(e, struct rfcomm_dlc, list);
|
||||
|
||||
seq_printf(seq, "%s %s %ld %d %d %d %d\n",
|
||||
batostr(&bt_sk(sk)->src), batostr(&bt_sk(sk)->dst),
|
||||
d->state, d->dlci, d->mtu, d->rx_credits, d->tx_credits);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct seq_operations rfcomm_seq_ops = {
|
||||
.start = rfcomm_seq_start,
|
||||
.next = rfcomm_seq_next,
|
||||
.stop = rfcomm_seq_stop,
|
||||
.show = rfcomm_seq_show
|
||||
};
|
||||
|
||||
static int rfcomm_seq_open(struct inode *inode, struct file *file)
|
||||
{
|
||||
return seq_open(file, &rfcomm_seq_ops);
|
||||
}
|
||||
|
||||
static struct file_operations rfcomm_seq_fops = {
|
||||
.owner = THIS_MODULE,
|
||||
.open = rfcomm_seq_open,
|
||||
.read = seq_read,
|
||||
.llseek = seq_lseek,
|
||||
.release = seq_release,
|
||||
};
|
||||
|
||||
static int __init rfcomm_proc_init(void)
|
||||
{
|
||||
struct proc_dir_entry *p;
|
||||
|
||||
proc_bt_rfcomm = proc_mkdir("rfcomm", proc_bt);
|
||||
if (proc_bt_rfcomm) {
|
||||
proc_bt_rfcomm->owner = THIS_MODULE;
|
||||
|
||||
p = create_proc_entry("dlc", S_IRUGO, proc_bt_rfcomm);
|
||||
if (p)
|
||||
p->proc_fops = &rfcomm_seq_fops;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void __exit rfcomm_proc_cleanup(void)
|
||||
{
|
||||
remove_proc_entry("dlc", proc_bt_rfcomm);
|
||||
|
||||
remove_proc_entry("rfcomm", proc_bt);
|
||||
}
|
||||
|
||||
#else /* CONFIG_PROC_FS */
|
||||
|
||||
static int __init rfcomm_proc_init(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void __exit rfcomm_proc_cleanup(void)
|
||||
{
|
||||
return;
|
||||
}
|
||||
#endif /* CONFIG_PROC_FS */
|
||||
static CLASS_ATTR(rfcomm_dlc, S_IRUGO, rfcomm_dlc_sysfs_show, NULL);
|
||||
|
||||
/* ---- Initialization ---- */
|
||||
static int __init rfcomm_init(void)
|
||||
|
@ -2122,9 +2032,7 @@ static int __init rfcomm_init(void)
|
|||
|
||||
kernel_thread(rfcomm_run, NULL, CLONE_KERNEL);
|
||||
|
||||
BT_INFO("RFCOMM ver %s", VERSION);
|
||||
|
||||
rfcomm_proc_init();
|
||||
class_create_file(&bt_class, &class_attr_rfcomm_dlc);
|
||||
|
||||
rfcomm_init_sockets();
|
||||
|
||||
|
@ -2132,11 +2040,15 @@ static int __init rfcomm_init(void)
|
|||
rfcomm_init_ttys();
|
||||
#endif
|
||||
|
||||
BT_INFO("RFCOMM ver %s", VERSION);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void __exit rfcomm_exit(void)
|
||||
{
|
||||
class_remove_file(&bt_class, &class_attr_rfcomm_dlc);
|
||||
|
||||
hci_unregister_cb(&rfcomm_cb);
|
||||
|
||||
/* Terminate working thread.
|
||||
|
@ -2153,8 +2065,6 @@ static void __exit rfcomm_exit(void)
|
|||
#endif
|
||||
|
||||
rfcomm_cleanup_sockets();
|
||||
|
||||
rfcomm_proc_cleanup();
|
||||
}
|
||||
|
||||
module_init(rfcomm_init);
|
||||
|
|
|
@ -42,8 +42,7 @@
|
|||
#include <linux/socket.h>
|
||||
#include <linux/skbuff.h>
|
||||
#include <linux/list.h>
|
||||
#include <linux/proc_fs.h>
|
||||
#include <linux/seq_file.h>
|
||||
#include <linux/device.h>
|
||||
#include <net/sock.h>
|
||||
|
||||
#include <asm/system.h>
|
||||
|
@ -887,89 +886,26 @@ int rfcomm_connect_ind(struct rfcomm_session *s, u8 channel, struct rfcomm_dlc *
|
|||
return result;
|
||||
}
|
||||
|
||||
/* ---- Proc fs support ---- */
|
||||
#ifdef CONFIG_PROC_FS
|
||||
static void *rfcomm_seq_start(struct seq_file *seq, loff_t *pos)
|
||||
static ssize_t rfcomm_sock_sysfs_show(struct class *dev, char *buf)
|
||||
{
|
||||
struct sock *sk;
|
||||
struct hlist_node *node;
|
||||
loff_t l = *pos;
|
||||
char *str = buf;
|
||||
|
||||
read_lock_bh(&rfcomm_sk_list.lock);
|
||||
|
||||
sk_for_each(sk, node, &rfcomm_sk_list.head)
|
||||
if (!l--)
|
||||
return sk;
|
||||
return NULL;
|
||||
}
|
||||
sk_for_each(sk, node, &rfcomm_sk_list.head) {
|
||||
str += sprintf(str, "%s %s %d %d\n",
|
||||
batostr(&bt_sk(sk)->src), batostr(&bt_sk(sk)->dst),
|
||||
sk->sk_state, rfcomm_pi(sk)->channel);
|
||||
}
|
||||
|
||||
static void *rfcomm_seq_next(struct seq_file *seq, void *e, loff_t *pos)
|
||||
{
|
||||
struct sock *sk = e;
|
||||
(*pos)++;
|
||||
return sk_next(sk);
|
||||
}
|
||||
|
||||
static void rfcomm_seq_stop(struct seq_file *seq, void *e)
|
||||
{
|
||||
read_unlock_bh(&rfcomm_sk_list.lock);
|
||||
|
||||
return (str - buf);
|
||||
}
|
||||
|
||||
static int rfcomm_seq_show(struct seq_file *seq, void *e)
|
||||
{
|
||||
struct sock *sk = e;
|
||||
seq_printf(seq, "%s %s %d %d\n",
|
||||
batostr(&bt_sk(sk)->src), batostr(&bt_sk(sk)->dst),
|
||||
sk->sk_state, rfcomm_pi(sk)->channel);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct seq_operations rfcomm_seq_ops = {
|
||||
.start = rfcomm_seq_start,
|
||||
.next = rfcomm_seq_next,
|
||||
.stop = rfcomm_seq_stop,
|
||||
.show = rfcomm_seq_show
|
||||
};
|
||||
|
||||
static int rfcomm_seq_open(struct inode *inode, struct file *file)
|
||||
{
|
||||
return seq_open(file, &rfcomm_seq_ops);
|
||||
}
|
||||
|
||||
static struct file_operations rfcomm_seq_fops = {
|
||||
.owner = THIS_MODULE,
|
||||
.open = rfcomm_seq_open,
|
||||
.read = seq_read,
|
||||
.llseek = seq_lseek,
|
||||
.release = seq_release,
|
||||
};
|
||||
|
||||
static int __init rfcomm_sock_proc_init(void)
|
||||
{
|
||||
struct proc_dir_entry *p = create_proc_entry("sock", S_IRUGO, proc_bt_rfcomm);
|
||||
if (!p)
|
||||
return -ENOMEM;
|
||||
p->proc_fops = &rfcomm_seq_fops;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void __exit rfcomm_sock_proc_cleanup(void)
|
||||
{
|
||||
remove_proc_entry("sock", proc_bt_rfcomm);
|
||||
}
|
||||
|
||||
#else /* CONFIG_PROC_FS */
|
||||
|
||||
static int __init rfcomm_sock_proc_init(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void __exit rfcomm_sock_proc_cleanup(void)
|
||||
{
|
||||
return;
|
||||
}
|
||||
#endif /* CONFIG_PROC_FS */
|
||||
static CLASS_ATTR(rfcomm, S_IRUGO, rfcomm_sock_sysfs_show, NULL);
|
||||
|
||||
static struct proto_ops rfcomm_sock_ops = {
|
||||
.family = PF_BLUETOOTH,
|
||||
|
@ -997,7 +933,7 @@ static struct net_proto_family rfcomm_sock_family_ops = {
|
|||
.create = rfcomm_sock_create
|
||||
};
|
||||
|
||||
int __init rfcomm_init_sockets(void)
|
||||
int __init rfcomm_init_sockets(void)
|
||||
{
|
||||
int err;
|
||||
|
||||
|
@ -1009,7 +945,7 @@ int __init rfcomm_init_sockets(void)
|
|||
if (err < 0)
|
||||
goto error;
|
||||
|
||||
rfcomm_sock_proc_init();
|
||||
class_create_file(&bt_class, &class_attr_rfcomm);
|
||||
|
||||
BT_INFO("RFCOMM socket layer initialized");
|
||||
|
||||
|
@ -1023,7 +959,7 @@ int __init rfcomm_init_sockets(void)
|
|||
|
||||
void __exit rfcomm_cleanup_sockets(void)
|
||||
{
|
||||
rfcomm_sock_proc_cleanup();
|
||||
class_remove_file(&bt_class, &class_attr_rfcomm);
|
||||
|
||||
if (bt_sock_unregister(BTPROTO_RFCOMM) < 0)
|
||||
BT_ERR("RFCOMM socket layer unregistration failed");
|
||||
|
|
|
@ -38,8 +38,7 @@
|
|||
#include <linux/interrupt.h>
|
||||
#include <linux/socket.h>
|
||||
#include <linux/skbuff.h>
|
||||
#include <linux/proc_fs.h>
|
||||
#include <linux/seq_file.h>
|
||||
#include <linux/device.h>
|
||||
#include <linux/list.h>
|
||||
#include <net/sock.h>
|
||||
|
||||
|
@ -55,7 +54,7 @@
|
|||
#define BT_DBG(D...)
|
||||
#endif
|
||||
|
||||
#define VERSION "0.4"
|
||||
#define VERSION "0.5"
|
||||
|
||||
static struct proto_ops sco_sock_ops;
|
||||
|
||||
|
@ -893,91 +892,26 @@ static int sco_recv_scodata(struct hci_conn *hcon, struct sk_buff *skb)
|
|||
return 0;
|
||||
}
|
||||
|
||||
/* ---- Proc fs support ---- */
|
||||
#ifdef CONFIG_PROC_FS
|
||||
static void *sco_seq_start(struct seq_file *seq, loff_t *pos)
|
||||
static ssize_t sco_sysfs_show(struct class *dev, char *buf)
|
||||
{
|
||||
struct sock *sk;
|
||||
struct hlist_node *node;
|
||||
loff_t l = *pos;
|
||||
char *str = buf;
|
||||
|
||||
read_lock_bh(&sco_sk_list.lock);
|
||||
|
||||
sk_for_each(sk, node, &sco_sk_list.head)
|
||||
if (!l--)
|
||||
goto found;
|
||||
sk = NULL;
|
||||
found:
|
||||
return sk;
|
||||
}
|
||||
sk_for_each(sk, node, &sco_sk_list.head) {
|
||||
str += sprintf(str, "%s %s %d\n",
|
||||
batostr(&bt_sk(sk)->src), batostr(&bt_sk(sk)->dst),
|
||||
sk->sk_state);
|
||||
}
|
||||
|
||||
static void *sco_seq_next(struct seq_file *seq, void *e, loff_t *pos)
|
||||
{
|
||||
struct sock *sk = e;
|
||||
(*pos)++;
|
||||
return sk_next(sk);
|
||||
}
|
||||
|
||||
static void sco_seq_stop(struct seq_file *seq, void *e)
|
||||
{
|
||||
read_unlock_bh(&sco_sk_list.lock);
|
||||
|
||||
return (str - buf);
|
||||
}
|
||||
|
||||
static int sco_seq_show(struct seq_file *seq, void *e)
|
||||
{
|
||||
struct sock *sk = e;
|
||||
seq_printf(seq, "%s %s %d\n",
|
||||
batostr(&bt_sk(sk)->src), batostr(&bt_sk(sk)->dst), sk->sk_state);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct seq_operations sco_seq_ops = {
|
||||
.start = sco_seq_start,
|
||||
.next = sco_seq_next,
|
||||
.stop = sco_seq_stop,
|
||||
.show = sco_seq_show
|
||||
};
|
||||
|
||||
static int sco_seq_open(struct inode *inode, struct file *file)
|
||||
{
|
||||
return seq_open(file, &sco_seq_ops);
|
||||
}
|
||||
|
||||
static struct file_operations sco_seq_fops = {
|
||||
.owner = THIS_MODULE,
|
||||
.open = sco_seq_open,
|
||||
.read = seq_read,
|
||||
.llseek = seq_lseek,
|
||||
.release = seq_release,
|
||||
};
|
||||
|
||||
static int __init sco_proc_init(void)
|
||||
{
|
||||
struct proc_dir_entry *p = create_proc_entry("sco", S_IRUGO, proc_bt);
|
||||
if (!p)
|
||||
return -ENOMEM;
|
||||
p->owner = THIS_MODULE;
|
||||
p->proc_fops = &sco_seq_fops;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void __exit sco_proc_cleanup(void)
|
||||
{
|
||||
remove_proc_entry("sco", proc_bt);
|
||||
}
|
||||
|
||||
#else /* CONFIG_PROC_FS */
|
||||
|
||||
static int __init sco_proc_init(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void __exit sco_proc_cleanup(void)
|
||||
{
|
||||
return;
|
||||
}
|
||||
#endif /* CONFIG_PROC_FS */
|
||||
static CLASS_ATTR(sco, S_IRUGO, sco_sysfs_show, NULL);
|
||||
|
||||
static struct proto_ops sco_sock_ops = {
|
||||
.family = PF_BLUETOOTH,
|
||||
|
@ -1035,7 +969,7 @@ static int __init sco_init(void)
|
|||
goto error;
|
||||
}
|
||||
|
||||
sco_proc_init();
|
||||
class_create_file(&bt_class, &class_attr_sco);
|
||||
|
||||
BT_INFO("SCO (Voice Link) ver %s", VERSION);
|
||||
BT_INFO("SCO socket layer initialized");
|
||||
|
@ -1049,7 +983,7 @@ static int __init sco_init(void)
|
|||
|
||||
static void __exit sco_exit(void)
|
||||
{
|
||||
sco_proc_cleanup();
|
||||
class_remove_file(&bt_class, &class_attr_sco);
|
||||
|
||||
if (bt_sock_unregister(BTPROTO_SCO) < 0)
|
||||
BT_ERR("SCO socket unregistration failed");
|
||||
|
|
Loading…
Reference in a new issue