summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorShaun Ruffell <sruffell@digium.com>2010-07-26 00:30:41 +0000
committerShaun Ruffell <sruffell@digium.com>2010-07-26 00:30:41 +0000
commit9e8885a50b7923c9a9b7456bbf2ecc61923c8734 (patch)
tree57dc2f7e5a6c358c0a13eb4a8d0f7856b5e8077a
parent5fd3fdc1cea7af8b1c46bbf2a5edd0c6fe2d3e54 (diff)
dahdi: Move the callbacks in dahdi_span into its own structure.
Part of preparation for adding additional callbacks to allow board drivers to advertise and support gathering pre-echocan data from hardware echocans. git-svn-id: http://svn.asterisk.org/svn/dahdi/linux/trunk@8985 a0bf4364-ded3-4de4-8d8a-66a801d63aff
-rw-r--r--drivers/dahdi/dahdi-base.c154
-rw-r--r--drivers/dahdi/dahdi_dynamic.c12
-rw-r--r--drivers/dahdi/pciradio.c14
-rw-r--r--drivers/dahdi/tor2.c23
-rw-r--r--drivers/dahdi/wcb4xxp/base.c35
-rw-r--r--drivers/dahdi/wcfxo.c12
-rw-r--r--drivers/dahdi/wct1xxp.c23
-rw-r--r--drivers/dahdi/wct4xxp/base.c67
-rw-r--r--drivers/dahdi/wctdm.c14
-rw-r--r--drivers/dahdi/wctdm24xxp/base.c55
-rw-r--r--drivers/dahdi/wcte11xp.c22
-rw-r--r--drivers/dahdi/wcte12xp/base.c38
-rw-r--r--drivers/dahdi/xpp/card_bri.c29
-rw-r--r--drivers/dahdi/xpp/card_pri.c33
-rw-r--r--drivers/dahdi/xpp/xpp_dahdi.c33
-rw-r--r--drivers/dahdi/xpp/xpp_dahdi.h1
-rw-r--r--include/dahdi/kernel.h94
17 files changed, 400 insertions, 259 deletions
diff --git a/drivers/dahdi/dahdi-base.c b/drivers/dahdi/dahdi-base.c
index f7364fa..32f60ce 100644
--- a/drivers/dahdi/dahdi-base.c
+++ b/drivers/dahdi/dahdi-base.c
@@ -508,6 +508,33 @@ static inline void rotate_sums(void)
memset(conf_sums_next, 0, maxconfs * sizeof(sumtype));
}
+static int dahdi_chan_dacs(struct dahdi_chan *chan1, struct dahdi_chan *chan2)
+{
+ if (chan2) {
+ if (chan1->span && chan2->span &&
+ (chan1->span->ops->dacs == chan2->span->ops->dacs))
+ return chan1->span->ops->dacs(chan1, chan2);
+ else
+ return -ENOSYS;
+ } else {
+ if (chan1->span && chan1->span->ops->dacs)
+ return chan1->span->ops->dacs(chan1, NULL);
+ else
+ return -ENOSYS;
+ }
+}
+
+static int dahdi_chan_echocan_create(struct dahdi_chan *chan,
+ struct dahdi_echocanparams *ecp,
+ struct dahdi_echocanparam *p,
+ struct dahdi_echocan_state **ec)
+{
+ if (chan->span && chan->span->ops->echocan_create)
+ return chan->span->ops->echocan_create(chan, ecp, p, ec);
+ else
+ return -ENODEV;
+}
+
/*!
* \return quiescent (idle) signalling states, for the various signalling types
*/
@@ -532,7 +559,7 @@ static int dahdi_q_sig(struct dahdi_chan *chan)
return -1;
/* if RBS does not apply, return error */
- if (!(chan->span->flags & DAHDI_FLAG_RBS) || !chan->span->rbsbits)
+ if (!(chan->span->flags & DAHDI_FLAG_RBS) || !chan->span->ops->rbsbits)
return -1;
if (chan->sig == DAHDI_SIG_CAS)
@@ -1313,8 +1340,8 @@ static void close_channel(struct dahdi_chan *chan)
memset(chan->conflast1, 0, sizeof(chan->conflast1));
memset(chan->conflast2, 0, sizeof(chan->conflast2));
- if (chan->span && chan->span->dacs && oldconf)
- chan->span->dacs(chan, NULL);
+ if (chan->span && oldconf)
+ dahdi_chan_dacs(chan, NULL);
if (ec_state) {
ec_state->ops->echocan_free(chan, ec_state);
@@ -1978,8 +2005,8 @@ static void dahdi_chan_unreg(struct dahdi_chan *chan)
/* release conference resource if any */
if (chans[x]->confna) {
dahdi_check_conf(chans[x]->confna);
- if (chans[x]->span && chans[x]->span->dacs)
- chans[x]->span->dacs(chans[x], NULL);
+ if (chans[x]->span)
+ dahdi_chan_dacs(chans[x], NULL);
}
chans[x]->confna = 0;
chans[x]->_confn = 0;
@@ -2251,8 +2278,8 @@ static ssize_t dahdi_chan_write(struct file *file, const char __user *usrbuf, si
spin_unlock_irqrestore(&chan->lock, flags);
- if (chan->flags & DAHDI_FLAG_NOSTDTXRX && chan->span->hdlc_hard_xmit)
- chan->span->hdlc_hard_xmit(chan);
+ if (chan->flags & DAHDI_FLAG_NOSTDTXRX && chan->span->ops->hdlc_hard_xmit)
+ chan->span->ops->hdlc_hard_xmit(chan);
}
return amnt;
}
@@ -2373,7 +2400,7 @@ static void dahdi_rbs_sethook(struct dahdi_chan *chan, int txsig, int txstate,
module_printk(KERN_NOTICE, "dahdi_rbs: Tried to set RBS hook state %d (> 3) on channel %s\n", txsig, chan->name);
return;
}
- if (!chan->span->rbsbits && !chan->span->hooksig) {
+ if (!chan->span->ops->rbsbits && !chan->span->ops->hooksig) {
module_printk(KERN_NOTICE, "dahdi_rbs: Tried to set RBS hook state %d on channel %s while span %s lacks rbsbits or hooksig function\n",
txsig, chan->name, chan->span->name);
return;
@@ -2397,10 +2424,10 @@ static void dahdi_rbs_sethook(struct dahdi_chan *chan, int txsig, int txstate,
chan->otimer = timeout * DAHDI_CHUNKSIZE; /* Otimer is timer in samples */
return;
}
- if (chan->span->hooksig) {
+ if (chan->span->ops->hooksig) {
if (chan->txhooksig != txsig) {
chan->txhooksig = txsig;
- chan->span->hooksig(chan, txsig);
+ chan->span->ops->hooksig(chan, txsig);
}
chan->otimer = timeout * DAHDI_CHUNKSIZE; /* Otimer is timer in samples */
return;
@@ -2412,7 +2439,7 @@ static void dahdi_rbs_sethook(struct dahdi_chan *chan, int txsig, int txstate,
#endif
chan->txhooksig = txsig;
chan->txsig = outs[x].bits[txsig];
- chan->span->rbsbits(chan, chan->txsig);
+ chan->span->ops->rbsbits(chan, chan->txsig);
chan->otimer = timeout * DAHDI_CHUNKSIZE; /* Otimer is timer in samples */
return;
}
@@ -2426,9 +2453,9 @@ static int dahdi_cas_setbits(struct dahdi_chan *chan, int bits)
/* if no span, return as error */
if (!chan->span)
return -1;
- if (chan->span->rbsbits) {
+ if (chan->span->ops->rbsbits) {
chan->txsig = bits;
- chan->span->rbsbits(chan, bits);
+ chan->span->ops->rbsbits(chan, bits);
} else {
module_printk(KERN_NOTICE, "Huh? CAS setbits, but no RBS bits function\n");
}
@@ -2467,10 +2494,10 @@ static int dahdi_hangup(struct dahdi_chan *chan)
dahdi_rbs_sethook(chan, DAHDI_TXSIG_ONHOOK, DAHDI_TXSTATE_ONHOOK, 0);
} else {
/* Let the driver hang up the line if it wants to */
- if (chan->span->sethook) {
+ if (chan->span->ops->sethook) {
if (chan->txhooksig != DAHDI_ONHOOK) {
chan->txhooksig = DAHDI_ONHOOK;
- res = chan->span->sethook(chan, DAHDI_ONHOOK);
+ res = chan->span->ops->sethook(chan, DAHDI_ONHOOK);
} else
res = 0;
}
@@ -2581,8 +2608,7 @@ static int initialize_channel(struct dahdi_chan *chan)
if ((chan->sig & __DAHDI_SIG_DACS) != __DAHDI_SIG_DACS) {
chan->confna = 0;
chan->confmode = 0;
- if (chan->span && chan->span->dacs)
- chan->span->dacs(chan, NULL);
+ dahdi_chan_dacs(chan, NULL);
}
chan->_confn = 0;
memset(chan->conflast, 0, sizeof(chan->conflast));
@@ -2710,8 +2736,8 @@ static int dahdi_specchan_open(struct file *file, int unit)
if (chan->span) {
if (!try_module_get(chan->span->owner))
res = -ENXIO;
- else if (chan->span->open)
- res = chan->span->open(chan);
+ else if (chan->span->ops->open)
+ res = chan->span->ops->open(chan);
}
if (!res) {
chan->file = file;
@@ -2743,11 +2769,9 @@ static int dahdi_specchan_release(struct file *file, int unit)
spin_unlock_irqrestore(&chan->lock, flags);
close_channel(chan);
if (chan->span) {
- struct module *owner = chan->span->owner;
-
- if (chan->span->close)
- res = chan->span->close(chan);
- module_put(owner);
+ if (chan->span->ops->close)
+ res = chan->span->ops->close(chan);
+ module_put(chan->span->owner);
}
/* The channel might be destroyed by low-level driver span->close() */
if (chans[unit])
@@ -3728,7 +3752,7 @@ static int dahdi_common_ioctl(struct file *file, unsigned int cmd, unsigned long
stack.param.rxisoffhook = 1;
else
stack.param.rxisoffhook = 0;
- if (chan->span && chan->span->rbsbits && !(chan->sig & DAHDI_SIG_CLEAR)) {
+ if (chan->span && chan->span->ops->rbsbits && !(chan->sig & DAHDI_SIG_CLEAR)) {
stack.param.rxbits = chan->rxsig;
stack.param.txbits = chan->txsig;
stack.param.idlebits = chan->idlebits;
@@ -3737,7 +3761,7 @@ static int dahdi_common_ioctl(struct file *file, unsigned int cmd, unsigned long
stack.param.txbits = -1;
stack.param.idlebits = 0;
}
- if (chan->span && (chan->span->rbsbits || chan->span->hooksig) &&
+ if (chan->span && (chan->span->ops->rbsbits || chan->span->ops->hooksig) &&
!(chan->sig & DAHDI_SIG_CLEAR)) {
stack.param.rxhooksig = chan->rxhooksig;
stack.param.txhooksig = chan->txhooksig;
@@ -4088,13 +4112,13 @@ static int dahdi_ctl_ioctl(struct file *file, unsigned int cmd, unsigned long da
if ((lc.lineconfig & 0x1ff0 & spans[lc.span]->linecompat) !=
(lc.lineconfig & 0x1ff0))
return -EINVAL;
- if (spans[lc.span]->spanconfig) {
+ if (spans[lc.span]->ops->spanconfig) {
spans[lc.span]->lineconfig = lc.lineconfig;
spans[lc.span]->lbo = lc.lbo;
spans[lc.span]->txlevel = lc.lbo;
spans[lc.span]->rxlevel = 0;
- return spans[lc.span]->spanconfig(spans[lc.span], &lc);
+ return spans[lc.span]->ops->spanconfig(spans[lc.span], &lc);
}
return 0;
}
@@ -4103,8 +4127,8 @@ static int dahdi_ctl_ioctl(struct file *file, unsigned int cmd, unsigned long da
if (spans[j]->flags & DAHDI_FLAG_RUNNING)
return 0;
- if (spans[j]->startup)
- res = spans[j]->startup(spans[j]);
+ if (spans[j]->ops->startup)
+ res = spans[j]->ops->startup(spans[j]);
if (!res) {
/* Mark as running and hangup any channels */
@@ -4128,8 +4152,8 @@ static int dahdi_ctl_ioctl(struct file *file, unsigned int cmd, unsigned long da
return 0;
case DAHDI_SHUTDOWN:
CHECK_VALID_SPAN(j);
- if (spans[j]->shutdown)
- res = spans[j]->shutdown(spans[j]);
+ if (spans[j]->ops->shutdown)
+ res = spans[j]->ops->shutdown(spans[j]);
spans[j]->flags &= ~DAHDI_FLAG_RUNNING;
return 0;
case DAHDI_ATTACH_ECHOCAN:
@@ -4259,14 +4283,9 @@ static int dahdi_ctl_ioctl(struct file *file, unsigned int cmd, unsigned long da
/* Setup conference properly */
chans[ch.chan]->confmode = DAHDI_CONF_DIGITALMON;
chans[ch.chan]->confna = ch.idlebits;
- if (chans[ch.chan]->span &&
- chans[ch.chan]->span->dacs &&
- chans[ch.idlebits] &&
- chans[ch.chan]->span &&
- (chans[ch.chan]->span->dacs == chans[ch.idlebits]->span->dacs))
- chans[ch.chan]->span->dacs(chans[ch.chan], chans[ch.idlebits]);
- } else if (chans[ch.chan]->span && chans[ch.chan]->span->dacs) {
- chans[ch.chan]->span->dacs(chans[ch.chan], NULL);
+ dahdi_chan_dacs(chans[ch.chan], chans[ch.idlebits]);
+ } else {
+ dahdi_chan_dacs(chans[ch.chan], NULL);
}
chans[ch.chan]->master = newmaster;
/* Note new slave if we are not our own master */
@@ -4287,8 +4306,8 @@ static int dahdi_ctl_ioctl(struct file *file, unsigned int cmd, unsigned long da
chans[ch.chan]->flags &= ~DAHDI_FLAG_MTP2;
}
- if (!res && chans[ch.chan]->span->chanconfig) {
- res = chans[ch.chan]->span->chanconfig(chans[ch.chan],
+ if (!res && chans[ch.chan]->span->ops->chanconfig) {
+ res = chans[ch.chan]->span->ops->chanconfig(chans[ch.chan],
ch.sigtype);
}
@@ -4492,7 +4511,7 @@ static int dahdi_ctl_ioctl(struct file *file, unsigned int cmd, unsigned long da
/* must be valid span number */
if ((maint.spanno < 1) || (maint.spanno > DAHDI_MAX_SPANS) || (!spans[maint.spanno]))
return -EINVAL;
- if (!spans[maint.spanno]->maint)
+ if (!spans[maint.spanno]->ops->maint)
return -ENOSYS;
spin_lock_irqsave(&spans[maint.spanno]->lock, flags);
/* save current maint state */
@@ -4507,7 +4526,7 @@ static int dahdi_ctl_ioctl(struct file *file, unsigned int cmd, unsigned long da
/* if same, ignore it */
if (i == maint.command)
break;
- rv = spans[maint.spanno]->maint(spans[maint.spanno], maint.command);
+ rv = spans[maint.spanno]->ops->maint(spans[maint.spanno], maint.command);
spin_unlock_irqrestore(&spans[maint.spanno]->lock, flags);
if (rv)
return rv;
@@ -4516,7 +4535,7 @@ static int dahdi_ctl_ioctl(struct file *file, unsigned int cmd, unsigned long da
case DAHDI_MAINT_LOOPUP:
case DAHDI_MAINT_LOOPDOWN:
spans[maint.spanno]->mainttimer = DAHDI_LOOPCODE_TIME * DAHDI_CHUNKSIZE;
- rv = spans[maint.spanno]->maint(spans[maint.spanno], maint.command);
+ rv = spans[maint.spanno]->ops->maint(spans[maint.spanno], maint.command);
spin_unlock_irqrestore(&spans[maint.spanno]->lock, flags);
if (rv)
return rv;
@@ -4539,8 +4558,8 @@ static int dahdi_ctl_ioctl(struct file *file, unsigned int cmd, unsigned long da
if(!i)
spans[maint.spanno]->maintstat = 0;
- rv = spans[maint.spanno]->maint(spans[maint.spanno],
- maint.command);
+ rv = spans[maint.spanno]->ops->maint(spans[maint.spanno],
+ maint.command);
spin_unlock_irqrestore(&spans[maint.spanno]->lock,
flags);
if (rv)
@@ -4928,17 +4947,15 @@ dahdi_chanandpseudo_ioctl(struct file *file, unsigned int cmd,
chans[i]->_confn = 0; /* Clear confn */
dahdi_check_conf(j);
dahdi_check_conf(stack.conf.confno);
- if (chans[i]->span && chans[i]->span->dacs) {
+ if (chans[i]->span && chans[i]->span->ops->dacs) {
if (((stack.conf.confmode & DAHDI_CONF_MODE_MASK) == DAHDI_CONF_DIGITALMON) &&
- chans[stack.conf.confno]->span &&
- chans[stack.conf.confno]->span->dacs == chans[i]->span->dacs &&
chans[i]->txgain == defgain &&
chans[i]->rxgain == defgain &&
chans[stack.conf.confno]->txgain == defgain &&
chans[stack.conf.confno]->rxgain == defgain) {
- chans[i]->span->dacs(chans[i], chans[stack.conf.confno]);
+ dahdi_chan_dacs(chans[i], chans[stack.conf.confno]);
} else {
- chans[i]->span->dacs(chans[i], NULL);
+ dahdi_chan_dacs(chans[i], NULL);
}
}
/* if we are going onto a conf */
@@ -5137,8 +5154,8 @@ dahdi_chanandpseudo_ioctl(struct file *file, unsigned int cmd,
rv = dahdi_common_ioctl(file, cmd, data, unit);
/* if no span, just return with value */
if (!chan->span) return rv;
- if ((rv == -ENOTTY) && chan->span->ioctl)
- rv = chan->span->ioctl(chan, cmd, data);
+ if ((rv == -ENOTTY) && chan->span->ops->ioctl)
+ rv = chan->span->ops->ioctl(chan, cmd, data);
return rv;
}
@@ -5238,13 +5255,11 @@ ioctl_echocancel(struct dahdi_chan *chan, struct dahdi_echocanparams *ecp,
ecp->tap_length = deftaps;
}
- ret = -ENODEV;
ec_current = NULL;
/* attempt to use the span's echo canceler; fall back to built-in
if it fails (but not if an error occurs) */
- if (chan->span && chan->span->echocan_create)
- ret = chan->span->echocan_create(chan, ecp, params, &ec);
+ ret = dahdi_chan_echocan_create(chan, ecp, params, &ec);
if ((ret == -ENODEV) && chan->ec_factory) {
/* try to get another reference to the module providing
@@ -5399,8 +5414,7 @@ static int dahdi_chan_ioctl(struct file *file, unsigned int cmd, unsigned long d
/* initialize conference variables */
chan->_confn = 0;
chan->confna = 0;
- if (chan->span && chan->span->dacs)
- chan->span->dacs(chan, NULL);
+ dahdi_chan_dacs(chan, NULL);
chan->confmode = 0;
chan->confmute = 0;
memset(chan->conflast, 0, sizeof(chan->conflast));
@@ -5432,8 +5446,8 @@ static int dahdi_chan_ioctl(struct file *file, unsigned int cmd, unsigned long d
if (oldconf) dahdi_check_conf(oldconf);
}
#ifdef DAHDI_AUDIO_NOTIFY
- if (chan->span->audio_notify)
- chan->span->audio_notify(chan, j);
+ if (chan->span->ops->audio_notify)
+ chan->span->ops->audio_notify(chan, j);
#endif
break;
case DAHDI_HDLCPPP:
@@ -5704,10 +5718,10 @@ static int dahdi_chan_ioctl(struct file *file, unsigned int cmd, unsigned long d
default:
return -EINVAL;
}
- } else if (chan->span->sethook) {
+ } else if (chan->span->ops->sethook) {
if (chan->txhooksig != j) {
chan->txhooksig = j;
- chan->span->sethook(chan, j);
+ chan->span->ops->sethook(chan, j);
}
} else
return -ENOSYS;
@@ -5975,8 +5989,8 @@ int dahdi_unregister(struct dahdi_span *span)
}
/* Shutdown the span if it's running */
if (span->flags & DAHDI_FLAG_RUNNING)
- if (span->shutdown)
- span->shutdown(span);
+ 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);
@@ -8184,7 +8198,7 @@ int dahdi_transmit(struct dahdi_span *span)
/* Just set bits for our destination */
if (span->chans[x]->txsig != chans[span->chans[x]->confna]->rxsig) {
span->chans[x]->txsig = chans[span->chans[x]->confna]->rxsig;
- span->rbsbits(span->chans[x], chans[span->chans[x]->confna]->rxsig);
+ span->ops->rbsbits(span->chans[x], chans[span->chans[x]->confna]->rxsig);
}
}
}
@@ -8196,8 +8210,8 @@ int dahdi_transmit(struct dahdi_span *span)
span->mainttimer -= DAHDI_CHUNKSIZE;
if (span->mainttimer <= 0) {
span->mainttimer = 0;
- if (span->maint)
- span->maint(span, DAHDI_MAINT_LOOPSTOP);
+ if (span->ops->maint)
+ span->ops->maint(span, DAHDI_MAINT_LOOPSTOP);
span->maintstat = 0;
wake_up_interruptible(&span->maintq);
}
@@ -8297,8 +8311,8 @@ static void process_masterspan(void)
#ifdef DAHDI_SYNC_TICK
for (x = 0; x < maxspans; x++) {
struct dahdi_span *const s = spans[x];
- if (s && s->sync_tick)
- s->sync_tick(s, s == master);
+ if (s && s->ops->sync_tick)
+ s->ops->sync_tick(s, s == master);
}
#endif
read_unlock(&chan_lock);
diff --git a/drivers/dahdi/dahdi_dynamic.c b/drivers/dahdi/dahdi_dynamic.c
index 9b2542c..6a5bab5 100644
--- a/drivers/dahdi/dahdi_dynamic.c
+++ b/drivers/dahdi/dahdi_dynamic.c
@@ -527,6 +527,13 @@ static int ztd_close(struct dahdi_chan *chan)
return 0;
}
+static const struct dahdi_span_ops dynamic_ops = {
+ .rbsbits = ztd_rbsbits,
+ .open = ztd_open,
+ .close = ztd_close,
+ .chanconfig = ztd_chanconfig,
+};
+
static int create_dynamic(struct dahdi_dynamic_span *zds)
{
struct dahdi_dynamic *z;
@@ -590,10 +597,7 @@ static int create_dynamic(struct dahdi_dynamic_span *zds)
z->span.deflaw = DAHDI_LAW_MULAW;
z->span.flags |= DAHDI_FLAG_RBS;
z->span.chans = z->chans;
- z->span.rbsbits = ztd_rbsbits;
- z->span.open = ztd_open;
- z->span.close = ztd_close;
- z->span.chanconfig = ztd_chanconfig;
+ z->span.ops = &dynamic_ops;
for (x=0; x < z->span.channels; x++) {
sprintf(z->chans[x]->name, "DYN/%s/%s/%d", zds->driver, zds->addr, x+1);
z->chans[x]->sigcap = DAHDI_SIG_EM | DAHDI_SIG_CLEAR | DAHDI_SIG_FXSLS |
diff --git a/drivers/dahdi/pciradio.c b/drivers/dahdi/pciradio.c
index 901d8f6..b6e885f 100644
--- a/drivers/dahdi/pciradio.c
+++ b/drivers/dahdi/pciradio.c
@@ -1458,6 +1458,14 @@ static int pciradio_hooksig(struct dahdi_chan *chan, enum dahdi_txsig txsig)
return 0;
}
+static const struct dahdi_span_ops pciradio_span_ops = {
+ .hooksig = pciradio_hooksig,
+ .open = pciradio_open,
+ .close = pciradio_close,
+ .ioctl = pciradio_ioctl,
+ .watchdog = pciradio_watchdog,
+};
+
static int pciradio_initialize(struct pciradio *rad)
{
int x;
@@ -1478,12 +1486,8 @@ static int pciradio_initialize(struct pciradio *rad)
}
rad->span.chans = &rad->chans;
rad->span.channels = rad->nchans;
- rad->span.hooksig = pciradio_hooksig;
- rad->span.open = pciradio_open;
- rad->span.close = pciradio_close;
rad->span.flags = DAHDI_FLAG_RBS;
- rad->span.ioctl = pciradio_ioctl;
- rad->span.watchdog = pciradio_watchdog;
+ rad->span.ops = &pciradio_span_ops;
init_waitqueue_head(&rad->span.maintq);
if (dahdi_register(&rad->span, 0)) {
diff --git a/drivers/dahdi/tor2.c b/drivers/dahdi/tor2.c
index ee8ebe9..633369c 100644
--- a/drivers/dahdi/tor2.c
+++ b/drivers/dahdi/tor2.c
@@ -259,6 +259,18 @@ static int tor2_close(struct dahdi_chan *chan)
return 0;
}
+static const struct dahdi_span_ops tor2_span_ops = {
+ .spanconfig = tor2_spanconfig,
+ .chanconfig = tor2_chanconfig,
+ .startup = tor2_startup,
+ .shutdown = tor2_shutdown,
+ .rbsbits = tor2_rbsbits,
+ .maint = tor2_maint,
+ .open = tor2_open,
+ .close = tor2_close,
+ .ioctl = tor2_ioctl,
+};
+
static void init_spans(struct tor2 *tor)
{
int x, y, c;
@@ -274,14 +286,6 @@ static void init_spans(struct tor2 *tor)
snprintf(s->location, sizeof(s->location) - 1,
"PCI Bus %02d Slot %02d", tor->pci->bus->number, PCI_SLOT(tor->pci->devfn) + 1);
s->owner = THIS_MODULE;
- s->spanconfig = tor2_spanconfig;
- s->chanconfig = tor2_chanconfig;
- s->startup = tor2_startup;
- s->shutdown = tor2_shutdown;
- s->rbsbits = tor2_rbsbits;
- s->maint = tor2_maint;
- s->open = tor2_open;
- s->close = tor2_close;
if (tor->cardtype == TYPE_T1) {
s->channels = 24;
s->deflaw = DAHDI_LAW_MULAW;
@@ -295,7 +299,8 @@ static void init_spans(struct tor2 *tor)
}
s->chans = tor->chans[x];
s->flags = DAHDI_FLAG_RBS;
- s->ioctl = tor2_ioctl;
+ s->ops = &tor2_span_ops;
+
tor->tspans[x].tor = tor;
tor->tspans[x].span = x;
init_waitqueue_head(&s->maintq);
diff --git a/drivers/dahdi/wcb4xxp/base.c b/drivers/dahdi/wcb4xxp/base.c
index a4ccaf4..fd916dc 100644
--- a/drivers/dahdi/wcb4xxp/base.c
+++ b/drivers/dahdi/wcb4xxp/base.c
@@ -143,8 +143,6 @@ static struct devtype hfc4s_EV = {"CCD HFC-4S Eval. Board", .ports = 4,
#define CARD_HAS_EC(card) ((card)->card_type == B410P)
-static int echocan_create(struct dahdi_chan *chan, struct dahdi_echocanparams *ecp,
- struct dahdi_echocanparam *p, struct dahdi_echocan_state **ec);
static void echocan_free(struct dahdi_chan *chan, struct dahdi_echocan_state *ec);
static const struct dahdi_echocan_features my_ec_features = {
@@ -2085,12 +2083,17 @@ static void b4xxp_update_leds(struct b4xxp *b4)
}
}
-static int echocan_create(struct dahdi_chan *chan, struct dahdi_echocanparams *ecp,
- struct dahdi_echocanparam *p, struct dahdi_echocan_state **ec)
+static int b4xxp_echocan_create(struct dahdi_chan *chan,
+ struct dahdi_echocanparams *ecp,
+ struct dahdi_echocanparam *p,
+ struct dahdi_echocan_state **ec)
{
struct b4xxp_span *bspan = container_of(chan->span, struct b4xxp_span, span);
int channel;
+ if (!vpmsupport || !CARD_HAS_EC(bspan->parent))
+ return -ENODEV;
+
if (chan->chanpos == 3) {
printk(KERN_WARNING "Cannot enable echo canceller on D channel of span %d; failing request\n", chan->span->offset);
return -EINVAL;
@@ -2309,6 +2312,18 @@ static void b4xxp_hdlc_hard_xmit(struct dahdi_chan *chan)
/* internal functions, not specific to the hardware or DAHDI */
+static const struct dahdi_span_ops b4xxp_span_ops = {
+ .spanconfig = b4xxp_spanconfig,
+ .chanconfig = b4xxp_chanconfig,
+ .startup = b4xxp_startup,
+ .shutdown = b4xxp_shutdown,
+ .open = b4xxp_open,
+ .close = b4xxp_close,
+ .ioctl = b4xxp_ioctl,
+ .hdlc_hard_xmit = b4xxp_hdlc_hard_xmit,
+ .echocan_create = b4xxp_echocan_create,
+};
+
/* initialize the span/chan structures. Doesn't touch hardware, although the callbacks might. */
static void init_spans(struct b4xxp *b4)
{
@@ -2346,17 +2361,7 @@ static void init_spans(struct b4xxp *b4)
b4->pdev->bus->number, PCI_SLOT(b4->pdev->devfn) + 1);
bspan->span.owner = THIS_MODULE;
- bspan->span.spanconfig = b4xxp_spanconfig;
- bspan->span.chanconfig = b4xxp_chanconfig;
- bspan->span.startup = b4xxp_startup;
- bspan->span.shutdown = b4xxp_shutdown;
- bspan->span.open = b4xxp_open;
- bspan->span.close = b4xxp_close;
- bspan->span.ioctl = b4xxp_ioctl;
- bspan->span.hdlc_hard_xmit = b4xxp_hdlc_hard_xmit;
- if (vpmsupport && CARD_HAS_EC(b4))
- bspan->span.echocan_create = echocan_create;
-
+ bspan->span.ops = &b4xxp_span_ops;
/* HDLC stuff */
bspan->sigchan = NULL;
bspan->sigactive = 0;
diff --git a/drivers/dahdi/wcfxo.c b/drivers/dahdi/wcfxo.c
index f0f4ee9..bf495d7 100644
--- a/drivers/dahdi/wcfxo.c
+++ b/drivers/dahdi/wcfxo.c
@@ -638,6 +638,13 @@ static int wcfxo_hooksig(struct dahdi_chan *chan, enum dahdi_txsig txsig)
return 0;
}
+static const struct dahdi_span_ops wcfxo_span_ops = {
+ .hooksig = wcfxo_hooksig,
+ .open = wcfxo_open,
+ .close = wcfxo_close,
+ .watchdog = wcfxo_watchdog,
+};
+
static int wcfxo_initialize(struct wcfxo *wc)
{
/* DAHDI stuff */
@@ -653,19 +660,16 @@ static int wcfxo_initialize(struct wcfxo *wc)
wc->chan->chanpos = 1;
wc->span.chans = &wc->chan;
wc->span.channels = 1;
- wc->span.hooksig = wcfxo_hooksig;
wc->span.irq = wc->dev->irq;
- wc->span.open = wcfxo_open;
- wc->span.close = wcfxo_close;
wc->span.flags = DAHDI_FLAG_RBS;
wc->span.deflaw = DAHDI_LAW_MULAW;
- wc->span.watchdog = wcfxo_watchdog;
#ifdef ENABLE_TASKLETS
tasklet_init(&wc->wcfxo_tlet, wcfxo_tasklet, (unsigned long)wc);
#endif
init_waitqueue_head(&wc->span.maintq);
wc->chan->pvt = wc;
+ wc->span.ops = &wcfxo_span_ops;
if (dahdi_register(&wc->span, 0)) {
printk(KERN_NOTICE "Unable to register span with DAHDI\n");
return -1;
diff --git a/drivers/dahdi/wct1xxp.c b/drivers/dahdi/wct1xxp.c
index 30d6457..80392c8 100644
--- a/drivers/dahdi/wct1xxp.c
+++ b/drivers/dahdi/wct1xxp.c
@@ -745,6 +745,19 @@ static int t1xxp_spanconfig(struct dahdi_span *span, struct dahdi_lineconfig *lc
return 0;
}
+
+static const struct dahdi_span_ops t1xxp_span_ops = {
+ .spanconfig = t1xxp_spanconfig,
+ .chanconfig = t1xxp_chanconfig,
+ .startup = t1xxp_startup,
+ .shutdown = t1xxp_shutdown,
+ .rbsbits = t1xxp_rbsbits,
+ .maint = t1xxp_maint,
+ .open = t1xxp_open,
+ .close = t1xxp_close,
+ .ioctl = t1xxp_ioctl,
+};
+
static int t1xxp_software_init(struct t1xxp *wc)
{
int x;
@@ -765,18 +778,9 @@ static int t1xxp_software_init(struct t1xxp *wc)
snprintf(wc->span.location, sizeof(wc->span.location) - 1,
"PCI Bus %02d Slot %02d", wc->dev->bus->number, PCI_SLOT(wc->dev->devfn) + 1);
wc->span.owner = THIS_MODULE;
- wc->span.spanconfig = t1xxp_spanconfig;
- wc->span.chanconfig = t1xxp_chanconfig;
wc->span.irq = wc->dev->irq;
- wc->span.startup = t1xxp_startup;
- wc->span.shutdown = t1xxp_shutdown;
- wc->span.rbsbits = t1xxp_rbsbits;
- wc->span.maint = t1xxp_maint;
- wc->span.open = t1xxp_open;
- wc->span.close = t1xxp_close;
wc->span.chans = wc->chans;
wc->span.flags = DAHDI_FLAG_RBS;
- wc->span.ioctl = t1xxp_ioctl;
if (wc->ise1) {
wc->span.channels = 31;
wc->span.deflaw = DAHDI_LAW_ALAW;
@@ -798,6 +802,7 @@ static int t1xxp_software_init(struct t1xxp *wc)
wc->chans[x]->pvt = wc;
wc->chans[x]->chanpos = x + 1;
}
+ wc->span.ops = &t1xxp_span_ops;
if (dahdi_register(&wc->span, 0)) {
printk(KERN_NOTICE "Unable to register span with DAHDI\n");
return -1;
diff --git a/drivers/dahdi/wct4xxp/base.c b/drivers/dahdi/wct4xxp/base.c
index d76dffd..a0564a9 100644
--- a/drivers/dahdi/wct4xxp/base.c
+++ b/drivers/dahdi/wct4xxp/base.c
@@ -385,8 +385,6 @@ static void t4_vpm400_init(struct t4 *wc);
static void t4_vpm450_init(struct t4 *wc);
static void t4_vpm_set_dtmf_threshold(struct t4 *wc, unsigned int threshold);
-static int echocan_create(struct dahdi_chan *chan, struct dahdi_echocanparams *ecp,
- struct dahdi_echocanparam *p, struct dahdi_echocan_state **ec);
static void echocan_free(struct dahdi_chan *chan, struct dahdi_echocan_state *ec);
static const struct dahdi_echocan_features vpm400m_ec_features = {
@@ -1232,8 +1230,10 @@ static int t4_vpm_unit(int span, int channel)
return unit;
}
-static int echocan_create(struct dahdi_chan *chan, struct dahdi_echocanparams *ecp,
- struct dahdi_echocanparam *p, struct dahdi_echocan_state **ec)
+static int t4_echocan_create(struct dahdi_chan *chan,
+ struct dahdi_echocanparams *ecp,
+ struct dahdi_echocanparam *p,
+ struct dahdi_echocan_state **ec)
{
struct t4 *wc = chan->pvt;
struct t4_span *tspan = container_of(chan->span, struct t4_span, span);
@@ -1241,7 +1241,7 @@ static int echocan_create(struct dahdi_chan *chan, struct dahdi_echocanparams *e
const struct dahdi_echocan_ops *ops;
const struct dahdi_echocan_features *features;
- if (!wc->vpm)
+ if (!vpmsupport || !wc->vpm)
return -ENODEV;
if (chan->span->offset >= vpmspans)
@@ -1846,6 +1846,36 @@ void setup_chunks(struct t4 *wc, int which)
}
}
+static const struct dahdi_span_ops t4_gen1_span_ops = {
+ .spanconfig = t4_spanconfig,
+ .chanconfig = t4_chanconfig,
+ .startup = t4_startup,
+ .shutdown = t4_shutdown,
+ .rbsbits = t4_rbsbits,
+ .maint = t4_maint,
+ .open = t4_open,
+ .close = t4_close,
+ .ioctl = t4_ioctl,
+ .hdlc_hard_xmit = t4_hdlc_hard_xmit,
+};
+
+static const struct dahdi_span_ops t4_gen2_span_ops = {
+ .spanconfig = t4_spanconfig,
+ .chanconfig = t4_chanconfig,
+ .startup = t4_startup,
+ .shutdown = t4_shutdown,
+ .rbsbits = t4_rbsbits,
+ .maint = t4_maint,
+ .open = t4_open,
+ .close = t4_close,
+ .ioctl = t4_ioctl,
+ .hdlc_hard_xmit = t4_hdlc_hard_xmit,
+ .dacs = t4_dacs,
+#ifdef VPM_SUPPORT
+ .echocan_create = t4_echocan_create,
+#endif
+};
+
static void init_spans(struct t4 *wc)
{
int x,y;
@@ -1878,15 +1908,7 @@ static void init_spans(struct t4 *wc)
break;
}
ts->span.owner = THIS_MODULE;
- ts->span.spanconfig = t4_spanconfig;
- ts->span.chanconfig = t4_chanconfig;
ts->span.irq = wc->dev->irq;
- ts->span.startup = t4_startup;
- ts->span.shutdown = t4_shutdown;
- ts->span.rbsbits = t4_rbsbits;
- ts->span.maint = t4_maint;
- ts->span.open = t4_open;
- ts->span.close = t4_close;
/* HDLC Specific init */
ts->sigchan = NULL;
@@ -1904,18 +1926,19 @@ static void init_spans(struct t4 *wc)
}
ts->span.chans = ts->chans;
ts->span.flags = DAHDI_FLAG_RBS;
- ts->span.ioctl = t4_ioctl;
- ts->span.hdlc_hard_xmit = t4_hdlc_hard_xmit;
- if (gen2) {
-#ifdef VPM_SUPPORT
- if (vpmsupport)
- ts->span.echocan_create = echocan_create;
-#endif
- ts->span.dacs = t4_dacs;
- }
+
ts->owner = wc;
ts->span.offset = x;
+ ts->writechunk = (void *)(wc->writechunk + x * 32 * 2);
+ ts->readchunk = (void *)(wc->readchunk + x * 32 * 2);
init_waitqueue_head(&ts->span.maintq);
+
+ if (gen2) {
+ ts->span.ops = &t4_gen2_span_ops;
+ } else {
+ ts->span.ops = &t4_gen1_span_ops;
+ }
+
for (y=0;y<wc->tspans[x]->span.channels;y++) {
struct dahdi_chan *mychans = ts->chans[y];
sprintf(mychans->name, "TE%d/%d/%d/%d", wc->numspans, wc->num, x + 1, y + 1);
diff --git a/drivers/dahdi/wctdm.c b/drivers/dahdi/wctdm.c
index c9e4f51..f533726 100644
--- a/drivers/dahdi/wctdm.c
+++ b/drivers/dahdi/wctdm.c
@@ -2334,6 +2334,14 @@ static int wctdm_hooksig(struct dahdi_chan *chan, enum dahdi_txsig txsig)
return 0;
}
+static const struct dahdi_span_ops wctdm_span_ops = {
+ .hooksig = wctdm_hooksig,
+ .open = wctdm_open,
+ .close = wctdm_close,
+ .ioctl = wctdm_ioctl,
+ .watchdog = wctdm_watchdog,
+};
+
static int wctdm_initialize(struct wctdm *wc)
{
int x;
@@ -2361,14 +2369,10 @@ static int wctdm_initialize(struct wctdm *wc)
wc->span.owner = THIS_MODULE;
wc->span.chans = wc->chans;
wc->span.channels = NUM_CARDS;
- wc->span.hooksig = wctdm_hooksig;
wc->span.irq = wc->dev->irq;
- wc->span.open = wctdm_open;
- wc->span.close = wctdm_close;
wc->span.flags = DAHDI_FLAG_RBS;
- wc->span.ioctl = wctdm_ioctl;
- wc->span.watchdog = wctdm_watchdog;
init_waitqueue_head(&wc->span.maintq);
+ wc->span.ops = &wctdm_span_ops;
if (dahdi_register(&wc->span, 0)) {
printk(KERN_NOTICE "Unable to register span with DAHDI\n");
diff --git a/drivers/dahdi/wctdm24xxp/base.c b/drivers/dahdi/wctdm24xxp/base.c
index 99236fa..1390176 100644
--- a/drivers/dahdi/wctdm24xxp/base.c
+++ b/drivers/dahdi/wctdm24xxp/base.c
@@ -256,8 +256,6 @@ static int vpmnlptype = DEFAULT_NLPTYPE;
static int vpmnlpthresh = DEFAULT_NLPTHRESH;
static int vpmnlpmaxsupp = DEFAULT_NLPMAXSUPP;
-static int echocan_create(struct dahdi_chan *chan, struct dahdi_echocanparams *ecp,
- struct dahdi_echocanparam *p, struct dahdi_echocan_state **ec);
static void echocan_free(struct dahdi_chan *chan, struct dahdi_echocan_state *ec);
static const struct dahdi_echocan_features vpm100m_ec_features = {
@@ -1206,7 +1204,7 @@ static inline void wctdm_receiveprep(struct wctdm *wc, const u8 *readchunk)
struct dahdi_span *s = &wc->spans[x]->span;
#if 1
/* Check for digital spans */
- if (s->chanconfig == b400m_chanconfig) {
+ if (s->ops->chanconfig == b400m_chanconfig) {
BUG_ON(!is_hx8(wc));
if (s->flags & DAHDI_FLAG_RUNNING)
b400m_dchan(s);
@@ -1844,14 +1842,20 @@ static inline void wctdm_vpm_check(struct wctdm *wc, int x)
}
}
-static int echocan_create(struct dahdi_chan *chan, struct dahdi_echocanparams *ecp,
- struct dahdi_echocanparam *p, struct dahdi_echocan_state **ec)
+static int wctdm_echocan_create(struct dahdi_chan *chan,
+ struct dahdi_echocanparams *ecp,
+ struct dahdi_echocanparam *p,
+ struct dahdi_echocan_state **ec)
{
struct wctdm *wc = chan->pvt;
struct wctdm_chan *wchan = container_of(chan, struct wctdm_chan, chan);
const struct dahdi_echocan_ops *ops;
const struct dahdi_echocan_features *features;
+#ifdef VPM_SUPPORT
+ if (!vpmsupport)
+ return -ENODEV;
+#endif
if (!wc->vpm100 && !wc->vpmadt032)
return -ENODEV;
@@ -3554,6 +3558,32 @@ static int wctdm_dacs(struct dahdi_chan *dst, struct dahdi_chan *src)
return 0;
}
+static const struct dahdi_span_ops wctdm24xxp_analog_span_ops = {
+ .hooksig = wctdm_hooksig,
+ .open = wctdm_open,
+ .close = wctdm_close,
+ .ioctl = wctdm_ioctl,
+ .watchdog = wctdm_watchdog,
+ .dacs = wctdm_dacs,
+#ifdef VPM_SUPPORT
+ .echocan_create = wctdm_echocan_create,
+#endif
+};
+
+static const struct dahdi_span_ops wctdm24xxp_digital_span_ops = {
+ .open = wctdm_open,
+ .close = wctdm_close,
+ .ioctl = wctdm_ioctl,
+ .watchdog = wctdm_watchdog,
+ .hdlc_hard_xmit = wctdm_hdlc_hard_xmit,
+ .spanconfig = b400m_spanconfig,
+ .chanconfig = b400m_chanconfig,
+ .dacs = wctdm_dacs,
+#ifdef VPM_SUPPORT
+ .echocan_create = wctdm_echocan_create,
+#endif
+};
+
static struct wctdm_chan *wctdm_init_chan(struct wctdm *wc, struct wctdm_span *s, int chanoffset, int channo)
{
struct wctdm_chan *c;
@@ -3645,14 +3675,12 @@ static struct wctdm_span *wctdm_init_span(struct wctdm *wc, int spanno, int chan
}
if (digital_span) {
- s->span.hdlc_hard_xmit = wctdm_hdlc_hard_xmit;
- s->span.spanconfig = b400m_spanconfig;
- s->span.chanconfig = b400m_chanconfig;
+ s->span.ops = &wctdm24xxp_digital_span_ops;
s->span.linecompat = DAHDI_CONFIG_AMI | DAHDI_CONFIG_B8ZS | DAHDI_CONFIG_D4;
s->span.linecompat |= DAHDI_CONFIG_ESF | DAHDI_CONFIG_HDB3 | DAHDI_CONFIG_CCS | DAHDI_CONFIG_CRC4;
s->span.linecompat |= DAHDI_CONFIG_NTTE | DAHDI_CONFIG_TERM;
} else {
- s->span.hooksig = wctdm_hooksig;
+ s->span.ops = &wctdm24xxp_analog_span_ops;
s->span.flags = DAHDI_FLAG_RBS;
/* analog sigcap handled in fixup_analog_span() */
}
@@ -3672,21 +3700,12 @@ static struct wctdm_span *wctdm_init_span(struct wctdm *wc, int spanno, int chan
s->span.channels = chancount;
s->span.irq = pdev->irq;
- s->span.open = wctdm_open;
- s->span.close = wctdm_close;
- s->span.ioctl = wctdm_ioctl;
- s->span.watchdog = wctdm_watchdog;
- s->span.dacs = wctdm_dacs;
if (digital_span) {
wc->chans[chanoffset + 0]->chan.sigcap = DAHDI_SIG_CLEAR;
wc->chans[chanoffset + 1]->chan.sigcap = DAHDI_SIG_CLEAR;
wc->chans[chanoffset + 2]->chan.sigcap = DAHDI_SIG_HARDHDLC;
}
-#ifdef VPM_SUPPORT
- if (vpmsupport)
- s->span.echocan_create = echocan_create;
-#endif
init_waitqueue_head(&s->span.maintq);
wc->spans[spanno] = s;
diff --git a/drivers/dahdi/wcte11xp.c b/drivers/dahdi/wcte11xp.c
index 32d4f5b..ec73cbf 100644
--- a/drivers/dahdi/wcte11xp.c
+++ b/drivers/dahdi/wcte11xp.c
@@ -955,6 +955,18 @@ static int t1xxp_spanconfig(struct dahdi_span *span, struct dahdi_lineconfig *lc
return 0;
}
+static const struct dahdi_span_ops t1xxp_span_ops = {
+ .startup = t1xxp_startup,
+ .shutdown = t1xxp_shutdown,
+ .rbsbits = t1xxp_rbsbits,
+ .maint = t1xxp_maint,
+ .open = t1xxp_open,
+ .close = t1xxp_close,
+ .spanconfig = t1xxp_spanconfig,
+ .chanconfig = t1xxp_chanconfig,
+ .ioctl = t1xxp_ioctl,
+};
+
static int t1xxp_software_init(struct t1 *wc)
{
int x;
@@ -976,15 +988,7 @@ static int t1xxp_software_init(struct t1 *wc)
dahdi_copy_string(wc->span.devicetype, wc->variety, sizeof(wc->span.devicetype));
snprintf(wc->span.location, sizeof(wc->span.location) - 1,
"PCI Bus %02d Slot %02d", wc->dev->bus->number, PCI_SLOT(wc->dev->devfn) + 1);
- wc->span.spanconfig = t1xxp_spanconfig;
- wc->span.chanconfig = t1xxp_chanconfig;
wc->span.irq = wc->dev->irq;
- wc->span.startup = t1xxp_startup;
- wc->span.shutdown = t1xxp_shutdown;
- wc->span.rbsbits = t1xxp_rbsbits;
- wc->span.maint = t1xxp_maint;
- wc->span.open = t1xxp_open;
- wc->span.close = t1xxp_close;
if (wc->spantype == TYPE_E1) {
if (unchannelized)
wc->span.channels = 32;
@@ -1001,7 +1005,6 @@ static int t1xxp_software_init(struct t1 *wc)
}
wc->span.chans = wc->chans;
wc->span.flags = DAHDI_FLAG_RBS;
- wc->span.ioctl = t1xxp_ioctl;
init_waitqueue_head(&wc->span.maintq);
for (x=0;x<wc->span.channels;x++) {
sprintf(wc->chans[x]->name, "WCT1/%d/%d", wc->num, x + 1);
@@ -1012,6 +1015,7 @@ static int t1xxp_software_init(struct t1 *wc)
wc->chans[x]->pvt = wc;
wc->chans[x]->chanpos = x + 1;
}
+ wc->span.ops = &t1xxp_span_ops;
if (dahdi_register(&wc->span, 0)) {
printk(KERN_NOTICE "Unable to register span with DAHDI\n");
return -1;
diff --git a/drivers/dahdi/wcte12xp/base.c b/drivers/dahdi/wcte12xp/base.c
index cbb1b04..3c58b64 100644
--- a/drivers/dahdi/wcte12xp/base.c
+++ b/drivers/dahdi/wcte12xp/base.c
@@ -73,8 +73,6 @@ static int vpmnlptype = DEFAULT_NLPTYPE;
static int vpmnlpthresh = DEFAULT_NLPTHRESH;
static int vpmnlpmaxsupp = DEFAULT_NLPMAXSUPP;
-static int echocan_create(struct dahdi_chan *chan, struct dahdi_echocanparams *ecp,
- struct dahdi_echocanparam *p, struct dahdi_echocan_state **ec);
static void echocan_free(struct dahdi_chan *chan, struct dahdi_echocan_state *ec);
static int t1xxp_clear_maint(struct dahdi_span *span);
static int check_and_load_vpm(struct t1 *wc);
@@ -1331,13 +1329,15 @@ static int t1xxp_ioctl(struct dahdi_chan *chan, unsigned int cmd, unsigned long
return 0;
}
-static int echocan_create(struct dahdi_chan *chan, struct dahdi_echocanparams *ecp,
- struct dahdi_echocanparam *p, struct dahdi_echocan_state **ec)
+static int t1xxp_echocan_create(struct dahdi_chan *chan,
+ struct dahdi_echocanparams *ecp,
+ struct dahdi_echocanparam *p,
+ struct dahdi_echocan_state **ec)
{
struct t1 *wc = chan->pvt;
enum adt_companding comp;
- if (!wc->vpmadt032 || !test_bit(4, &wc->ctlreg))
+ if (!vpmsupport || !wc->vpmadt032 || !test_bit(4, &wc->ctlreg))
return -ENODEV;
*ec = wc->ec[chan->chanpos - 1];
@@ -1506,6 +1506,20 @@ t1xxp_spanconfig(struct dahdi_span *span, struct dahdi_lineconfig *lc)
return 0;
}
+static const struct dahdi_span_ops t1_span_ops = {
+ .spanconfig = t1xxp_spanconfig,
+ .chanconfig = t1xxp_chanconfig,
+ .startup = t1xxp_startup,
+ .shutdown = t1xxp_shutdown,
+ .rbsbits = t1xxp_rbsbits,
+ .maint = t1xxp_maint,
+ .open = t1xxp_open,
+ .close = t1xxp_close,
+ .ioctl = t1xxp_ioctl,
+#ifdef VPM_SUPPORT
+ .echocan_create = t1xxp_echocan_create,
+#endif
+};
static int t1_software_init(struct t1 *wc)
{
@@ -1537,20 +1551,7 @@ static int t1_software_init(struct t1 *wc)
PCI_SLOT(pdev->devfn) + 1);
wc->span.owner = THIS_MODULE;
- wc->span.spanconfig = t1xxp_spanconfig;
- wc->span.chanconfig = t1xxp_chanconfig;
wc->span.irq = pdev->irq;
- wc->span.startup = t1xxp_startup;
- wc->span.shutdown = t1xxp_shutdown;
- wc->span.rbsbits = t1xxp_rbsbits;
- wc->span.maint = t1xxp_maint;
- wc->span.open = t1xxp_open;
- wc->span.close = t1xxp_close;
- wc->span.ioctl = t1xxp_ioctl;
-#ifdef VPM_SUPPORT
- if (vpmsupport)
- wc->span.echocan_create = echocan_create;
-#endif
if (wc->spantype == TYPE_E1) {
if (unchannelized)
@@ -1578,6 +1579,7 @@ static int t1_software_init(struct t1 *wc)
wc->chans[x]->pvt = wc;
wc->chans[x]->chanpos = x + 1;
}
+ wc->span.ops = &t1_span_ops;
if (dahdi_register(&wc->span, 0)) {
t1_info(wc, "Unable to register span with DAHDI\n");
return -1;
diff --git a/drivers/dahdi/xpp/card_bri.c b/drivers/dahdi/xpp/card_bri.c
index b390bf7..e15f064 100644
--- a/drivers/dahdi/xpp/card_bri.c
+++ b/drivers/dahdi/xpp/card_bri.c
@@ -861,6 +861,27 @@ static int BRI_card_remove(xbus_t *xbus, xpd_t *xpd)
return 0;
}
+static const struct dahdi_span_ops BRI_span_ops = {
+ .spanconfig = bri_spanconfig,
+ .chanconfig = bri_chanconfig,
+ .startup = bri_startup,
+ .shutdown = bri_shutdown,
+#ifndef CONFIG_DAHDI_BRI_DCHANS
+ .hdlc_hard_xmit = bri_hdlc_hard_xmit,
+#endif
+ .open = xpp_open,
+ .close = xpp_close,
+ .hooksig = xpp_hooksig, /* Only with RBS bits */
+ .ioctl = xpp_ioctl,
+ .maint = xpp_maint,
+#ifdef DAHDI_SYNC_TICK
+ .sync_tick = dahdi_sync_tick,
+#endif
+#ifdef CONFIG_DAHDI_WATCHDOG
+ .watchdog = xpp_watchdog,
+#endif
+};
+
static int BRI_card_dahdi_preregistration(xpd_t *xpd, bool on)
{
xbus_t *xbus;
@@ -912,13 +933,7 @@ static int BRI_card_dahdi_preregistration(xpd_t *xpd, bool on)
}
}
CALL_XMETHOD(card_pcm_recompute, xbus, xpd, 0);
- xpd->span.spanconfig = bri_spanconfig;
- xpd->span.chanconfig = bri_chanconfig;
- xpd->span.startup = bri_startup;
- xpd->span.shutdown = bri_shutdown;
-#ifndef CONFIG_DAHDI_BRI_DCHANS
- xpd->span.hdlc_hard_xmit = bri_hdlc_hard_xmit;
-#endif
+ xpd->span.ops = &BRI_span_ops;
return 0;
}
diff --git a/drivers/dahdi/xpp/card_pri.c b/drivers/dahdi/xpp/card_pri.c
index 53cd8d5..1003188 100644
--- a/drivers/dahdi/xpp/card_pri.c
+++ b/drivers/dahdi/xpp/card_pri.c
@@ -1273,6 +1273,29 @@ static int pri_audio_notify(struct dahdi_chan *chan, int on)
}
#endif
+static const struct dahdi_span_ops PRI_span_ops = {
+ .spanconfig = pri_spanconfig,
+ .chanconfig = pri_chanconfig,
+ .startup = pri_startup,
+ .shutdown = pri_shutdown,
+ .rbsbits = pri_rbsbits,
+ .open = xpp_open,
+ .close = xpp_close,
+ .hooksig = xpp_hooksig, /* Only with RBS bits */
+ .ioctl = xpp_ioctl,
+ .maint = xpp_maint,
+#ifdef DAHDI_SYNC_TICK
+ .sync_tick = dahdi_sync_tick,
+#endif
+#ifdef CONFIG_DAHDI_WATCHDOG
+ .watchdog = xpp_watchdog,
+#endif
+
+#ifdef DAHDI_AUDIO_NOTIFY
+ .audio_notify = pri_audio_notify,
+#endif
+};
+
static int PRI_card_dahdi_preregistration(xpd_t *xpd, bool on)
{
xbus_t *xbus;
@@ -1312,14 +1335,8 @@ static int PRI_card_dahdi_preregistration(xpd_t *xpd, bool on)
cur_chan->flags &= ~DAHDI_FLAG_HDLC;
}
}
- xpd->span.spanconfig = pri_spanconfig;
- xpd->span.chanconfig = pri_chanconfig;
- xpd->span.startup = pri_startup;
- xpd->span.shutdown = pri_shutdown;
- xpd->span.rbsbits = pri_rbsbits;
-#ifdef DAHDI_AUDIO_NOTIFY
- xpd->span.audio_notify = pri_audio_notify;
-#endif
+ xpd->offhook_state = xpd->wanted_pcm_mask;
+ xpd->span.ops = &PRI_span_ops;
return 0;
}
diff --git a/drivers/dahdi/xpp/xpp_dahdi.c b/drivers/dahdi/xpp/xpp_dahdi.c
index ebabdcc..82157f6 100644
--- a/drivers/dahdi/xpp/xpp_dahdi.c
+++ b/drivers/dahdi/xpp/xpp_dahdi.c
@@ -944,7 +944,7 @@ int xpp_ioctl(struct dahdi_chan *chan, unsigned int cmd, unsigned long arg)
return 0;
}
-static int xpp_hooksig(struct dahdi_chan *chan, enum dahdi_txsig txsig)
+int xpp_hooksig(struct dahdi_chan *chan, enum dahdi_txsig txsig)
{
xpd_t *xpd = chan->pvt;
xbus_t *xbus;
@@ -966,6 +966,7 @@ static int xpp_hooksig(struct dahdi_chan *chan, enum dahdi_txsig txsig)
DBG(SIGNAL, "Setting %s to %s (%d)\n", chan->name, txsig2str(txsig), txsig);
return CALL_XMETHOD(card_hooksig, xbus, xpd, pos, txsig);
}
+EXPORT_SYMBOL(xpp_hooksig);
/* Req: Set the requested chunk size. This is the unit in which you must
report results for conferencing, etc */
@@ -1068,6 +1069,21 @@ int dahdi_unregister_xpd(xpd_t *xpd)
return 0;
}
+static const struct dahdi_span_ops xpp_span_ops = {
+ .open = xpp_open,
+ .close = xpp_close,
+ .ioctl = xpp_ioctl,
+ .maint = xpp_maint,
+};
+
+static const struct dahdi_span_ops xpp_rbs_span_ops = {
+ .hooksig = xpp_hooksig,
+ .open = xpp_open,
+ .close = xpp_close,
+ .ioctl = xpp_ioctl,
+ .maint = xpp_maint,
+};
+
int dahdi_register_xpd(xpd_t *xpd)
{
struct dahdi_span *span;
@@ -1099,13 +1115,12 @@ int dahdi_register_xpd(xpd_t *xpd)
span->channels = cn;
span->chans = xpd->chans;
- span->open = xpp_open;
- span->close = xpp_close;
span->flags = DAHDI_FLAG_RBS;
if(xops->card_hooksig)
- span->hooksig = xpp_hooksig; /* Only with RBS bits */
- span->ioctl = xpp_ioctl;
- span->maint = xpp_maint;
+ span->ops = &xpp_rbs_span_ops; /* Only with RBS bits */
+ else
+ span->ops = &xpp_span_ops;
+
/*
* This actually describe the dahdi_spaninfo version 3
* A bunch of unrelated data exported via a modified ioctl()
@@ -1138,12 +1153,6 @@ int dahdi_register_xpd(xpd_t *xpd)
* No irq's for you today!
*/
span->irq = 0;
-#ifdef DAHDI_SYNC_TICK
- span->sync_tick = dahdi_sync_tick;
-#endif
-#ifdef CONFIG_DAHDI_WATCHDOG
- span->watchdog = xpp_watchdog;
-#endif
snprintf(xpd->span.desc, MAX_SPANDESC, "Xorcom XPD #%02d/%1d%1d: %s",
xbus->num, xpd->addr.unit, xpd->addr.subunit, xpd->type_name);
diff --git a/drivers/dahdi/xpp/xpp_dahdi.h b/drivers/dahdi/xpp/xpp_dahdi.h
index 96e7fc3..e048dc7 100644
--- a/drivers/dahdi/xpp/xpp_dahdi.h
+++ b/drivers/dahdi/xpp/xpp_dahdi.h
@@ -39,6 +39,7 @@ void hookstate_changed(xpd_t *xpd, int pos, bool good);
int xpp_open(struct dahdi_chan *chan);
int xpp_close(struct dahdi_chan *chan);
int xpp_ioctl(struct dahdi_chan *chan, unsigned int cmd, unsigned long arg);
+int xpp_hooksig(struct dahdi_chan *chan, enum dahdi_txsig txsig);
int xpp_maint(struct dahdi_span *span, int cmd);
void report_bad_ioctl(const char *msg, xpd_t *xpd, int pos, unsigned int cmd);
int total_registered_spans(void);
diff --git a/include/dahdi/kernel.h b/include/dahdi/kernel.h
index ab2551b..4c17bfa 100644
--- a/include/dahdi/kernel.h
+++ b/include/dahdi/kernel.h
@@ -750,38 +750,7 @@ struct dahdi_count {
#define DAHDI_FLAG_MTP2 DAHDI_FLAG(MTP2)
#define DAHDI_FLAG_HDLC56 DAHDI_FLAG(HDLC56)
-struct dahdi_span {
- spinlock_t lock;
- struct module *owner; /*!< Which module is exporting this span. */
- char name[40]; /*!< Span name */
- char desc[80]; /*!< Span description */
- const char *spantype; /*!< span type in text form */
- const char *manufacturer; /*!< span's device manufacturer */
- char devicetype[80]; /*!< span's device type */
- char location[40]; /*!< span device's location in system */
- int deflaw; /*!< Default law (DAHDI_MULAW or DAHDI_ALAW) */
- int alarms; /*!< Pending alarms on span */
- unsigned long flags;
- int irq; /*!< IRQ for this span's hardware */
- int lbo; /*!< Span Line-Buildout */
- int lineconfig; /*!< Span line configuration */
- int linecompat; /*!< Span line compatibility */
- int channels; /*!< Number of channels in span */
- int txlevel; /*!< Tx level */
- int rxlevel; /*!< Rx level */
- int syncsrc; /*!< current sync src (gets copied here) */
- struct dahdi_count count; /*!< Performance and Error counters */
-
- int maintstat; /*!< Maintenance state */
- wait_queue_head_t maintq; /*!< Maintenance queue */
- int mainttimer; /*!< Maintenance timer */
-
- int irqmisses; /*!< Interrupt misses */
-
- int timingslips; /*!< Clock slips */
-
- struct dahdi_chan **chans; /*!< Member channel structures */
-
+struct dahdi_span_ops {
/* ==== Span Callback Operations ==== */
/*! Req: Set the requested chunk size. This is the unit in which you must
report results for conferencing, etc */
@@ -803,7 +772,6 @@ struct dahdi_span {
/*! Opt: send sync to spans */
int (*sync_tick)(struct dahdi_span *span, int is_master);
#endif
-
/* ==== Channel Callback Operations ==== */
/*! Opt: Set signalling type (if appropriate) */
int (*chanconfig)(struct dahdi_chan *chan, int sigtype);
@@ -817,10 +785,6 @@ struct dahdi_span {
/*! Opt: IOCTL */
int (*ioctl)(struct dahdi_chan *chan, unsigned int cmd, unsigned long data);
- /*! Opt: Provide echo cancellation on a channel */
- int (*echocan_create)(struct dahdi_chan *chan, struct dahdi_echocanparams *ecp,
- struct dahdi_echocanparam *p, struct dahdi_echocan_state **ec);
-
/* Okay, now we get to the signalling. You have several options: */
/* Option 1: If you're a T1 like interface, you can just provide a
@@ -841,24 +805,66 @@ struct dahdi_span {
which handles the individual hook states */
int (*sethook)(struct dahdi_chan *chan, int hookstate);
- /*! Opt: Dacs the contents of chan2 into chan1 if possible */
- int (*dacs)(struct dahdi_chan *chan1, struct dahdi_chan *chan2);
-
/*! Opt: Used to tell an onboard HDLC controller that there is data ready to transmit */
void (*hdlc_hard_xmit)(struct dahdi_chan *chan);
+ /*! If the watchdog detects no received data, it will call the
+ watchdog routine */
+ int (*watchdog)(struct dahdi_span *span, int cause);
+
#ifdef DAHDI_AUDIO_NOTIFY
/*! Opt: audio is used, don't optimize out */
int (*audio_notify)(struct dahdi_chan *chan, int yes);
#endif
+ /*! Opt: Dacs the contents of chan2 into chan1 if possible */
+ int (*dacs)(struct dahdi_chan *chan1, struct dahdi_chan *chan2);
+
+ /*! Opt: Provide echo cancellation on a channel */
+ int (*echocan_create)(struct dahdi_chan *chan,
+ struct dahdi_echocanparams *ecp,
+ struct dahdi_echocanparam *p,
+ struct dahdi_echocan_state **ec);
+};
+
+struct dahdi_span {
+ spinlock_t lock;
+ struct module *owner; /*!< Which module is exporting this span. */
+ char name[40]; /*!< Span name */
+ char desc[80]; /*!< Span description */
+ const char *spantype; /*!< span type in text form */
+ const char *manufacturer; /*!< span's device manufacturer */
+ char devicetype[80]; /*!< span's device type */
+ char location[40]; /*!< span device's location in system */
+ int deflaw; /*!< Default law (DAHDI_MULAW or DAHDI_ALAW) */
+ int alarms; /*!< Pending alarms on span */
+ unsigned long flags;
+ int irq; /*!< IRQ for this span's hardware */
+ int lbo; /*!< Span Line-Buildout */
+ int lineconfig; /*!< Span line configuration */
+ int linecompat; /*!< Span line compatibility */
+ int channels; /*!< Number of channels in span */
+ int txlevel; /*!< Tx level */
+ int rxlevel; /*!< Rx level */
+ int syncsrc; /*!< current sync src (gets copied here) */
+ struct dahdi_count count; /*!< Performance and Error counters */
+
+ int maintstat; /*!< Maintenance state */
+ wait_queue_head_t maintq; /*!< Maintenance queue */
+ int mainttimer; /*!< Maintenance timer */
+
+ int irqmisses; /*!< Interrupt misses */
+ int timingslips; /*!< Clock slips */
+
+ struct dahdi_chan **chans; /*!< Member channel structures */
+
+ const struct dahdi_span_ops *ops; /*!< span callbacks. */
+
/* Used by DAHDI only -- no user servicable parts inside */
int spanno; /*!< Span number for DAHDI */
int offset; /*!< Offset within a given card */
- int lastalarms; /*!< Previous alarms */
- /*! If the watchdog detects no received data, it will call the
- watchdog routine */
- int (*watchdog)(struct dahdi_span *span, int cause);
+ int lastalarms; /*!< Previous alarms */
+
#ifdef CONFIG_DAHDI_WATCHDOG
int watchcounter;
int watchstate;