diff options
author | Kevin P. Fleming <kpfleming@digium.com> | 2008-07-02 13:31:31 +0000 |
---|---|---|
committer | Kevin P. Fleming <kpfleming@digium.com> | 2008-07-02 13:31:31 +0000 |
commit | 1340abc2e710509a9bbe8ca720c91eff896c3d33 (patch) | |
tree | 3d2cffb2090c445da8b3b8e741543c0287a2cc60 /drivers | |
parent | ef05eedbe6bffbdaaee55f26b0c54a06fd32b6f2 (diff) |
break up large memory allocations made by digital span drivers into smaller ones (one allocation for each dahdi_chan structure, separate from any private structures used by the driver)
(closes issue #12657)
Reported by: tzafrir
git-svn-id: http://svn.asterisk.org/svn/dahdi/linux/trunk@4513 a0bf4364-ded3-4de4-8d8a-66a801d63aff
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/dahdi/dahdi-base.c | 160 | ||||
-rw-r--r-- | drivers/dahdi/dahdi_dynamic.c | 8 | ||||
-rw-r--r-- | drivers/dahdi/tor2.c | 95 | ||||
-rw-r--r-- | drivers/dahdi/wct1xxp.c | 182 | ||||
-rw-r--r-- | drivers/dahdi/wct4xxp/base.c | 547 | ||||
-rw-r--r-- | drivers/dahdi/wcte11xp.c | 197 | ||||
-rw-r--r-- | drivers/dahdi/wcte12xp/base.c | 102 | ||||
-rw-r--r-- | drivers/dahdi/wcte12xp/vpmadt032.c | 2 | ||||
-rw-r--r-- | drivers/dahdi/wcte12xp/wcte12xp.h | 2 | ||||
-rw-r--r-- | drivers/dahdi/xpp/card_fxo.c | 10 | ||||
-rw-r--r-- | drivers/dahdi/xpp/card_fxs.c | 8 | ||||
-rw-r--r-- | drivers/dahdi/xpp/card_pri.c | 20 | ||||
-rw-r--r-- | drivers/dahdi/xpp/xbus-pcm.c | 18 | ||||
-rw-r--r-- | drivers/dahdi/xpp/xpd.h | 2 | ||||
-rw-r--r-- | drivers/dahdi/xpp/xpp_dahdi.c | 47 |
15 files changed, 744 insertions, 656 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 |