dahdi: Remove arbitrary limit on number of spans in the kernel.
Spans are no longer added to a static array, but they are chained together in a list. DAHDI_MAX_SPANS, while no longer used in the kernel, is still in include/dahdi/user.h since dahdi tools is currently using it. Signed-off-by: Shaun Ruffell <sruffell@digium.com> Acked-by: Kinsey Moore <kmoore@digium.com> git-svn-id: http://svn.asterisk.org/svn/dahdi/linux/trunk@9598 a0bf4364-ded3-4de4-8d8a-66a801d63aff
This commit is contained in:
parent
7a6d71f35c
commit
800c356cf3
@ -471,11 +471,10 @@ static bool valid_channo(const int channo)
|
|||||||
false : true;
|
false : true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Protected by chan_lock. */
|
static DEFINE_MUTEX(registration_mutex);
|
||||||
static struct dahdi_span *spans[DAHDI_MAX_SPANS];
|
static LIST_HEAD(span_list);
|
||||||
static struct dahdi_chan *chans[DAHDI_MAX_CHANNELS];
|
|
||||||
|
|
||||||
static int maxspans = 0;
|
static struct dahdi_chan *chans[DAHDI_MAX_CHANNELS];
|
||||||
|
|
||||||
static inline struct dahdi_chan *chan_from_num(unsigned int channo)
|
static inline struct dahdi_chan *chan_from_num(unsigned int channo)
|
||||||
{
|
{
|
||||||
@ -488,6 +487,22 @@ static inline struct dahdi_chan *chan_from_file(struct file *file)
|
|||||||
file->private_data : chan_from_num(UNIT(file));
|
file->private_data : chan_from_num(UNIT(file));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* _find_span() - Find a span by span number.
|
||||||
|
*
|
||||||
|
* Must be called with registration_lock held.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
static struct dahdi_span *_find_span(int spanno)
|
||||||
|
{
|
||||||
|
struct dahdi_span *s;
|
||||||
|
list_for_each_entry(s, &span_list, node) {
|
||||||
|
if (s->spanno == spanno) {
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
/**
|
/**
|
||||||
* span_find_and_get() - Search for the span by number, and if found take out
|
* span_find_and_get() - Search for the span by number, and if found take out
|
||||||
* a reference on it.
|
* a reference on it.
|
||||||
@ -498,15 +513,14 @@ static inline struct dahdi_chan *chan_from_file(struct file *file)
|
|||||||
*/
|
*/
|
||||||
static struct dahdi_span *span_find_and_get(int spanno)
|
static struct dahdi_span *span_find_and_get(int spanno)
|
||||||
{
|
{
|
||||||
unsigned long flags;
|
struct dahdi_span *found;
|
||||||
struct dahdi_span *span;
|
|
||||||
|
|
||||||
spin_lock_irqsave(&chan_lock, flags);
|
mutex_lock(®istration_mutex);
|
||||||
span = (spanno > 0 && spanno < DAHDI_MAX_SPANS) ? spans[spanno] : NULL;
|
found = _find_span(spanno);
|
||||||
if (likely(span && !try_module_get(span->ops->owner)))
|
if (found && !try_module_get(found->ops->owner))
|
||||||
span = NULL;
|
found = NULL;
|
||||||
spin_unlock_irqrestore(&chan_lock, flags);
|
mutex_unlock(®istration_mutex);
|
||||||
return span;
|
return found;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void put_span(struct dahdi_span *span)
|
static void put_span(struct dahdi_span *span)
|
||||||
@ -514,9 +528,16 @@ static void put_span(struct dahdi_span *span)
|
|||||||
module_put(span->ops->owner);
|
module_put(span->ops->owner);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline unsigned int span_count(void)
|
static unsigned int span_count(void)
|
||||||
{
|
{
|
||||||
return maxspans;
|
unsigned int count = 0;
|
||||||
|
struct dahdi_span *s;
|
||||||
|
unsigned long flags;
|
||||||
|
spin_lock_irqsave(&chan_lock, flags);
|
||||||
|
list_for_each_entry(s, &span_list, node)
|
||||||
|
++count;
|
||||||
|
spin_unlock_irqrestore(&chan_lock, flags);
|
||||||
|
return count;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline bool can_provide_timing(const struct dahdi_span *const s)
|
static inline bool can_provide_timing(const struct dahdi_span *const s)
|
||||||
@ -2905,7 +2926,7 @@ static int can_open_timer(void)
|
|||||||
#ifdef CONFIG_DAHDI_CORE_TIMER
|
#ifdef CONFIG_DAHDI_CORE_TIMER
|
||||||
return 1;
|
return 1;
|
||||||
#else
|
#else
|
||||||
return maxspans > 0;
|
return (list_empty(&span_list)) ? 0 : 1;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3551,6 +3572,7 @@ void dahdi_alarm_channel(struct dahdi_chan *chan, int alarms)
|
|||||||
void dahdi_alarm_notify(struct dahdi_span *span)
|
void dahdi_alarm_notify(struct dahdi_span *span)
|
||||||
{
|
{
|
||||||
int x;
|
int x;
|
||||||
|
unsigned long flags;
|
||||||
|
|
||||||
span->alarms &= ~DAHDI_ALARM_LOOPBACK;
|
span->alarms &= ~DAHDI_ALARM_LOOPBACK;
|
||||||
/* Determine maint status */
|
/* Determine maint status */
|
||||||
@ -3561,15 +3583,14 @@ void dahdi_alarm_notify(struct dahdi_span *span)
|
|||||||
as ((!a) != (!b)) */
|
as ((!a) != (!b)) */
|
||||||
/* if change in general state */
|
/* if change in general state */
|
||||||
if ((!span->alarms) != (!span->lastalarms)) {
|
if ((!span->alarms) != (!span->lastalarms)) {
|
||||||
|
struct dahdi_span *s;
|
||||||
span->lastalarms = span->alarms;
|
span->lastalarms = span->alarms;
|
||||||
for (x = 0; x < span->channels; x++)
|
for (x = 0; x < span->channels; x++)
|
||||||
dahdi_alarm_channel(span->chans[x], span->alarms);
|
dahdi_alarm_channel(span->chans[x], span->alarms);
|
||||||
|
|
||||||
/* Switch to other master if current master in alarm */
|
/* Switch to other master if current master in alarm */
|
||||||
for (x=1; x<maxspans; x++) {
|
spin_lock_irqsave(&chan_lock, flags);
|
||||||
struct dahdi_span *const s = spans[x];
|
list_for_each_entry(s, &span_list, node) {
|
||||||
if (!s)
|
|
||||||
continue;
|
|
||||||
if (s->alarms)
|
if (s->alarms)
|
||||||
continue;
|
continue;
|
||||||
if (!test_bit(DAHDI_FLAGBIT_RUNNING, &s->flags))
|
if (!test_bit(DAHDI_FLAGBIT_RUNNING, &s->flags))
|
||||||
@ -3587,6 +3608,7 @@ void dahdi_alarm_notify(struct dahdi_span *span)
|
|||||||
master = s;
|
master = s;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
spin_unlock_irqrestore(&chan_lock, flags);
|
||||||
|
|
||||||
/* Report more detailed alarms */
|
/* Report more detailed alarms */
|
||||||
if (debug & DEBUG_MAIN) {
|
if (debug & DEBUG_MAIN) {
|
||||||
@ -6220,70 +6242,43 @@ static long dahdi_ioctl_compat(struct file *file, unsigned int cmd,
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
static int _dahdi_register(struct dahdi_span *span, int prefmaster)
|
||||||
* dahdi_register() - unregister a new DAHDI span
|
|
||||||
* @span: the DAHDI span
|
|
||||||
* @prefmaster: will the new span be preferred as a master?
|
|
||||||
*
|
|
||||||
* Registers a span for usage with DAHDI. All the channel numbers in it
|
|
||||||
* will get the lowest available channel numbers.
|
|
||||||
*
|
|
||||||
* If prefmaster is set to anything > 0, span will attempt to become the
|
|
||||||
* master DAHDI span at registration time. If 0: it will only become
|
|
||||||
* master if no other span is currently the master (i.e.: it is the
|
|
||||||
* first one).
|
|
||||||
*/
|
|
||||||
int dahdi_register(struct dahdi_span *span, int prefmaster)
|
|
||||||
{
|
{
|
||||||
int x;
|
unsigned int spanno;
|
||||||
|
unsigned int x;
|
||||||
int res = 0;
|
int res = 0;
|
||||||
int spanno;
|
struct list_head *loc = &span_list;
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
|
|
||||||
if (!span)
|
if (!span || !span->ops || !span->ops->owner)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
if (!span->ops)
|
|
||||||
return -EINVAL;
|
|
||||||
|
|
||||||
if (!span->ops->owner)
|
|
||||||
return -EINVAL;
|
|
||||||
|
|
||||||
|
|
||||||
if (test_bit(DAHDI_FLAGBIT_REGISTERED, &span->flags)) {
|
|
||||||
module_printk(KERN_ERR, "Span %s already appears to be registered\n", span->name);
|
|
||||||
return -EBUSY;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (x = 1; x < maxspans; x++) {
|
|
||||||
if (spans[x] == span) {
|
|
||||||
module_printk(KERN_ERR, "Span %s already in list\n", span->name);
|
|
||||||
return -EBUSY;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (x = 1; x < DAHDI_MAX_SPANS; x++) {
|
|
||||||
if (!spans[x])
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (x < DAHDI_MAX_SPANS) {
|
|
||||||
spanno = x;
|
|
||||||
} else {
|
|
||||||
module_printk(KERN_ERR, "Too many DAHDI spans registered\n");
|
|
||||||
return -EBUSY;
|
|
||||||
}
|
|
||||||
|
|
||||||
span->spanno = x;
|
|
||||||
|
|
||||||
spin_lock_init(&span->lock);
|
|
||||||
|
|
||||||
if (!span->deflaw) {
|
if (!span->deflaw) {
|
||||||
module_printk(KERN_NOTICE, "Span %s didn't specify default law. "
|
module_printk(KERN_NOTICE, "Span %s didn't specify default law. "
|
||||||
"Assuming mulaw, please fix driver!\n", span->name);
|
"Assuming mulaw, please fix driver!\n", span->name);
|
||||||
span->deflaw = DAHDI_LAW_MULAW;
|
span->deflaw = DAHDI_LAW_MULAW;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
spin_lock_init(&span->lock);
|
||||||
|
|
||||||
|
spanno = 1;
|
||||||
|
|
||||||
|
/* Look through the span list to find the first available span number.
|
||||||
|
* The spans are kept on this list in sorted order. */
|
||||||
|
if (!list_empty(&span_list)) {
|
||||||
|
struct dahdi_span *pos;
|
||||||
|
list_for_each_entry(pos, &span_list, node) {
|
||||||
|
loc = &pos->node;
|
||||||
|
if (pos->spanno == spanno) {
|
||||||
|
++spanno;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
span->spanno = spanno;
|
||||||
for (x = 0; x < span->channels; x++) {
|
for (x = 0; x < span->channels; x++) {
|
||||||
span->chans[x]->span = span;
|
span->chans[x]->span = span;
|
||||||
res = dahdi_chan_reg(span->chans[x]);
|
res = dahdi_chan_reg(span->chans[x]);
|
||||||
@ -6297,9 +6292,9 @@ int dahdi_register(struct dahdi_span *span, int prefmaster)
|
|||||||
#ifdef CONFIG_PROC_FS
|
#ifdef CONFIG_PROC_FS
|
||||||
{
|
{
|
||||||
char tempfile[17];
|
char tempfile[17];
|
||||||
snprintf(tempfile, sizeof(tempfile), "dahdi/%d", span->spanno);
|
snprintf(tempfile, sizeof(tempfile), "%d", span->spanno);
|
||||||
span->proc_entry = create_proc_read_entry(tempfile, 0444,
|
span->proc_entry = create_proc_read_entry(tempfile, 0444,
|
||||||
NULL, dahdi_proc_read,
|
root_proc_entry, dahdi_proc_read,
|
||||||
(int *) (long) span->spanno);
|
(int *) (long) span->spanno);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@ -6328,61 +6323,64 @@ int dahdi_register(struct dahdi_span *span, int prefmaster)
|
|||||||
}
|
}
|
||||||
|
|
||||||
spin_lock_irqsave(&chan_lock, flags);
|
spin_lock_irqsave(&chan_lock, flags);
|
||||||
spans[spanno] = span;
|
list_add(&span->node, loc);
|
||||||
if (maxspans < x + 1)
|
|
||||||
maxspans = x + 1;
|
|
||||||
spin_unlock_irqrestore(&chan_lock, flags);
|
spin_unlock_irqrestore(&chan_lock, flags);
|
||||||
set_bit(DAHDI_FLAGBIT_REGISTERED, &span->flags);
|
set_bit(DAHDI_FLAGBIT_REGISTERED, &span->flags);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
unreg_channels:
|
unreg_channels:
|
||||||
spans[span->spanno] = NULL;
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* dahdi_unregister() - unregister a DAHDI span
|
* dahdi_register() - unregister a new DAHDI span
|
||||||
* @span: the DAHDI span
|
* @span: the DAHDI span
|
||||||
|
* @prefmaster: will the new span be preferred as a master?
|
||||||
|
*
|
||||||
|
* Registers a span for usage with DAHDI. All the channel numbers in it
|
||||||
|
* will get the lowest available channel numbers.
|
||||||
|
*
|
||||||
|
* If prefmaster is set to anything > 0, span will attempt to become the
|
||||||
|
* master DAHDI span at registration time. If 0: it will only become
|
||||||
|
* master if no other span is currently the master (i.e.: it is the
|
||||||
|
* first one).
|
||||||
*
|
*
|
||||||
* Unregisters a span that has been previously registered with
|
|
||||||
* dahdi_register().
|
|
||||||
*/
|
*/
|
||||||
int dahdi_unregister(struct dahdi_span *span)
|
int dahdi_register(struct dahdi_span *span, int prefmaster)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
mutex_lock(®istration_mutex);
|
||||||
|
ret = _dahdi_register(span, prefmaster);
|
||||||
|
mutex_unlock(®istration_mutex);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int _dahdi_unregister(struct dahdi_span *span)
|
||||||
{
|
{
|
||||||
int x;
|
int x;
|
||||||
|
struct dahdi_span *new_master, *s;
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
|
|
||||||
#ifdef CONFIG_PROC_FS
|
if (span != _find_span(span->spanno)) {
|
||||||
char tempfile[17];
|
|
||||||
#endif /* CONFIG_PROC_FS */
|
|
||||||
|
|
||||||
if (!test_bit(DAHDI_FLAGBIT_REGISTERED, &span->flags)) {
|
|
||||||
module_printk(KERN_ERR, "Span %s does not appear to be registered\n", span->name);
|
module_printk(KERN_ERR, "Span %s does not appear to be registered\n", span->name);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Shutdown the span if it's running */
|
|
||||||
if (span->flags & DAHDI_FLAG_RUNNING)
|
|
||||||
if (span->ops->shutdown)
|
|
||||||
span->ops->shutdown(span);
|
|
||||||
|
|
||||||
if (spans[span->spanno] != span) {
|
|
||||||
module_printk(KERN_ERR, "Span %s has spanno %d which is something else\n", span->name, span->spanno);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
clear_bit(DAHDI_FLAGBIT_REGISTERED, &span->flags);
|
|
||||||
spin_lock_irqsave(&chan_lock, flags);
|
spin_lock_irqsave(&chan_lock, flags);
|
||||||
spans[span->spanno] = NULL;
|
list_del_init(&span->node);
|
||||||
spin_unlock_irqrestore(&chan_lock, flags);
|
spin_unlock_irqrestore(&chan_lock, flags);
|
||||||
|
span->spanno = 0;
|
||||||
|
clear_bit(DAHDI_FLAGBIT_REGISTERED, &span->flags);
|
||||||
|
|
||||||
|
/* Shutdown the span if it's running */
|
||||||
|
if ((span->flags & DAHDI_FLAG_RUNNING) && span->ops->shutdown)
|
||||||
|
span->ops->shutdown(span);
|
||||||
|
|
||||||
if (debug & DEBUG_MAIN)
|
if (debug & DEBUG_MAIN)
|
||||||
module_printk(KERN_NOTICE, "Unregistering Span '%s' with %d channels\n", span->name, span->channels);
|
module_printk(KERN_NOTICE, "Unregistering Span '%s' with %d channels\n", span->name, span->channels);
|
||||||
#ifdef CONFIG_PROC_FS
|
#ifdef CONFIG_PROC_FS
|
||||||
snprintf(tempfile, sizeof(tempfile)-1, "dahdi/%d", span->spanno);
|
remove_proc_entry(span->proc_entry->name, root_proc_entry);
|
||||||
remove_proc_entry(tempfile, NULL);
|
|
||||||
#endif /* CONFIG_PROC_FS */
|
#endif /* CONFIG_PROC_FS */
|
||||||
|
|
||||||
for (x = 0; x < span->channels; x++) {
|
for (x = 0; x < span->channels; x++) {
|
||||||
@ -6393,37 +6391,44 @@ int dahdi_unregister(struct dahdi_span *span)
|
|||||||
for (x=0;x<span->channels;x++)
|
for (x=0;x<span->channels;x++)
|
||||||
dahdi_chan_unreg(span->chans[x]);
|
dahdi_chan_unreg(span->chans[x]);
|
||||||
|
|
||||||
if (master == span) {
|
new_master = master; /* FIXME: locking */
|
||||||
struct dahdi_span *new_master = NULL;
|
if (master == span)
|
||||||
int new_maxspans = 0;
|
new_master = NULL;
|
||||||
|
|
||||||
spin_lock_irqsave(&chan_lock, flags);
|
spin_lock_irqsave(&chan_lock, flags);
|
||||||
for (x = 1; x < DAHDI_MAX_SPANS; x++) {
|
list_for_each_entry(s, &span_list, node) {
|
||||||
struct dahdi_span *const cur = spans[x];
|
if ((s == new_master) || !can_provide_timing(s))
|
||||||
if (!cur)
|
|
||||||
continue;
|
continue;
|
||||||
|
new_master = s;
|
||||||
new_maxspans = x;
|
|
||||||
if (can_provide_timing(cur)) {
|
|
||||||
new_master = cur;
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
maxspans = new_maxspans;
|
|
||||||
spin_unlock_irqrestore(&chan_lock, flags);
|
spin_unlock_irqrestore(&chan_lock, flags);
|
||||||
|
if (master != new_master) {
|
||||||
if (debug & DEBUG_MAIN) {
|
if (debug & DEBUG_MAIN) {
|
||||||
module_printk(KERN_NOTICE, "%s: Span ('%s') is new "
|
module_printk(KERN_NOTICE, "%s: Span ('%s') is new master\n", __FUNCTION__,
|
||||||
"master\n", __func__,
|
(new_master)? new_master->name: "no master");
|
||||||
(new_master) ? new_master->name :
|
}
|
||||||
"no master");
|
|
||||||
}
|
}
|
||||||
master = new_master;
|
master = new_master;
|
||||||
}
|
|
||||||
span->spanno = 0;
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* dahdi_unregister() - unregister a DAHDI span
|
||||||
|
* @span: the DAHDI span
|
||||||
|
*
|
||||||
|
* Unregisters a span that has been previously registered with
|
||||||
|
* dahdi_register().
|
||||||
|
*/
|
||||||
|
int dahdi_unregister(struct dahdi_span *span)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
mutex_lock(®istration_mutex);
|
||||||
|
ret = _dahdi_unregister(span);
|
||||||
|
mutex_unlock(®istration_mutex);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** This routine converts from linear to ulaw
|
** This routine converts from linear to ulaw
|
||||||
**
|
**
|
||||||
@ -8631,8 +8636,7 @@ static inline void dahdi_sync_tick(struct dahdi_span *const s)
|
|||||||
static void process_masterspan(void)
|
static void process_masterspan(void)
|
||||||
{
|
{
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
int x, y;
|
int x;
|
||||||
struct dahdi_chan *chan;
|
|
||||||
struct pseudo_chan *pseudo;
|
struct pseudo_chan *pseudo;
|
||||||
struct dahdi_span *s;
|
struct dahdi_span *s;
|
||||||
u_char *data;
|
u_char *data;
|
||||||
@ -8651,12 +8655,9 @@ static void process_masterspan(void)
|
|||||||
/* Process any timers */
|
/* Process any timers */
|
||||||
process_timers();
|
process_timers();
|
||||||
|
|
||||||
for (y = 1; y < maxspans; ++y) {
|
list_for_each_entry(s, &span_list, node) {
|
||||||
s = spans[y];
|
for (x = 0; x < s->channels; ++x) {
|
||||||
if (!s)
|
struct dahdi_chan *const chan = s->chans[x];
|
||||||
continue;
|
|
||||||
for (x = 0; x < s->channels; x++) {
|
|
||||||
chan = s->chans[x];
|
|
||||||
if (!chan->confmode)
|
if (!chan->confmode)
|
||||||
continue;
|
continue;
|
||||||
spin_lock(&chan->lock);
|
spin_lock(&chan->lock);
|
||||||
@ -8684,12 +8685,9 @@ static void process_masterspan(void)
|
|||||||
pseudo_rx_audio(&pseudo->chan);
|
pseudo_rx_audio(&pseudo->chan);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (y = 1; y < maxspans; ++y) {
|
list_for_each_entry(s, &span_list, node) {
|
||||||
s = spans[y];
|
|
||||||
if (!s)
|
|
||||||
continue;
|
|
||||||
for (x = 0; x < s->channels; x++) {
|
for (x = 0; x < s->channels; x++) {
|
||||||
chan = s->chans[x];
|
struct dahdi_chan *const chan = s->chans[x];
|
||||||
if (!chan->confmode)
|
if (!chan->confmode)
|
||||||
continue;
|
continue;
|
||||||
spin_lock(&chan->lock);
|
spin_lock(&chan->lock);
|
||||||
@ -8979,14 +8977,13 @@ static struct timer_list watchdogtimer;
|
|||||||
|
|
||||||
static void watchdog_check(unsigned long ignored)
|
static void watchdog_check(unsigned long ignored)
|
||||||
{
|
{
|
||||||
int x;
|
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
static int wdcheck=0;
|
static int wdcheck=0;
|
||||||
|
struct dahdi_span *s;
|
||||||
|
|
||||||
local_irq_save(flags);
|
spin_lock_irqsave(&span_list_lock, flags);
|
||||||
for (x=0;x<maxspans;x++) {
|
list_for_each_entry(s, &span_list, node) {
|
||||||
s = spans[x];
|
if (s->flags & DAHDI_FLAG_RUNNING) {
|
||||||
if (s && (s->flags & DAHDI_FLAG_RUNNING)) {
|
|
||||||
if (s->watchcounter == DAHDI_WATCHDOG_INIT) {
|
if (s->watchcounter == DAHDI_WATCHDOG_INIT) {
|
||||||
/* Whoops, dead card */
|
/* Whoops, dead card */
|
||||||
if ((s->watchstate == DAHDI_WATCHSTATE_OK) ||
|
if ((s->watchstate == DAHDI_WATCHSTATE_OK) ||
|
||||||
@ -9009,7 +9006,7 @@ static void watchdog_check(unsigned long ignored)
|
|||||||
s->watchcounter = DAHDI_WATCHDOG_INIT;
|
s->watchcounter = DAHDI_WATCHDOG_INIT;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
local_irq_restore(flags);
|
spin_unlock_irqrestore(&span_list_lock, flags);
|
||||||
if (!wdcheck) {
|
if (!wdcheck) {
|
||||||
module_printk(KERN_NOTICE, "watchdog on duty!\n");
|
module_printk(KERN_NOTICE, "watchdog on duty!\n");
|
||||||
wdcheck=1;
|
wdcheck=1;
|
||||||
@ -9137,7 +9134,7 @@ static void __exit dahdi_cleanup(void)
|
|||||||
unregister_chrdev(DAHDI_MAJOR, "dahdi");
|
unregister_chrdev(DAHDI_MAJOR, "dahdi");
|
||||||
|
|
||||||
#ifdef CONFIG_PROC_FS
|
#ifdef CONFIG_PROC_FS
|
||||||
remove_proc_entry("dahdi", NULL);
|
remove_proc_entry(root_proc_entry->name, NULL);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
module_printk(KERN_INFO, "Telephony Interface Unloaded\n");
|
module_printk(KERN_INFO, "Telephony Interface Unloaded\n");
|
||||||
|
@ -898,6 +898,7 @@ struct dahdi_span {
|
|||||||
#ifdef CONFIG_PROC_FS
|
#ifdef CONFIG_PROC_FS
|
||||||
struct proc_dir_entry *proc_entry;
|
struct proc_dir_entry *proc_entry;
|
||||||
#endif
|
#endif
|
||||||
|
struct list_head node;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct dahdi_transcoder_channel {
|
struct dahdi_transcoder_channel {
|
||||||
|
Loading…
Reference in New Issue
Block a user