summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--drivers/dahdi/dahdi-base.c160
-rw-r--r--drivers/dahdi/dahdi_dynamic.c8
-rw-r--r--drivers/dahdi/tor2.c95
-rw-r--r--drivers/dahdi/wct1xxp.c182
-rw-r--r--drivers/dahdi/wct4xxp/base.c547
-rw-r--r--drivers/dahdi/wcte11xp.c197
-rw-r--r--drivers/dahdi/wcte12xp/base.c102
-rw-r--r--drivers/dahdi/wcte12xp/vpmadt032.c2
-rw-r--r--drivers/dahdi/wcte12xp/wcte12xp.h2
-rw-r--r--drivers/dahdi/xpp/card_fxo.c10
-rw-r--r--drivers/dahdi/xpp/card_fxs.c8
-rw-r--r--drivers/dahdi/xpp/card_pri.c20
-rw-r--r--drivers/dahdi/xpp/xbus-pcm.c18
-rw-r--r--drivers/dahdi/xpp/xpd.h2
-rw-r--r--drivers/dahdi/xpp/xpp_dahdi.c47
-rw-r--r--include/dahdi/kernel.h2
16 files changed, 745 insertions, 657 deletions
diff --git a/drivers/dahdi/dahdi-base.c b/drivers/dahdi/dahdi-base.c
index f2b4cd7..824f095 100644
--- a/drivers/dahdi/dahdi-base.c
+++ b/drivers/dahdi/dahdi-base.c
@@ -3113,7 +3113,7 @@ void dahdi_alarm_notify(struct dahdi_span *span)
if ((!span->alarms) != (!span->lastalarms)) {
span->lastalarms = span->alarms;
for (x = 0; x < span->channels; x++)
- dahdi_alarm_channel(&span->chans[x], span->alarms);
+ dahdi_alarm_channel(span->chans[x], span->alarms);
/* Switch to other master if current master in alarm */
for (x=1; x<maxspans; x++) {
if (spans[x] && !spans[x]->alarms && (spans[x]->flags & DAHDI_FLAG_RUNNING)) {
@@ -3424,7 +3424,7 @@ static int dahdi_common_ioctl(struct inode *node, struct file *file, unsigned in
stack.spaninfo.totalchans = spans[i]->channels;
stack.spaninfo.numchans = 0;
for (j = 0; j < spans[i]->channels; j++) {
- if (spans[i]->chans[j].sig)
+ if (spans[i]->chans[j]->sig)
stack.spaninfo.numchans++;
}
stack.spaninfo.lbo = spans[i]->lbo;
@@ -3536,13 +3536,13 @@ static void recalc_slaves(struct dahdi_chan *chan)
/* Link all slaves appropriately */
for (x=chan->chanpos;x<chan->span->channels;x++)
- if (chan->span->chans[x].master == chan) {
+ if (chan->span->chans[x]->master == chan) {
#ifdef CONFIG_DAHDI_DEBUG
module_printk(KERN_NOTICE, "Channel %s, slave to %s, last is %s, its next will be %d\n",
chan->span->chans[x].name, chan->name, last->name, x);
#endif
last->nextslave = x;
- last = &chan->span->chans[x];
+ last = chan->span->chans[x];
}
/* Terminate list */
last->nextslave = 0;
@@ -3600,12 +3600,12 @@ static int dahdi_ctl_ioctl(struct inode *inode, struct file *file, unsigned int
/* Mark as running and hangup any channels */
spans[j]->flags |= DAHDI_FLAG_RUNNING;
for (x=0;x<spans[j]->channels;x++) {
- y = dahdi_q_sig(&spans[j]->chans[x]) & 0xff;
- if (y >= 0) spans[j]->chans[x].rxsig = (unsigned char)y;
- spin_lock_irqsave(&spans[j]->chans[x].lock, flags);
- dahdi_hangup(&spans[j]->chans[x]);
- spin_unlock_irqrestore(&spans[j]->chans[x].lock, flags);
- spans[j]->chans[x].rxhooksig = DAHDI_RXSIG_INITIAL;
+ y = dahdi_q_sig(spans[j]->chans[x]) & 0xff;
+ if (y >= 0) spans[j]->chans[x]->rxsig = (unsigned char)y;
+ spin_lock_irqsave(&spans[j]->chans[x]->lock, flags);
+ dahdi_hangup(spans[j]->chans[x]);
+ spin_unlock_irqrestore(&spans[j]->chans[x]->lock, flags);
+ spans[j]->chans[x]->rxhooksig = DAHDI_RXSIG_INITIAL;
}
}
return 0;
@@ -5193,8 +5193,8 @@ int dahdi_register(struct dahdi_span *span, int prefmaster)
}
for (x=0;x<span->channels;x++) {
- span->chans[x].span = span;
- dahdi_chan_reg(&span->chans[x]);
+ span->chans[x]->span = span;
+ dahdi_chan_reg(span->chans[x]);
}
#ifdef CONFIG_PROC_FS
@@ -5204,9 +5204,9 @@ int dahdi_register(struct dahdi_span *span, int prefmaster)
for (x = 0; x < span->channels; x++) {
char chan_name[50];
- if (span->chans[x].channo < 250) {
- sprintf(chan_name, "dahdi%d", span->chans[x].channo);
- CLASS_DEV_CREATE(dahdi_class, MKDEV(DAHDI_MAJOR, span->chans[x].channo), NULL, chan_name);
+ if (span->chans[x]->channo < 250) {
+ sprintf(chan_name, "dahdi%d", span->chans[x]->channo);
+ CLASS_DEV_CREATE(dahdi_class, MKDEV(DAHDI_MAJOR, span->chans[x]->channo), NULL, chan_name);
}
}
@@ -5251,15 +5251,15 @@ int dahdi_unregister(struct dahdi_span *span)
#endif /* CONFIG_PROC_FS */
for (x = 0; x < span->channels; x++) {
- if (span->chans[x].channo < 250)
- class_device_destroy(dahdi_class, MKDEV(DAHDI_MAJOR, span->chans[x].channo));
+ if (span->chans[x]->channo < 250)
+ class_device_destroy(dahdi_class, MKDEV(DAHDI_MAJOR, span->chans[x]->channo));
}
spans[span->spanno] = NULL;
span->spanno = 0;
span->flags &= ~DAHDI_FLAG_REGISTERED;
for (x=0;x<span->channels;x++)
- dahdi_chan_unreg(&span->chans[x]);
+ dahdi_chan_unreg(span->chans[x]);
new_maxspans = 0;
new_master = master; /* FIXME: locking */
if (master == span)
@@ -6322,8 +6322,8 @@ void dahdi_ec_span(struct dahdi_span *span)
{
int x;
for (x = 0; x < span->channels; x++) {
- if (span->chans[x].ec_current)
- __dahdi_ec_chunk(&span->chans[x], span->chans[x].readchunk, span->chans[x].writechunk);
+ if (span->chans[x]->ec_current)
+ __dahdi_ec_chunk(span->chans[x], span->chans[x]->readchunk, span->chans[x]->writechunk);
}
}
@@ -7309,22 +7309,22 @@ int dahdi_transmit(struct dahdi_span *span)
#if 1
for (x=0;x<span->channels;x++) {
- spin_lock_irqsave(&span->chans[x].lock, flags);
- if (span->chans[x].flags & DAHDI_FLAG_NOSTDTXRX) {
- spin_unlock_irqrestore(&span->chans[x].lock, flags);
+ spin_lock_irqsave(&span->chans[x]->lock, flags);
+ if (span->chans[x]->flags & DAHDI_FLAG_NOSTDTXRX) {
+ spin_unlock_irqrestore(&span->chans[x]->lock, flags);
continue;
}
- if (&span->chans[x] == span->chans[x].master) {
- if (span->chans[x].otimer) {
- span->chans[x].otimer -= DAHDI_CHUNKSIZE;
- if (span->chans[x].otimer <= 0) {
- __rbs_otimer_expire(&span->chans[x]);
+ if (span->chans[x] == span->chans[x]->master) {
+ if (span->chans[x]->otimer) {
+ span->chans[x]->otimer -= DAHDI_CHUNKSIZE;
+ if (span->chans[x]->otimer <= 0) {
+ __rbs_otimer_expire(span->chans[x]);
}
}
- if (span->chans[x].flags & DAHDI_FLAG_AUDIO) {
- __dahdi_real_transmit(&span->chans[x]);
+ if (span->chans[x]->flags & DAHDI_FLAG_AUDIO) {
+ __dahdi_real_transmit(span->chans[x]);
} else {
- if (span->chans[x].nextslave) {
+ if (span->chans[x]->nextslave) {
u_char data[DAHDI_CHUNKSIZE];
int pos=DAHDI_CHUNKSIZE;
/* Process master/slaves one way */
@@ -7334,30 +7334,30 @@ int dahdi_transmit(struct dahdi_span *span)
do {
if (pos==DAHDI_CHUNKSIZE) {
/* Get next chunk */
- __dahdi_transmit_chunk(&span->chans[x], data);
+ __dahdi_transmit_chunk(span->chans[x], data);
pos = 0;
}
- span->chans[z].writechunk[y] = data[pos++];
- z = span->chans[z].nextslave;
+ span->chans[z]->writechunk[y] = data[pos++];
+ z = span->chans[z]->nextslave;
} while(z);
}
} else {
/* Process independents elsewise */
- __dahdi_real_transmit(&span->chans[x]);
+ __dahdi_real_transmit(span->chans[x]);
}
}
- if (span->chans[x].sig == DAHDI_SIG_DACS_RBS) {
- if (chans[span->chans[x].confna]) {
+ if (span->chans[x]->sig == DAHDI_SIG_DACS_RBS) {
+ if (chans[span->chans[x]->confna]) {
/* 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);
+ 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);
}
}
}
}
- spin_unlock_irqrestore(&span->chans[x].lock, flags);
+ spin_unlock_irqrestore(&span->chans[x]->lock, flags);
}
if (span->mainttimer) {
span->mainttimer -= DAHDI_CHUNKSIZE;
@@ -7383,9 +7383,9 @@ int dahdi_receive(struct dahdi_span *span)
span->watchcounter--;
#endif
for (x=0;x<span->channels;x++) {
- if (span->chans[x].master == &span->chans[x]) {
- spin_lock_irqsave(&span->chans[x].lock, flags);
- if (span->chans[x].nextslave) {
+ if (span->chans[x]->master == span->chans[x]) {
+ spin_lock_irqsave(&span->chans[x]->lock, flags);
+ if (span->chans[x]->nextslave) {
/* Must process each slave at the same time */
u_char data[DAHDI_CHUNKSIZE];
int pos = 0;
@@ -7393,65 +7393,65 @@ int dahdi_receive(struct dahdi_span *span)
/* Put all its slaves, too */
z = x;
do {
- data[pos++] = span->chans[z].readchunk[y];
+ data[pos++] = span->chans[z]->readchunk[y];
if (pos == DAHDI_CHUNKSIZE) {
- if(!(span->chans[x].flags & DAHDI_FLAG_NOSTDTXRX))
- __dahdi_receive_chunk(&span->chans[x], data);
+ if(!(span->chans[x]->flags & DAHDI_FLAG_NOSTDTXRX))
+ __dahdi_receive_chunk(span->chans[x], data);
pos = 0;
}
- z=span->chans[z].nextslave;
+ z=span->chans[z]->nextslave;
} while(z);
}
} else {
/* Process a normal channel */
- if (!(span->chans[x].flags & DAHDI_FLAG_NOSTDTXRX))
- __dahdi_real_receive(&span->chans[x]);
+ if (!(span->chans[x]->flags & DAHDI_FLAG_NOSTDTXRX))
+ __dahdi_real_receive(span->chans[x]);
}
- if (span->chans[x].itimer) {
- span->chans[x].itimer -= DAHDI_CHUNKSIZE;
- if (span->chans[x].itimer <= 0) {
- rbs_itimer_expire(&span->chans[x]);
+ if (span->chans[x]->itimer) {
+ span->chans[x]->itimer -= DAHDI_CHUNKSIZE;
+ if (span->chans[x]->itimer <= 0) {
+ rbs_itimer_expire(span->chans[x]);
}
}
- if (span->chans[x].ringdebtimer)
- span->chans[x].ringdebtimer--;
- if (span->chans[x].sig & __DAHDI_SIG_FXS) {
- if (span->chans[x].rxhooksig == DAHDI_RXSIG_RING)
- span->chans[x].ringtrailer = DAHDI_RINGTRAILER;
- else if (span->chans[x].ringtrailer) {
- span->chans[x].ringtrailer-= DAHDI_CHUNKSIZE;
+ if (span->chans[x]->ringdebtimer)
+ span->chans[x]->ringdebtimer--;
+ if (span->chans[x]->sig & __DAHDI_SIG_FXS) {
+ if (span->chans[x]->rxhooksig == DAHDI_RXSIG_RING)
+ span->chans[x]->ringtrailer = DAHDI_RINGTRAILER;
+ else if (span->chans[x]->ringtrailer) {
+ span->chans[x]->ringtrailer-= DAHDI_CHUNKSIZE;
/* See if RING trailer is expired */
- if (!span->chans[x].ringtrailer && !span->chans[x].ringdebtimer)
- __qevent(&span->chans[x],DAHDI_EVENT_RINGOFFHOOK);
+ if (!span->chans[x]->ringtrailer && !span->chans[x]->ringdebtimer)
+ __qevent(span->chans[x],DAHDI_EVENT_RINGOFFHOOK);
}
}
- if (span->chans[x].pulsetimer)
+ if (span->chans[x]->pulsetimer)
{
- span->chans[x].pulsetimer--;
- if (span->chans[x].pulsetimer <= 0)
+ span->chans[x]->pulsetimer--;
+ if (span->chans[x]->pulsetimer <= 0)
{
- if (span->chans[x].pulsecount)
+ if (span->chans[x]->pulsecount)
{
- if (span->chans[x].pulsecount > 12) {
+ if (span->chans[x]->pulsecount > 12) {
module_printk(KERN_NOTICE, "Got pulse digit %d on %s???\n",
- span->chans[x].pulsecount,
- span->chans[x].name);
- } else if (span->chans[x].pulsecount > 11) {
- __qevent(&span->chans[x], DAHDI_EVENT_PULSEDIGIT | '#');
- } else if (span->chans[x].pulsecount > 10) {
- __qevent(&span->chans[x], DAHDI_EVENT_PULSEDIGIT | '*');
- } else if (span->chans[x].pulsecount > 9) {
- __qevent(&span->chans[x], DAHDI_EVENT_PULSEDIGIT | '0');
+ span->chans[x]->pulsecount,
+ span->chans[x]->name);
+ } else if (span->chans[x]->pulsecount > 11) {
+ __qevent(span->chans[x], DAHDI_EVENT_PULSEDIGIT | '#');
+ } else if (span->chans[x]->pulsecount > 10) {
+ __qevent(span->chans[x], DAHDI_EVENT_PULSEDIGIT | '*');
+ } else if (span->chans[x]->pulsecount > 9) {
+ __qevent(span->chans[x], DAHDI_EVENT_PULSEDIGIT | '0');
} else {
- __qevent(&span->chans[x], DAHDI_EVENT_PULSEDIGIT | ('0' +
- span->chans[x].pulsecount));
+ __qevent(span->chans[x], DAHDI_EVENT_PULSEDIGIT | ('0' +
+ span->chans[x]->pulsecount));
}
- span->chans[x].pulsecount = 0;
+ span->chans[x]->pulsecount = 0;
}
}
}
- spin_unlock_irqrestore(&span->chans[x].lock, flags);
+ spin_unlock_irqrestore(&span->chans[x]->lock, flags);
}
}
diff --git a/drivers/dahdi/dahdi_dynamic.c b/drivers/dahdi/dahdi_dynamic.c
index f29bbda..00e0a66 100644
--- a/drivers/dahdi/dahdi_dynamic.c
+++ b/drivers/dahdi/dahdi_dynamic.c
@@ -236,7 +236,7 @@ static void __ztdynamic_run(void)
/* Ignore dead spans */
for (y=0;y<z->span.channels;y++) {
/* Echo cancel double buffered data */
- dahdi_ec_chunk(&z->span.chans[y], z->span.chans[y].readchunk, z->span.chans[y].writechunk);
+ dahdi_ec_chunk(z->span.chans[y], z->span.chans[y]->readchunk, z->span.chans[y]->writechunk);
}
dahdi_receive(&z->span);
dahdi_transmit(&z->span);
@@ -368,15 +368,15 @@ void dahdi_dynamic_receive(struct dahdi_span *span, unsigned char *msg, int msgl
sig = (bits >> ((x % 4) << 2)) & 0xff;
/* Update signalling if appropriate */
- if (sig != span->chans[x].rxsig)
- dahdi_rbsbits(&span->chans[x], sig);
+ if (sig != span->chans[x]->rxsig)
+ dahdi_rbsbits(span->chans[x], sig);
}
}
/* Record data for channels */
for (x=0;x<nchans;x++) {
- memcpy(span->chans[x].readchunk, msg, DAHDI_CHUNKSIZE);
+ memcpy(span->chans[x]->readchunk, msg, DAHDI_CHUNKSIZE);
msg += DAHDI_CHUNKSIZE;
}
diff --git a/drivers/dahdi/tor2.c b/drivers/dahdi/tor2.c
index 2f51403..2496612 100644
--- a/drivers/dahdi/tor2.c
+++ b/drivers/dahdi/tor2.c
@@ -101,7 +101,7 @@ struct tor2 {
volatile unsigned char *mem8; /* Virtual representation of 8 bit Xilinx memory area */
struct dahdi_span spans[SPANS_PER_CARD]; /* Spans */
struct tor2_span tspans[SPANS_PER_CARD]; /* Span data */
- struct dahdi_chan *chans[SPANS_PER_CARD]; /* Pointers to blocks of 24(30/31) contiguous dahdi_chans for each span */
+ struct dahdi_chan **chans[SPANS_PER_CARD]; /* Pointers to blocks of 24(30/31) contiguous dahdi_chans for each span */
struct tor2_chan tchans[32 * SPANS_PER_CARD]; /* Channel user data */
unsigned char txsigs[SPANS_PER_CARD][16]; /* Copy of tx sig registers */
int loopupcnt[SPANS_PER_CARD]; /* loop up code counter */
@@ -296,7 +296,7 @@ static void init_spans(struct tor2 *tor)
tor->tspans[x].span = x;
init_waitqueue_head(&tor->spans[x].maintq);
for (y=0;y<tor->spans[x].channels;y++) {
- struct dahdi_chan *mychans = tor->chans[x] + y;
+ struct dahdi_chan *mychans = tor->chans[x][y];
sprintf(mychans->name, "Tor2/%d/%d/%d", tor->num, x + 1, y + 1);
mychans->sigcap = DAHDI_SIG_EM | DAHDI_SIG_CLEAR | DAHDI_SIG_FXSLS | DAHDI_SIG_FXSGS | DAHDI_SIG_FXSKS |
DAHDI_SIG_FXOLS | DAHDI_SIG_FXOGS | DAHDI_SIG_FXOKS | DAHDI_SIG_CAS | DAHDI_SIG_SF | DAHDI_SIG_EM_E1;
@@ -343,6 +343,20 @@ static int __devinit tor2_launch(struct tor2 *tor)
return 0;
}
+static void free_tor(struct tor2 *tor)
+{
+ unsigned int x, f;
+
+ for (x = 0; x < SPANS_PER_CARD; x++) {
+ for (f = 0; f < (tor->cardtype == TYPE_E1 ? 31 : 24); f++) {
+ if (tor->chans[x][f]) {
+ kfree(tor->chans[x][f]);
+ }
+ }
+ }
+ kfree(tor);
+}
+
static int __devinit tor2_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
{
int res,x,f;
@@ -359,12 +373,6 @@ static int __devinit tor2_probe(struct pci_dev *pdev, const struct pci_device_id
return -ENOMEM;
memset(tor,0,sizeof(struct tor2));
spin_lock_init(&tor->lock);
- for (x = 0; x < SPANS_PER_CARD; x++) {
- tor->chans[x] = kmalloc(sizeof(struct dahdi_chan) * 31,GFP_KERNEL);
- if (!tor->chans[x])
- return -ENOMEM;
- memset(tor->chans[x],0,sizeof(struct dahdi_chan) * 31);
- }
/* Load the resources */
tor->pci = pdev;
tor->irq = pdev->irq;
@@ -524,7 +532,6 @@ static int __devinit tor2_probe(struct pci_dev *pdev, const struct pci_device_id
#endif
for (x = 0; x < 256; x++) tor->mem32[x] = 0x7f7f7f7f;
-
if (request_irq(tor->irq, tor2_intr, DAHDI_IRQ_SHARED_DISABLED, "tor2", tor)) {
printk(KERN_ERR "Unable to request tormenta IRQ %d\n", tor->irq);
goto err_out_release_all;
@@ -539,6 +546,16 @@ static int __devinit tor2_probe(struct pci_dev *pdev, const struct pci_device_id
tor->cardtype = TYPE_T1;
tor->datxlt = datxlt_t1;
}
+
+ for (x = 0; x < SPANS_PER_CARD; x++) {
+ for (f = 0; f < (tor->cardtype == TYPE_E1 ? 31 : 24); f++) {
+ if (!(tor->chans[x][f] = kmalloc(sizeof(*tor->chans[x][f]), GFP_KERNEL))) {
+ return -ENOMEM;
+ }
+ memset(tor->chans[x][f], 0, sizeof(*tor->chans[x][f]));
+ }
+ }
+
init_spans(tor);
tor->order = tor->mem8[SWREG];
@@ -575,8 +592,7 @@ err_out_free_tor:
if (tor->mem8) iounmap((void *)tor->mem8);
if (tor->mem32) iounmap((void *)tor->mem32);
if (tor) {
- for (x = 0; x < 3; x++) kfree(tor->chans[x]);
- kfree(tor);
+ free_tor(tor);
}
return -ENODEV;
}
@@ -585,8 +601,8 @@ static struct pci_driver tor2_driver;
static void __devexit tor2_remove(struct pci_dev *pdev)
{
- int x;
struct tor2 *tor;
+
tor = pci_get_drvdata(pdev);
if (!tor)
BUG();
@@ -612,10 +628,7 @@ static void __devexit tor2_remove(struct pci_dev *pdev)
cards[tor->num] = 0;
pci_set_drvdata(pdev, NULL);
- for (x = 0; x < 3; x++)
- if (tor->chans[x])
- kfree(tor->chans[x]);
- kfree(tor);
+ free_tor(tor);
}
static struct pci_driver tor2_driver = {
@@ -644,7 +657,7 @@ static void set_clear(struct tor2 *tor)
for (s = 0; s < SPANS_PER_CARD; s++) {
for (i = 0; i < 24; i++) {
j = (i/8);
- if (tor->spans[s].chans[i].flags & DAHDI_FLAG_CLEAR)
+ if (tor->spans[s].chans[i]->flags & DAHDI_FLAG_CLEAR)
val |= 1 << (i % 8);
if ((i % 8)==7) {
@@ -797,9 +810,9 @@ static int tor2_startup(struct dahdi_span *span)
for (i = 0; i < span->channels; i++)
{
memset(p->tor->ec_chunk1[p->span][i],
- DAHDI_LIN2X(0,&span->chans[i]),DAHDI_CHUNKSIZE);
+ DAHDI_LIN2X(0,span->chans[i]),DAHDI_CHUNKSIZE);
memset(p->tor->ec_chunk2[p->span][i],
- DAHDI_LIN2X(0,&span->chans[i]),DAHDI_CHUNKSIZE);
+ DAHDI_LIN2X(0,span->chans[i]),DAHDI_CHUNKSIZE);
}
/* Force re-evaluation of the timing source */
if (timingcable)
@@ -1052,13 +1065,13 @@ static inline void tor2_run(struct tor2 *tor)
need to delay the transmit data 2 entire chunks so
that the transmit will be in sync with the receive */
for (y=0;y<tor->spans[x].channels;y++) {
- dahdi_ec_chunk(&tor->spans[x].chans[y],
- tor->spans[x].chans[y].readchunk,
+ dahdi_ec_chunk(tor->spans[x].chans[y],
+ tor->spans[x].chans[y]->readchunk,
tor->ec_chunk2[x][y]);
memcpy(tor->ec_chunk2[x][y],tor->ec_chunk1[x][y],
DAHDI_CHUNKSIZE);
memcpy(tor->ec_chunk1[x][y],
- tor->spans[x].chans[y].writechunk,
+ tor->spans[x].chans[y]->writechunk,
DAHDI_CHUNKSIZE);
}
dahdi_receive(&tor->spans[x]);
@@ -1199,13 +1212,13 @@ DAHDI_IRQ_HANDLER(tor2_intr)
for (n = 0; n < tor->spans[0].channels; n++) {
for (i = 0; i < DAHDI_CHUNKSIZE; i++) {
/* span 1 */
- txword = tor->spans[0].chans[n].writechunk[i] << 24;
+ txword = tor->spans[0].chans[n]->writechunk[i] << 24;
/* span 2 */
- txword |= tor->spans[1].chans[n].writechunk[i] << 16;
+ txword |= tor->spans[1].chans[n]->writechunk[i] << 16;
/* span 3 */
- txword |= tor->spans[2].chans[n].writechunk[i] << 8;
+ txword |= tor->spans[2].chans[n]->writechunk[i] << 8;
/* span 4 */
- txword |= tor->spans[3].chans[n].writechunk[i];
+ txword |= tor->spans[3].chans[n]->writechunk[i];
/* write to part */
#ifdef FIXTHISFOR64
tor->mem32[tor->datxlt[n] + (32 * i)] = txword;
@@ -1225,13 +1238,13 @@ DAHDI_IRQ_HANDLER(tor2_intr)
rxword = le32_to_cpu(tor->mem32[tor->datxlt[n] + (32 * i)]);
#endif
/* span 1 */
- tor->spans[0].chans[n].readchunk[i] = rxword >> 24;
+ tor->spans[0].chans[n]->readchunk[i] = rxword >> 24;
/* span 2 */
- tor->spans[1].chans[n].readchunk[i] = (rxword & 0xff0000) >> 16;
+ tor->spans[1].chans[n]->readchunk[i] = (rxword & 0xff0000) >> 16;
/* span 3 */
- tor->spans[2].chans[n].readchunk[i] = (rxword & 0xff00) >> 8;
+ tor->spans[2].chans[n]->readchunk[i] = (rxword & 0xff00) >> 8;
/* span 4 */
- tor->spans[3].chans[n].readchunk[i] = rxword & 0xff;
+ tor->spans[3].chans[n]->readchunk[i] = rxword & 0xff;
}
}
@@ -1242,16 +1255,16 @@ DAHDI_IRQ_HANDLER(tor2_intr)
for (k = 1; k <= SPANS_PER_CARD; k++) {
c = t1in(tor,k,0x31 + j);
rxc = c & 15;
- if (rxc != tor->spans[k - 1].chans[j + 16].rxsig) {
+ if (rxc != tor->spans[k - 1].chans[j + 16]->rxsig) {
/* Check for changes in received bits */
- if (!(tor->spans[k - 1].chans[j + 16].sig & DAHDI_SIG_CLEAR))
- dahdi_rbsbits(&tor->spans[k - 1].chans[j + 16], rxc);
+ if (!(tor->spans[k - 1].chans[j + 16]->sig & DAHDI_SIG_CLEAR))
+ dahdi_rbsbits(tor->spans[k - 1].chans[j + 16], rxc);
}
rxc = c >> 4;
- if (rxc != tor->spans[k - 1].chans[j].rxsig) {
+ if (rxc != tor->spans[k - 1].chans[j]->rxsig) {
/* Check for changes in received bits */
- if (!(tor->spans[k - 1].chans[j].sig & DAHDI_SIG_CLEAR))
- dahdi_rbsbits(&tor->spans[k - 1].chans[j], rxc);
+ if (!(tor->spans[k - 1].chans[j]->sig & DAHDI_SIG_CLEAR))
+ dahdi_rbsbits(tor->spans[k - 1].chans[j], rxc);
}
}
}
@@ -1269,10 +1282,10 @@ DAHDI_IRQ_HANDLER(tor2_intr)
rxc = 0;
if (abits & (1 << j)) rxc |= DAHDI_ABIT;
if (bbits & (1 << j)) rxc |= DAHDI_BBIT;
- if (tor->spans[k].chans[i].rxsig != rxc) {
+ if (tor->spans[k].chans[i]->rxsig != rxc) {
/* Check for changes in received bits */
- if (!(tor->spans[k].chans[i].sig & DAHDI_SIG_CLEAR)) {
- dahdi_rbsbits(&tor->spans[k].chans[i], rxc);
+ if (!(tor->spans[k].chans[i]->sig & DAHDI_SIG_CLEAR)) {
+ dahdi_rbsbits(tor->spans[k].chans[i], rxc);
}
}
}
@@ -1357,8 +1370,8 @@ DAHDI_IRQ_HANDLER(tor2_intr)
/* go thru all chans, and count # open */
for (n = 0,k = 0; k < tor->spans[i].channels; k++)
{
- if (((tor->chans[i] + k)->flags & DAHDI_FLAG_OPEN) ||
- ((tor->chans[i] + k)->flags & DAHDI_FLAG_NETDEV)) n++;
+ if (((tor->chans[i][k])->flags & DAHDI_FLAG_OPEN) ||
+ ((tor->chans[i][k])->flags & DAHDI_FLAG_NETDEV)) n++;
}
/* if none open, set alarm condition */
if (!n) j |= DAHDI_ALARM_NOTOPEN;
diff --git a/drivers/dahdi/wct1xxp.c b/drivers/dahdi/wct1xxp.c
index 54377bf..c59cf1a 100644
--- a/drivers/dahdi/wct1xxp.c
+++ b/drivers/dahdi/wct1xxp.c
@@ -161,7 +161,7 @@ struct t1xxp {
unsigned char ec_chunk2[31][DAHDI_CHUNKSIZE];
unsigned char tempo[32];
struct dahdi_span span; /* Span */
- struct dahdi_chan chans[31]; /* Channels */
+ struct dahdi_chan *chans[31]; /* Channels */
};
#define CANARY 0xca1e
@@ -272,7 +272,12 @@ static int control_get_reg(struct t1xxp *wc, int reg)
static void t1xxp_release(struct t1xxp *wc)
{
+ unsigned int x;
+
dahdi_unregister(&wc->span);
+ for (x = 0; x < (wc->ise1 ? 31 : 24); x++) {
+ kfree(wc->chans[x]);
+ }
kfree(wc);
printk("Freed a Wildcard\n");
}
@@ -334,7 +339,7 @@ static void __t1xxp_set_clear(struct t1xxp *wc)
for (x=0;x<3;x++) {
b = 0;
for (y=0;y<8;y++)
- if (wc->chans[x * 8 + y].sig & DAHDI_SIG_CLEAR)
+ if (wc->chans[x * 8 + y]->sig & DAHDI_SIG_CLEAR)
b |= (1 << y);
__t1_set_reg(wc, 0x39 + x, b);
}
@@ -555,14 +560,14 @@ static int t1xxp_rbsbits(struct dahdi_chan *chan, int bits)
spin_lock_irqsave(&wc->lock, flags);
if (wc->ise1) {
if (chan->chanpos < 16) {
- mask = ((bits << 4) | wc->chans[chan->chanpos - 1 + 16].txsig);
+ mask = ((bits << 4) | wc->chans[chan->chanpos - 1 + 16]->txsig);
__t1_set_reg(wc, 0x40 + chan->chanpos, mask);
}
else if (chan->chanpos > 16) {
- mask = (bits | (wc->chans[chan->chanpos - 1 - 16].txsig << 4));
+ mask = (bits | (wc->chans[chan->chanpos - 1 - 16]->txsig << 4));
__t1_set_reg(wc, 0x40 + chan->chanpos - 16, mask);
}
- wc->chans[chan->chanpos - 1].txsig = bits;
+ wc->chans[chan->chanpos - 1]->txsig = bits;
} else {
b = (chan->chanpos - 1) / 8;
o = (chan->chanpos - 1) % 8;
@@ -610,9 +615,9 @@ static int t1xxp_startup(struct dahdi_span *span)
for(i = 0; i < span->channels; i++)
{
memset(wc->ec_chunk1[i],
- DAHDI_LIN2X(0,&span->chans[i]),DAHDI_CHUNKSIZE);
+ DAHDI_LIN2X(0,span->chans[i]),DAHDI_CHUNKSIZE);
memset(wc->ec_chunk2[i],
- DAHDI_LIN2X(0,&span->chans[i]),DAHDI_CHUNKSIZE);
+ DAHDI_LIN2X(0,span->chans[i]),DAHDI_CHUNKSIZE);
}
/* Reset framer with proper parameters and start */
@@ -781,13 +786,13 @@ static int t1xxp_software_init(struct t1xxp *wc)
}
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);
- wc->chans[x].sigcap = DAHDI_SIG_EM | DAHDI_SIG_CLEAR | DAHDI_SIG_EM_E1 |
+ sprintf(wc->chans[x]->name, "WCT1/%d/%d", wc->num, x + 1);
+ wc->chans[x]->sigcap = DAHDI_SIG_EM | DAHDI_SIG_CLEAR | DAHDI_SIG_EM_E1 |
DAHDI_SIG_FXSLS | DAHDI_SIG_FXSGS |
DAHDI_SIG_FXSKS | DAHDI_SIG_FXOLS | DAHDI_SIG_DACS_RBS |
DAHDI_SIG_FXOGS | DAHDI_SIG_FXOKS | DAHDI_SIG_CAS | DAHDI_SIG_SF;
- wc->chans[x].pvt = wc;
- wc->chans[x].chanpos = x + 1;
+ wc->chans[x]->pvt = wc;
+ wc->chans[x]->chanpos = x + 1;
}
if (dahdi_register(&wc->span, 0)) {
printk("Unable to register span with DAHDI\n");
@@ -870,9 +875,9 @@ static void t1xxp_transmitprep(struct t1xxp *wc, int ints)
pos = y * 32 + wc->chanmap[x] + wc->offset;
/* Put channel number as outgoing data */
if (pos < 32 * DAHDI_CHUNKSIZE)
- txbuf[pos] = wc->chans[x].writechunk[y];
+ txbuf[pos] = wc->chans[x]->writechunk[y];
else
- wc->tempo[pos - 32 * DAHDI_CHUNKSIZE] = wc->chans[x].writechunk[y];
+ wc->tempo[pos - 32 * DAHDI_CHUNKSIZE] = wc->chans[x]->writechunk[y];
}
}
}
@@ -905,7 +910,7 @@ static void t1xxp_receiveprep(struct t1xxp *wc, int ints)
for (x=0;x<wc->span.channels;x++) {
/* XXX Optimize, remove * and + XXX */
/* Must map received channels into appropriate data */
- wc->chans[x].readchunk[y] =
+ wc->chans[x]->readchunk[y] =
rxbuf[32 * y + ((wc->chanmap[x] + WC_OFFSET + wc->offset) & 0x1f)];
}
if (!wc->ise1) {
@@ -944,10 +949,9 @@ static void t1xxp_receiveprep(struct t1xxp *wc, int ints)
canary = (unsigned int *)(rxbuf + DAHDI_CHUNKSIZE * 32 - 4);
*canary = (wc->canary++) | (CANARY << 16);
for (x=0;x<wc->span.channels;x++) {
- dahdi_ec_chunk(&wc->chans[x], wc->chans[x].readchunk,
- wc->ec_chunk2[x]);
+ dahdi_ec_chunk(wc->chans[x], wc->chans[x]->readchunk, wc->ec_chunk2[x]);
memcpy(wc->ec_chunk2[x],wc->ec_chunk1[x],DAHDI_CHUNKSIZE);
- memcpy(wc->ec_chunk1[x],wc->chans[x].writechunk,DAHDI_CHUNKSIZE);
+ memcpy(wc->ec_chunk1[x],wc->chans[x]->writechunk,DAHDI_CHUNKSIZE);
}
dahdi_receive(&wc->span);
}
@@ -964,18 +968,18 @@ static void t1xxp_check_sigbits(struct t1xxp *wc, int x)
a = __t1_get_reg(wc, 0x31 + i);
/* Get high channel in low bits */
rxs = (a & 0xf);
- if (!(wc->chans[i+16].sig & DAHDI_SIG_CLEAR)) {
- if (wc->chans[i+16].rxsig != rxs) {
+ if (!(wc->chans[i+16]->sig & DAHDI_SIG_CLEAR)) {
+ if (wc->chans[i+16]->rxsig != rxs) {
spin_unlock_irqrestore(&wc->lock, flags);
- dahdi_rbsbits(&wc->chans[i+16], rxs);
+ dahdi_rbsbits(wc->chans[i+16], rxs);
spin_lock_irqsave(&wc->lock, flags);
}
}
rxs = (a >> 4) & 0xf;
- if (!(wc->chans[i].sig & DAHDI_SIG_CLEAR)) {
- if (wc->chans[i].rxsig != rxs) {
+ if (!(wc->chans[i]->sig & DAHDI_SIG_CLEAR)) {
+ if (wc->chans[i]->rxsig != rxs) {
spin_unlock_irqrestore(&wc->lock, flags);
- dahdi_rbsbits(&wc->chans[i], rxs);
+ dahdi_rbsbits(wc->chans[i], rxs);
spin_lock_irqsave(&wc->lock, flags);
}
}
@@ -990,10 +994,10 @@ static void t1xxp_check_sigbits(struct t1xxp *wc, int x)
rxs |= DAHDI_ABIT;
if (b & (1 << y))
rxs |= DAHDI_BBIT;
- if (!(wc->chans[i].sig & DAHDI_SIG_CLEAR)) {
- if (wc->chans[i].rxsig != rxs) {
+ if (!(wc->chans[i]->sig & DAHDI_SIG_CLEAR)) {
+ if (wc->chans[i]->rxsig != rxs) {
spin_unlock_irqrestore(&wc->lock, flags);
- dahdi_rbsbits(&wc->chans[i], rxs);
+ dahdi_rbsbits(wc->chans[i], rxs);
spin_lock_irqsave(&wc->lock, flags);
}
}
@@ -1058,8 +1062,8 @@ static void t1xxp_check_alarms(struct t1xxp *wc)
if (wc->span.lineconfig & DAHDI_CONFIG_NOTOPEN) {
for (x=0,j=0;x < wc->span.channels;x++)
- if ((wc->chans[x].flags & DAHDI_FLAG_OPEN) ||
- (wc->chans[x].flags & DAHDI_FLAG_NETDEV))
+ if ((wc->chans[x]->flags & DAHDI_FLAG_OPEN) ||
+ (wc->chans[x]->flags & DAHDI_FLAG_NETDEV))
j++;
if (!j)
alarms |= DAHDI_ALARM_NOTOPEN;
@@ -1266,72 +1270,86 @@ static int t1xxp_hardware_init(struct t1xxp *wc)
static int __devinit t1xxp_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
{
- int res;
struct t1xxp *wc;
unsigned int *canary;
+ unsigned int x;
- if (pci_enable_device(pdev)) {
- res = -EIO;
- } else {
- wc = kmalloc(sizeof(struct t1xxp), GFP_KERNEL);
- if (wc) {
- memset(wc, 0x0, sizeof(struct t1xxp));
- spin_lock_init(&wc->lock);
- wc->ioaddr = pci_resource_start(pdev, 0);
- wc->dev = pdev;
- wc->offset = 28; /* And you thought 42 was the answer */
-
- wc->writechunk =
- /* 32 channels, Double-buffer, Read/Write */
- (unsigned char *)pci_alloc_consistent(pdev, DAHDI_MAX_CHUNKSIZE * 32 * 2 * 2, &wc->writedma);
- if (!wc->writechunk) {
- printk("wct1xxp: Unable to allocate DMA-able memory\n");
- return -ENOMEM;
- }
-
- /* Read is after the whole write piece (in bytes) */
- wc->readchunk = wc->writechunk + DAHDI_CHUNKSIZE * 32 * 2;
-
- /* Same thing... */
- wc->readdma = wc->writedma + DAHDI_CHUNKSIZE * 32 * 2;
-
- /* Initialize Write/Buffers to all blank data */
- memset((void *)wc->writechunk,0x00,DAHDI_MAX_CHUNKSIZE * 2 * 2 * 32);
- /* Initialize canary */
- canary = (unsigned int *)(wc->readchunk + DAHDI_CHUNKSIZE * 64 - 4);
- *canary = (CANARY << 16) | (0xffff);
+ if (!pci_enable_device(pdev)) {
+ return -EIO;
+ }
- /* Enable bus mastering */
- pci_set_master(pdev);
+ if (!(wc = kmalloc(sizeof(*wc), GFP_KERNEL))) {
+ return -ENOMEM;
+ }
- /* Keep track of which device we are */
- pci_set_drvdata(pdev, wc);
+ memset(wc, 0x0, sizeof(*wc));
+ spin_lock_init(&wc->lock);
+ wc->ioaddr = pci_resource_start(pdev, 0);
+ wc->dev = pdev;
+ wc->offset = 28; /* And you thought 42 was the answer */
+
+ wc->writechunk =
+ /* 32 channels, Double-buffer, Read/Write */
+ (unsigned char *)pci_alloc_consistent(pdev, DAHDI_MAX_CHUNKSIZE * 32 * 2 * 2, &wc->writedma);
+ if (!wc->writechunk) {
+ printk("wct1xxp: Unable to allocate DMA-able memory\n");
+ return -ENOMEM;
+ }
+
+ /* Read is after the whole write piece (in bytes) */
+ wc->readchunk = wc->writechunk + DAHDI_CHUNKSIZE * 32 * 2;
+
+ /* Same thing... */
+ wc->readdma = wc->writedma + DAHDI_CHUNKSIZE * 32 * 2;
+
+ /* Initialize Write/Buffers to all blank data */
+ memset((void *)wc->writechunk,0x00,DAHDI_MAX_CHUNKSIZE * 2 * 2 * 32);
+ /* Initialize canary */
+ canary = (unsigned int *)(wc->readchunk + DAHDI_CHUNKSIZE * 64 - 4);
+ *canary = (CANARY << 16) | (0xffff);
+
+ /* Enable bus mastering */
+ pci_set_master(pdev);
+
+ /* Keep track of which device we are */
+ pci_set_drvdata(pdev, wc);
+
+ if (request_irq(pdev->irq, t1xxp_interrupt, DAHDI_IRQ_SHARED_DISABLED, "t1xxp", wc)) {
+ printk("t1xxp: Unable to request IRQ %d\n", pdev->irq);
+ kfree(wc);
+ return -EIO;
+ }
+ /* Initialize hardware */
+ t1xxp_hardware_init(wc);
+
+ /* We now know which version of card we have */
+ if (wc->ise1) {
+ wc->variety = "Digium Wildcard E100P E1/PRA";
+ } else {
+ wc->variety = "Digium Wildcard T100P T1/PRI";
+ }
- if (request_irq(pdev->irq, t1xxp_interrupt, DAHDI_IRQ_SHARED_DISABLED, "t1xxp", wc)) {
- printk("t1xxp: Unable to request IRQ %d\n", pdev->irq);
- kfree(wc);
- return -EIO;
+ for (x = 0; x < (wc->ise1 ? 31 : 24); x++) {
+ if (!(wc->chans[x] = kmalloc(sizeof(*wc->chans[x]), GFP_KERNEL))) {
+ while (x) {
+ kfree(wc->chans[--x]);
}
- /* Initialize hardware */
- t1xxp_hardware_init(wc);
- /* We now know which version of card we have */
- if (wc->ise1)
- wc->variety = "Digium Wildcard E100P E1/PRA";
- else
- wc->variety = "Digium Wildcard T100P T1/PRI";
+ kfree(wc);
+ return -ENOMEM;
+ }
+ memset(wc->chans[x], 0, sizeof(*wc->chans[x]));
+ }
- /* Misc. software stuff */
- t1xxp_software_init(wc);
+ /* Misc. software stuff */
+ t1xxp_software_init(wc);
+
+ printk("Found a Wildcard: %s\n", wc->variety);
- printk("Found a Wildcard: %s\n", wc->variety);
- res = 0;
- } else
- res = -ENOMEM;
- }
- return res;
+ return 0;
}
+
static void t1xxp_stop_stuff(struct t1xxp *wc)
{
/* Kill clock */
diff --git a/drivers/dahdi/wct4xxp/base.c b/drivers/dahdi/wct4xxp/base.c
index 66d1433..65ae0b1 100644
--- a/drivers/dahdi/wct4xxp/base.c
+++ b/drivers/dahdi/wct4xxp/base.c
@@ -282,7 +282,7 @@ struct t4_span {
#ifdef ENABLE_WORKQUEUES
struct work_struct swork;
#endif
- struct dahdi_chan chans[0]; /* Individual channels */
+ struct dahdi_chan *chans[32]; /* Individual channels */
};
struct t4 {
@@ -743,7 +743,7 @@ static void t4_check_vpm450(struct t4 *wc)
guessed it. */
if (test_bit(channel, &wc->tspans[span]->dtmfmutemask)) {
unsigned long flags;
- struct dahdi_chan *chan = &wc->tspans[span]->span.chans[channel];
+ struct dahdi_chan *chan = wc->tspans[span]->span.chans[channel];
int y;
spin_lock_irqsave(&chan->lock, flags);
for (y=0;y<chan->numbufs;y++) {
@@ -753,10 +753,10 @@ static void t4_check_vpm450(struct t4 *wc)
spin_unlock_irqrestore(&chan->lock, flags);
}
set_bit(channel, &wc->tspans[span]->dtmfactive);
- dahdi_qevent_lock(&wc->tspans[span]->span.chans[channel], (DAHDI_EVENT_DTMFDOWN | tone));
+ dahdi_qevent_lock(wc->tspans[span]->span.chans[channel], (DAHDI_EVENT_DTMFDOWN | tone));
} else {
clear_bit(channel, &wc->tspans[span]->dtmfactive);
- dahdi_qevent_lock(&wc->tspans[span]->span.chans[channel], (DAHDI_EVENT_DTMFUP | tone));
+ dahdi_qevent_lock(wc->tspans[span]->span.chans[channel], (DAHDI_EVENT_DTMFUP | tone));
}
}
}
@@ -800,21 +800,21 @@ static void t4_check_vpm400(struct t4 *wc, unsigned int newio)
digit = vpm_digits[regbyte];
if (!(wc->tspans[0]->spanflags & FLAG_VPM2GEN)) {
energy = t4_vpm_in(wc, x, 0x58 + channel);
- energy = DAHDI_XLAW(energy, ts->chans);
+ energy = DAHDI_XLAW(energy, ts->chans[0]);
ts->dtmfenergy[base] = energy;
}
set_bit(base, &ts->dtmfactive);
if (ts->dtmfdigit[base]) {
if (ts->dtmfmask & (1 << base))
- dahdi_qevent_lock(&ts->span.chans[base], (DAHDI_EVENT_DTMFUP | ts->dtmfdigit[base]));
+ dahdi_qevent_lock(ts->span.chans[base], (DAHDI_EVENT_DTMFUP | ts->dtmfdigit[base]));
}
ts->dtmfdigit[base] = digit;
if (test_bit(base, &ts->dtmfmask))
- dahdi_qevent_lock(&ts->span.chans[base], (DAHDI_EVENT_DTMFDOWN | digit));
+ dahdi_qevent_lock(ts->span.chans[base], (DAHDI_EVENT_DTMFDOWN | digit));
if (test_bit(base, &ts->dtmfmutemask)) {
/* Mute active receive buffer*/
unsigned long flags;
- struct dahdi_chan *chan = &ts->span.chans[base];
+ struct dahdi_chan *chan = ts->span.chans[base];
int y;
spin_lock_irqsave(&chan->lock, flags);
for (y=0;y<chan->numbufs;y++) {
@@ -850,7 +850,7 @@ static void t4_check_vpm400(struct t4 *wc, unsigned int newio)
clear_bit(base, &ts->dtmfactive);
if (ts->dtmfdigit[base]) {
if (test_bit(base, &ts->dtmfmask))
- dahdi_qevent_lock(&ts->span.chans[base], (DAHDI_EVENT_DTMFUP | ts->dtmfdigit[base]));
+ dahdi_qevent_lock(ts->span.chans[base], (DAHDI_EVENT_DTMFUP | ts->dtmfdigit[base]));
}
digit = ts->dtmfdigit[base];
ts->dtmfdigit[base] = 0;
@@ -982,7 +982,7 @@ static void __set_clear(struct t4 *wc, int span)
if ((ts->spantype == TYPE_T1) || (ts->spantype == TYPE_J1)) {
for (i=0;i<24;i++) {
j = (i/8);
- if (ts->span.chans[i].flags & DAHDI_FLAG_CLEAR) {
+ if (ts->span.chans[i]->flags & DAHDI_FLAG_CLEAR) {
val |= 1 << (7 - (i % 8));
ts->notclear &= ~(1 << i);
} else
@@ -997,7 +997,7 @@ static void __set_clear(struct t4 *wc, int span)
}
} else {
for (i=0;i<31;i++) {
- if (ts->span.chans[i].flags & DAHDI_FLAG_CLEAR)
+ if (ts->span.chans[i]->flags & DAHDI_FLAG_CLEAR)
ts->notclear &= ~(1 << i);
else
ts->notclear |= (1 << i);
@@ -1603,7 +1603,7 @@ static void init_spans(struct t4 *wc)
ts->readchunk = (void *)(wc->readchunk + x * 32 * 2);
init_waitqueue_head(&ts->span.maintq);
for (y=0;y<wc->tspans[x]->span.channels;y++) {
- struct dahdi_chan *mychans = ts->chans + y;
+ struct dahdi_chan *mychans = ts->chans[y];
sprintf(mychans->name, "TE%d/%d/%d/%d", wc->numspans, wc->num, x + 1, y + 1);
mychans->sigcap = DAHDI_SIG_EM | DAHDI_SIG_CLEAR | DAHDI_SIG_FXSLS | DAHDI_SIG_FXSGS | DAHDI_SIG_FXSKS | DAHDI_SIG_HARDHDLC | DAHDI_SIG_MTP2 |
DAHDI_SIG_FXOLS | DAHDI_SIG_FXOGS | DAHDI_SIG_FXOKS | DAHDI_SIG_CAS | DAHDI_SIG_EM_E1 | DAHDI_SIG_DACS_RBS;
@@ -2011,9 +2011,9 @@ static int t4_startup(struct dahdi_span *span)
for(i = 0; i < span->channels; i++)
{
memset(ts->ec_chunk1[i],
- DAHDI_LIN2X(0,&span->chans[i]),DAHDI_CHUNKSIZE);
+ DAHDI_LIN2X(0,span->chans[i]),DAHDI_CHUNKSIZE);
memset(ts->ec_chunk2[i],
- DAHDI_LIN2X(0,&span->chans[i]),DAHDI_CHUNKSIZE);
+ DAHDI_LIN2X(0,span->chans[i]),DAHDI_CHUNKSIZE);
}
#endif
/* Force re-evaluation fo timing source */
@@ -2146,11 +2146,11 @@ static void t4_receiveprep(struct t4 *wc, int irq)
/* All T1/E1 channels */
tmp = readchunk[z+1+offset];
if (wc->numspans == 4) {
- wc->tspans[3]->span.chans[z].readchunk[x] = tmp & 0xff;
- wc->tspans[2]->span.chans[z].readchunk[x] = (tmp & 0xff00) >> 8;
+ wc->tspans[3]->span.chans[z]->readchunk[x] = tmp & 0xff;
+ wc->tspans[2]->span.chans[z]->readchunk[x] = (tmp & 0xff00) >> 8;
}
- wc->tspans[1]->span.chans[z].readchunk[x] = (tmp & 0xff0000) >> 16;
- wc->tspans[0]->span.chans[z].readchunk[x] = tmp >> 24;
+ wc->tspans[1]->span.chans[z]->readchunk[x] = (tmp & 0xff0000) >> 16;
+ wc->tspans[0]->span.chans[z]->readchunk[x] = tmp >> 24;
}
if (wc->t1e1) {
if (wc->e1recover > 0)
@@ -2167,14 +2167,14 @@ static void t4_receiveprep(struct t4 *wc, int irq)
tmp = readchunk[z+1];
if (wc->numspans == 4) {
if (wc->tspans[3]->span.channels > 24)
- wc->tspans[3]->span.chans[z].readchunk[x] = tmp & 0xff;
+ wc->tspans[3]->span.chans[z]->readchunk[x] = tmp & 0xff;
if (wc->tspans[2]->span.channels > 24)
- wc->tspans[2]->span.chans[z].readchunk[x] = (tmp & 0xff00) >> 8;
+ wc->tspans[2]->span.chans[z]->readchunk[x] = (tmp & 0xff00) >> 8;
}
if (wc->tspans[1]->span.channels > 24)
- wc->tspans[1]->span.chans[z].readchunk[x] = (tmp & 0xff0000) >> 16;
+ wc->tspans[1]->span.chans[z]->readchunk[x] = (tmp & 0xff0000) >> 16;
if (wc->tspans[0]->span.channels > 24)
- wc->tspans[0]->span.chans[z].readchunk[x] = tmp >> 24;
+ wc->tspans[0]->span.chans[z]->readchunk[x] = tmp >> 24;
}
}
/* Advance pointer by 4 TDM frame lengths */
@@ -2184,13 +2184,13 @@ static void t4_receiveprep(struct t4 *wc, int irq)
if (wc->tspans[x]->span.flags & DAHDI_FLAG_RUNNING) {
for (y=0;y<wc->tspans[x]->span.channels;y++) {
/* Echo cancel double buffered data */
- dahdi_ec_chunk(&wc->tspans[x]->span.chans[y],
- wc->tspans[x]->span.chans[y].readchunk,
+ dahdi_ec_chunk(wc->tspans[x]->span.chans[y],
+ wc->tspans[x]->span.chans[y]->readchunk,
wc->tspans[x]->ec_chunk2[y]);
memcpy(wc->tspans[x]->ec_chunk2[y],wc->tspans[x]->ec_chunk1[y],
DAHDI_CHUNKSIZE);
memcpy(wc->tspans[x]->ec_chunk1[y],
- wc->tspans[x]->span.chans[y].writechunk,
+ wc->tspans[x]->span.chans[y]->writechunk,
DAHDI_CHUNKSIZE);
}
dahdi_receive(&wc->tspans[x]->span);
@@ -2213,7 +2213,7 @@ static inline void __receive_span(struct t4_span *ts)
for (y=0;y<ts->span.channels;y++) {
/* Mute any DTMFs which are supposed to be muted */
if (test_bit(y, &merged)) {
- memset(ts->span.chans[y].readchunk, DAHDI_XLAW(0, (ts->span.chans + y)), DAHDI_CHUNKSIZE);
+ memset(ts->span.chans[y]->readchunk, DAHDI_XLAW(0, ts->span.chans[y]), DAHDI_CHUNKSIZE);
}
}
}
@@ -2296,10 +2296,10 @@ static void t4_transmitprep(struct t4 *wc, int irq)
/* Once per chunk */
for (z=0;z<24;z++) {
/* All T1/E1 channels */
- tmp = (wc->tspans[3]->span.chans[z].writechunk[x]) |
- (wc->tspans[2]->span.chans[z].writechunk[x] << 8) |
- (wc->tspans[1]->span.chans[z].writechunk[x] << 16) |
- (wc->tspans[0]->span.chans[z].writechunk[x] << 24);
+ tmp = (wc->tspans[3]->span.chans[z]->writechunk[x]) |
+ (wc->tspans[2]->span.chans[z]->writechunk[x] << 8) |
+ (wc->tspans[1]->span.chans[z]->writechunk[x] << 16) |
+ (wc->tspans[0]->span.chans[z]->writechunk[x] << 24);
writechunk[z+offset] = tmp;
}
if (wc->t1e1) {
@@ -2308,14 +2308,14 @@ static void t4_transmitprep(struct t4 *wc, int irq)
tmp = 0;
if (wc->numspans == 4) {
if (wc->tspans[3]->span.channels > 24)
- tmp |= wc->tspans[3]->span.chans[z].writechunk[x];
+ tmp |= wc->tspans[3]->span.chans[z]->writechunk[x];
if (wc->tspans[2]->span.channels > 24)
- tmp |= (wc->tspans[2]->span.chans[z].writechunk[x] << 8);
+ tmp |= (wc->tspans[2]->span.chans[z]->writechunk[x] << 8);
}
if (wc->tspans[1]->span.channels > 24)
- tmp |= (wc->tspans[1]->span.chans[z].writechunk[x] << 16);
+ tmp |= (wc->tspans[1]->span.chans[z]->writechunk[x] << 16);
if (wc->tspans[0]->span.channels > 24)
- tmp |= (wc->tspans[0]->span.chans[z].writechunk[x] << 24);
+ tmp |= (wc->tspans[0]->span.chans[z]->writechunk[x] << 24);
writechunk[z] = tmp;
}
}
@@ -2341,14 +2341,14 @@ static void t4_check_sigbits(struct t4 *wc, int span)
a = t4_framer_in(wc, span, 0x71 + i);
/* Get high channel in low bits */
rxs = (a & 0xf);
- if (!(ts->span.chans[i+16].sig & DAHDI_SIG_CLEAR)) {
- if (ts->span.chans[i+16].rxsig != rxs)
- dahdi_rbsbits(&ts->span.chans[i+16], rxs);
+ if (!(ts->span.chans[i+16]->sig & DAHDI_SIG_CLEAR)) {
+ if (ts->span.chans[i+16]->rxsig != rxs)
+ dahdi_rbsbits(ts->span.chans[i+16], rxs);
}
rxs = (a >> 4) & 0xf;
- if (!(ts->span.chans[i].sig & DAHDI_SIG_CLEAR)) {
- if (ts->span.chans[i].rxsig != rxs)
- dahdi_rbsbits(&ts->span.chans[i], rxs);
+ if (!(ts->span.chans[i]->sig & DAHDI_SIG_CLEAR)) {
+ if (ts->span.chans[i]->rxsig != rxs)
+ dahdi_rbsbits(ts->span.chans[i], rxs);
}
}
} else if (ts->span.lineconfig & DAHDI_CONFIG_D4) {
@@ -2356,24 +2356,24 @@ static void t4_check_sigbits(struct t4 *wc, int span)
a = t4_framer_in(wc, span, 0x70 + (i>>2));
/* Get high channel in low bits */
rxs = (a & 0x3) << 2;
- if (!(ts->span.chans[i+3].sig & DAHDI_SIG_CLEAR)) {
- if (ts->span.chans[i+3].rxsig != rxs)
- dahdi_rbsbits(&ts->span.chans[i+3], rxs);
+ if (!(ts->span.chans[i+3]->sig & DAHDI_SIG_CLEAR)) {
+ if (ts->span.chans[i+3]->rxsig != rxs)
+ dahdi_rbsbits(ts->span.chans[i+3], rxs);
}
rxs = (a & 0xc);
- if (!(ts->span.chans[i+2].sig & DAHDI_SIG_CLEAR)) {
- if (ts->span.chans[i+2].rxsig != rxs)
- dahdi_rbsbits(&ts->span.chans[i+2], rxs);
+ if (!(ts->span.chans[i+2]->sig & DAHDI_SIG_CLEAR)) {
+ if (ts->span.chans[i+2]->rxsig != rxs)
+ dahdi_rbsbits(ts->span.chans[i+2], rxs);
}
rxs = (a >> 2) & 0xc;
- if (!(ts->span.chans[i+1].sig & DAHDI_SIG_CLEAR)) {
- if (ts->span.chans[i+1].rxsig != rxs)
- dahdi_rbsbits(&ts->span.chans[i+1], rxs);
+ if (!(ts->span.chans[i+1]->sig & DAHDI_SIG_CLEAR)) {
+ if (ts->span.chans[i+1]->rxsig != rxs)
+ dahdi_rbsbits(ts->span.chans[i+1], rxs);
}
rxs = (a >> 4) & 0xc;
- if (!(ts->span.chans[i].sig & DAHDI_SIG_CLEAR)) {
- if (ts->span.chans[i].rxsig != rxs)
- dahdi_rbsbits(&ts->span.chans[i], rxs);
+ if (!(ts->span.chans[i]->sig & DAHDI_SIG_CLEAR)) {
+ if (ts->span.chans[i]->rxsig != rxs)
+ dahdi_rbsbits(ts->span.chans[i], rxs);
}
}
} else {
@@ -2381,17 +2381,17 @@ static void t4_check_sigbits(struct t4 *wc, int span)
a = t4_framer_in(wc, span, 0x70 + (i>>1));
/* Get high channel in low bits */
rxs = (a & 0xf);
- if (!(ts->span.chans[i+1].sig & DAHDI_SIG_CLEAR)) {
+ if (!(ts->span.chans[i+1]->sig & DAHDI_SIG_CLEAR)) {
/* XXX Not really reset on every trans! XXX */
- if (ts->span.chans[i+1].rxsig != rxs) {
- dahdi_rbsbits(&ts->span.chans[i+1], rxs);
+ if (ts->span.chans[i+1]->rxsig != rxs) {
+ dahdi_rbsbits(ts->span.chans[i+1], rxs);
}
}
rxs = (a >> 4) & 0xf;
- if (!(ts->span.chans[i].sig & DAHDI_SIG_CLEAR)) {
+ if (!(ts->span.chans[i]->sig & DAHDI_SIG_CLEAR)) {
/* XXX Not really reset on every trans! XXX */
- if (ts->span.chans[i].rxsig != rxs) {
- dahdi_rbsbits(&ts->span.chans[i], rxs);
+ if (ts->span.chans[i]->rxsig != rxs) {
+ dahdi_rbsbits(ts->span.chans[i], rxs);
}
}
}
@@ -2465,8 +2465,8 @@ static void t4_check_alarms(struct t4 *wc, int span)
if (ts->span.lineconfig & DAHDI_CONFIG_NOTOPEN) {
for (x=0,j=0;x < ts->span.channels;x++)
- if ((ts->span.chans[x].flags & DAHDI_FLAG_OPEN) ||
- (ts->span.chans[x].flags & DAHDI_FLAG_NETDEV))
+ if ((ts->span.chans[x]->flags & DAHDI_FLAG_OPEN) ||
+ (ts->span.chans[x]->flags & DAHDI_FLAG_NETDEV))
j++;
if (!j)
alarms |= DAHDI_ALARM_NOTOPEN;
@@ -3480,197 +3480,220 @@ static int __devinit t4_launch(struct t4 *wc)
return 0;
}
+static void free_wc(struct t4 *wc)
+{
+ unsigned int x, y;
+
+ for (x = 0; x < sizeof(wc->tspans)/sizeof(wc->tspans[0]); x++) {
+ if (!wc->tspans[x]) {
+ continue;
+ }
+
+ for (y = 0; y < sizeof(wc->tspans[x]->chans)/sizeof(wc->tspans[x]->chans[0]); y++) {
+ if (wc->tspans[x]->chans[y]) {
+ kfree(wc->tspans[x]->chans[y]);
+ }
+ }
+ kfree(wc->tspans[x]);
+ }
+ kfree(wc);
+}
+
static int __devinit t4_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
{
- int res;
struct t4 *wc;
struct devtype *dt;
- int x,f;
+ unsigned int x, f;
int basesize;
#if 0
int y;
unsigned int *canary;
#endif
-
if (pci_enable_device(pdev)) {
- res = -EIO;
- } else {
- wc = kmalloc(sizeof(struct t4), GFP_KERNEL);
- if (wc) {
- memset(wc, 0x0, sizeof(struct t4));
- spin_lock_init(&wc->reglock);
- dt = (struct devtype *)(ent->driver_data);
- if (dt->flags & FLAG_2NDGEN)
- basesize = DAHDI_MAX_CHUNKSIZE * 32 * 4;
- else
- basesize = DAHDI_MAX_CHUNKSIZE * 32 * 2 * 4;
-
- if (dt->flags & FLAG_2PORT)
- wc->numspans = 2;
- else
- wc->numspans = 4;
+ return -EIO;
+ }
- wc->variety = dt->desc;
+ if (!(wc = kmalloc(sizeof(*wc), GFP_KERNEL))) {
+ return -ENOMEM;
+ }
- wc->memaddr = pci_resource_start(pdev, 0);
- wc->memlen = pci_resource_len(pdev, 0);
- wc->membase = ioremap(wc->memaddr, wc->memlen);
- /* This rids of the Double missed interrupt message after loading */
- wc->last0 = 1;
+ memset(wc, 0x0, sizeof(*wc));
+ spin_lock_init(&wc->reglock);
+ dt = (struct devtype *) (ent->driver_data);
+ if (dt->flags & FLAG_2NDGEN)
+ basesize = DAHDI_MAX_CHUNKSIZE * 32 * 4;
+ else
+ basesize = DAHDI_MAX_CHUNKSIZE * 32 * 2 * 4;
+
+ if (dt->flags & FLAG_2PORT)
+ wc->numspans = 2;
+ else
+ wc->numspans = 4;
+
+ wc->variety = dt->desc;
+
+ wc->memaddr = pci_resource_start(pdev, 0);
+ wc->memlen = pci_resource_len(pdev, 0);
+ wc->membase = ioremap(wc->memaddr, wc->memlen);
+ /* This rids of the Double missed interrupt message after loading */
+ wc->last0 = 1;
#if 0
- if (!request_mem_region(wc->memaddr, wc->memlen, wc->variety))
- printk("wct4: Unable to request memory region :(, using anyway...\n");
+ if (!request_mem_region(wc->memaddr, wc->memlen, wc->variety))
+ printk("wct4: Unable to request memory region :(, using anyway...\n");
#endif
- if (pci_request_regions(pdev, wc->variety))
- printk("wct%dxxp: Unable to request regions\n", wc->numspans);
-
- printk("Found TE%dXXP at base address %08lx, remapped to %p\n", wc->numspans, wc->memaddr, wc->membase);
-
- wc->dev = pdev;
-
- wc->writechunk =
- /* 32 channels, Double-buffer, Read/Write, 4 spans */
- (unsigned int *)pci_alloc_consistent(pdev, basesize * 2, &wc->writedma);
- if (!wc->writechunk) {
- printk("wct%dxxp: Unable to allocate DMA-able memory\n", wc->numspans);
- return -ENOMEM;
- }
-
- /* Read is after the whole write piece (in words) */
- wc->readchunk = wc->writechunk + basesize / 4;
-
- /* Same thing but in bytes... */
- wc->readdma = wc->writedma + basesize;
-
- /* Initialize Write/Buffers to all blank data */
- memset((void *)wc->writechunk,0x00, basesize);
- memset((void *)wc->readchunk,0xff, basesize);
+ if (pci_request_regions(pdev, wc->variety))
+ printk("wct%dxxp: Unable to request regions\n", wc->numspans);
+
+ printk("Found TE%dXXP at base address %08lx, remapped to %p\n", wc->numspans, wc->memaddr, wc->membase);
+
+ wc->dev = pdev;
+
+ wc->writechunk =
+ /* 32 channels, Double-buffer, Read/Write, 4 spans */
+ (unsigned int *)pci_alloc_consistent(pdev, basesize * 2, &wc->writedma);
+ if (!wc->writechunk) {
+ printk("wct%dxxp: Unable to allocate DMA-able memory\n", wc->numspans);
+ return -ENOMEM;
+ }
+
+ /* Read is after the whole write piece (in words) */
+ wc->readchunk = wc->writechunk + basesize / 4;
+
+ /* Same thing but in bytes... */
+ wc->readdma = wc->writedma + basesize;
+
+ /* Initialize Write/Buffers to all blank data */
+ memset((void *)wc->writechunk,0x00, basesize);
+ memset((void *)wc->readchunk,0xff, basesize);
#if 0
- memset((void *)wc->readchunk,0xff,DAHDI_MAX_CHUNKSIZE * 2 * 32 * 4);
- /* Initialize canary */
- canary = (unsigned int *)(wc->readchunk + DAHDI_CHUNKSIZE * 64 * 4 - 4);
- *canary = (CANARY << 16) | (0xffff);
+ memset((void *)wc->readchunk,0xff,DAHDI_MAX_CHUNKSIZE * 2 * 32 * 4);
+ /* Initialize canary */
+ canary = (unsigned int *)(wc->readchunk + DAHDI_CHUNKSIZE * 64 * 4 - 4);
+ *canary = (CANARY << 16) | (0xffff);
#endif
+
+ /* Enable bus mastering */
+ pci_set_master(pdev);
- /* Enable bus mastering */
- pci_set_master(pdev);
-
- /* Keep track of which device we are */
- pci_set_drvdata(pdev, wc);
+ /* Keep track of which device we are */
+ pci_set_drvdata(pdev, wc);
+
+ /* Initialize hardware */
+ t4_hardware_init_1(wc, dt->flags);
+
+ for(x = 0; x < MAX_T4_CARDS; x++) {
+ if (!cards[x])
+ break;
+ }
+
+ if (x >= MAX_T4_CARDS) {
+ printk("No cards[] slot available!!\n");
+ kfree(wc);
+ return -ENOMEM;
+ }
+
+ wc->num = x;
+ cards[x] = wc;
+
+#ifdef ENABLE_WORKQUEUES
+ if (dt->flags & FLAG_2NDGEN) {
+ char tmp[20];
- /* Initialize hardware */
- t4_hardware_init_1(wc, dt->flags);
+ sprintf(tmp, "te%dxxp[%d]", wc->numspans, wc->num);
+ wc->workq = create_workqueue(tmp);
+ }
+#endif
- for(x = 0; x < MAX_T4_CARDS; x++) {
- if (!cards[x]) break;
- }
+ /* Allocate pieces we need here */
+ for (x = 0; x < wc->numspans; x++) {
+ if (!(wc->tspans[x] = kmalloc(sizeof(*wc->tspans[x]), GFP_KERNEL))) {
+ free_wc(wc);
+ return -ENOMEM;
+ }
- if (x >= MAX_T4_CARDS) {
- printk("No cards[] slot available!!\n");
- return -ENOMEM;
- }
+ memset(wc->tspans[x], 0, sizeof(*wc->tspans[x]));
- wc->num = x;
- cards[x] = wc;
-
+ if (wc->t1e1 & (1 << x)) {
+ wc->tspans[x]->spantype = TYPE_E1;
+ } else {
+ if (j1mode)
+ wc->tspans[x]->spantype = TYPE_J1;
+ else
+ wc->tspans[x]->spantype = TYPE_T1;
+ }
-#ifdef ENABLE_WORKQUEUES
- if (dt->flags & FLAG_2NDGEN) {
- char tmp[20];
- sprintf(tmp, "te%dxxp[%d]", wc->numspans, wc->num);
- wc->workq = create_workqueue(tmp);
+ for (f = 0; f < (wc->tspans[x]->spantype == TYPE_E1 ? 31 : 24); f++) {
+ if (!(wc->tspans[x]->chans[f] = kmalloc(sizeof(*wc->tspans[x]->chans[f]), GFP_KERNEL))) {
+ free_wc(wc);
+ return -ENOMEM;
}
-#endif
+ memset(wc->tspans[x]->chans[f], 0, sizeof(*wc->tspans[x]->chans[f]));
+ }
- /* Allocate pieces we need here */
- for (x=0;x<4;x++) {
- if (wc->t1e1 & (1 << x)) {
- wc->tspans[x] = kmalloc(sizeof(struct t4_span) + sizeof(struct dahdi_chan) * 31, GFP_KERNEL);
- if (wc->tspans[x]) {
- memset(wc->tspans[x], 0, sizeof(struct t4_span) + sizeof(struct dahdi_chan) * 31);
- wc->tspans[x]->spantype = TYPE_E1;
- }
- } else {
- wc->tspans[x] = kmalloc(sizeof(struct t4_span) + sizeof(struct dahdi_chan) * 24, GFP_KERNEL);
- if (wc->tspans[x]) {
- memset(wc->tspans[x], 0, sizeof(struct t4_span) + sizeof(struct dahdi_chan) * 24);
- if (j1mode)
- wc->tspans[x]->spantype = TYPE_J1;
- else
- wc->tspans[x]->spantype = TYPE_T1;
- }
- }
- if (!wc->tspans[x])
- return -ENOMEM;
#ifdef ENABLE_WORKQUEUES
- INIT_WORK(&wc->tspans[x]->swork, workq_handlespan, wc->tspans[x]);
+ INIT_WORK(&wc->tspans[x]->swork, workq_handlespan, wc->tspans[x]);
#endif
- wc->tspans[x]->spanflags |= dt->flags;
- }
-
-
- /* Continue hardware intiialization */
- t4_hardware_init_2(wc);
-
-
+ wc->tspans[x]->spanflags |= dt->flags;
+ }
+
+ /* Continue hardware intiialization */
+ t4_hardware_init_2(wc);
+
#ifdef SUPPORT_GEN1
- if (request_irq(pdev->irq, (dt->flags & FLAG_2NDGEN) ? t4_interrupt_gen2 :t4_interrupt, DAHDI_IRQ_SHARED_DISABLED, (wc->numspans == 2) ? "wct2xxp" : "wct4xxp", wc))
+ if (request_irq(pdev->irq, (dt->flags & FLAG_2NDGEN) ? t4_interrupt_gen2 : t4_interrupt, DAHDI_IRQ_SHARED_DISABLED, (wc->numspans == 2) ? "wct2xxp" : "wct4xxp", wc))
#else
- if (!(wc->tspans[0]->spanflags & FLAG_2NDGEN)) {
- printk("This driver does not support 1st gen modules\n");
- kfree(wc);
- return -ENODEV;
- }
- if (request_irq(pdev->irq, t4_interrupt_gen2, DAHDI_IRQ_SHARED_DISABLED, "t4xxp", wc))
-#endif
- {
- printk("t4xxp: Unable to request IRQ %d\n", pdev->irq);
- kfree(wc);
- return -EIO;
- }
-
- init_spans(wc);
-
- /* Launch cards as appropriate */
- for (;;) {
- /* Find a card to activate */
- f = 0;
- for (x=0;cards[x];x++) {
- if (cards[x]->order <= highestorder) {
- t4_launch(cards[x]);
- if (cards[x]->order == highestorder)
- f = 1;
- }
- }
- /* If we found at least one, increment the highest order and search again, otherwise stop */
- if (f)
- highestorder++;
- else
- break;
+ if (!(wc->tspans[0]->spanflags & FLAG_2NDGEN)) {
+ printk("This driver does not support 1st gen modules\n");
+ free_wc(wc);
+ return -ENODEV;
+ }
+ if (request_irq(pdev->irq, t4_interrupt_gen2, DAHDI_IRQ_SHARED_DISABLED, "t4xxp", wc))
+#endif
+ {
+ printk("t4xxp: Unable to request IRQ %d\n", pdev->irq);
+ free_wc(wc);
+ return -EIO;
+ }
+
+ init_spans(wc);
+
+ /* Launch cards as appropriate */
+ for (;;) {
+ /* Find a card to activate */
+ f = 0;
+ for (x = 0; cards[x]; x++) {
+ if (cards[x]->order <= highestorder) {
+ t4_launch(cards[x]);
+ if (cards[x]->order == highestorder)
+ f = 1;
}
-
- printk("Found a Wildcard: %s\n", wc->variety);
- wc->gpio = 0x00000000;
- t4_pci_out(wc, WC_GPIO, wc->gpio);
- t4_gpio_setdir(wc, (1 << 17), (1 << 17));
- t4_gpio_setdir(wc, (0xff), (0xff));
-
+ }
+ /* If we found at least one, increment the highest order and search again, otherwise stop */
+ if (f)
+ highestorder++;
+ else
+ break;
+ }
+
+ printk("Found a Wildcard: %s\n", wc->variety);
+ wc->gpio = 0x00000000;
+ t4_pci_out(wc, WC_GPIO, wc->gpio);
+ t4_gpio_setdir(wc, (1 << 17), (1 << 17));
+ t4_gpio_setdir(wc, (0xff), (0xff));
+
#if 0
- for (x=0;x<0x10000;x++) {
- __t4_raw_oct_out(wc, 0x0004, x);
- __t4_raw_oct_out(wc, 0x000a, x ^ 0xffff);
- if (__t4_raw_oct_in(wc, 0x0004) != x)
- printk("Register 4 failed %04x\n", x);
- if (__t4_raw_oct_in(wc, 0x000a) != (x ^ 0xffff))
- printk("Register 10 failed %04x\n", x);
- }
-#endif
- res = 0;
- } else
- res = -ENOMEM;
+ for (x=0;x<0x10000;x++) {
+ __t4_raw_oct_out(wc, 0x0004, x);
+ __t4_raw_oct_out(wc, 0x000a, x ^ 0xffff);
+ if (__t4_raw_oct_in(wc, 0x0004) != x)
+ printk("Register 4 failed %04x\n", x);
+ if (__t4_raw_oct_in(wc, 0x000a) != (x ^ 0xffff))
+ printk("Register 10 failed %04x\n", x);
}
- return res;
+#endif
+
+ return 0;
}
static int t4_hardware_stop(struct t4 *wc)
@@ -3701,53 +3724,51 @@ static int t4_hardware_stop(struct t4 *wc)
static void __devexit t4_remove_one(struct pci_dev *pdev)
{
struct t4 *wc = pci_get_drvdata(pdev);
- int x;
- if (wc) {
- /* Stop hardware */
- t4_hardware_stop(wc);
-
- /* Release vpm450m */
- if (wc->vpm450m)
- release_vpm450m(wc->vpm450m);
- wc->vpm450m = NULL;
- /* Unregister spans */
- if (wc->tspans[0]->span.flags & DAHDI_FLAG_REGISTERED)
- dahdi_unregister(&wc->tspans[0]->span);
- if (wc->tspans[1]->span.flags & DAHDI_FLAG_REGISTERED)
- dahdi_unregister(&wc->tspans[1]->span);
- if (wc->numspans == 4) {
- if (wc->tspans[2]->span.flags & DAHDI_FLAG_REGISTERED)
- dahdi_unregister(&wc->tspans[2]->span);
- if (wc->tspans[3]->span.flags & DAHDI_FLAG_REGISTERED)
- dahdi_unregister(&wc->tspans[3]->span);
- }
-#ifdef ENABLE_WORKQUEUES
- if (wc->workq) {
- flush_workqueue(wc->workq);
- destroy_workqueue(wc->workq);
- }
-#endif
-
- free_irq(pdev->irq, wc);
-
- if (wc->membase)
- iounmap((void *)wc->membase);
-
- pci_release_regions(pdev);
- /* Immediately free resources */
- pci_free_consistent(pdev, DAHDI_MAX_CHUNKSIZE * 2 * 2 * 32 * 4, (void *)wc->writechunk, wc->writedma);
-
- order_index[wc->order]--;
+ if (!wc) {
+ return;
+ }
- cards[wc->num] = NULL;
- pci_set_drvdata(pdev, NULL);
- for (x=0;x<wc->numspans;x++) {
- if (wc->tspans[x])
- kfree(wc->tspans[x]);
- }
- kfree(wc);
+ /* Stop hardware */
+ t4_hardware_stop(wc);
+
+ /* Release vpm450m */
+ if (wc->vpm450m)
+ release_vpm450m(wc->vpm450m);
+ wc->vpm450m = NULL;
+ /* Unregister spans */
+ if (wc->tspans[0]->span.flags & DAHDI_FLAG_REGISTERED)
+ dahdi_unregister(&wc->tspans[0]->span);
+ if (wc->tspans[1]->span.flags & DAHDI_FLAG_REGISTERED)
+ dahdi_unregister(&wc->tspans[1]->span);
+ if (wc->numspans == 4) {
+ if (wc->tspans[2]->span.flags & DAHDI_FLAG_REGISTERED)
+ dahdi_unregister(&wc->tspans[2]->span);
+ if (wc->tspans[3]->span.flags & DAHDI_FLAG_REGISTERED)
+ dahdi_unregister(&wc->tspans[3]->span);
+ }
+#ifdef ENABLE_WORKQUEUES
+ if (wc->workq) {
+ flush_workqueue(wc->workq);
+ destroy_workqueue(wc->workq);
}
+#endif
+
+ free_irq(pdev->irq, wc);
+
+ if (wc->membase)
+ iounmap((void *)wc->membase);
+
+ pci_release_regions(pdev);
+
+ /* Immediately free resources */
+ pci_free_consistent(pdev, DAHDI_MAX_CHUNKSIZE * 2 * 2 * 32 * 4, (void *)wc->writechunk, wc->writedma);
+
+ order_index[wc->order]--;
+
+ cards[wc->num] = NULL;
+ pci_set_drvdata(pdev, NULL);
+ free_wc(wc);
}
diff --git a/drivers/dahdi/wcte11xp.c b/drivers/dahdi/wcte11xp.c
index f454bc4..f829036 100644
--- a/drivers/dahdi/wcte11xp.c
+++ b/drivers/dahdi/wcte11xp.c
@@ -178,7 +178,7 @@ struct t1 {
unsigned char ec_chunk2[32][DAHDI_CHUNKSIZE];
unsigned char tempo[33];
struct dahdi_span span; /* Span */
- struct dahdi_chan chans[32]; /* Channels */
+ struct dahdi_chan *chans[32]; /* Channels */
};
#define CANARY 0xca1e
@@ -342,7 +342,12 @@ static inline void t1_framer_out(struct t1 *wc, const unsigned int addr, const u
static void t1xxp_release(struct t1 *wc)
{
+ unsigned int x;
+
dahdi_unregister(&wc->span);
+ for (x = 0; x < (wc->spantype == TYPE_E1 ? 31 : 24); x++) {
+ kfree(wc->chans[x]);
+ }
kfree(wc);
printk("Freed a Wildcard\n");
}
@@ -400,7 +405,7 @@ static void __t1xxp_set_clear(struct t1 *wc)
unsigned short val=0;
for (i=0;i<24;i++) {
j = (i/8);
- if (wc->span.chans[i].flags & DAHDI_FLAG_CLEAR)
+ if (wc->span.chans[i]->flags & DAHDI_FLAG_CLEAR)
val |= 1 << (7 - (i % 8));
if ((i % 8)==7) {
if (debug > 1)
@@ -564,18 +569,18 @@ static void t1_check_sigbits(struct t1 *wc)
a = __t1_framer_in(wc, 0x71 + i);
/* Get high channel in low bits */
rxs = (a & 0xf);
- if (!(wc->span.chans[i+16].sig & DAHDI_SIG_CLEAR)) {
- if (wc->span.chans[i+16].rxsig != rxs) {
+ if (!(wc->span.chans[i+16]->sig & DAHDI_SIG_CLEAR)) {
+ if (wc->span.chans[i+16]->rxsig != rxs) {
spin_unlock_irqrestore(&wc->lock, flags);
- dahdi_rbsbits(&wc->span.chans[i+16], rxs);
+ dahdi_rbsbits(wc->span.chans[i+16], rxs);
spin_lock_irqsave(&wc->lock, flags);
}
}
rxs = (a >> 4) & 0xf;
- if (!(wc->span.chans[i].sig & DAHDI_SIG_CLEAR)) {
- if (wc->span.chans[i].rxsig != rxs) {
+ if (!(wc->span.chans[i]->sig & DAHDI_SIG_CLEAR)) {
+ if (wc->span.chans[i]->rxsig != rxs) {
spin_unlock_irqrestore(&wc->lock, flags);
- dahdi_rbsbits(&wc->span.chans[i], rxs);
+ dahdi_rbsbits(wc->span.chans[i], rxs);
spin_lock_irqsave(&wc->lock, flags);
}
}
@@ -585,34 +590,34 @@ static void t1_check_sigbits(struct t1 *wc)
a = __t1_framer_in(wc, 0x70 + (i>>2));
/* Get high channel in low bits */
rxs = (a & 0x3) << 2;
- if (!(wc->span.chans[i+3].sig & DAHDI_SIG_CLEAR)) {
- if (wc->span.chans[i+3].rxsig != rxs) {
+ if (!(wc->span.chans[i+3]->sig & DAHDI_SIG_CLEAR)) {
+ if (wc->span.chans[i+3]->rxsig != rxs) {
spin_unlock_irqrestore(&wc->lock, flags);
- dahdi_rbsbits(&wc->span.chans[i+3], rxs);
+ dahdi_rbsbits(wc->span.chans[i+3], rxs);
spin_lock_irqsave(&wc->lock, flags);
}
}
rxs = (a & 0xc);
- if (!(wc->span.chans[i+2].sig & DAHDI_SIG_CLEAR)) {
- if (wc->span.chans[i+2].rxsig != rxs) {
+ if (!(wc->span.chans[i+2]->sig & DAHDI_SIG_CLEAR)) {
+ if (wc->span.chans[i+2]->rxsig != rxs) {
spin_unlock_irqrestore(&wc->lock, flags);
- dahdi_rbsbits(&wc->span.chans[i+2], rxs);
+ dahdi_rbsbits(wc->span.chans[i+2], rxs);
spin_lock_irqsave(&wc->lock, flags);
}
}
rxs = (a >> 2) & 0xc;
- if (!(wc->span.chans[i+1].sig & DAHDI_SIG_CLEAR)) {
- if (wc->span.chans[i+1].rxsig != rxs) {
+ if (!(wc->span.chans[i+1]->sig & DAHDI_SIG_CLEAR)) {
+ if (wc->span.chans[i+1]->rxsig != rxs) {
spin_unlock_irqrestore(&wc->lock, flags);
- dahdi_rbsbits(&wc->span.chans[i+1], rxs);
+ dahdi_rbsbits(wc->span.chans[i+1], rxs);
spin_lock_irqsave(&wc->lock, flags);
}
}
rxs = (a >> 4) & 0xc;
- if (!(wc->span.chans[i].sig & DAHDI_SIG_CLEAR)) {
- if (wc->span.chans[i].rxsig != rxs) {
+ if (!(wc->span.chans[i]->sig & DAHDI_SIG_CLEAR)) {
+ if (wc->span.chans[i]->rxsig != rxs) {
spin_unlock_irqrestore(&wc->lock, flags);
- dahdi_rbsbits(&wc->span.chans[i], rxs);
+ dahdi_rbsbits(wc->span.chans[i], rxs);
spin_lock_irqsave(&wc->lock, flags);
}
}
@@ -622,18 +627,18 @@ static void t1_check_sigbits(struct t1 *wc)
a = __t1_framer_in(wc, 0x70 + (i>>1));
/* Get high channel in low bits */
rxs = (a & 0xf);
- if (!(wc->span.chans[i+1].sig & DAHDI_SIG_CLEAR)) {
- if (wc->span.chans[i+1].rxsig != rxs) {
+ if (!(wc->span.chans[i+1]->sig & DAHDI_SIG_CLEAR)) {
+ if (wc->span.chans[i+1]->rxsig != rxs) {
spin_unlock_irqrestore(&wc->lock, flags);
- dahdi_rbsbits(&wc->span.chans[i+1], rxs);
+ dahdi_rbsbits(wc->span.chans[i+1], rxs);
spin_lock_irqsave(&wc->lock, flags);
}
}
rxs = (a >> 4) & 0xf;
- if (!(wc->span.chans[i].sig & DAHDI_SIG_CLEAR)) {
- if (wc->span.chans[i].rxsig != rxs) {
+ if (!(wc->span.chans[i]->sig & DAHDI_SIG_CLEAR)) {
+ if (wc->span.chans[i]->rxsig != rxs) {
spin_unlock_irqrestore(&wc->lock, flags);
- dahdi_rbsbits(&wc->span.chans[i], rxs);
+ dahdi_rbsbits(wc->span.chans[i], rxs);
spin_lock_irqsave(&wc->lock, flags);
}
}
@@ -888,9 +893,9 @@ static int t1xxp_startup(struct dahdi_span *span)
for(i = 0; i < span->channels; i++)
{
memset(wc->ec_chunk1[i],
- DAHDI_LIN2X(0,&span->chans[i]),DAHDI_CHUNKSIZE);
+ DAHDI_LIN2X(0,span->chans[i]),DAHDI_CHUNKSIZE);
memset(wc->ec_chunk2[i],
- DAHDI_LIN2X(0,&span->chans[i]),DAHDI_CHUNKSIZE);
+ DAHDI_LIN2X(0,span->chans[i]),DAHDI_CHUNKSIZE);
}
/* Reset framer with proper parameters and start */
@@ -998,13 +1003,13 @@ static int t1xxp_software_init(struct t1 *wc)
wc->span.pvt = wc;
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);
- wc->chans[x].sigcap = DAHDI_SIG_EM | DAHDI_SIG_CLEAR | DAHDI_SIG_EM_E1 |
+ sprintf(wc->chans[x]->name, "WCT1/%d/%d", wc->num, x + 1);
+ wc->chans[x]->sigcap = DAHDI_SIG_EM | DAHDI_SIG_CLEAR | DAHDI_SIG_EM_E1 |
DAHDI_SIG_FXSLS | DAHDI_SIG_FXSGS | DAHDI_SIG_MTP2 |
DAHDI_SIG_FXSKS | DAHDI_SIG_FXOLS | DAHDI_SIG_DACS_RBS |
DAHDI_SIG_FXOGS | DAHDI_SIG_FXOKS | DAHDI_SIG_CAS | DAHDI_SIG_SF;
- wc->chans[x].pvt = wc;
- wc->chans[x].chanpos = x + 1;
+ wc->chans[x]->pvt = wc;
+ wc->chans[x]->chanpos = x + 1;
}
if (dahdi_register(&wc->span, 0)) {
printk("Unable to register span with DAHDI\n");
@@ -1087,9 +1092,9 @@ static void t1xxp_transmitprep(struct t1 *wc, int ints)
pos = y * 32 + wc->chanmap[x] + wc->offset;
/* Put channel number as outgoing data */
if (pos < 32 * DAHDI_CHUNKSIZE)
- txbuf[pos] = wc->chans[x].writechunk[y];
+ txbuf[pos] = wc->chans[x]->writechunk[y];
else
- wc->tempo[pos - 32 * DAHDI_CHUNKSIZE] = wc->chans[x].writechunk[y];
+ wc->tempo[pos - 32 * DAHDI_CHUNKSIZE] = wc->chans[x]->writechunk[y];
}
}
}
@@ -1122,7 +1127,7 @@ static void t1xxp_receiveprep(struct t1 *wc, int ints)
for (x=0;x<wc->span.channels;x++) {
/* XXX Optimize, remove * and + XXX */
/* Must map received channels into appropriate data */
- wc->chans[x].readchunk[y] =
+ wc->chans[x]->readchunk[y] =
rxbuf[32 * y + ((wc->chanmap[x] + WC_OFFSET + wc->offset) & 0x1f)];
}
if (wc->spantype != TYPE_E1) {
@@ -1161,10 +1166,9 @@ static void t1xxp_receiveprep(struct t1 *wc, int ints)
canary = (unsigned int *)(rxbuf + DAHDI_CHUNKSIZE * 32 - 4);
*canary = (wc->canary++) | (CANARY << 16);
for (x=0;x<wc->span.channels;x++) {
- dahdi_ec_chunk(&wc->chans[x], wc->chans[x].readchunk,
- wc->ec_chunk2[x]);
+ dahdi_ec_chunk(wc->chans[x], wc->chans[x]->readchunk, wc->ec_chunk2[x]);
memcpy(wc->ec_chunk2[x],wc->ec_chunk1[x],DAHDI_CHUNKSIZE);
- memcpy(wc->ec_chunk1[x],wc->chans[x].writechunk,DAHDI_CHUNKSIZE);
+ memcpy(wc->ec_chunk1[x],wc->chans[x]->writechunk,DAHDI_CHUNKSIZE);
}
dahdi_receive(&wc->span);
}
@@ -1238,8 +1242,8 @@ static void t1_check_alarms(struct t1 *wc)
if (wc->span.lineconfig & DAHDI_CONFIG_NOTOPEN) {
for (x=0,j=0;x < wc->span.channels;x++)
- if ((wc->span.chans[x].flags & DAHDI_FLAG_OPEN) ||
- (wc->span.chans[x].flags & DAHDI_FLAG_NETDEV))
+ if ((wc->span.chans[x]->flags & DAHDI_FLAG_OPEN) ||
+ (wc->span.chans[x]->flags & DAHDI_FLAG_NETDEV))
j++;
if (!j)
alarms |= DAHDI_ALARM_NOTOPEN;
@@ -1466,67 +1470,78 @@ static int t1xxp_hardware_init(struct t1 *wc)
static int __devinit t1xxp_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
{
- int res;
struct t1 *wc;
unsigned int *canary;
+ unsigned int x;
if (pci_enable_device(pdev)) {
- res = -EIO;
- } else {
- wc = kmalloc(sizeof(struct t1), GFP_KERNEL);
- if (wc) {
- memset(wc, 0x0, sizeof(struct t1));
- spin_lock_init(&wc->lock);
- wc->ioaddr = pci_resource_start(pdev, 0);
- wc->dev = pdev;
- wc->offset = 28; /* And you thought 42 was the answer */
-
- wc->writechunk =
- /* 32 channels, Double-buffer, Read/Write */
- (unsigned char *)pci_alloc_consistent(pdev, DAHDI_MAX_CHUNKSIZE * 32 * 2 * 2, &wc->writedma);
- if (!wc->writechunk) {
+ return -EIO;
+ }
+ if (!(wc = kmalloc(sizeof(*wc), GFP_KERNEL))) {
+ return -ENOMEM;
+ }
+
+ memset(wc, 0x0, sizeof(*wc));
+ spin_lock_init(&wc->lock);
+ wc->ioaddr = pci_resource_start(pdev, 0);
+ wc->dev = pdev;
+ wc->offset = 28; /* And you thought 42 was the answer */
+
+ wc->writechunk =
+ /* 32 channels, Double-buffer, Read/Write */
+ (unsigned char *)pci_alloc_consistent(pdev, DAHDI_MAX_CHUNKSIZE * 32 * 2 * 2, &wc->writedma);
+ if (!wc->writechunk) {
printk("wcte11xp: Unable to allocate DMA-able memory\n");
return -ENOMEM;
+ }
+
+ /* Read is after the whole write piece (in bytes) */
+ wc->readchunk = wc->writechunk + DAHDI_CHUNKSIZE * 32 * 2;
+
+ /* Same thing... */
+ wc->readdma = wc->writedma + DAHDI_CHUNKSIZE * 32 * 2;
+
+ /* Initialize Write/Buffers to all blank data */
+ memset((void *)wc->writechunk,0x00,DAHDI_MAX_CHUNKSIZE * 2 * 2 * 32);
+ /* Initialize canary */
+ canary = (unsigned int *)(wc->readchunk + DAHDI_CHUNKSIZE * 64 - 4);
+ *canary = (CANARY << 16) | (0xffff);
+
+ /* Enable bus mastering */
+ pci_set_master(pdev);
+
+ /* Keep track of which device we are */
+ pci_set_drvdata(pdev, wc);
+
+ if (request_irq(pdev->irq, t1xxp_interrupt, DAHDI_IRQ_SHARED_DISABLED, "wcte11xp", wc)) {
+ printk("wcte11xp: Unable to request IRQ %d\n", pdev->irq);
+ kfree(wc);
+ return -EIO;
+ }
+ /* Initialize hardware */
+ t1xxp_hardware_init(wc);
+
+ /* We now know which version of card we have */
+ wc->variety = "Digium Wildcard TE110P T1/E1";
+
+ for (x = 0; x < (wc->spantype == TYPE_E1 ? 31 : 24); x++) {
+ if (!(wc->chans[x] = kmalloc(sizeof(*wc->chans[x]), GFP_KERNEL))) {
+ while (x) {
+ kfree(wc->chans[--x]);
}
- /* Read is after the whole write piece (in bytes) */
- wc->readchunk = wc->writechunk + DAHDI_CHUNKSIZE * 32 * 2;
-
- /* Same thing... */
- wc->readdma = wc->writedma + DAHDI_CHUNKSIZE * 32 * 2;
-
- /* Initialize Write/Buffers to all blank data */
- memset((void *)wc->writechunk,0x00,DAHDI_MAX_CHUNKSIZE * 2 * 2 * 32);
- /* Initialize canary */
- canary = (unsigned int *)(wc->readchunk + DAHDI_CHUNKSIZE * 64 - 4);
- *canary = (CANARY << 16) | (0xffff);
-
- /* Enable bus mastering */
- pci_set_master(pdev);
-
- /* Keep track of which device we are */
- pci_set_drvdata(pdev, wc);
-
- if (request_irq(pdev->irq, t1xxp_interrupt, DAHDI_IRQ_SHARED_DISABLED, "wcte11xp", wc)) {
- printk("wcte11xp: Unable to request IRQ %d\n", pdev->irq);
- kfree(wc);
- return -EIO;
- }
- /* Initialize hardware */
- t1xxp_hardware_init(wc);
-
- /* We now know which version of card we have */
- wc->variety = "Digium Wildcard TE110P T1/E1";
+ kfree(wc);
+ return -ENOMEM;
+ }
+ memset(wc->chans[x], 0, sizeof(*wc->chans[x]));
+ }
- /* Misc. software stuff */
- t1xxp_software_init(wc);
+ /* Misc. software stuff */
+ t1xxp_software_init(wc);
+
+ printk("Found a Wildcard: %s\n", wc->variety);
- printk("Found a Wildcard: %s\n", wc->variety);
- res = 0;
- } else
- res = -ENOMEM;
- }
- return res;
+ return 0;
}
static void t1xxp_stop_stuff(struct t1 *wc)
diff --git a/drivers/dahdi/wcte12xp/base.c b/drivers/dahdi/wcte12xp/base.c
index 422b704..3b284f5 100644
--- a/drivers/dahdi/wcte12xp/base.c
+++ b/drivers/dahdi/wcte12xp/base.c
@@ -437,7 +437,7 @@ static void __t1xxp_set_clear(struct t1 *wc, int channo)
for (i = 0; i < 24; i++) {
j = (i / 8);
- if (wc->span.chans[i].flags & DAHDI_FLAG_CLEAR)
+ if (wc->span.chans[i]->flags & DAHDI_FLAG_CLEAR)
val |= 1 << (7 - (i % 8));
if (((i % 8)==7) && /* write byte every 8 channels */
((channo < 0) || /* channo=-1 means all channels */
@@ -452,7 +452,12 @@ static void __t1xxp_set_clear(struct t1 *wc, int channo)
static void t1_release(struct t1 *wc)
{
+ unsigned int x;
+
dahdi_unregister(&wc->span);
+ for (x = 0; x < (wc->spantype == TYPE_E1 ? 31 : 24); x++) {
+ kfree(wc->chans[x]);
+ }
kfree(wc);
printk("Freed a Wildcard TE12xP\n");
}
@@ -688,8 +693,8 @@ static int t1xxp_startup(struct dahdi_span *span)
/* initialize the start value for the entire chunk of last ec buffer */
for (i = 0; i < span->channels; i++) {
- memset(wc->ec_chunk1[i], DAHDI_LIN2X(0, &span->chans[i]), DAHDI_CHUNKSIZE);
- memset(wc->ec_chunk2[i], DAHDI_LIN2X(0, &span->chans[i]), DAHDI_CHUNKSIZE);
+ memset(wc->ec_chunk1[i], DAHDI_LIN2X(0, span->chans[i]), DAHDI_CHUNKSIZE);
+ memset(wc->ec_chunk2[i], DAHDI_LIN2X(0, span->chans[i]), DAHDI_CHUNKSIZE);
}
/* Reset framer with proper parameters and start */
@@ -831,18 +836,18 @@ static inline void __t1_check_sigbits(struct t1 *wc)
if (a > -1) {
/* Get high channel in low bits */
rxs = (a & 0xf);
- if (!(wc->span.chans[i+16].sig & DAHDI_SIG_CLEAR)) {
- if (wc->span.chans[i+16].rxsig != rxs) {
+ if (!(wc->span.chans[i+16]->sig & DAHDI_SIG_CLEAR)) {
+ if (wc->span.chans[i+16]->rxsig != rxs) {
spin_unlock(&wc->reglock);
- dahdi_rbsbits(&wc->span.chans[i+16], rxs);
+ dahdi_rbsbits(wc->span.chans[i+16], rxs);
spin_lock(&wc->reglock);
}
}
rxs = (a >> 4) & 0xf;
- if (!(wc->span.chans[i].sig & DAHDI_SIG_CLEAR)) {
- if (wc->span.chans[i].rxsig != rxs) {
+ if (!(wc->span.chans[i]->sig & DAHDI_SIG_CLEAR)) {
+ if (wc->span.chans[i]->rxsig != rxs) {
spin_unlock(&wc->reglock);
- dahdi_rbsbits(&wc->span.chans[i], rxs);
+ dahdi_rbsbits(wc->span.chans[i], rxs);
spin_lock(&wc->reglock);
}
}
@@ -854,34 +859,34 @@ static inline void __t1_check_sigbits(struct t1 *wc)
if (a > -1) {
/* Get high channel in low bits */
rxs = (a & 0x3) << 2;
- if (!(wc->span.chans[i+3].sig & DAHDI_SIG_CLEAR)) {
- if (wc->span.chans[i+3].rxsig != rxs) {
+ if (!(wc->span.chans[i+3]->sig & DAHDI_SIG_CLEAR)) {
+ if (wc->span.chans[i+3]->rxsig != rxs) {
spin_unlock(&wc->reglock);
- dahdi_rbsbits(&wc->span.chans[i+3], rxs);
+ dahdi_rbsbits(wc->span.chans[i+3], rxs);
spin_lock(&wc->reglock);
}
}
rxs = (a & 0xc);
- if (!(wc->span.chans[i+2].sig & DAHDI_SIG_CLEAR)) {
- if (wc->span.chans[i+2].rxsig != rxs) {
+ if (!(wc->span.chans[i+2]->sig & DAHDI_SIG_CLEAR)) {
+ if (wc->span.chans[i+2]->rxsig != rxs) {
spin_unlock(&wc->reglock);
- dahdi_rbsbits(&wc->span.chans[i+2], rxs);
+ dahdi_rbsbits(wc->span.chans[i+2], rxs);
spin_lock(&wc->reglock);
}
}
rxs = (a >> 2) & 0xc;
- if (!(wc->span.chans[i+1].sig & DAHDI_SIG_CLEAR)) {
- if (wc->span.chans[i+1].rxsig != rxs) {
+ if (!(wc->span.chans[i+1]->sig & DAHDI_SIG_CLEAR)) {
+ if (wc->span.chans[i+1]->rxsig != rxs) {
spin_unlock(&wc->reglock);
- dahdi_rbsbits(&wc->span.chans[i+1], rxs);
+ dahdi_rbsbits(wc->span.chans[i+1], rxs);
spin_lock(&wc->reglock);
}
}
rxs = (a >> 4) & 0xc;
- if (!(wc->span.chans[i].sig & DAHDI_SIG_CLEAR)) {
- if (wc->span.chans[i].rxsig != rxs) {
+ if (!(wc->span.chans[i]->sig & DAHDI_SIG_CLEAR)) {
+ if (wc->span.chans[i]->rxsig != rxs) {
spin_unlock(&wc->reglock);
- dahdi_rbsbits(&wc->span.chans[i], rxs);
+ dahdi_rbsbits(wc->span.chans[i], rxs);
spin_lock(&wc->reglock);
}
}
@@ -893,18 +898,18 @@ static inline void __t1_check_sigbits(struct t1 *wc)
if (a > -1) {
/* Get high channel in low bits */
rxs = (a & 0xf);
- if (!(wc->span.chans[i+1].sig & DAHDI_SIG_CLEAR)) {
- if (wc->span.chans[i+1].rxsig != rxs) {
+ if (!(wc->span.chans[i+1]->sig & DAHDI_SIG_CLEAR)) {
+ if (wc->span.chans[i+1]->rxsig != rxs) {
spin_unlock(&wc->reglock);
- dahdi_rbsbits(&wc->span.chans[i+1], rxs);
+ dahdi_rbsbits(wc->span.chans[i+1], rxs);
spin_lock(&wc->reglock);
}
}
rxs = (a >> 4) & 0xf;
- if (!(wc->span.chans[i].sig & DAHDI_SIG_CLEAR)) {
- if (wc->span.chans[i].rxsig != rxs) {
+ if (!(wc->span.chans[i]->sig & DAHDI_SIG_CLEAR)) {
+ if (wc->span.chans[i]->rxsig != rxs) {
spin_unlock(&wc->reglock);
- dahdi_rbsbits(&wc->span.chans[i], rxs);
+ dahdi_rbsbits(wc->span.chans[i], rxs);
spin_lock(&wc->reglock);
}
}
@@ -1152,13 +1157,13 @@ static int t1_software_init(struct t1 *wc)
wc->span.pvt = wc;
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);
- wc->chans[x].sigcap = DAHDI_SIG_EM | DAHDI_SIG_CLEAR | DAHDI_SIG_EM_E1 |
+ sprintf(wc->chans[x]->name, "WCT1/%d/%d", wc->num, x + 1);
+ wc->chans[x]->sigcap = DAHDI_SIG_EM | DAHDI_SIG_CLEAR | DAHDI_SIG_EM_E1 |
DAHDI_SIG_FXSLS | DAHDI_SIG_FXSGS | DAHDI_SIG_MTP2 |
DAHDI_SIG_FXSKS | DAHDI_SIG_FXOLS | DAHDI_SIG_DACS_RBS |
DAHDI_SIG_FXOGS | DAHDI_SIG_FXOKS | DAHDI_SIG_CAS | DAHDI_SIG_SF;
- wc->chans[x].pvt = wc;
- wc->chans[x].chanpos = x + 1;
+ wc->chans[x]->pvt = wc;
+ wc->chans[x]->chanpos = x + 1;
}
if (dahdi_register(&wc->span, 0)) {
module_printk("Unable to register span with DAHDI\n");
@@ -1318,8 +1323,8 @@ static inline void __t1_check_alarms(struct t1 *wc)
if (wc->span.lineconfig & DAHDI_CONFIG_NOTOPEN) {
for (x=0,j=0;x < wc->span.channels;x++)
- if ((wc->span.chans[x].flags & DAHDI_FLAG_OPEN) ||
- (wc->span.chans[x].flags & DAHDI_FLAG_NETDEV))
+ if ((wc->span.chans[x]->flags & DAHDI_FLAG_OPEN) ||
+ (wc->span.chans[x]->flags & DAHDI_FLAG_NETDEV))
j++;
if (!j)
alarms |= DAHDI_ALARM_NOTOPEN;
@@ -1460,7 +1465,7 @@ static inline void t1_transmitprep(struct t1 *wc, unsigned char* writechunk)
for (x = 0; x < DAHDI_CHUNKSIZE; x++) {
if (likely(wc->initialized)) {
for (chan = 0; chan < wc->span.channels; chan++)
- writechunk[(chan+1)*2] = wc->chans[chan].writechunk[x];
+ writechunk[(chan+1)*2] = wc->chans[chan]->writechunk[x];
}
/* process the command queue */
@@ -1501,7 +1506,7 @@ static inline void t1_receiveprep(struct t1 *wc, unsigned char* readchunk)
for (x = 0; x < DAHDI_CHUNKSIZE; x++) {
if (likely(wc->initialized)) {
for (chan = 0; chan < wc->span.channels; chan++) {
- wc->chans[chan].readchunk[x]= readchunk[(chan+1)*2];
+ wc->chans[chan]->readchunk[x]= readchunk[(chan+1)*2];
}
}
if (x < DAHDI_CHUNKSIZE - 1) {
@@ -1527,9 +1532,9 @@ static inline void t1_receiveprep(struct t1 *wc, unsigned char* readchunk)
if (likely(wc->initialized)) {
spin_unlock(&wc->reglock);
for (x = 0; x < wc->span.channels; x++) {
- dahdi_ec_chunk(&wc->chans[x], wc->chans[x].readchunk, wc->ec_chunk2[x]);
+ dahdi_ec_chunk(wc->chans[x], wc->chans[x]->readchunk, wc->ec_chunk2[x]);
memcpy(wc->ec_chunk2[x],wc->ec_chunk1[x],DAHDI_CHUNKSIZE);
- memcpy(wc->ec_chunk1[x],wc->chans[x].writechunk,DAHDI_CHUNKSIZE);
+ memcpy(wc->ec_chunk1[x],wc->chans[x]->writechunk,DAHDI_CHUNKSIZE);
}
dahdi_receive(&wc->span);
spin_lock(&wc->reglock);
@@ -1588,9 +1593,9 @@ static int __devinit te12xp_init_one(struct pci_dev *pdev, const struct pci_devi
}
retry:
- wc = kmalloc(sizeof(*wc), GFP_KERNEL);
- if (!wc)
+ if (!(wc = kmalloc(sizeof(*wc), GFP_KERNEL))) {
return -ENOMEM;
+ }
ifaces[x] = wc;
memset(wc, 0, sizeof(*wc));
@@ -1600,9 +1605,8 @@ retry:
init_waitqueue_head(&wc->regq);
snprintf(wc->name, sizeof(wc->name)-1, "wcte12xp%d", x);
- if ((res=voicebus_init(pdev, SFRAME_SIZE, wc->name,
- t1_handle_receive, t1_handle_transmit, wc, &wc->vb)))
- {
+ if ((res = voicebus_init(pdev, SFRAME_SIZE, wc->name,
+ t1_handle_receive, t1_handle_transmit, wc, &wc->vb))) {
WARN_ON(1);
kfree(wc);
return res;
@@ -1616,6 +1620,19 @@ retry:
voicebus_start(wc->vb);
startinglatency = voicebus_current_latency(wc->vb);
t1_hardware_post_init(wc);
+
+ for (x = 0; x < (wc->spantype == TYPE_E1 ? 31 : 24); x++) {
+ if (!(wc->chans[x] = kmalloc(sizeof(*wc->chans[x]), GFP_KERNEL))) {
+ while (x) {
+ kfree(wc->chans[--x]);
+ }
+
+ kfree(wc);
+ return -ENOMEM;
+ }
+ memset(wc->chans[x], 0, sizeof(*wc->chans[x]));
+ }
+
t1_software_init(wc);
if (voicebus_current_latency(wc->vb) > startinglatency) {
/* The voicebus library increased the latency during
@@ -1633,6 +1650,7 @@ retry:
wc = NULL;
goto retry;
}
+
module_printk("Found a %s\n", wc->variety);
return 0;
diff --git a/drivers/dahdi/wcte12xp/vpmadt032.c b/drivers/dahdi/wcte12xp/vpmadt032.c
index f8e385b..3d02dc3 100644
--- a/drivers/dahdi/wcte12xp/vpmadt032.c
+++ b/drivers/dahdi/wcte12xp/vpmadt032.c
@@ -649,7 +649,7 @@ static void vpm150m_dtmf_bh(struct work_struct *data)
debug_printk(1, "Channel %d: Detected DTMF tone %d of duration %d\n", channel + 1, tone, duration);
if (test_bit(channel, &wc->dtmfmask) && (eventdata.toneEvent.ToneDuration > 0)) {
- struct dahdi_chan *chan = &wc->chans[channel];
+ struct dahdi_chan *chan = wc->chans[channel];
module_printk("DTMF detected channel=%d tone=%d duration=%d\n", channel + 1, tone, duration);
diff --git a/drivers/dahdi/wcte12xp/wcte12xp.h b/drivers/dahdi/wcte12xp/wcte12xp.h
index 2ba4609..93bda0d 100644
--- a/drivers/dahdi/wcte12xp/wcte12xp.h
+++ b/drivers/dahdi/wcte12xp/wcte12xp.h
@@ -140,7 +140,7 @@ struct t1 {
unsigned char ec_chunk1[32][DAHDI_CHUNKSIZE];
unsigned char ec_chunk2[32][DAHDI_CHUNKSIZE];
struct dahdi_span span; /* Span */
- struct dahdi_chan chans[32]; /* Channels */
+ struct dahdi_chan *chans[32]; /* Channels */
wait_queue_head_t regq;
struct cmdq cmdq;
struct command dummy; /* preallocate for dummy noop command */
diff --git a/drivers/dahdi/xpp/card_fxo.c b/drivers/dahdi/xpp/card_fxo.c
index 96e528c..4d9dec5 100644
--- a/drivers/dahdi/xpp/card_fxo.c
+++ b/drivers/dahdi/xpp/card_fxo.c
@@ -280,7 +280,7 @@ static void update_dahdi_ring(xpd_t *xpd, int pos, bool on)
* a nested spinlock scenario
*/
if(SPAN_REGISTERED(xpd))
- dahdi_hooksig(&xpd->chans[pos], rxsig);
+ dahdi_hooksig(xpd->chans[pos], rxsig);
}
static void mark_ring(xpd_t *xpd, lineno_t pos, bool on, bool update_dahdi)
@@ -502,7 +502,7 @@ static int FXO_card_dahdi_preregistration(xpd_t *xpd, bool on)
XPD_DBG(GENERAL, xpd, "%s\n", (on)?"ON":"OFF");
xpd->span.spantype = "FXO";
for_each_line(xpd, i) {
- struct dahdi_chan *cur_chan = &xpd->chans[i];
+ struct dahdi_chan *cur_chan = xpd->chans[i];
XPD_DBG(GENERAL, xpd, "setting FXO channel %d\n", i);
snprintf(cur_chan->name, MAX_CHANNAME, "XPP_FXO/%02d/%1d%1d/%d",
@@ -582,11 +582,11 @@ static void dahdi_report_battery(xpd_t *xpd, lineno_t chan)
break;
case BATTERY_OFF:
LINE_DBG(SIGNAL, xpd, chan, "Send DAHDI_ALARM_RED\n");
- dahdi_alarm_channel(&xpd->chans[chan], DAHDI_ALARM_RED);
+ dahdi_alarm_channel(xpd->chans[chan], DAHDI_ALARM_RED);
break;
case BATTERY_ON:
LINE_DBG(SIGNAL, xpd, chan, "Send DAHDI_ALARM_NONE\n");
- dahdi_alarm_channel(&xpd->chans[chan], DAHDI_ALARM_NONE);
+ dahdi_alarm_channel(xpd->chans[chan], DAHDI_ALARM_NONE);
break;
}
}
@@ -927,7 +927,7 @@ static void update_battery_voltage(xpd_t *xpd, byte data_low, xportno_t portno)
if(SPAN_REGISTERED(xpd)) {
LINE_DBG(SIGNAL, xpd, portno,
"Send DAHDI_EVENT_POLARITY: %s\n", polname);
- dahdi_qevent_lock(&xpd->chans[portno], DAHDI_EVENT_POLARITY);
+ dahdi_qevent_lock(xpd->chans[portno], DAHDI_EVENT_POLARITY);
}
}
priv->polarity[portno] = pol;
diff --git a/drivers/dahdi/xpp/card_fxs.c b/drivers/dahdi/xpp/card_fxs.c
index ac89204..cabda03 100644
--- a/drivers/dahdi/xpp/card_fxs.c
+++ b/drivers/dahdi/xpp/card_fxs.c
@@ -479,7 +479,7 @@ static int FXS_card_dahdi_preregistration(xpd_t *xpd, bool on)
XPD_DBG(GENERAL, xpd, "%s\n", (on)?"on":"off");
xpd->span.spantype = "FXS";
for_each_line(xpd, i) {
- struct dahdi_chan *cur_chan = &xpd->chans[i];
+ struct dahdi_chan *cur_chan = xpd->chans[i];
XPD_DBG(GENERAL, xpd, "setting FXS channel %d\n", i);
if(IS_SET(xpd->digital_outputs, i)) {
@@ -651,7 +651,7 @@ static int FXS_card_hooksig(xbus_t *xbus, xpd_t *xpd, int pos, dahdi_txsig_t txs
return 0;
}
if(SPAN_REGISTERED(xpd))
- chan = &xpd->span.chans[pos];
+ chan = xpd->span.chans[pos];
switch(txsig) {
case DAHDI_TXSIG_ONHOOK:
spin_lock_irqsave(&xpd->lock, flags);
@@ -998,7 +998,7 @@ static void detect_vmwi(xpd_t *xpd)
priv = xpd->priv;
BUG_ON(!priv);
for_each_line(xpd, i) {
- struct dahdi_chan *chan = &xpd->span.chans[i];
+ struct dahdi_chan *chan = xpd->span.chans[i];
byte *writechunk = chan->writechunk;
if(IS_SET(xpd->offhook | xpd->cid_on | xpd->digital_inputs | xpd->digital_outputs, i))
@@ -1234,7 +1234,7 @@ static void process_dtmf(xpd_t *xpd, xpp_line_t lines, byte val)
__do_mute_dtmf(xpd, i, 0);
__pcm_recompute(xpd, 0); /* XPD is locked */
if(want_event)
- dahdi_qevent_lock(&xpd->chans[i], event | digit);
+ dahdi_qevent_lock(xpd->chans[i], event | digit);
break;
}
}
diff --git a/drivers/dahdi/xpp/card_pri.c b/drivers/dahdi/xpp/card_pri.c
index 7eb6a58..c78c71e 100644
--- a/drivers/dahdi/xpp/card_pri.c
+++ b/drivers/dahdi/xpp/card_pri.c
@@ -889,7 +889,7 @@ static int PRI_card_dahdi_preregistration(xpd_t *xpd, bool on)
xpd->span.linecompat = pri_linecompat(priv->pri_protocol);
xpd->span.deflaw = priv->deflaw;
for_each_line(xpd, i) {
- struct dahdi_chan *cur_chan = &xpd->chans[i];
+ struct dahdi_chan *cur_chan = xpd->chans[i];
bool is_dchan = i == PRI_DCHAN_IDX(priv);
XPD_DBG(GENERAL, xpd, "setting PRI channel %d (%s)\n", i,
@@ -953,9 +953,9 @@ static void dchan_state(xpd_t *xpd, bool up)
if(SPAN_REGISTERED(xpd) && d >= 0 && d < xpd->channels) {
byte *pcm;
- pcm = (byte *)xpd->span.chans[d].readchunk;
+ pcm = (byte *)xpd->span.chans[d]->readchunk;
pcm[0] = 0x00;
- pcm = (byte *)xpd->span.chans[d].writechunk;
+ pcm = (byte *)xpd->span.chans[d]->writechunk;
pcm[0] = 0x00;
}
XPD_DBG(SIGNAL, xpd, "STATE CHANGE: D-Channel STOPPED\n");
@@ -1146,7 +1146,7 @@ static void PRI_card_pcm_fromspan(xbus_t *xbus, xpd_t *xpd, xpp_line_t lines, xp
{
struct PRI_priv_data *priv;
byte *pcm;
- struct dahdi_chan *chans;
+ struct dahdi_chan **chans;
unsigned long flags;
int i;
int physical_chan;
@@ -1177,10 +1177,10 @@ static void PRI_card_pcm_fromspan(xbus_t *xbus, xpd_t *xpd, xpp_line_t lines, xp
physical_mask |= BIT(physical_chan);
if(SPAN_REGISTERED(xpd)) {
if(i == PRI_DCHAN_IDX(priv)) {
- if(priv->dchan_tx_sample != chans[i].writechunk[0]) {
- priv->dchan_tx_sample = chans[i].writechunk[0];
+ if(priv->dchan_tx_sample != chans[i]->writechunk[0]) {
+ priv->dchan_tx_sample = chans[i]->writechunk[0];
priv->dchan_tx_counter++;
- } else if(chans[i].writechunk[0] == 0xFF)
+ } else if(chans[i]->writechunk[0] == 0xFF)
dchan_state(xpd, 0);
}
#ifdef DEBUG_PCMTX
@@ -1188,7 +1188,7 @@ static void PRI_card_pcm_fromspan(xbus_t *xbus, xpd_t *xpd, xpp_line_t lines, xp
memset((u_char *)pcm, pcmtx, DAHDI_CHUNKSIZE);
else
#endif
- memcpy((u_char *)pcm, chans[i].writechunk, DAHDI_CHUNKSIZE);
+ memcpy((u_char *)pcm, chans[i]->writechunk, DAHDI_CHUNKSIZE);
// fill_beep((u_char *)pcm, xpd->addr.subunit, 2);
} else
memset((u_char *)pcm, 0x7F, DAHDI_CHUNKSIZE);
@@ -1215,7 +1215,7 @@ static void PRI_card_pcm_tospan(xbus_t *xbus, xpd_t *xpd, xpacket_t *pack)
{
struct PRI_priv_data *priv;
byte *pcm;
- struct dahdi_chan *chans;
+ struct dahdi_chan **chans;
xpp_line_t physical_mask;
unsigned long flags;
int i;
@@ -1255,7 +1255,7 @@ static void PRI_card_pcm_tospan(xbus_t *xbus, xpd_t *xpd, xpacket_t *pack)
dchan_state(xpd, 0);
}
if(IS_SET(physical_mask, i)) {
- r = chans[logical_chan].readchunk;
+ r = chans[logical_chan]->readchunk;
// memset((u_char *)r, 0x5A, DAHDI_CHUNKSIZE); // DEBUG
// fill_beep((u_char *)r, 1, 1); // DEBUG: BEEP
memcpy((u_char *)r, pcm, DAHDI_CHUNKSIZE);
diff --git a/drivers/dahdi/xpp/xbus-pcm.c b/drivers/dahdi/xpp/xbus-pcm.c
index 1e3a915..09ebc13 100644
--- a/drivers/dahdi/xpp/xbus-pcm.c
+++ b/drivers/dahdi/xpp/xbus-pcm.c
@@ -648,7 +648,7 @@ void fill_beep(u_char *buf, int num, int duration)
static void do_ec(xpd_t *xpd)
{
- struct dahdi_chan *chans = xpd->span.chans;
+ struct dahdi_chan **chans = xpd->span.chans;
int i;
for (i = 0;i < xpd->span.channels; i++) {
@@ -656,9 +656,9 @@ static void do_ec(xpd_t *xpd)
continue;
if(!IS_SET(xpd->wanted_pcm_mask, i)) /* No ec for unwanted PCM */
continue;
- dahdi_ec_chunk(&chans[i], chans[i].readchunk, xpd->ec_chunk2[i]);
+ dahdi_ec_chunk(chans[i], chans[i]->readchunk, xpd->ec_chunk2[i]);
memcpy(xpd->ec_chunk2[i], xpd->ec_chunk1[i], DAHDI_CHUNKSIZE);
- memcpy(xpd->ec_chunk1[i], chans[i].writechunk, DAHDI_CHUNKSIZE);
+ memcpy(xpd->ec_chunk1[i], chans[i]->writechunk, DAHDI_CHUNKSIZE);
}
}
@@ -764,10 +764,10 @@ dropit:
*/
void generic_card_pcm_fromspan(xbus_t *xbus, xpd_t *xpd, xpp_line_t lines, xpacket_t *pack)
{
- byte *pcm;
- struct dahdi_chan *chans;
- unsigned long flags;
- int i;
+ byte *pcm;
+ struct dahdi_chan **chans;
+ unsigned long flags;
+ int i;
BUG_ON(!xbus);
BUG_ON(!xpd);
@@ -784,7 +784,7 @@ void generic_card_pcm_fromspan(xbus_t *xbus, xpd_t *xpd, xpp_line_t lines, xpack
memset((u_char *)pcm, pcmtx, DAHDI_CHUNKSIZE);
else
#endif
- memcpy((u_char *)pcm, chans[i].writechunk, DAHDI_CHUNKSIZE);
+ memcpy((u_char *)pcm, chans[i]->writechunk, DAHDI_CHUNKSIZE);
// fill_beep((u_char *)pcm, xpd->addr.subunit, 2);
} else
memset((u_char *)pcm, 0x7F, DAHDI_CHUNKSIZE);
@@ -808,7 +808,7 @@ void generic_card_pcm_tospan(xbus_t *xbus, xpd_t *xpd, xpacket_t *pack)
if(!SPAN_REGISTERED(xpd))
goto out;
for (i = 0; i < xpd->channels; i++) {
- volatile u_char *r = xpd->span.chans[i].readchunk;
+ volatile u_char *r = xpd->span.chans[i]->readchunk;
if(!IS_SET(xpd->wanted_pcm_mask, i)) {
if(IS_SET(xpd->silence_pcm, i)) {
diff --git a/drivers/dahdi/xpp/xpd.h b/drivers/dahdi/xpp/xpd.h
index e800e43..d9a00aa 100644
--- a/drivers/dahdi/xpp/xpd.h
+++ b/drivers/dahdi/xpp/xpd.h
@@ -140,7 +140,7 @@ static struct xpd_counters {
struct xpd {
char xpdname[XPD_NAMELEN];
struct dahdi_span span;
- struct dahdi_chan *chans;
+ struct dahdi_chan *chans[32];
int channels;
xpd_type_t type;
const char *type_name;
diff --git a/drivers/dahdi/xpp/xpp_dahdi.c b/drivers/dahdi/xpp/xpp_dahdi.c
index a8fbfee..81c0486 100644
--- a/drivers/dahdi/xpp/xpp_dahdi.c
+++ b/drivers/dahdi/xpp/xpp_dahdi.c
@@ -190,7 +190,8 @@ err:
void xpd_free(xpd_t *xpd)
{
- xbus_t *xbus = NULL;
+ xbus_t *xbus = NULL;
+ unsigned int x;
if(!xpd)
return;
@@ -203,6 +204,11 @@ void xpd_free(xpd_t *xpd)
XPD_DBG(DEVICES, xpd, "\n");
xpd_proc_remove(xbus, xpd);
xbus_unregister_xpd(xbus, xpd);
+ for (x = 0; x < xpd->channels; x++) {
+ if (xpd->chans[x]) {
+ kfree(xpd->chans[x]);
+ }
+ }
KZFREE(xpd);
}
@@ -350,7 +356,7 @@ static int xpd_read_proc(char *page, char **start, off_t off, int count, int *eo
if(SPAN_REGISTERED(xpd)) {
len += sprintf(page + len, "\nPCM:\n | [readchunk] | [writechunk] | W D");
for_each_line(xpd, i) {
- struct dahdi_chan *chans = xpd->span.chans;
+ struct dahdi_chan *chan = xpd->span.chans[i];
byte rchunk[DAHDI_CHUNKSIZE];
byte wchunk[DAHDI_CHUNKSIZE];
byte *rp;
@@ -363,8 +369,8 @@ static int xpd_read_proc(char *page, char **start, off_t off, int count, int *eo
continue;
if(IS_SET(xpd->digital_signalling, i))
continue;
- rp = chans[i].readchunk;
- wp = chans[i].writechunk;
+ rp = chan->readchunk;
+ wp = chan->writechunk;
memcpy(rchunk, rp, DAHDI_CHUNKSIZE);
memcpy(wchunk, wp, DAHDI_CHUNKSIZE);
len += sprintf(page + len, "\n port %2d> | ", i);
@@ -421,6 +427,7 @@ xpd_t *xpd_alloc(size_t privsize, const xproto_table_t *proto_table, int channel
xpd_t *xpd = NULL;
size_t alloc_size = sizeof(xpd_t) + privsize;
int type = proto_table->type;
+ unsigned int x;
BUG_ON(!proto_table);
DBG(DEVICES, "type=%d channels=%d (alloc_size=%zd)\n",
@@ -438,10 +445,8 @@ xpd_t *xpd_alloc(size_t privsize, const xproto_table_t *proto_table, int channel
}
xpd->priv = (byte *)xpd + sizeof(xpd_t);
spin_lock_init(&xpd->lock);
- xpd->xbus = NULL;
xpd->xbus_idx = -1;
xpd->channels = channels;
- xpd->chans = NULL;
xpd->card_present = 0;
xpd->offhook = 0x0; /* ONHOOK */
xpd->type = proto_table->type;
@@ -453,29 +458,27 @@ xpd_t *xpd_alloc(size_t privsize, const xproto_table_t *proto_table, int channel
atomic_set(&xpd->dahdi_registered, 0);
atomic_set(&xpd->open_counter, 0);
- xpd->chans = kmalloc(sizeof(struct dahdi_chan)*xpd->channels, GFP_KERNEL);
- if (xpd->chans == NULL) {
- ERR("%s: Unable to allocate channels\n", __FUNCTION__);
- goto err;
+ for (x = 0; x < xpd->channels; x++) {
+ if (!(xpd->chans[x] = kmalloc(sizeof(*xpd->chans[x]), GFP_KERNEL))) {
+ ERR("%s: Unable to allocate channel %d\n", __FUNCTION__, x);
+ goto err;
+ }
}
+
xproto_get(type); /* will be returned in xpd_free() */
return xpd;
err:
if(xpd) {
- if(xpd->chans)
- kfree((void *)xpd->chans);
- kfree(xpd);
+ for (x = 0; x < xpd->channels; x++) {
+ if (xpd->chans[x]) {
+ kfree(xpd->chans[x]);
+ }
+ }
+ KZFREE(xpd);
}
return NULL;
}
-/* FIXME: this should be removed once digium patch their dahdi.h
- * I simply wish to avoid changing dahdi.h in the xpp patches.
- */
-#ifndef DAHDI_EVENT_REMOVED
-#define DAHDI_EVENT_REMOVED (20)
-#endif
-
void xpd_disconnect(xpd_t *xpd)
{
unsigned long flags;
@@ -494,7 +497,7 @@ void xpd_disconnect(xpd_t *xpd)
/* TODO: Should this be done before releasing the spinlock? */
XPD_DBG(DEVICES, xpd, "Queuing DAHDI_EVENT_REMOVED on all channels to ask user to release them\n");
for (i=0; i<xpd->span.channels; i++)
- dahdi_qevent_lock(&xpd->chans[i],DAHDI_EVENT_REMOVED);
+ dahdi_qevent_lock(xpd->chans[i],DAHDI_EVENT_REMOVED);
}
out:
spin_unlock_irqrestore(&xpd->lock, flags);
@@ -563,7 +566,7 @@ void update_line_status(xpd_t *xpd, int pos, bool to_offhook)
*/
LINE_DBG(SIGNAL, xpd, pos, "rxsig=%s\n", (rxsig == DAHDI_RXSIG_ONHOOK) ? "ONHOOK" : "OFFHOOK");
if(SPAN_REGISTERED(xpd))
- dahdi_hooksig(&xpd->chans[pos], rxsig);
+ dahdi_hooksig(xpd->chans[pos], rxsig);
}
#ifdef CONFIG_PROC_FS
diff --git a/include/dahdi/kernel.h b/include/dahdi/kernel.h
index fccd10f..b2ac0ff 100644
--- a/include/dahdi/kernel.h
+++ b/include/dahdi/kernel.h
@@ -1531,7 +1531,7 @@ struct dahdi_span {
int timingslips; /* Clock slips */
- struct dahdi_chan *chans; /* Member channel structures */
+ struct dahdi_chan **chans; /* Member channel structures */
/* ==== Span Callback Operations ==== */
/* Req: Set the requested chunk size. This is the unit in which you must