Commit be9d1227 authored by Marcel Holtmann's avatar Marcel Holtmann Committed by David S. Miller

[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: default avatarMarcel Holtmann <marcel@holtmann.org>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 1ebb9252
...@@ -57,8 +57,6 @@ ...@@ -57,8 +57,6 @@
#define BT_DBG(fmt, arg...) printk(KERN_INFO "%s: " fmt "\n" , __FUNCTION__ , ## arg) #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) #define BT_ERR(fmt, arg...) printk(KERN_ERR "%s: " fmt "\n" , __FUNCTION__ , ## arg)
extern struct proc_dir_entry *proc_bt;
/* Connection and socket states */ /* Connection and socket states */
enum { enum {
BT_CONNECTED = 1, /* Equal to TCP_ESTABLISHED to make net code happy */ BT_CONNECTED = 1, /* Equal to TCP_ESTABLISHED to make net code happy */
...@@ -177,4 +175,6 @@ extern int hci_sock_cleanup(void); ...@@ -177,4 +175,6 @@ extern int 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;
#endif /* __BLUETOOTH_H */ #endif /* __BLUETOOTH_H */
...@@ -25,7 +25,6 @@ ...@@ -25,7 +25,6 @@
#ifndef __HCI_CORE_H #ifndef __HCI_CORE_H
#define __HCI_CORE_H #define __HCI_CORE_H
#include <linux/proc_fs.h>
#include <net/bluetooth/hci.h> #include <net/bluetooth/hci.h>
/* HCI upper protocols */ /* HCI upper protocols */
...@@ -34,8 +33,6 @@ ...@@ -34,8 +33,6 @@
#define HCI_INIT_TIMEOUT (HZ * 10) #define HCI_INIT_TIMEOUT (HZ * 10)
extern struct proc_dir_entry *proc_bt_hci;
/* HCI Core structures */ /* HCI Core structures */
struct inquiry_data { struct inquiry_data {
...@@ -126,10 +123,6 @@ struct hci_dev { ...@@ -126,10 +123,6 @@ struct hci_dev {
atomic_t promisc; atomic_t promisc;
#ifdef CONFIG_PROC_FS
struct proc_dir_entry *proc;
#endif
struct class_device class_dev; struct class_device class_dev;
struct module *owner; struct module *owner;
......
...@@ -351,6 +351,4 @@ int rfcomm_dev_ioctl(struct sock *sk, unsigned int cmd, void __user *arg); ...@@ -351,6 +351,4 @@ int rfcomm_dev_ioctl(struct sock *sk, unsigned int cmd, void __user *arg);
int rfcomm_init_ttys(void); int rfcomm_init_ttys(void);
void rfcomm_cleanup_ttys(void); void rfcomm_cleanup_ttys(void);
extern struct proc_dir_entry *proc_bt_rfcomm;
#endif /* __RFCOMM_H */ #endif /* __RFCOMM_H */
...@@ -36,7 +36,6 @@ ...@@ -36,7 +36,6 @@
#include <linux/skbuff.h> #include <linux/skbuff.h>
#include <linux/init.h> #include <linux/init.h>
#include <linux/poll.h> #include <linux/poll.h>
#include <linux/proc_fs.h>
#include <net/sock.h> #include <net/sock.h>
#if defined(CONFIG_KMOD) #if defined(CONFIG_KMOD)
...@@ -50,10 +49,7 @@ ...@@ -50,10 +49,7 @@
#define BT_DBG(D...) #define BT_DBG(D...)
#endif #endif
#define VERSION "2.7" #define VERSION "2.8"
struct proc_dir_entry *proc_bt;
EXPORT_SYMBOL(proc_bt);
/* Bluetooth sockets */ /* Bluetooth sockets */
#define BT_MAX_PROTO 8 #define BT_MAX_PROTO 8
...@@ -312,10 +308,6 @@ static int __init bt_init(void) ...@@ -312,10 +308,6 @@ static int __init bt_init(void)
{ {
BT_INFO("Core ver %s", VERSION); 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); sock_register(&bt_sock_family_ops);
BT_INFO("HCI device and connection manager initialized"); BT_INFO("HCI device and connection manager initialized");
...@@ -334,8 +326,6 @@ static void __exit bt_exit(void) ...@@ -334,8 +326,6 @@ static void __exit bt_exit(void)
bt_sysfs_cleanup(); bt_sysfs_cleanup();
sock_unregister(PF_BLUETOOTH); sock_unregister(PF_BLUETOOTH);
remove_proc_entry("bluetooth", NULL);
} }
subsys_initcall(bt_init); subsys_initcall(bt_init);
......
...@@ -103,7 +103,7 @@ static void bt_release(struct class_device *cdev) ...@@ -103,7 +103,7 @@ static void bt_release(struct class_device *cdev)
kfree(hdev); kfree(hdev);
} }
static struct class bt_class = { struct class bt_class = {
.name = "bluetooth", .name = "bluetooth",
.release = bt_release, .release = bt_release,
#ifdef CONFIG_HOTPLUG #ifdef CONFIG_HOTPLUG
...@@ -111,6 +111,8 @@ static struct class bt_class = { ...@@ -111,6 +111,8 @@ static struct class bt_class = {
#endif #endif
}; };
EXPORT_SYMBOL_GPL(bt_class);
int hci_register_sysfs(struct hci_dev *hdev) int hci_register_sysfs(struct hci_dev *hdev)
{ {
struct class_device *cdev = &hdev->class_dev; struct class_device *cdev = &hdev->class_dev;
......
...@@ -38,9 +38,8 @@ ...@@ -38,9 +38,8 @@
#include <linux/interrupt.h> #include <linux/interrupt.h>
#include <linux/socket.h> #include <linux/socket.h>
#include <linux/skbuff.h> #include <linux/skbuff.h>
#include <linux/proc_fs.h>
#include <linux/seq_file.h>
#include <linux/list.h> #include <linux/list.h>
#include <linux/device.h>
#include <net/sock.h> #include <net/sock.h>
#include <asm/system.h> #include <asm/system.h>
...@@ -56,7 +55,7 @@ ...@@ -56,7 +55,7 @@
#define BT_DBG(D...) #define BT_DBG(D...)
#endif #endif
#define VERSION "2.7" #define VERSION "2.8"
static struct proto_ops l2cap_sock_ops; static struct proto_ops l2cap_sock_ops;
...@@ -2137,94 +2136,29 @@ drop: ...@@ -2137,94 +2136,29 @@ drop:
return 0; return 0;
} }
/* ---- Proc fs support ---- */ static ssize_t l2cap_sysfs_show(struct class *dev, char *buf)
#ifdef CONFIG_PROC_FS
static void *l2cap_seq_start(struct seq_file *seq, loff_t *pos)
{ {
struct sock *sk; struct sock *sk;
struct hlist_node *node; struct hlist_node *node;
loff_t l = *pos; 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) {
if (!l--)
goto found;
sk = NULL;
found:
return sk;
}
static void *l2cap_seq_next(struct seq_file *seq, void *e, loff_t *pos)
{
(*pos)++;
return sk_next(e);
}
static void l2cap_seq_stop(struct seq_file *seq, void *e)
{
read_unlock_bh(&l2cap_sk_list.lock);
}
static int l2cap_seq_show(struct seq_file *seq, void *e)
{
struct sock *sk = e;
struct l2cap_pinfo *pi = l2cap_pi(sk); 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", 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), batostr(&bt_sk(sk)->src), batostr(&bt_sk(sk)->dst),
sk->sk_state, pi->psm, pi->scid, pi->dcid, pi->imtu, sk->sk_state, pi->psm, pi->scid, pi->dcid, pi->imtu,
pi->omtu, pi->link_mode); 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 */ read_unlock_bh(&l2cap_sk_list.lock);
static int __init l2cap_proc_init(void) return (str - buf);
{
return 0;
} }
static void __exit l2cap_proc_cleanup(void) static CLASS_ATTR(l2cap, S_IRUGO, l2cap_sysfs_show, NULL);
{
return;
}
#endif /* CONFIG_PROC_FS */
static struct proto_ops l2cap_sock_ops = { static struct proto_ops l2cap_sock_ops = {
.family = PF_BLUETOOTH, .family = PF_BLUETOOTH,
...@@ -2284,7 +2218,7 @@ static int __init l2cap_init(void) ...@@ -2284,7 +2218,7 @@ static int __init l2cap_init(void)
goto error; goto error;
} }
l2cap_proc_init(); class_create_file(&bt_class, &class_attr_l2cap);
BT_INFO("L2CAP ver %s", VERSION); BT_INFO("L2CAP ver %s", VERSION);
BT_INFO("L2CAP socket layer initialized"); BT_INFO("L2CAP socket layer initialized");
...@@ -2298,7 +2232,7 @@ error: ...@@ -2298,7 +2232,7 @@ error:
static void __exit l2cap_exit(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) if (bt_sock_unregister(BTPROTO_L2CAP) < 0)
BT_ERR("L2CAP socket unregistration failed"); BT_ERR("L2CAP socket unregistration failed");
......
...@@ -35,9 +35,8 @@ ...@@ -35,9 +35,8 @@
#include <linux/signal.h> #include <linux/signal.h>
#include <linux/init.h> #include <linux/init.h>
#include <linux/wait.h> #include <linux/wait.h>
#include <linux/device.h>
#include <linux/net.h> #include <linux/net.h>
#include <linux/proc_fs.h>
#include <linux/seq_file.h>
#include <net/sock.h> #include <net/sock.h>
#include <asm/uaccess.h> #include <asm/uaccess.h>
#include <asm/unaligned.h> #include <asm/unaligned.h>
...@@ -47,17 +46,13 @@ ...@@ -47,17 +46,13 @@
#include <net/bluetooth/l2cap.h> #include <net/bluetooth/l2cap.h>
#include <net/bluetooth/rfcomm.h> #include <net/bluetooth/rfcomm.h>
#define VERSION "1.5" #define VERSION "1.6"
#ifndef CONFIG_BT_RFCOMM_DEBUG #ifndef CONFIG_BT_RFCOMM_DEBUG
#undef BT_DBG #undef BT_DBG
#define BT_DBG(D...) #define BT_DBG(D...)
#endif #endif
#ifdef CONFIG_PROC_FS
struct proc_dir_entry *proc_bt_rfcomm;
#endif
static struct task_struct *rfcomm_thread; static struct task_struct *rfcomm_thread;
static DECLARE_MUTEX(rfcomm_sem); static DECLARE_MUTEX(rfcomm_sem);
...@@ -2001,117 +1996,32 @@ static struct hci_cb rfcomm_cb = { ...@@ -2001,117 +1996,32 @@ static struct hci_cb rfcomm_cb = {
.encrypt_cfm = rfcomm_encrypt_cfm .encrypt_cfm = rfcomm_encrypt_cfm
}; };
/* ---- Proc fs support ---- */ static ssize_t rfcomm_dlc_sysfs_show(struct class *dev, char *buf)
#ifdef CONFIG_PROC_FS
static void *rfcomm_seq_start(struct seq_file *seq, loff_t *pos)
{ {
struct rfcomm_session *s; struct rfcomm_session *s;
struct list_head *pp, *p; struct list_head *pp, *p;
loff_t l = *pos; char *str = buf;
rfcomm_lock(); rfcomm_lock();
list_for_each(p, &session_list) { list_for_each(p, &session_list) {
s = list_entry(p, struct rfcomm_session, list); s = list_entry(p, struct rfcomm_session, list);
list_for_each(pp, &s->dlcs) list_for_each(pp, &s->dlcs) {
if (!l--) {
seq->private = s;
return pp;
}
}
return NULL;
}
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;
}
}
return NULL;
}
static void rfcomm_seq_stop(struct seq_file *seq, void *e)
{
rfcomm_unlock();
}
static int rfcomm_seq_show(struct seq_file *seq, void *e)
{
struct rfcomm_session *s = seq->private;
struct sock *sk = s->sock->sk; struct sock *sk = s->sock->sk;
struct rfcomm_dlc *d = list_entry(e, struct rfcomm_dlc, list); struct rfcomm_dlc *d = list_entry(pp, struct rfcomm_dlc, list);
seq_printf(seq, "%s %s %ld %d %d %d %d\n", str += sprintf(str, "%s %s %ld %d %d %d %d\n",
batostr(&bt_sk(sk)->src), batostr(&bt_sk(sk)->dst), batostr(&bt_sk(sk)->src), batostr(&bt_sk(sk)->dst),
d->state, d->dlci, d->mtu, d->rx_credits, d->tx_credits); 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 */ rfcomm_unlock();
static int __init rfcomm_proc_init(void) return (str - buf);
{
return 0;
} }
static void __exit rfcomm_proc_cleanup(void) static CLASS_ATTR(rfcomm_dlc, S_IRUGO, rfcomm_dlc_sysfs_show, NULL);
{
return;
}
#endif /* CONFIG_PROC_FS */
/* ---- Initialization ---- */ /* ---- Initialization ---- */
static int __init rfcomm_init(void) static int __init rfcomm_init(void)
...@@ -2122,9 +2032,7 @@ static int __init rfcomm_init(void) ...@@ -2122,9 +2032,7 @@ static int __init rfcomm_init(void)
kernel_thread(rfcomm_run, NULL, CLONE_KERNEL); kernel_thread(rfcomm_run, NULL, CLONE_KERNEL);
BT_INFO("RFCOMM ver %s", VERSION); class_create_file(&bt_class, &class_attr_rfcomm_dlc);
rfcomm_proc_init();
rfcomm_init_sockets(); rfcomm_init_sockets();
...@@ -2132,11 +2040,15 @@ static int __init rfcomm_init(void) ...@@ -2132,11 +2040,15 @@ static int __init rfcomm_init(void)
rfcomm_init_ttys(); rfcomm_init_ttys();
#endif #endif
BT_INFO("RFCOMM ver %s", VERSION);
return 0; return 0;
} }
static void __exit rfcomm_exit(void) static void __exit rfcomm_exit(void)
{ {
class_remove_file(&bt_class, &class_attr_rfcomm_dlc);
hci_unregister_cb(&rfcomm_cb); hci_unregister_cb(&rfcomm_cb);
/* Terminate working thread. /* Terminate working thread.
...@@ -2153,8 +2065,6 @@ static void __exit rfcomm_exit(void) ...@@ -2153,8 +2065,6 @@ static void __exit rfcomm_exit(void)
#endif #endif
rfcomm_cleanup_sockets(); rfcomm_cleanup_sockets();
rfcomm_proc_cleanup();
} }
module_init(rfcomm_init); module_init(rfcomm_init);
......
...@@ -42,8 +42,7 @@ ...@@ -42,8 +42,7 @@
#include <linux/socket.h> #include <linux/socket.h>
#include <linux/skbuff.h> #include <linux/skbuff.h>
#include <linux/list.h> #include <linux/list.h>
#include <linux/proc_fs.h> #include <linux/device.h>
#include <linux/seq_file.h>
#include <net/sock.h> #include <net/sock.h>
#include <asm/system.h> #include <asm/system.h>
...@@ -887,89 +886,26 @@ done: ...@@ -887,89 +886,26 @@ done:
return result; return result;
} }
/* ---- Proc fs support ---- */ static ssize_t rfcomm_sock_sysfs_show(struct class *dev, char *buf)
#ifdef CONFIG_PROC_FS
static void *rfcomm_seq_start(struct seq_file *seq, loff_t *pos)
{ {
struct sock *sk; struct sock *sk;
struct hlist_node *node; struct hlist_node *node;
loff_t l = *pos; 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) {
if (!l--) str += sprintf(str, "%s %s %d %d\n",
return sk;
return NULL;
}
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);
}
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), batostr(&bt_sk(sk)->src), batostr(&bt_sk(sk)->dst),
sk->sk_state, rfcomm_pi(sk)->channel); 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 */ read_unlock_bh(&rfcomm_sk_list.lock);
static int __init rfcomm_sock_proc_init(void) return (str - buf);
{
return 0;
} }
static void __exit rfcomm_sock_proc_cleanup(void) static CLASS_ATTR(rfcomm, S_IRUGO, rfcomm_sock_sysfs_show, NULL);
{
return;
}
#endif /* CONFIG_PROC_FS */
static struct proto_ops rfcomm_sock_ops = { static struct proto_ops rfcomm_sock_ops = {
.family = PF_BLUETOOTH, .family = PF_BLUETOOTH,
...@@ -1009,7 +945,7 @@ int __init rfcomm_init_sockets(void) ...@@ -1009,7 +945,7 @@ int __init rfcomm_init_sockets(void)
if (err < 0) if (err < 0)
goto error; goto error;
rfcomm_sock_proc_init(); class_create_file(&bt_class, &class_attr_rfcomm);
BT_INFO("RFCOMM socket layer initialized"); BT_INFO("RFCOMM socket layer initialized");
...@@ -1023,7 +959,7 @@ error: ...@@ -1023,7 +959,7 @@ error:
void __exit rfcomm_cleanup_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) if (bt_sock_unregister(BTPROTO_RFCOMM) < 0)
BT_ERR("RFCOMM socket layer unregistration failed"); BT_ERR("RFCOMM socket layer unregistration failed");
......
...@@ -38,8 +38,7 @@ ...@@ -38,8 +38,7 @@
#include <linux/interrupt.h> #include <linux/interrupt.h>
#include <linux/socket.h> #include <linux/socket.h>
#include <linux/skbuff.h> #include <linux/skbuff.h>
#include <linux/proc_fs.h> #include <linux/device.h>
#include <linux/seq_file.h>
#include <linux/list.h> #include <linux/list.h>
#include <net/sock.h> #include <net/sock.h>
...@@ -55,7 +54,7 @@ ...@@ -55,7 +54,7 @@
#define BT_DBG(D...) #define BT_DBG(D...)
#endif #endif
#define VERSION "0.4" #define VERSION "0.5"
static struct proto_ops sco_sock_ops; static struct proto_ops sco_sock_ops;
...@@ -893,91 +892,26 @@ drop: ...@@ -893,91 +892,26 @@ drop:
return 0; return 0;
} }
/* ---- Proc fs support ---- */ static ssize_t sco_sysfs_show(struct class *dev, char *buf)
#ifdef CONFIG_PROC_FS
static void *sco_seq_start(struct seq_file *seq, loff_t *pos)
{ {
struct sock *sk; struct sock *sk;
struct hlist_node *node; struct hlist_node *node;
loff_t l = *pos; 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) {
if (!l--) str += sprintf(str, "%s %s %d\n",
goto found; batostr(&bt_sk(sk)->src), batostr(&bt_sk(sk)->dst),
sk = NULL; sk->sk_state);
found: }
return sk;
}
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); read_unlock_bh(&sco_sk_list.lock);
}
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 = { return (str - buf);
.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 = { static CLASS_ATTR(sco, S_IRUGO, sco_sysfs_show, NULL);
.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 struct proto_ops sco_sock_ops = { static struct proto_ops sco_sock_ops = {
.family = PF_BLUETOOTH, .family = PF_BLUETOOTH,
...@@ -1035,7 +969,7 @@ static int __init sco_init(void) ...@@ -1035,7 +969,7 @@ static int __init sco_init(void)
goto error; goto error;
} }
sco_proc_init(); class_create_file(&bt_class, &class_attr_sco);
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");
...@@ -1049,7 +983,7 @@ error: ...@@ -1049,7 +983,7 @@ error:
static void __exit sco_exit(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) if (bt_sock_unregister(BTPROTO_SCO) < 0)
BT_ERR("SCO socket unregistration failed"); BT_ERR("SCO socket unregistration failed");
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment