sysfs channels: dahdi-sysfs-chan.c
* Move sysfs class and device files management into dahdi-sysfs-chan.c * This does not change functionality, just a preparation for later code cleanups and improvements. Signed-off-by: Oron Peled <oron.peled@xorcom.com> Acked-by: Tzafrir Cohen <tzafrir.cohen@xorcom.com> Acked-by: Shaun Ruffell <sruffell@digium.com> git-svn-id: http://svn.asterisk.org/svn/dahdi/linux/trunk@10463 a0bf4364-ded3-4de4-8d8a-66a801d63aff
This commit is contained in:
parent
6b59211b3d
commit
56a3c35273
@ -77,7 +77,7 @@ CFLAGS_dahdi_dynamic_ethmf.o := -DNEW_SKB_LINEARIZE
|
||||
endif
|
||||
endif
|
||||
|
||||
dahdi-objs := dahdi-base.o dahdi-sysfs.o dahdi-version.o
|
||||
dahdi-objs := dahdi-base.o dahdi-sysfs.o dahdi-sysfs-chan.o dahdi-version.o
|
||||
|
||||
###############################################################################
|
||||
# Find appropriate ARCH value for VPMADT032 and HPEC binary modules
|
||||
|
170
drivers/dahdi/dahdi-sysfs-chan.c
Normal file
170
drivers/dahdi/dahdi-sysfs-chan.c
Normal file
@ -0,0 +1,170 @@
|
||||
#include <linux/version.h>
|
||||
#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 0)
|
||||
# warning "This module is tested only with 2.6 kernels"
|
||||
#endif
|
||||
|
||||
#define DAHDI_PRINK_MACROS_USE_debug
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/slab.h>
|
||||
#include <dahdi/kernel.h>
|
||||
#include "dahdi.h"
|
||||
#include "dahdi-sysfs.h"
|
||||
|
||||
#define MAKE_DAHDI_DEV(num, name) \
|
||||
CLASS_DEV_CREATE(dahdi_class, MKDEV(DAHDI_MAJOR, num), NULL, name)
|
||||
#define DEL_DAHDI_DEV(num) \
|
||||
CLASS_DEV_DESTROY(dahdi_class, MKDEV(DAHDI_MAJOR, num))
|
||||
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 13)
|
||||
static struct class *dahdi_class;
|
||||
#else
|
||||
static struct class_simple *dahdi_class;
|
||||
#define class_create class_simple_create
|
||||
#define class_destroy class_simple_destroy
|
||||
#endif
|
||||
|
||||
int chan_sysfs_create(struct dahdi_chan *chan)
|
||||
{
|
||||
char chan_name[32];
|
||||
void *dummy;
|
||||
int res = 0;
|
||||
|
||||
if (chan->channo >= 250)
|
||||
return 0;
|
||||
if (test_bit(DAHDI_FLAGBIT_DEVFILE, &chan->flags))
|
||||
return 0;
|
||||
snprintf(chan_name, sizeof(chan_name), "dahdi!%d", chan->channo);
|
||||
dummy = (void *)CLASS_DEV_CREATE(dahdi_class,
|
||||
MKDEV(DAHDI_MAJOR, chan->channo),
|
||||
NULL, chan_name);
|
||||
if (IS_ERR(dummy)) {
|
||||
res = PTR_ERR(dummy);
|
||||
chan_err(chan, "Failed creating sysfs device: %d\n",
|
||||
res);
|
||||
return res;
|
||||
}
|
||||
set_bit(DAHDI_FLAGBIT_DEVFILE, &chan->flags);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void chan_sysfs_remove(struct dahdi_chan *chan)
|
||||
{
|
||||
if (!test_bit(DAHDI_FLAGBIT_DEVFILE, &chan->flags))
|
||||
return;
|
||||
CLASS_DEV_DESTROY(dahdi_class, MKDEV(DAHDI_MAJOR, chan->channo));
|
||||
clear_bit(DAHDI_FLAGBIT_DEVFILE, &chan->flags);
|
||||
}
|
||||
|
||||
int dahdi_register_chardev(struct dahdi_chardev *dev)
|
||||
{
|
||||
static const char *DAHDI_STRING = "dahdi!";
|
||||
char *udevname;
|
||||
|
||||
udevname = kzalloc(strlen(dev->name) + sizeof(DAHDI_STRING) + 1,
|
||||
GFP_KERNEL);
|
||||
if (!udevname)
|
||||
return -ENOMEM;
|
||||
|
||||
strcpy(udevname, DAHDI_STRING);
|
||||
strcat(udevname, dev->name);
|
||||
CLASS_DEV_CREATE(dahdi_class,
|
||||
MKDEV(DAHDI_MAJOR, dev->minor), NULL, udevname);
|
||||
kfree(udevname);
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(dahdi_register_chardev);
|
||||
|
||||
int dahdi_unregister_chardev(struct dahdi_chardev *dev)
|
||||
{
|
||||
CLASS_DEV_DESTROY(dahdi_class, MKDEV(DAHDI_MAJOR, dev->minor));
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(dahdi_unregister_chardev);
|
||||
|
||||
/* Only used to flag that the device exists: */
|
||||
static struct {
|
||||
unsigned int ctl:1;
|
||||
unsigned int timer:1;
|
||||
unsigned int channel:1;
|
||||
unsigned int pseudo:1;
|
||||
} dummy_dev;
|
||||
|
||||
int __init dahdi_sysfs_chan_init(const struct file_operations *fops)
|
||||
{
|
||||
int res = 0;
|
||||
void *dev;
|
||||
|
||||
dahdi_class = class_create(THIS_MODULE, "dahdi");
|
||||
if (IS_ERR(dahdi_class)) {
|
||||
res = PTR_ERR(dahdi_class);
|
||||
dahdi_err("%s: class_create(dahi_chan) failed. Error: %d\n",
|
||||
__func__, res);
|
||||
goto cleanup;
|
||||
}
|
||||
dahdi_dbg(DEVICES, "Creating /dev/dahdi/timer:\n");
|
||||
dev = MAKE_DAHDI_DEV(DAHDI_TIMER, "dahdi!timer");
|
||||
if (IS_ERR(dev)) {
|
||||
res = PTR_ERR(dev);
|
||||
goto cleanup;
|
||||
}
|
||||
dummy_dev.timer = 1;
|
||||
|
||||
dahdi_dbg(DEVICES, "Creating /dev/dahdi/channel:\n");
|
||||
dev = MAKE_DAHDI_DEV(DAHDI_CHANNEL, "dahdi!channel");
|
||||
if (IS_ERR(dev)) {
|
||||
res = PTR_ERR(dev);
|
||||
goto cleanup;
|
||||
}
|
||||
dummy_dev.channel = 1;
|
||||
|
||||
dahdi_dbg(DEVICES, "Creating /dev/dahdi/pseudo:\n");
|
||||
dev = MAKE_DAHDI_DEV(DAHDI_PSEUDO, "dahdi!pseudo");
|
||||
if (IS_ERR(dev)) {
|
||||
res = PTR_ERR(dev);
|
||||
goto cleanup;
|
||||
}
|
||||
dummy_dev.pseudo = 1;
|
||||
|
||||
dahdi_dbg(DEVICES, "Creating /dev/dahdi/ctl:\n");
|
||||
dev = MAKE_DAHDI_DEV(DAHDI_CTL, "dahdi!ctl");
|
||||
if (IS_ERR(dev)) {
|
||||
res = PTR_ERR(dev);
|
||||
goto cleanup;
|
||||
}
|
||||
dummy_dev.ctl = 1;
|
||||
return 0;
|
||||
cleanup:
|
||||
dahdi_sysfs_chan_exit();
|
||||
return res;
|
||||
}
|
||||
|
||||
void dahdi_sysfs_chan_exit(void)
|
||||
{
|
||||
if (dummy_dev.pseudo) {
|
||||
dahdi_dbg(DEVICES, "Removing /dev/dahdi/pseudo:\n");
|
||||
DEL_DAHDI_DEV(DAHDI_PSEUDO);
|
||||
dummy_dev.pseudo = 0;
|
||||
}
|
||||
if (dummy_dev.channel) {
|
||||
dahdi_dbg(DEVICES, "Removing /dev/dahdi/channel:\n");
|
||||
DEL_DAHDI_DEV(DAHDI_CHANNEL);
|
||||
dummy_dev.channel = 0;
|
||||
}
|
||||
if (dummy_dev.timer) {
|
||||
dahdi_dbg(DEVICES, "Removing /dev/dahdi/timer:\n");
|
||||
DEL_DAHDI_DEV(DAHDI_TIMER);
|
||||
dummy_dev.timer = 0;
|
||||
}
|
||||
if (dummy_dev.ctl) {
|
||||
dahdi_dbg(DEVICES, "Removing /dev/dahdi/ctl:\n");
|
||||
DEL_DAHDI_DEV(DAHDI_CTL);
|
||||
dummy_dev.ctl = 0;
|
||||
}
|
||||
if (dahdi_class && !IS_ERR(dahdi_class)) {
|
||||
dahdi_dbg(DEVICES, "Destroying DAHDI class\n");
|
||||
class_destroy(dahdi_class);
|
||||
dahdi_class = NULL;
|
||||
}
|
||||
}
|
@ -8,14 +8,6 @@
|
||||
#include "dahdi.h"
|
||||
#include "dahdi-sysfs.h"
|
||||
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 13)
|
||||
static struct class *dahdi_class;
|
||||
#else
|
||||
static struct class_simple *dahdi_class;
|
||||
#define class_create class_simple_create
|
||||
#define class_destroy class_simple_destroy
|
||||
#endif
|
||||
|
||||
|
||||
static char *initdir = "/usr/share/dahdi";
|
||||
module_param(initdir, charp, 0644);
|
||||
@ -293,33 +285,6 @@ static void span_release(struct device *dev)
|
||||
dahdi_dbg(DEVICES, "%s: %s\n", __func__, dev_name(dev));
|
||||
}
|
||||
|
||||
int dahdi_register_chardev(struct dahdi_chardev *dev)
|
||||
{
|
||||
static const char *DAHDI_STRING = "dahdi!";
|
||||
char *udevname;
|
||||
|
||||
udevname = kzalloc(strlen(dev->name) + sizeof(DAHDI_STRING) + 1,
|
||||
GFP_KERNEL);
|
||||
if (!udevname)
|
||||
return -ENOMEM;
|
||||
|
||||
strcpy(udevname, DAHDI_STRING);
|
||||
strcat(udevname, dev->name);
|
||||
CLASS_DEV_CREATE(dahdi_class,
|
||||
MKDEV(DAHDI_MAJOR, dev->minor), NULL, udevname);
|
||||
kfree(udevname);
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(dahdi_register_chardev);
|
||||
|
||||
int dahdi_unregister_chardev(struct dahdi_chardev *dev)
|
||||
{
|
||||
CLASS_DEV_DESTROY(dahdi_class, MKDEV(DAHDI_MAJOR, dev->minor));
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(dahdi_unregister_chardev);
|
||||
|
||||
void span_sysfs_remove(struct dahdi_span *span)
|
||||
{
|
||||
struct device *span_device;
|
||||
@ -331,15 +296,8 @@ void span_sysfs_remove(struct dahdi_span *span)
|
||||
if (!span_device)
|
||||
return;
|
||||
|
||||
for (x = 0; x < span->channels; x++) {
|
||||
struct dahdi_chan *chan = span->chans[x];
|
||||
if (!test_bit(DAHDI_FLAGBIT_DEVFILE, &chan->flags))
|
||||
continue;
|
||||
|
||||
CLASS_DEV_DESTROY(dahdi_class,
|
||||
MKDEV(DAHDI_MAJOR, chan->channo));
|
||||
clear_bit(DAHDI_FLAGBIT_DEVFILE, &chan->flags);
|
||||
}
|
||||
for (x = 0; x < span->channels; x++)
|
||||
chan_sysfs_remove(span->chans[x]);
|
||||
if (!dev_get_drvdata(span_device))
|
||||
return;
|
||||
|
||||
@ -390,28 +348,9 @@ int span_sysfs_create(struct dahdi_span *span)
|
||||
}
|
||||
|
||||
for (x = 0; x < span->channels; x++) {
|
||||
struct dahdi_chan *chan = span->chans[x];
|
||||
char chan_name[32];
|
||||
void *dummy;
|
||||
|
||||
if (chan->channo >= 250)
|
||||
continue;
|
||||
if (test_bit(DAHDI_FLAGBIT_DEVFILE, &chan->flags))
|
||||
continue;
|
||||
|
||||
snprintf(chan_name, sizeof(chan_name), "dahdi!%d",
|
||||
chan->channo);
|
||||
dummy = (void *)CLASS_DEV_CREATE(dahdi_class,
|
||||
MKDEV(DAHDI_MAJOR, chan->channo),
|
||||
NULL, chan_name);
|
||||
if (IS_ERR(dummy)) {
|
||||
res = PTR_ERR(dummy);
|
||||
chan_err(chan, "Failed creating sysfs device: %d\n",
|
||||
res);
|
||||
res = chan_sysfs_create(span->chans[x]);
|
||||
if (res < 0)
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
set_bit(DAHDI_FLAGBIT_DEVFILE, &chan->flags);
|
||||
}
|
||||
return 0;
|
||||
|
||||
@ -420,21 +359,12 @@ cleanup:
|
||||
return res;
|
||||
}
|
||||
|
||||
#define MAKE_DAHDI_DEV(num, name) \
|
||||
CLASS_DEV_CREATE(dahdi_class, MKDEV(DAHDI_MAJOR, num), NULL, name)
|
||||
#define DEL_DAHDI_DEV(num) \
|
||||
CLASS_DEV_DESTROY(dahdi_class, MKDEV(DAHDI_MAJOR, num))
|
||||
|
||||
/* Only used to flag that the device exists: */
|
||||
static struct {
|
||||
unsigned int ctl:1;
|
||||
unsigned int timer:1;
|
||||
unsigned int channel:1;
|
||||
unsigned int pseudo:1;
|
||||
unsigned int sysfs_driver_registered:1;
|
||||
unsigned int sysfs_spans_bus_type:1;
|
||||
unsigned int dahdi_device_bus_registered:1;
|
||||
} dummy_dev;
|
||||
} device_state_flags;
|
||||
|
||||
static inline struct dahdi_device *to_ddev(struct device *dev)
|
||||
{
|
||||
@ -676,46 +606,22 @@ static struct bus_type dahdi_device_bus = {
|
||||
void dahdi_sysfs_exit(void)
|
||||
{
|
||||
dahdi_dbg(DEVICES, "SYSFS\n");
|
||||
if (dummy_dev.pseudo) {
|
||||
dahdi_dbg(DEVICES, "Removing /dev/dahdi/pseudo:\n");
|
||||
DEL_DAHDI_DEV(DAHDI_PSEUDO);
|
||||
dummy_dev.pseudo = 0;
|
||||
}
|
||||
if (dummy_dev.channel) {
|
||||
dahdi_dbg(DEVICES, "Removing /dev/dahdi/channel:\n");
|
||||
DEL_DAHDI_DEV(DAHDI_CHANNEL);
|
||||
dummy_dev.channel = 0;
|
||||
}
|
||||
if (dummy_dev.timer) {
|
||||
dahdi_dbg(DEVICES, "Removing /dev/dahdi/timer:\n");
|
||||
DEL_DAHDI_DEV(DAHDI_TIMER);
|
||||
dummy_dev.timer = 0;
|
||||
}
|
||||
if (dummy_dev.ctl) {
|
||||
dahdi_dbg(DEVICES, "Removing /dev/dahdi/ctl:\n");
|
||||
DEL_DAHDI_DEV(DAHDI_CTL);
|
||||
dummy_dev.ctl = 0;
|
||||
}
|
||||
if (dahdi_class && !IS_ERR(dahdi_class)) {
|
||||
dahdi_dbg(DEVICES, "Destroying DAHDI class:\n");
|
||||
class_destroy(dahdi_class);
|
||||
dahdi_class = NULL;
|
||||
}
|
||||
if (dummy_dev.sysfs_driver_registered) {
|
||||
dahdi_sysfs_chan_exit();
|
||||
if (device_state_flags.sysfs_driver_registered) {
|
||||
dahdi_dbg(DEVICES, "Unregister driver\n");
|
||||
driver_unregister(&dahdi_driver);
|
||||
dummy_dev.sysfs_driver_registered = 0;
|
||||
device_state_flags.sysfs_driver_registered = 0;
|
||||
}
|
||||
if (dummy_dev.sysfs_spans_bus_type) {
|
||||
if (device_state_flags.sysfs_spans_bus_type) {
|
||||
dahdi_dbg(DEVICES, "Unregister span bus type\n");
|
||||
bus_unregister(&spans_bus_type);
|
||||
dummy_dev.sysfs_spans_bus_type = 0;
|
||||
device_state_flags.sysfs_spans_bus_type = 0;
|
||||
}
|
||||
unregister_chrdev(DAHDI_MAJOR, "dahdi");
|
||||
|
||||
if (dummy_dev.dahdi_device_bus_registered) {
|
||||
if (device_state_flags.dahdi_device_bus_registered) {
|
||||
bus_unregister(&dahdi_device_bus);
|
||||
dummy_dev.dahdi_device_bus_registered = 0;
|
||||
device_state_flags.dahdi_device_bus_registered = 0;
|
||||
}
|
||||
}
|
||||
|
||||
@ -767,13 +673,12 @@ void dahdi_sysfs_unregister_device(struct dahdi_device *ddev)
|
||||
int __init dahdi_sysfs_init(const struct file_operations *dahdi_fops)
|
||||
{
|
||||
int res = 0;
|
||||
void *dev;
|
||||
|
||||
res = bus_register(&dahdi_device_bus);
|
||||
if (res)
|
||||
return res;
|
||||
|
||||
dummy_dev.dahdi_device_bus_registered = 1;
|
||||
device_state_flags.dahdi_device_bus_registered = 1;
|
||||
|
||||
res = register_chrdev(DAHDI_MAJOR, "dahdi", dahdi_fops);
|
||||
if (res) {
|
||||
@ -786,57 +691,21 @@ int __init dahdi_sysfs_init(const struct file_operations *dahdi_fops)
|
||||
DAHDI_MAJOR);
|
||||
module_printk(KERN_INFO, "Version: %s\n", dahdi_version);
|
||||
|
||||
dahdi_class = class_create(THIS_MODULE, "dahdi");
|
||||
if (IS_ERR(dahdi_class)) {
|
||||
res = PTR_ERR(dahdi_class);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
dahdi_dbg(DEVICES, "Creating /dev/dahdi/timer:\n");
|
||||
dev = MAKE_DAHDI_DEV(DAHDI_TIMER, "dahdi!timer");
|
||||
if (IS_ERR(dev)) {
|
||||
res = PTR_ERR(dev);
|
||||
goto cleanup;
|
||||
}
|
||||
dummy_dev.timer = 1;
|
||||
|
||||
dahdi_dbg(DEVICES, "Creating /dev/dahdi/channel:\n");
|
||||
dev = MAKE_DAHDI_DEV(DAHDI_CHANNEL, "dahdi!channel");
|
||||
if (IS_ERR(dev)) {
|
||||
res = PTR_ERR(dev);
|
||||
goto cleanup;
|
||||
}
|
||||
dummy_dev.channel = 1;
|
||||
|
||||
dahdi_dbg(DEVICES, "Creating /dev/dahdi/pseudo:\n");
|
||||
dev = MAKE_DAHDI_DEV(DAHDI_PSEUDO, "dahdi!pseudo");
|
||||
if (IS_ERR(dev)) {
|
||||
res = PTR_ERR(dev);
|
||||
goto cleanup;
|
||||
}
|
||||
dummy_dev.pseudo = 1;
|
||||
|
||||
dahdi_dbg(DEVICES, "Creating /dev/dahdi/ctl:\n");
|
||||
dev = MAKE_DAHDI_DEV(DAHDI_CTL, "dahdi!ctl");
|
||||
if (IS_ERR(dev)) {
|
||||
res = PTR_ERR(dev);
|
||||
goto cleanup;
|
||||
}
|
||||
dummy_dev.ctl = 1;
|
||||
dahdi_sysfs_chan_init(dahdi_fops);
|
||||
res = bus_register(&spans_bus_type);
|
||||
if (res != 0) {
|
||||
dahdi_err("%s: bus_register(%s) failed. Error number %d",
|
||||
__func__, spans_bus_type.name, res);
|
||||
goto cleanup;
|
||||
}
|
||||
dummy_dev.sysfs_spans_bus_type = 1;
|
||||
device_state_flags.sysfs_spans_bus_type = 1;
|
||||
res = driver_register(&dahdi_driver);
|
||||
if (res < 0) {
|
||||
dahdi_err("%s: driver_register(%s) failed. Error number %d",
|
||||
__func__, dahdi_driver.name, res);
|
||||
goto cleanup;
|
||||
}
|
||||
dummy_dev.sysfs_driver_registered = 1;
|
||||
device_state_flags.sysfs_driver_registered = 1;
|
||||
|
||||
return 0;
|
||||
|
||||
|
@ -95,4 +95,12 @@ enum kobject_action {
|
||||
class_simple_device_remove(class, devt)
|
||||
#endif
|
||||
|
||||
/* Global */
|
||||
int __init dahdi_sysfs_chan_init(const struct file_operations *fops);
|
||||
void dahdi_sysfs_chan_exit(void);
|
||||
|
||||
/* Channel Handling */
|
||||
int chan_sysfs_create(struct dahdi_chan *chan);
|
||||
void chan_sysfs_remove(struct dahdi_chan *chan);
|
||||
|
||||
#endif /* DAHDI_SYSFS_H */
|
||||
|
Loading…
Reference in New Issue
Block a user