[svn-commits] sruffell: linux/trunk r9608 - /linux/trunk/drivers/dahdi/dahdi-base.c
SVN commits to the Digium repositories
svn-commits at lists.digium.com
Mon Jan 3 18:28:14 UTC 2011
Author: sruffell
Date: Mon Jan 3 12:28:11 2011
New Revision: 9608
URL: http://svnview.digium.com/svn/dahdi?view=rev&rev=9608
Log:
dahdi: Remove three maxchans/DAHDI_MAX_CHANNELS references.
In dahdi_chec_conf, dahdi_chan_unreg, and dahdi_ioctl_confdiag maxchans
and DAHDI_MAX_CHANNELS was used to scan through all the channels. Since
the channels are stored on the list of spans and list of pseudo
channels, we can directly iterate through those lists. This also paves
the way for removing the arbitrary limit on the number of channels in
the driver.
Signed-off-by: Shaun Ruffell <sruffell at digium.com>
Acked-by: Kinsey Moore <kmoore at digium.com>
Modified:
linux/trunk/drivers/dahdi/dahdi-base.c
Modified: linux/trunk/drivers/dahdi/dahdi-base.c
URL: http://svnview.digium.com/svn/dahdi/linux/trunk/drivers/dahdi/dahdi-base.c?view=diff&rev=9608&r1=9607&r2=9608
==============================================================================
--- linux/trunk/drivers/dahdi/dahdi-base.c (original)
+++ linux/trunk/drivers/dahdi/dahdi-base.c Mon Jan 3 12:28:11 2011
@@ -475,6 +475,33 @@
static LIST_HEAD(span_list);
static struct dahdi_chan *chans[DAHDI_MAX_CHANNELS];
+
+static unsigned long
+__for_each_channel(unsigned long (*func)(struct dahdi_chan *chan,
+ unsigned long data),
+ unsigned long data)
+{
+ int res;
+ struct dahdi_span *s;
+ struct pseudo_chan *pseudo;
+
+ list_for_each_entry(s, &span_list, node) {
+ unsigned long x;
+ for (x = 0; x < s->channels; x++) {
+ struct dahdi_chan *const chan = s->chans[x];
+ res = func(chan, data);
+ if (res)
+ return res;
+ }
+ }
+
+ list_for_each_entry(pseudo, &pseudo_chans, node) {
+ res = func(&pseudo->chan, data);
+ if (res)
+ return res;
+ }
+ return 0;
+}
static struct dahdi_chan *chan_from_num(unsigned int channo)
{
@@ -1046,9 +1073,21 @@
return a;
}
+static unsigned long _chan_in_conf(struct dahdi_chan *chan, unsigned long x)
+{
+ const int confmode = chan->confmode & DAHDI_CONF_MODE_MASK;
+ return (chan && (chan->confna == x) &&
+ (confmode == DAHDI_CONF_CONF ||
+ confmode == DAHDI_CONF_CONFANN ||
+ confmode == DAHDI_CONF_CONFMON ||
+ confmode == DAHDI_CONF_CONFANNMON ||
+ confmode == DAHDI_CONF_REALANDPSEUDO)) ? 1 : 0;
+}
+
static void dahdi_check_conf(int x)
{
- int y;
+ unsigned long res;
+ unsigned long flags;
/* return if no valid conf number */
if (x <= 0)
@@ -1058,21 +1097,11 @@
if (!confalias[x])
return;
- for (y = 0; y < maxchans; y++) {
- struct dahdi_chan *const chan = chan_from_num(y);
- int confmode;
- if (!chan)
- continue;
- confmode = chan->confmode & DAHDI_CONF_MODE_MASK;
- if ((chan->confna == x) &&
- (confmode == DAHDI_CONF_CONF ||
- confmode == DAHDI_CONF_CONFANN ||
- confmode == DAHDI_CONF_CONFMON ||
- confmode == DAHDI_CONF_CONFANNMON ||
- confmode == DAHDI_CONF_REALANDPSEUDO)) {
- return;
- }
- }
+ spin_lock_irqsave(&chan_lock, flags);
+ res = __for_each_channel(_chan_in_conf, x);
+ spin_unlock_irqrestore(&chan_lock, flags);
+ if (res)
+ return;
/* If we get here, nobody is in the conference anymore. Clear it out
both forward and reverse */
@@ -2100,10 +2129,41 @@
}
}
+static unsigned long _chan_cleanup(struct dahdi_chan *pos, unsigned long data)
+{
+ unsigned long flags;
+ struct dahdi_chan *const chan = (struct dahdi_chan *)data;
+
+ ++maxchans;
+
+ /* Remove anyone pointing to us as master
+ and make them their own thing */
+ if (pos->master == chan)
+ pos->master = pos;
+
+ if (((pos->confna == chan->channo) &&
+ is_monitor_mode(pos->confmode)) ||
+ (pos->dacs_chan == chan)) {
+ /* Take them out of conference with us */
+ /* release conference resource if any */
+ if (pos->confna)
+ dahdi_check_conf(pos->confna);
+
+ dahdi_disable_dacs(pos);
+ spin_lock_irqsave(&pos->lock, flags);
+ pos->confna = 0;
+ pos->_confn = 0;
+ pos->confmode = 0;
+ pos->conf_chan = NULL;
+ pos->dacs_chan = NULL;
+ spin_unlock_irqrestore(&pos->lock, flags);
+ }
+
+ return 0;
+}
static void dahdi_chan_unreg(struct dahdi_chan *chan)
{
- int x;
unsigned long flags;
might_sleep();
@@ -2137,36 +2197,10 @@
module_printk(KERN_NOTICE, "HUH??? PPP still attached??\n");
}
#endif
- maxchans = 0;
- for (x = 1; x < DAHDI_MAX_CHANNELS; x++) {
- struct dahdi_chan *const pos = chan_from_num(x);
- if (!pos)
- continue;
- maxchans = x + 1;
- /* Remove anyone pointing to us as master
- and make them their own thing */
- if (pos->master == chan)
- pos->master = pos;
-
- if ((pos->confna == chan->channo) &&
- (is_monitor_mode(pos->confmode) ||
- ((pos->confmode & DAHDI_CONF_MODE_MASK) ==
- DAHDI_CONF_DIGITALMON))) {
- /* Take them out of conference with us */
- /* release conference resource if any */
- if (pos->confna)
- dahdi_check_conf(pos->confna);
-
- dahdi_disable_dacs(pos);
- pos->confna = 0;
- pos->_confn = 0;
- pos->confmode = 0;
- pos->dacs_chan = NULL;
- pos->conf_chan = NULL;
- }
- }
+ __for_each_channel(_chan_cleanup, (unsigned long)chan);
+ spin_unlock_irqrestore(&chan_lock, flags);
+
chan->channo = -1;
- spin_unlock_irqrestore(&chan_lock, flags);
}
static ssize_t dahdi_chan_read(struct file *file, char __user *usrbuf,
@@ -5127,11 +5161,11 @@
static int dahdi_ioctl_confdiag(struct file *file, unsigned long data)
{
struct dahdi_chan *chan;
+ unsigned long flags;
int rv;
int i;
int j;
int c;
- int k;
chan = chan_from_file(file);
if (!chan)
@@ -5144,23 +5178,34 @@
/* loop thru the interesting ones */
for (i = ((j) ? j : 1); i <= ((j) ? j : DAHDI_MAX_CONF); i++) {
+ struct dahdi_span *s;
+ struct pseudo_chan *pseudo;
c = 0;
- for (k = 1; k < DAHDI_MAX_CHANNELS; k++) {
- struct dahdi_chan *const pos = chan_from_num(k);
- /* skip if no pointer */
- if (!pos)
+ spin_lock_irqsave(&chan_lock, flags);
+ list_for_each_entry(s, &span_list, node) {
+ int k;
+ for (k = 0; k < s->channels; k++) {
+ chan = s->chans[k];
+ if (chan->confna != i)
+ continue;
+ if (!c)
+ module_printk(KERN_NOTICE, "Conf #%d:\n", i);
+ c = 1;
+ module_printk(KERN_NOTICE, "chan %d, mode %x\n",
+ chan->channo, chan->confmode);
+ }
+ }
+ list_for_each_entry(pseudo, &pseudo_chans, node) {
+ /* skip if not in this conf */
+ if (pseudo->chan.confna != i)
continue;
- /* skip if not in this conf */
- if (pos->confna != i)
- continue;
- if (!c) {
- module_printk(KERN_NOTICE,
- "Conf #%d:\n", i);
- }
+ if (!c)
+ module_printk(KERN_NOTICE, "Conf #%d:\n", i);
c = 1;
module_printk(KERN_NOTICE, "chan %d, mode %x\n",
- k, pos->confmode);
- }
+ pseudo->chan.channo, pseudo->chan.confmode);
+ }
+ spin_unlock_irqrestore(&chan_lock, flags);
rv = 0;
if (c)
module_printk(KERN_NOTICE, "\n");
More information about the svn-commits
mailing list