dahdi: Expose spans in sysfs.
This change will facilitate creating rules that will allow spans and channels to be accessed by named device files instead of by numbers. Signed-off-by: Oron Peled <oron.peled@xorcom.com> Signed-off-by: Shaun Ruffell <sruffell@digium.com> git-svn-id: http://svn.asterisk.org/svn/dahdi/linux/trunk@10274 a0bf4364-ded3-4de4-8d8a-66a801d63aff
This commit is contained in:
parent
935c9ba50a
commit
2794bb4937
@ -612,6 +612,12 @@ void dahdi_unregister_echocan_factory(const struct dahdi_echocan_factory *ec)
|
|||||||
spin_unlock(&ecfactory_list_lock);
|
spin_unlock(&ecfactory_list_lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Is this span our syncronization master? */
|
||||||
|
int dahdi_is_sync_master(const struct dahdi_span *span)
|
||||||
|
{
|
||||||
|
return span == master;
|
||||||
|
}
|
||||||
|
|
||||||
static inline void rotate_sums(void)
|
static inline void rotate_sums(void)
|
||||||
{
|
{
|
||||||
/* Rotate where we sum and so forth */
|
/* Rotate where we sum and so forth */
|
||||||
@ -805,7 +811,7 @@ static int dahdi_seq_show(struct seq_file *sfile, void *v)
|
|||||||
else
|
else
|
||||||
seq_printf(sfile, "\"\"");
|
seq_printf(sfile, "\"\"");
|
||||||
|
|
||||||
if (s == master)
|
if (dahdi_is_sync_master(s))
|
||||||
seq_printf(sfile, " (MASTER)");
|
seq_printf(sfile, " (MASTER)");
|
||||||
|
|
||||||
if (s->lineconfig) {
|
if (s->lineconfig) {
|
||||||
@ -6669,6 +6675,7 @@ struct dahdi_device *dahdi_create_device(void)
|
|||||||
ddev = kzalloc(sizeof(*ddev), GFP_KERNEL);
|
ddev = kzalloc(sizeof(*ddev), GFP_KERNEL);
|
||||||
if (!ddev)
|
if (!ddev)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
device_initialize(&ddev->dev);
|
||||||
return ddev;
|
return ddev;
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(dahdi_create_device);
|
EXPORT_SYMBOL(dahdi_create_device);
|
||||||
@ -6817,6 +6824,8 @@ static int _dahdi_register_device(struct dahdi_device *ddev,
|
|||||||
ddev->location = (ddev->location) ?: UNKNOWN;
|
ddev->location = (ddev->location) ?: UNKNOWN;
|
||||||
ddev->devicetype = (ddev->devicetype) ?: UNKNOWN;
|
ddev->devicetype = (ddev->devicetype) ?: UNKNOWN;
|
||||||
|
|
||||||
|
ddev->dev.parent = parent;
|
||||||
|
|
||||||
list_for_each_entry(s, &ddev->spans, device_node) {
|
list_for_each_entry(s, &ddev->spans, device_node) {
|
||||||
s->parent = ddev;
|
s->parent = ddev;
|
||||||
ret = _dahdi_register_span(s, 1);
|
ret = _dahdi_register_span(s, 1);
|
||||||
@ -6911,16 +6920,6 @@ static int _dahdi_unregister_span(struct dahdi_span *span)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int dahdi_unregister_span(struct dahdi_span *span)
|
|
||||||
{
|
|
||||||
module_printk(KERN_NOTICE, "%s: %s\n", __func__, span->name);
|
|
||||||
mutex_lock(®istration_mutex);
|
|
||||||
_dahdi_unregister_span(span);
|
|
||||||
list_del_init(&span->device_node);
|
|
||||||
mutex_unlock(®istration_mutex);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* dahdi_unregister_device() - unregister a DAHDI device
|
* dahdi_unregister_device() - unregister a DAHDI device
|
||||||
* @span: the DAHDI span
|
* @span: the DAHDI span
|
||||||
@ -9184,7 +9183,7 @@ static inline void pseudo_rx_audio(struct dahdi_chan *chan)
|
|||||||
static inline void dahdi_sync_tick(struct dahdi_span *const s)
|
static inline void dahdi_sync_tick(struct dahdi_span *const s)
|
||||||
{
|
{
|
||||||
if (s->ops->sync_tick)
|
if (s->ops->sync_tick)
|
||||||
s->ops->sync_tick(s, s == master);
|
s->ops->sync_tick(s, dahdi_is_sync_master(s));
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
#define dahdi_sync_tick(x) do { ; } while (0)
|
#define dahdi_sync_tick(x) do { ; } while (0)
|
||||||
@ -9521,7 +9520,7 @@ int _dahdi_receive(struct dahdi_span *span)
|
|||||||
spin_unlock(&chan->lock);
|
spin_unlock(&chan->lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (span == master)
|
if (dahdi_is_sync_master(span))
|
||||||
_process_masterspan();
|
_process_masterspan();
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -49,6 +49,292 @@ static struct class_simple *dahdi_class = NULL;
|
|||||||
#define class_destroy class_simple_destroy
|
#define class_destroy class_simple_destroy
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Very old hotplug support
|
||||||
|
*/
|
||||||
|
#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 9)
|
||||||
|
#define OLD_HOTPLUG_SUPPORT /* for older kernels */
|
||||||
|
#define OLD_HOTPLUG_SUPPORT_269
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef OLD_HOTPLUG_SUPPORT_269
|
||||||
|
/* Copy from new kernels lib/kobject_uevent.c */
|
||||||
|
enum kobject_action {
|
||||||
|
KOBJ_ADD,
|
||||||
|
KOBJ_REMOVE,
|
||||||
|
KOBJ_CHANGE,
|
||||||
|
KOBJ_MOUNT,
|
||||||
|
KOBJ_UMOUNT,
|
||||||
|
KOBJ_OFFLINE,
|
||||||
|
KOBJ_ONLINE,
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Hotplug replaced with uevent in 2.6.16
|
||||||
|
*/
|
||||||
|
#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 16)
|
||||||
|
#define OLD_HOTPLUG_SUPPORT /* for older kernels */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 14)
|
||||||
|
#define DEVICE_ATTR_READER(name, dev, buf) \
|
||||||
|
ssize_t name(struct device *dev, struct device_attribute *attr,\
|
||||||
|
char *buf)
|
||||||
|
#define DEVICE_ATTR_WRITER(name, dev, buf, count) \
|
||||||
|
ssize_t name(struct device *dev, struct device_attribute *attr,\
|
||||||
|
const char *buf, size_t count)
|
||||||
|
#define BUS_ATTR_READER(name, dev, buf) \
|
||||||
|
ssize_t name(struct device *dev, struct device_attribute *attr, \
|
||||||
|
char *buf)
|
||||||
|
#define BUS_ATTR_WRITER(name, dev, buf, count) \
|
||||||
|
ssize_t name(struct device *dev, struct device_attribute *attr,\
|
||||||
|
const char *buf, size_t count)
|
||||||
|
#else
|
||||||
|
#define DEVICE_ATTR_READER(name, dev, buf) \
|
||||||
|
ssize_t name(struct device *dev, char *buf)
|
||||||
|
#define DEVICE_ATTR_WRITER(name, dev, buf, count) \
|
||||||
|
ssize_t name(struct device *dev, const char *buf, size_t count)
|
||||||
|
#define BUS_ATTR_READER(name, dev, buf) \
|
||||||
|
ssize_t name(struct device *dev, char *buf)
|
||||||
|
#define BUS_ATTR_WRITER(name, dev, buf, count) \
|
||||||
|
ssize_t name(struct device *dev, const char *buf, size_t count)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define DRIVER_ATTR_READER(name, drv, buf) \
|
||||||
|
ssize_t name(struct device_driver *drv, char * buf)
|
||||||
|
|
||||||
|
|
||||||
|
static char *initdir = "/usr/share/dahdi";
|
||||||
|
module_param(initdir, charp, 0644);
|
||||||
|
|
||||||
|
static int span_match(struct device *dev, struct device_driver *driver)
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline struct dahdi_span *dev_to_span(struct device *dev)
|
||||||
|
{
|
||||||
|
return dev_get_drvdata(dev);
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef OLD_HOTPLUG_SUPPORT
|
||||||
|
static int span_hotplug(struct device *dev, char **envp, int envnum,
|
||||||
|
char *buff, int bufsize)
|
||||||
|
{
|
||||||
|
struct dahdi_span *span;
|
||||||
|
|
||||||
|
if (!dev)
|
||||||
|
return -ENODEV;
|
||||||
|
span = dev_to_span(dev);
|
||||||
|
envp[0] = buff;
|
||||||
|
if (snprintf(buff, bufsize, "SPAN_NAME=%s", span->name) >= bufsize)
|
||||||
|
return -ENOMEM;
|
||||||
|
envp[1] = NULL;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
|
||||||
|
#define SPAN_VAR_BLOCK \
|
||||||
|
do { \
|
||||||
|
DAHDI_ADD_UEVENT_VAR("DAHDI_INIT_DIR=%s", initdir); \
|
||||||
|
DAHDI_ADD_UEVENT_VAR("SPAN_NUM=%d", span->spanno); \
|
||||||
|
DAHDI_ADD_UEVENT_VAR("SPAN_NAME=%s", span->name); \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 24)
|
||||||
|
#define DAHDI_ADD_UEVENT_VAR(fmt, val...) \
|
||||||
|
do { \
|
||||||
|
int err = add_uevent_var(envp, num_envp, &i, \
|
||||||
|
buffer, buffer_size, &len, \
|
||||||
|
fmt, val); \
|
||||||
|
if (err) \
|
||||||
|
return err; \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 26)
|
||||||
|
#define dev_name(dev) ((dev)->bus_id)
|
||||||
|
#define dev_set_name(dev, format, ...) \
|
||||||
|
snprintf((dev)->bus_id, BUS_ID_SIZE, format, ## __VA_ARGS__);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static int span_uevent(struct device *dev, char **envp, int num_envp,
|
||||||
|
char *buffer, int buffer_size)
|
||||||
|
{
|
||||||
|
struct dahdi_span *span;
|
||||||
|
int i = 0;
|
||||||
|
int len = 0;
|
||||||
|
|
||||||
|
if (!dev)
|
||||||
|
return -ENODEV;
|
||||||
|
|
||||||
|
span = dev_to_span(dev);
|
||||||
|
if (!span)
|
||||||
|
return -ENODEV;
|
||||||
|
|
||||||
|
dahdi_dbg(GENERAL, "SYFS dev_name=%s span=%s\n",
|
||||||
|
dev_name(dev), span->name);
|
||||||
|
SPAN_VAR_BLOCK;
|
||||||
|
envp[i] = NULL;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
#define DAHDI_ADD_UEVENT_VAR(fmt, val...) \
|
||||||
|
do { \
|
||||||
|
int err = add_uevent_var(kenv, fmt, val); \
|
||||||
|
if (err) \
|
||||||
|
return err; \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
static int span_uevent(struct device *dev, struct kobj_uevent_env *kenv)
|
||||||
|
{
|
||||||
|
struct dahdi_span *span;
|
||||||
|
|
||||||
|
if (!dev)
|
||||||
|
return -ENODEV;
|
||||||
|
span = dev_to_span(dev);
|
||||||
|
if (!span)
|
||||||
|
return -ENODEV;
|
||||||
|
dahdi_dbg(GENERAL, "SYFS dev_name=%s span=%s\n",
|
||||||
|
dev_name(dev), span->name);
|
||||||
|
SPAN_VAR_BLOCK;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* OLD_HOTPLUG_SUPPORT */
|
||||||
|
|
||||||
|
#define span_attr(field, format_string) \
|
||||||
|
static BUS_ATTR_READER(field##_show, dev, buf) \
|
||||||
|
{ \
|
||||||
|
struct dahdi_span *span; \
|
||||||
|
\
|
||||||
|
span = dev_to_span(dev); \
|
||||||
|
return sprintf(buf, format_string, span->field); \
|
||||||
|
}
|
||||||
|
|
||||||
|
span_attr(name, "%s\n");
|
||||||
|
span_attr(desc, "%s\n");
|
||||||
|
span_attr(spantype, "%s\n");
|
||||||
|
span_attr(offset, "%d\n");
|
||||||
|
span_attr(alarms, "0x%x\n");
|
||||||
|
span_attr(irq, "%d\n");
|
||||||
|
span_attr(irqmisses, "%d\n");
|
||||||
|
span_attr(lbo, "%d\n");
|
||||||
|
span_attr(syncsrc, "%d\n");
|
||||||
|
|
||||||
|
static BUS_ATTR_READER(is_digital_show, dev, buf)
|
||||||
|
{
|
||||||
|
struct dahdi_span *span;
|
||||||
|
|
||||||
|
span = dev_to_span(dev);
|
||||||
|
return sprintf(buf, "%d\n", dahdi_is_digital_span(span));
|
||||||
|
}
|
||||||
|
|
||||||
|
static BUS_ATTR_READER(is_sync_master_show, dev, buf)
|
||||||
|
{
|
||||||
|
struct dahdi_span *span;
|
||||||
|
|
||||||
|
span = dev_to_span(dev);
|
||||||
|
return sprintf(buf, "%d\n", dahdi_is_sync_master(span));
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct device_attribute span_dev_attrs[] = {
|
||||||
|
__ATTR_RO(name),
|
||||||
|
__ATTR_RO(desc),
|
||||||
|
__ATTR_RO(spantype),
|
||||||
|
__ATTR_RO(offset),
|
||||||
|
__ATTR_RO(alarms),
|
||||||
|
__ATTR_RO(irq),
|
||||||
|
__ATTR_RO(irqmisses),
|
||||||
|
__ATTR_RO(lbo),
|
||||||
|
__ATTR_RO(syncsrc),
|
||||||
|
__ATTR_RO(is_digital),
|
||||||
|
__ATTR_RO(is_sync_master),
|
||||||
|
__ATTR_NULL,
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
static struct driver_attribute dahdi_attrs[] = {
|
||||||
|
__ATTR_NULL,
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct bus_type spans_bus_type = {
|
||||||
|
.name = "dahdi_spans",
|
||||||
|
.match = span_match,
|
||||||
|
#ifdef OLD_HOTPLUG_SUPPORT
|
||||||
|
.hotplug = span_hotplug,
|
||||||
|
#else
|
||||||
|
.uevent = span_uevent,
|
||||||
|
#endif
|
||||||
|
.dev_attrs = span_dev_attrs,
|
||||||
|
.drv_attrs = dahdi_attrs,
|
||||||
|
};
|
||||||
|
|
||||||
|
static int span_probe(struct device *dev)
|
||||||
|
{
|
||||||
|
struct dahdi_span *span;
|
||||||
|
|
||||||
|
span = dev_to_span(dev);
|
||||||
|
span_dbg(DEVICES, span, "\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int span_remove(struct device *dev)
|
||||||
|
{
|
||||||
|
struct dahdi_span *span;
|
||||||
|
|
||||||
|
span = dev_to_span(dev);
|
||||||
|
span_dbg(DEVICES, span, "\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct device_driver dahdi_driver = {
|
||||||
|
.name = "generic_lowlevel",
|
||||||
|
.bus = &spans_bus_type,
|
||||||
|
.probe = span_probe,
|
||||||
|
.remove = span_remove,
|
||||||
|
#ifndef OLD_HOTPLUG_SUPPORT
|
||||||
|
.owner = THIS_MODULE
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
static void span_uevent_send(struct dahdi_span *span, enum kobject_action act)
|
||||||
|
{
|
||||||
|
struct kobject *kobj;
|
||||||
|
|
||||||
|
kobj = &span->span_device->kobj;
|
||||||
|
span_dbg(DEVICES, span, "SYFS dev_name=%s action=%d\n",
|
||||||
|
dev_name(span->span_device), act);
|
||||||
|
|
||||||
|
#if defined(OLD_HOTPLUG_SUPPORT_269)
|
||||||
|
{
|
||||||
|
/* Copy from new kernels lib/kobject_uevent.c */
|
||||||
|
static const char *const str[] = {
|
||||||
|
[KOBJ_ADD] "add",
|
||||||
|
[KOBJ_REMOVE] "remove",
|
||||||
|
[KOBJ_CHANGE] "change",
|
||||||
|
[KOBJ_MOUNT] "mount",
|
||||||
|
[KOBJ_UMOUNT] "umount",
|
||||||
|
[KOBJ_OFFLINE] "offline",
|
||||||
|
[KOBJ_ONLINE] "online"
|
||||||
|
};
|
||||||
|
kobject_hotplug(str[act], kobj);
|
||||||
|
}
|
||||||
|
#elif defined(OLD_HOTPLUG_SUPPORT)
|
||||||
|
kobject_hotplug(kobj, act);
|
||||||
|
#else
|
||||||
|
kobject_uevent(kobj, act);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
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)
|
int dahdi_register_chardev(struct dahdi_chardev *dev)
|
||||||
{
|
{
|
||||||
@ -78,7 +364,17 @@ EXPORT_SYMBOL(dahdi_unregister_chardev);
|
|||||||
|
|
||||||
void span_sysfs_remove(struct dahdi_span *span)
|
void span_sysfs_remove(struct dahdi_span *span)
|
||||||
{
|
{
|
||||||
|
struct device *span_device;
|
||||||
int x;
|
int x;
|
||||||
|
|
||||||
|
span_dbg(DEVICES, span, "\n");
|
||||||
|
span_device = span->span_device;
|
||||||
|
|
||||||
|
if (!span_device) {
|
||||||
|
WARN_ON(!span_device);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
for (x = 0; x < span->channels; x++) {
|
for (x = 0; x < span->channels; x++) {
|
||||||
struct dahdi_chan *chan = span->chans[x];
|
struct dahdi_chan *chan = span->chans[x];
|
||||||
if (!test_bit(DAHDI_FLAGBIT_DEVFILE, &chan->flags))
|
if (!test_bit(DAHDI_FLAGBIT_DEVFILE, &chan->flags))
|
||||||
@ -88,13 +384,49 @@ void span_sysfs_remove(struct dahdi_span *span)
|
|||||||
MKDEV(DAHDI_MAJOR, chan->channo));
|
MKDEV(DAHDI_MAJOR, chan->channo));
|
||||||
clear_bit(DAHDI_FLAGBIT_DEVFILE, &chan->flags);
|
clear_bit(DAHDI_FLAGBIT_DEVFILE, &chan->flags);
|
||||||
}
|
}
|
||||||
|
if (!dev_get_drvdata(span_device))
|
||||||
|
return;
|
||||||
|
|
||||||
|
/* Grab an extra reference to the device since we'll still want it
|
||||||
|
* after we've unregistered it */
|
||||||
|
|
||||||
|
get_device(span_device);
|
||||||
|
span_uevent_send(span, KOBJ_OFFLINE);
|
||||||
|
device_unregister(span->span_device);
|
||||||
|
dev_set_drvdata(span_device, NULL);
|
||||||
|
span_device->parent = NULL;
|
||||||
|
put_device(span_device);
|
||||||
}
|
}
|
||||||
|
|
||||||
int span_sysfs_create(struct dahdi_span *span)
|
int span_sysfs_create(struct dahdi_span *span)
|
||||||
{
|
{
|
||||||
|
struct device *span_device;
|
||||||
int res = 0;
|
int res = 0;
|
||||||
int x;
|
int x;
|
||||||
|
|
||||||
|
BUG_ON(span->span_device);
|
||||||
|
|
||||||
|
span->span_device = kzalloc(sizeof(*span->span_device), GFP_KERNEL);
|
||||||
|
if (!span->span_device)
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
|
span_device = span->span_device;
|
||||||
|
span_dbg(DEVICES, span, "\n");
|
||||||
|
|
||||||
|
span_device->bus = &spans_bus_type;
|
||||||
|
span_device->parent = span->parent->dev.parent;
|
||||||
|
dev_set_name(span_device, "span-%03d", span->spanno);
|
||||||
|
dev_set_drvdata(span_device, span);
|
||||||
|
span_device->release = span_release;
|
||||||
|
res = device_register(span_device);
|
||||||
|
if (res) {
|
||||||
|
span_err(span, "%s: device_register failed: %d\n", __func__,
|
||||||
|
res);
|
||||||
|
kfree(span->span_device);
|
||||||
|
span->span_device = NULL;
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
for (x = 0; x < span->channels; x++) {
|
for (x = 0; x < span->channels; x++) {
|
||||||
struct dahdi_chan *chan = span->chans[x];
|
struct dahdi_chan *chan = span->chans[x];
|
||||||
char chan_name[32];
|
char chan_name[32];
|
||||||
@ -137,10 +469,13 @@ static struct {
|
|||||||
unsigned int timer:1;
|
unsigned int timer:1;
|
||||||
unsigned int channel:1;
|
unsigned int channel:1;
|
||||||
unsigned int pseudo:1;
|
unsigned int pseudo:1;
|
||||||
|
unsigned int sysfs_driver_registered:1;
|
||||||
|
unsigned int sysfs_spans_bus_type:1;
|
||||||
} dummy_dev;
|
} dummy_dev;
|
||||||
|
|
||||||
void dahdi_sysfs_exit(void)
|
void dahdi_sysfs_exit(void)
|
||||||
{
|
{
|
||||||
|
dahdi_dbg(DEVICES, "SYSFS\n");
|
||||||
if (dummy_dev.pseudo) {
|
if (dummy_dev.pseudo) {
|
||||||
dahdi_dbg(DEVICES, "Removing /dev/dahdi/pseudo:\n");
|
dahdi_dbg(DEVICES, "Removing /dev/dahdi/pseudo:\n");
|
||||||
DEL_DAHDI_DEV(DAHDI_PSEUDO);
|
DEL_DAHDI_DEV(DAHDI_PSEUDO);
|
||||||
@ -166,6 +501,16 @@ void dahdi_sysfs_exit(void)
|
|||||||
class_destroy(dahdi_class);
|
class_destroy(dahdi_class);
|
||||||
dahdi_class = NULL;
|
dahdi_class = NULL;
|
||||||
}
|
}
|
||||||
|
if (dummy_dev.sysfs_driver_registered) {
|
||||||
|
dahdi_dbg(DEVICES, "Unregister driver\n");
|
||||||
|
driver_unregister(&dahdi_driver);
|
||||||
|
dummy_dev.sysfs_driver_registered = 0;
|
||||||
|
}
|
||||||
|
if (dummy_dev.sysfs_spans_bus_type) {
|
||||||
|
dahdi_dbg(DEVICES, "Unregister span bus type\n");
|
||||||
|
bus_unregister(&spans_bus_type);
|
||||||
|
dummy_dev.sysfs_spans_bus_type = 0;
|
||||||
|
}
|
||||||
unregister_chrdev(DAHDI_MAJOR, "dahdi");
|
unregister_chrdev(DAHDI_MAJOR, "dahdi");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -220,6 +565,20 @@ int __init dahdi_sysfs_init(const struct file_operations *dahdi_fops)
|
|||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
dummy_dev.ctl = 1;
|
dummy_dev.ctl = 1;
|
||||||
|
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;
|
||||||
|
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;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
@ -54,6 +54,8 @@
|
|||||||
#include <linux/skbuff.h>
|
#include <linux/skbuff.h>
|
||||||
#include <linux/interrupt.h>
|
#include <linux/interrupt.h>
|
||||||
#endif
|
#endif
|
||||||
|
#include <linux/device.h>
|
||||||
|
#include <linux/sysfs.h>
|
||||||
|
|
||||||
#include <linux/poll.h>
|
#include <linux/poll.h>
|
||||||
|
|
||||||
@ -905,6 +907,7 @@ struct dahdi_device {
|
|||||||
const char *manufacturer;
|
const char *manufacturer;
|
||||||
const char *location;
|
const char *location;
|
||||||
const char *devicetype;
|
const char *devicetype;
|
||||||
|
struct device dev;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct dahdi_span {
|
struct dahdi_span {
|
||||||
@ -954,6 +957,7 @@ struct dahdi_span {
|
|||||||
|
|
||||||
struct dahdi_device *parent;
|
struct dahdi_device *parent;
|
||||||
struct list_head device_node;
|
struct list_head device_node;
|
||||||
|
struct device *span_device;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct dahdi_transcoder_channel {
|
struct dahdi_transcoder_channel {
|
||||||
@ -970,6 +974,8 @@ struct dahdi_transcoder_channel {
|
|||||||
u32 srcfmt;
|
u32 srcfmt;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
int dahdi_is_sync_master(const struct dahdi_span *span);
|
||||||
|
|
||||||
static inline int
|
static inline int
|
||||||
dahdi_tc_is_built(struct dahdi_transcoder_channel *dtc) {
|
dahdi_tc_is_built(struct dahdi_transcoder_channel *dtc) {
|
||||||
return test_bit(DAHDI_TC_FLAG_CHAN_BUILT, &dtc->flags);
|
return test_bit(DAHDI_TC_FLAG_CHAN_BUILT, &dtc->flags);
|
||||||
|
Loading…
Reference in New Issue
Block a user