[svn-commits] sruffell: linux/trunk r8985 - in /linux/trunk: drivers/dahdi/ drivers/dahdi/w...

SVN commits to the Digium repositories svn-commits at lists.digium.com
Sun Jul 25 19:30:52 CDT 2010


Author: sruffell
Date: Sun Jul 25 19:30:41 2010
New Revision: 8985

URL: http://svnview.digium.com/svn/dahdi?view=rev&rev=8985
Log:
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.

Modified:
    linux/trunk/drivers/dahdi/dahdi-base.c
    linux/trunk/drivers/dahdi/dahdi_dynamic.c
    linux/trunk/drivers/dahdi/pciradio.c
    linux/trunk/drivers/dahdi/tor2.c
    linux/trunk/drivers/dahdi/wcb4xxp/base.c
    linux/trunk/drivers/dahdi/wcfxo.c
    linux/trunk/drivers/dahdi/wct1xxp.c
    linux/trunk/drivers/dahdi/wct4xxp/base.c
    linux/trunk/drivers/dahdi/wctdm.c
    linux/trunk/drivers/dahdi/wctdm24xxp/base.c
    linux/trunk/drivers/dahdi/wcte11xp.c
    linux/trunk/drivers/dahdi/wcte12xp/base.c
    linux/trunk/drivers/dahdi/xpp/card_bri.c
    linux/trunk/drivers/dahdi/xpp/card_pri.c
    linux/trunk/drivers/dahdi/xpp/xpp_dahdi.c
    linux/trunk/drivers/dahdi/xpp/xpp_dahdi.h
    linux/trunk/include/dahdi/kernel.h

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=8985&r1=8984&r2=8985
==============================================================================
--- linux/trunk/drivers/dahdi/dahdi-base.c (original)
+++ linux/trunk/drivers/dahdi/dahdi-base.c Sun Jul 25 19:30:41 2010
@@ -508,6 +508,33 @@
 	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 @@
 		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 @@
 	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 @@
 				/* 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 @@
 
 		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 @@
 		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 @@
 		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 @@
 #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 @@
 	/* 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 @@
 			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 @@
 	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 @@
 			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 @@
 		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 @@
 			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 @@
 			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 @@
 		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 @@
 		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 @@
 		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 @@
 				/* 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 @@
 				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 @@
 		/* 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 @@
 			/* 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 @@
 		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 @@
 			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 @@
 		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 @@
 		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 @@
 		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 @@
 			  /* 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 @@
 			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 @@
 			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 @@
 	}
 	/* 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 @@
 				    	/* 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 @@
 		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 @@
 #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);

Modified: linux/trunk/drivers/dahdi/dahdi_dynamic.c
URL: http://svnview.digium.com/svn/dahdi/linux/trunk/drivers/dahdi/dahdi_dynamic.c?view=diff&rev=8985&r1=8984&r2=8985
==============================================================================
--- linux/trunk/drivers/dahdi/dahdi_dynamic.c (original)
+++ linux/trunk/drivers/dahdi/dahdi_dynamic.c Sun Jul 25 19:30:41 2010
@@ -527,6 +527,13 @@
 	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 @@
 	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 |

Modified: linux/trunk/drivers/dahdi/pciradio.c
URL: http://svnview.digium.com/svn/dahdi/linux/trunk/drivers/dahdi/pciradio.c?view=diff&rev=8985&r1=8984&r2=8985
==============================================================================
--- linux/trunk/drivers/dahdi/pciradio.c (original)
+++ linux/trunk/drivers/dahdi/pciradio.c Sun Jul 25 19:30:41 2010
@@ -1458,6 +1458,14 @@
 	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 @@
 	}
 	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)) {

Modified: linux/trunk/drivers/dahdi/tor2.c
URL: http://svnview.digium.com/svn/dahdi/linux/trunk/drivers/dahdi/tor2.c?view=diff&rev=8985&r1=8984&r2=8985
==============================================================================
--- linux/trunk/drivers/dahdi/tor2.c (original)
+++ linux/trunk/drivers/dahdi/tor2.c Sun Jul 25 19:30:41 2010
@@ -259,6 +259,18 @@
 	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 @@
 		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 @@
 		}
 		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);

Modified: linux/trunk/drivers/dahdi/wcb4xxp/base.c
URL: http://svnview.digium.com/svn/dahdi/linux/trunk/drivers/dahdi/wcb4xxp/base.c?view=diff&rev=8985&r1=8984&r2=8985
==============================================================================
--- linux/trunk/drivers/dahdi/wcb4xxp/base.c (original)
+++ linux/trunk/drivers/dahdi/wcb4xxp/base.c Sun Jul 25 19:30:41 2010
@@ -143,8 +143,6 @@
  
 #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,11 +2083,16 @@
 	}
 }
 
-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);
@@ -2308,6 +2311,18 @@
 }
 
 /* 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 @@
 			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;

Modified: linux/trunk/drivers/dahdi/wcfxo.c
URL: http://svnview.digium.com/svn/dahdi/linux/trunk/drivers/dahdi/wcfxo.c?view=diff&rev=8985&r1=8984&r2=8985
==============================================================================
--- linux/trunk/drivers/dahdi/wcfxo.c (original)
+++ linux/trunk/drivers/dahdi/wcfxo.c Sun Jul 25 19:30:41 2010
@@ -638,6 +638,13 @@
 	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 @@
 	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;

Modified: linux/trunk/drivers/dahdi/wct1xxp.c
URL: http://svnview.digium.com/svn/dahdi/linux/trunk/drivers/dahdi/wct1xxp.c?view=diff&rev=8985&r1=8984&r2=8985
==============================================================================
--- linux/trunk/drivers/dahdi/wct1xxp.c (original)
+++ linux/trunk/drivers/dahdi/wct1xxp.c Sun Jul 25 19:30:41 2010
@@ -745,6 +745,19 @@
 
 	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 @@
 	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 @@
 		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;

Modified: linux/trunk/drivers/dahdi/wct4xxp/base.c
URL: http://svnview.digium.com/svn/dahdi/linux/trunk/drivers/dahdi/wct4xxp/base.c?view=diff&rev=8985&r1=8984&r2=8985
==============================================================================
--- linux/trunk/drivers/dahdi/wct4xxp/base.c (original)
+++ linux/trunk/drivers/dahdi/wct4xxp/base.c Sun Jul 25 19:30:41 2010
@@ -385,8 +385,6 @@
 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 @@
 	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 @@
 	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 @@
 	}
 }
 
+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 @@
 			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 @@
 		}
 		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);

Modified: linux/trunk/drivers/dahdi/wctdm.c
URL: http://svnview.digium.com/svn/dahdi/linux/trunk/drivers/dahdi/wctdm.c?view=diff&rev=8985&r1=8984&r2=8985
==============================================================================
--- linux/trunk/drivers/dahdi/wctdm.c (original)
+++ linux/trunk/drivers/dahdi/wctdm.c Sun Jul 25 19:30:41 2010
@@ -2334,6 +2334,14 @@
 	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 @@
 	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");

Modified: linux/trunk/drivers/dahdi/wctdm24xxp/base.c
URL: http://svnview.digium.com/svn/dahdi/linux/trunk/drivers/dahdi/wctdm24xxp/base.c?view=diff&rev=8985&r1=8984&r2=8985
==============================================================================
--- linux/trunk/drivers/dahdi/wctdm24xxp/base.c (original)
+++ linux/trunk/drivers/dahdi/wctdm24xxp/base.c Sun Jul 25 19:30:41 2010
@@ -256,8 +256,6 @@
 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 @@
 				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 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 @@
 	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 @@
 	}
 
 	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 @@
 
 	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;

Modified: linux/trunk/drivers/dahdi/wcte11xp.c
URL: http://svnview.digium.com/svn/dahdi/linux/trunk/drivers/dahdi/wcte11xp.c?view=diff&rev=8985&r1=8984&r2=8985
==============================================================================
--- linux/trunk/drivers/dahdi/wcte11xp.c (original)
+++ linux/trunk/drivers/dahdi/wcte11xp.c Sun Jul 25 19:30:41 2010
@@ -955,6 +955,18 @@
 	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 @@
 	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 @@
 	}
 	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 @@
 		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;

Modified: linux/trunk/drivers/dahdi/wcte12xp/base.c
URL: http://svnview.digium.com/svn/dahdi/linux/trunk/drivers/dahdi/wcte12xp/base.c?view=diff&rev=8985&r1=8984&r2=8985
==============================================================================
--- linux/trunk/drivers/dahdi/wcte12xp/base.c (original)
+++ linux/trunk/drivers/dahdi/wcte12xp/base.c Sun Jul 25 19:30:41 2010
@@ -73,8 +73,6 @@
 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 @@
 	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 @@
 	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 @@
 		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 @@
 		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;

Modified: linux/trunk/drivers/dahdi/xpp/card_bri.c
URL: http://svnview.digium.com/svn/dahdi/linux/trunk/drivers/dahdi/xpp/card_bri.c?view=diff&rev=8985&r1=8984&r2=8985
==============================================================================
--- linux/trunk/drivers/dahdi/xpp/card_bri.c (original)
+++ linux/trunk/drivers/dahdi/xpp/card_bri.c Sun Jul 25 19:30:41 2010
@@ -861,6 +861,27 @@
 	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 @@
 		}
 	}
 	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;
 }
 

Modified: linux/trunk/drivers/dahdi/xpp/card_pri.c
URL: http://svnview.digium.com/svn/dahdi/linux/trunk/drivers/dahdi/xpp/card_pri.c?view=diff&rev=8985&r1=8984&r2=8985
==============================================================================
--- linux/trunk/drivers/dahdi/xpp/card_pri.c (original)
+++ linux/trunk/drivers/dahdi/xpp/card_pri.c Sun Jul 25 19:30:41 2010
@@ -1273,6 +1273,29 @@
 }
 #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,

[... 312 lines stripped ...]



More information about the svn-commits mailing list