dahdi: Restore DAHDI_CONFLINK functionality as compile time option.
This is mostly a revert of commit r9463. If you need to use DAHDI_CONFLINK ioctl, make sure to define CONFIG_DAHDI_CONFLINK in include/dahdi/dahdi_config.h. Apparently there were some users of CONFLINK out there still. It's a compile time option now since most users won't need to run the test for conflinks in the hot-path that is the process_masterspan function. Signed-off-by: Shaun Ruffell <sruffell@digium.com> Tested-by: Ted Gerold <ted@twg.org>
This commit is contained in:
parent
0498450db0
commit
a4feafc124
@ -176,6 +176,17 @@ static sumtype *conf_sums_prev;
|
|||||||
static struct dahdi_span *master;
|
static struct dahdi_span *master;
|
||||||
struct file_operations *dahdi_transcode_fops = NULL;
|
struct file_operations *dahdi_transcode_fops = NULL;
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef CONFIG_DAHDI_CONFLINK
|
||||||
|
static struct {
|
||||||
|
int src; /* source conf number */
|
||||||
|
int dst; /* dst conf number */
|
||||||
|
} conf_links[DAHDI_MAX_CONF + 1];
|
||||||
|
|
||||||
|
static int maxlinks;
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef CONFIG_DAHDI_CORE_TIMER
|
#ifdef CONFIG_DAHDI_CORE_TIMER
|
||||||
|
|
||||||
static struct core_timer {
|
static struct core_timer {
|
||||||
@ -4507,6 +4518,104 @@ static int dahdi_ioctl_spanstat_v1(struct file *file, unsigned long data)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef CONFIG_DAHDI_CONFLINK
|
||||||
|
static void recalc_maxlinks(void)
|
||||||
|
{
|
||||||
|
int x;
|
||||||
|
|
||||||
|
for (x = DAHDI_MAX_CONF - 1; x > 0; x--) {
|
||||||
|
if (conf_links[x].src || conf_links[x].dst) {
|
||||||
|
maxlinks = x + 1;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
maxlinks = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int dahdi_ioctl_conflink(struct file *file, unsigned long data)
|
||||||
|
{
|
||||||
|
struct dahdi_chan *chan;
|
||||||
|
struct dahdi_confinfo conf;
|
||||||
|
unsigned long flags;
|
||||||
|
int res = 0;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
chan = chan_from_file(file);
|
||||||
|
if (!chan)
|
||||||
|
return -EINVAL;
|
||||||
|
if (!(chan->flags & DAHDI_FLAG_AUDIO))
|
||||||
|
return -EINVAL;
|
||||||
|
if (copy_from_user(&conf, (void __user *)data, sizeof(conf)))
|
||||||
|
return -EFAULT;
|
||||||
|
/* check sanity of arguments */
|
||||||
|
if ((conf.chan < 0) || (conf.chan > DAHDI_MAX_CONF))
|
||||||
|
return -EINVAL;
|
||||||
|
if ((conf.confno < 0) || (conf.confno > DAHDI_MAX_CONF))
|
||||||
|
return -EINVAL;
|
||||||
|
/* cant listen to self!! */
|
||||||
|
if (conf.chan && (conf.chan == conf.confno))
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
spin_lock_irqsave(&chan_lock, flags);
|
||||||
|
spin_lock(&chan->lock);
|
||||||
|
|
||||||
|
/* if to clear all links */
|
||||||
|
if ((!conf.chan) && (!conf.confno)) {
|
||||||
|
/* clear all the links */
|
||||||
|
memset(conf_links, 0, sizeof(conf_links));
|
||||||
|
recalc_maxlinks();
|
||||||
|
spin_unlock(&chan->lock);
|
||||||
|
spin_unlock_irqrestore(&chan_lock, flags);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
/* look for already existant specified combination */
|
||||||
|
for (i = 1; i <= DAHDI_MAX_CONF; i++) {
|
||||||
|
/* if found, exit */
|
||||||
|
if ((conf_links[i].src == conf.chan) &&
|
||||||
|
(conf_links[i].dst == conf.confno))
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (i <= DAHDI_MAX_CONF) { /* if found */
|
||||||
|
if (!conf.confmode) { /* if to remove link */
|
||||||
|
conf_links[i].src = 0;
|
||||||
|
conf_links[i].dst = 0;
|
||||||
|
} else { /* if to add and already there, error */
|
||||||
|
res = -EEXIST;
|
||||||
|
}
|
||||||
|
} else { /* if not found */
|
||||||
|
if (conf.confmode) { /* if to add link */
|
||||||
|
/* look for empty location */
|
||||||
|
for (i = 1; i <= DAHDI_MAX_CONF; i++) {
|
||||||
|
/* if empty, exit loop */
|
||||||
|
if ((!conf_links[i].src) &&
|
||||||
|
(!conf_links[i].dst))
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
/* if empty spot found */
|
||||||
|
if (i <= DAHDI_MAX_CONF) {
|
||||||
|
conf_links[i].src = conf.chan;
|
||||||
|
conf_links[i].dst = conf.confno;
|
||||||
|
} else { /* if no empties -- error */
|
||||||
|
res = -ENOSPC;
|
||||||
|
}
|
||||||
|
} else { /* if to remove, and not found -- error */
|
||||||
|
res = -ENOENT;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
recalc_maxlinks();
|
||||||
|
spin_unlock(&chan->lock);
|
||||||
|
spin_unlock_irqrestore(&chan_lock, flags);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
static int dahdi_ioctl_conflink(struct file *file, unsigned long data)
|
||||||
|
{
|
||||||
|
return -ENOSYS;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
static int dahdi_common_ioctl(struct file *file, unsigned int cmd,
|
static int dahdi_common_ioctl(struct file *file, unsigned int cmd,
|
||||||
unsigned long data)
|
unsigned long data)
|
||||||
{
|
{
|
||||||
@ -4535,6 +4644,10 @@ static int dahdi_common_ioctl(struct file *file, unsigned int cmd,
|
|||||||
case DAHDI_CHANDIAG_V1: /* Intentional drop through. */
|
case DAHDI_CHANDIAG_V1: /* Intentional drop through. */
|
||||||
case DAHDI_CHANDIAG:
|
case DAHDI_CHANDIAG:
|
||||||
return dahdi_ioctl_chandiag(file, data);
|
return dahdi_ioctl_chandiag(file, data);
|
||||||
|
|
||||||
|
case DAHDI_CONFLINK:
|
||||||
|
return dahdi_ioctl_conflink(file, data);
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return -ENOTTY;
|
return -ENOTTY;
|
||||||
}
|
}
|
||||||
@ -5607,10 +5720,10 @@ static int dahdi_ioctl_confdiag(struct file *file, unsigned long data)
|
|||||||
for (i = ((j) ? j : 1); i <= ((j) ? j : DAHDI_MAX_CONF); i++) {
|
for (i = ((j) ? j : 1); i <= ((j) ? j : DAHDI_MAX_CONF); i++) {
|
||||||
struct dahdi_span *s;
|
struct dahdi_span *s;
|
||||||
struct pseudo_chan *pseudo;
|
struct pseudo_chan *pseudo;
|
||||||
|
int k;
|
||||||
c = 0;
|
c = 0;
|
||||||
spin_lock_irqsave(&chan_lock, flags);
|
spin_lock_irqsave(&chan_lock, flags);
|
||||||
list_for_each_entry(s, &span_list, spans_node) {
|
list_for_each_entry(s, &span_list, spans_node) {
|
||||||
int k;
|
|
||||||
for (k = 0; k < s->channels; k++) {
|
for (k = 0; k < s->channels; k++) {
|
||||||
chan = s->chans[k];
|
chan = s->chans[k];
|
||||||
if (chan->confna != i)
|
if (chan->confna != i)
|
||||||
@ -5632,6 +5745,29 @@ static int dahdi_ioctl_confdiag(struct file *file, unsigned long data)
|
|||||||
module_printk(KERN_NOTICE, "chan %d, mode %x\n",
|
module_printk(KERN_NOTICE, "chan %d, mode %x\n",
|
||||||
pseudo->chan.channo, pseudo->chan.confmode);
|
pseudo->chan.channo, pseudo->chan.confmode);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef CONFIG_DAHDI_CONFLINK
|
||||||
|
{
|
||||||
|
int rv;
|
||||||
|
rv = 0;
|
||||||
|
for (k = 1; k <= DAHDI_MAX_CONF; k++) {
|
||||||
|
if (conf_links[k].dst == i) {
|
||||||
|
if (!c) {
|
||||||
|
c = 1;
|
||||||
|
module_printk(KERN_NOTICE,
|
||||||
|
"Conf #%d:\n", i);
|
||||||
|
}
|
||||||
|
if (!rv) {
|
||||||
|
rv = 1;
|
||||||
|
module_printk(KERN_NOTICE,
|
||||||
|
"Snooping on:\n");
|
||||||
|
}
|
||||||
|
module_printk(KERN_NOTICE, "conf %d\n",
|
||||||
|
conf_links[k].src);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
spin_unlock_irqrestore(&chan_lock, flags);
|
spin_unlock_irqrestore(&chan_lock, flags);
|
||||||
if (c)
|
if (c)
|
||||||
module_printk(KERN_NOTICE, "\n");
|
module_printk(KERN_NOTICE, "\n");
|
||||||
@ -9714,6 +9850,29 @@ static void _process_masterspan(void)
|
|||||||
spin_unlock(&pseudo->chan.lock);
|
spin_unlock(&pseudo->chan.lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef CONFIG_DAHDI_CONFLINK
|
||||||
|
if (maxlinks) {
|
||||||
|
int z;
|
||||||
|
int y;
|
||||||
|
#ifdef CONFIG_DAHDI_MMX
|
||||||
|
dahdi_kernel_fpu_begin();
|
||||||
|
#endif
|
||||||
|
/* process all the conf links */
|
||||||
|
for (x = 1; x <= maxlinks; x++) {
|
||||||
|
/* if we have a destination conf */
|
||||||
|
z = confalias[conf_links[x].dst];
|
||||||
|
if (z) {
|
||||||
|
y = confalias[conf_links[x].src];
|
||||||
|
if (y)
|
||||||
|
ACSS(conf_sums[z], conf_sums[y]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#ifdef CONFIG_DAHDI_MMX
|
||||||
|
dahdi_kernel_fpu_end();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
#endif /* CONFIG_DAHDI_CONFLINK */
|
||||||
|
|
||||||
/* do all the pseudo/conferenced channel transmits (putbuf's) */
|
/* do all the pseudo/conferenced channel transmits (putbuf's) */
|
||||||
list_for_each_entry(pseudo, &pseudo_chans, node) {
|
list_for_each_entry(pseudo, &pseudo_chans, node) {
|
||||||
pseudo_rx_audio(&pseudo->chan);
|
pseudo_rx_audio(&pseudo->chan);
|
||||||
|
@ -190,4 +190,10 @@
|
|||||||
*/
|
*/
|
||||||
/* #define CONFIG_DAHDI_MIRROR */
|
/* #define CONFIG_DAHDI_MIRROR */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Adds support for conference links. There are some non-Asterisk users of this
|
||||||
|
* functionality.
|
||||||
|
*/
|
||||||
|
/* #define CONFIG_DAHDI_CONFLINK */
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -636,6 +636,11 @@ struct dahdi_confinfo {
|
|||||||
#define DAHDI_SETCONF_V1 _IOW(DAHDI_CODE, 12, struct dahdi_confinfo)
|
#define DAHDI_SETCONF_V1 _IOW(DAHDI_CODE, 12, struct dahdi_confinfo)
|
||||||
#define DAHDI_SETCONF _IOWR(DAHDI_CODE, 13, struct dahdi_confinfo)
|
#define DAHDI_SETCONF _IOWR(DAHDI_CODE, 13, struct dahdi_confinfo)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Setup or Remove Conference Link
|
||||||
|
*/
|
||||||
|
#define DAHDI_CONFLINK _IOW(DAHDI_CODE, 14, struct dahdi_confinfo)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Display Conference Diagnostic Information on Console
|
* Display Conference Diagnostic Information on Console
|
||||||
*/
|
*/
|
||||||
|
Loading…
Reference in New Issue
Block a user