[svn-commits] sruffell: branch linux/sruffell/chan_list r9335 - in /linux/team/sruffell/cha...
SVN commits to the Digium repositories
svn-commits at lists.digium.com
Fri Sep 17 14:11:40 CDT 2010
Author: sruffell
Date: Fri Sep 17 14:11:36 2010
New Revision: 9335
URL: http://svnview.digium.com/svn/dahdi?view=rev&rev=9335
Log:
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 at digium.com>
Modified:
linux/team/sruffell/chan_list/drivers/dahdi/dahdi-base.c
linux/team/sruffell/chan_list/include/dahdi/kernel.h
Modified: linux/team/sruffell/chan_list/drivers/dahdi/dahdi-base.c
URL: http://svnview.digium.com/svn/dahdi/linux/team/sruffell/chan_list/drivers/dahdi/dahdi-base.c?view=diff&rev=9335&r1=9334&r2=9335
==============================================================================
--- linux/team/sruffell/chan_list/drivers/dahdi/dahdi-base.c (original)
+++ linux/team/sruffell/chan_list/drivers/dahdi/dahdi-base.c Fri Sep 17 14:11:36 2010
@@ -437,11 +437,9 @@
false : true;
}
-/* Protected by chan_lock. */
-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 inline struct dahdi_chan *chan_from_num(unsigned int channo)
{
@@ -456,12 +454,30 @@
static struct dahdi_span *find_span(int spanno)
{
- return (spanno > 0 && spanno < DAHDI_MAX_SPANS) ? spans[spanno] : NULL;
-}
-
-static inline unsigned int span_count(void)
-{
- return maxspans;
+ struct dahdi_span *found = NULL;
+ struct dahdi_span *s;
+ unsigned long flags;
+ read_lock_irqsave(&chan_lock, flags);
+ list_for_each_entry(s, &span_list, node) {
+ if (s->spanno == spanno) {
+ found = s;
+ break;
+ }
+ }
+ read_unlock_irqrestore(&chan_lock, flags);
+ return found;
+}
+
+static unsigned int span_count(void)
+{
+ unsigned int count = 0;
+ struct dahdi_span *s;
+ unsigned long flags;
+ read_lock_irqsave(&chan_lock, flags);
+ list_for_each_entry(s, &span_list, node)
+ ++count;
+ read_unlock_irqrestore(&chan_lock, flags);
+ return count;
}
static int maxchans = 0;
@@ -737,8 +753,6 @@
return 0;
s = find_span(spanno);
- if (!s)
- return -ENODEV;
if (s->name)
len += snprintf(page + len, count - len, "Span %d: %s ",
@@ -2918,9 +2932,11 @@
#ifdef CONFIG_DAHDI_CORE_TIMER
return 1;
#else
- return maxspans > 0;
-#endif
-}
+ return (list_empty(&span_list)) ? 0 : 1;
+#endif
+}
+
+static DECLARE_MUTEX(registration_lock);
static struct dahdi_chan *dahdi_alloc_pseudo(void)
{
@@ -3569,6 +3585,7 @@
void dahdi_alarm_notify(struct dahdi_span *span)
{
int x;
+ unsigned long flags;
span->alarms &= ~DAHDI_ALARM_LOOPBACK;
/* Determine maint status */
@@ -3579,23 +3596,28 @@
as ((!a) != (!b)) */
/* if change in general state */
if ((!span->alarms) != (!span->lastalarms)) {
+ struct dahdi_span *s;
span->lastalarms = span->alarms;
for (x = 0; x < span->channels; x++)
dahdi_alarm_channel(span->chans[x], span->alarms);
/* Switch to other master if current master in alarm */
- for (x=1; x<maxspans; x++) {
- struct dahdi_span *const s = spans[x];
- if (s && !s->alarms && (s->flags & DAHDI_FLAG_RUNNING)) {
- if (master != s) {
- module_printk(KERN_NOTICE,
- "Master changed to %s\n",
- s->name);
- }
- master = s;
- break;
- }
- }
+ read_lock_irqsave(&chan_lock, flags);
+ list_for_each_entry(s, &span_list, node) {
+ if (s->alarms)
+ continue;
+ if (!test_bit(DAHDI_FLAGBIT_RUNNING, &s->flags))
+ continue;
+ if (master == s)
+ continue;
+
+ module_printk(KERN_NOTICE,
+ "Master changed to %s\n", s->name);
+ master = s;
+ break;
+ }
+ read_unlock_irqrestore(&chan_lock, flags);
+
/* Report more detailed alarms */
if (debug) {
if (span->alarms & DAHDI_ALARM_LOS) {
@@ -6144,6 +6166,24 @@
}
#endif
+static bool is_span_registered(const struct dahdi_span *const span)
+{
+ unsigned long flags;
+ struct dahdi_span *pos;
+ bool registered = false;
+
+ read_lock_irqsave(&chan_lock, flags);
+ list_for_each_entry(pos, &span_list, node) {
+ if (likely(pos != span))
+ continue;
+
+ registered = true;
+ break;
+ }
+ read_unlock_irqrestore(&chan_lock, flags);
+ return registered;
+}
+
/**
* dahdi_register() - unregister a new DAHDI span
* @span: the DAHDI span
@@ -6156,52 +6196,18 @@
* 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;
-
- if (!span)
+ struct list_head *loc = &span_list;
+ unsigned long flags;
+
+ if (!span || !span->ops || !span->ops->owner)
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) {
- spans[x] = span;
- if (maxspans < x + 1)
- maxspans = x + 1;
- } else {
- module_printk(KERN_ERR, "Too many DAHDI spans registered\n");
- return -EBUSY;
- }
-
- set_bit(DAHDI_FLAGBIT_REGISTERED, &span->flags);
- span->spanno = x;
-
- spin_lock_init(&span->lock);
if (!span->deflaw) {
module_printk(KERN_NOTICE, "Span %s didn't specify default law. "
@@ -6209,6 +6215,37 @@
span->deflaw = DAHDI_LAW_MULAW;
}
+ down(®istration_lock);
+
+ if (unlikely(is_span_registered(span))) {
+ module_printk(KERN_ERR, "Span %s already registered.\n",
+ span->name);
+ up(®istration_lock);
+ return -EBUSY;
+ }
+
+ INIT_LIST_HEAD(&span->node);
+ 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. */
+ read_lock_irqsave(&chan_lock, flags);
+ 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;
+ }
+ }
+ read_unlock_irqrestore(&chan_lock, flags);
+
+ span->spanno = spanno;
for (x = 0; x < span->channels; x++) {
span->chans[x]->span = span;
res = dahdi_chan_reg(span->chans[x]);
@@ -6252,10 +6289,16 @@
}
}
+ write_lock_irqsave(&chan_lock, flags);
+ list_add(&span->node, loc);
+ write_unlock_irqrestore(&chan_lock, flags);
+ set_bit(DAHDI_FLAGBIT_REGISTERED, &span->flags);
+ up(®istration_lock);
+
return 0;
unreg_channels:
- spans[span->spanno] = NULL;
+ up(®istration_lock);
return res;
}
@@ -6270,26 +6313,25 @@
int dahdi_unregister(struct dahdi_span *span)
{
int x;
- int new_maxspans;
static struct dahdi_span *new_master;
+ unsigned long flags;
#ifdef CONFIG_PROC_FS
char tempfile[17];
#endif /* CONFIG_PROC_FS */
- if (!test_bit(DAHDI_FLAGBIT_REGISTERED, &span->flags)) {
+ if (span != find_span(span->spanno)) {
module_printk(KERN_ERR, "Span %s does not appear to be registered\n", span->name);
return -1;
}
+
+ down(®istration_lock);
+
/* 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;
- }
if (debug)
module_printk(KERN_NOTICE, "Unregistering Span '%s' with %d channels\n", span->name, span->channels);
#ifdef CONFIG_PROC_FS
@@ -6302,29 +6344,31 @@
CLASS_DEV_DESTROY(dahdi_class, MKDEV(DAHDI_MAJOR, span->chans[x]->channo));
}
- spans[span->spanno] = NULL;
+ write_lock_irqsave(&chan_lock, flags);
+ list_del_init(&span->node);
+ write_unlock_irqrestore(&chan_lock, flags);
span->spanno = 0;
clear_bit(DAHDI_FLAGBIT_REGISTERED, &span->flags);
+
for (x=0;x<span->channels;x++)
dahdi_chan_unreg(span->chans[x]);
- new_maxspans = 0;
new_master = master; /* FIXME: locking */
if (master == span)
new_master = NULL;
- for (x=1;x<DAHDI_MAX_SPANS;x++) {
- if (spans[x]) {
- new_maxspans = x+1;
- if (!new_master)
- new_master = spans[x];
- }
- }
- maxspans = new_maxspans;
+
+ read_lock_irqsave(&chan_lock, flags);
+ if (!list_empty(&span_list)) {
+ new_master = list_entry(span_list.next,
+ struct dahdi_span, node);
+ }
+ read_unlock_irqrestore(&chan_lock, flags);
if (master != new_master)
if (debug)
module_printk(KERN_NOTICE, "%s: Span ('%s') is new master\n", __FUNCTION__,
(new_master)? new_master->name: "no master");
master = new_master;
+ up(®istration_lock);
return 0;
}
@@ -8497,7 +8541,6 @@
{
unsigned long flags;
int x, y, z;
- struct dahdi_chan *chan;
struct pseudo_chan *pseudo;
struct dahdi_span *s;
u_char *data;
@@ -8520,12 +8563,9 @@
if (dahdi_dynamic_ioctl)
dahdi_dynamic_ioctl(0, 0);
- for (y = 1; y < maxspans; ++y) {
- s = spans[y];
- if (!s)
- continue;
- for (x = 0; x < s->channels; x++) {
- chan = s->chans[x];
+ list_for_each_entry(s, &span_list, node) {
+ for (x = 0; x < s->channels; ++x) {
+ struct dahdi_chan *const chan = s->chans[x];
if (!chan->confmode)
continue;
spin_lock(&chan->lock);
@@ -8577,12 +8617,9 @@
spin_unlock(&pseudo->chan.lock);
}
- for (y = 1; y < maxspans; ++y) {
- s = spans[y];
- if (!s)
- continue;
+ list_for_each_entry(s, &span_list, node) {
for (x = 0; x < s->channels; x++) {
- chan = s->chans[x];
+ struct dahdi_chan *const chan = s->chans[x];
if (!chan->confmode)
continue;
spin_lock(&chan->lock);
@@ -8857,14 +8894,13 @@
static void watchdog_check(unsigned long ignored)
{
- int x;
unsigned long flags;
static int wdcheck=0;
-
- local_irq_save(flags);
- for (x=0;x<maxspans;x++) {
- s = spans[x];
- if (s && (s->flags & DAHDI_FLAG_RUNNING)) {
+ struct dahdi_span *s;
+
+ spin_lock_irqsave(&span_list_lock, flags);
+ list_for_each_entry(s, &span_list, node) {
+ if (s->flags & DAHDI_FLAG_RUNNING) {
if (s->watchcounter == DAHDI_WATCHDOG_INIT) {
/* Whoops, dead card */
if ((s->watchstate == DAHDI_WATCHSTATE_OK) ||
@@ -8887,7 +8923,7 @@
s->watchcounter = DAHDI_WATCHDOG_INIT;
}
}
- local_irq_restore(flags);
+ spin_unlock_irqrestore(&span_list_lock, flags);
if (!wdcheck) {
module_printk(KERN_NOTICE, "watchdog on duty!\n");
wdcheck=1;
Modified: linux/team/sruffell/chan_list/include/dahdi/kernel.h
URL: http://svnview.digium.com/svn/dahdi/linux/team/sruffell/chan_list/include/dahdi/kernel.h?view=diff&rev=9335&r1=9334&r2=9335
==============================================================================
--- linux/team/sruffell/chan_list/include/dahdi/kernel.h (original)
+++ linux/team/sruffell/chan_list/include/dahdi/kernel.h Fri Sep 17 14:11:36 2010
@@ -870,6 +870,7 @@
#ifdef CONFIG_PROC_FS
struct proc_dir_entry *proc_entry;
#endif
+ struct list_head node;
};
struct dahdi_transcoder_channel {
More information about the svn-commits
mailing list