[dahdi-commits] rmeyerriecks: branch linux/mspiceland/dahdi-qfalc31 r7662 - in /linux/team/ms...
SVN commits to the DAHDI project
dahdi-commits at lists.digium.com
Thu Dec 3 14:40:31 CST 2009
Author: rmeyerriecks
Date: Thu Dec 3 14:40:27 2009
New Revision: 7662
URL: http://svnview.digium.com/svn/dahdi?view=rev&rev=7662
Log:
Merged revisions 7445,7456-7457,7480,7486-7487,7512-7524,7527-7528,7534-7536,7549,7565-7571,7576,7579,7582,7587,7590-7591,7595,7601,7614-7615,7622,7625,7632,7638-7640 via svnmerge from
https://origsvn.digium.com/svn/dahdi/linux/trunk
........
r7445 | mspiceland | 2009-10-29 16:37:45 -0500 (Thu, 29 Oct 2009) | 3 lines
Debounce alarms by default for wct4xxp per AT&T 54016. Also, the
various alarm conditions can be debounced separately.
........
r7456 | tzafrir | 2009-11-03 13:30:30 -0600 (Tue, 03 Nov 2009) | 2 lines
xpp: compile fix in (mostly) unused code.
........
r7457 | tzafrir | 2009-11-03 14:24:13 -0600 (Tue, 03 Nov 2009) | 4 lines
xpp: More E1/T1 CAS fixes. Mostly connect/disconnect
xpp revs: mostly 7458, 7466
........
r7480 | sruffell | 2009-11-04 14:43:05 -0600 (Wed, 04 Nov 2009) | 4 lines
voicebus: Increase the NLP converged threshold to 18.
Brings in the change from r7065 that was on the team/sruffell/dahdi-linux-vpm119
branch.
........
r7486 | mspiceland | 2009-11-04 17:25:32 -0600 (Wed, 04 Nov 2009) | 9 lines
Adding alarm debounce to single span driver (wcte12xp).
Debounce yellow alarm also.
In wcte12xp, change check alarm frequency to 100ms for better debounce
granularity.
Fix lines over 80 cols from last alarm debounce commit.
........
r7487 | mspiceland | 2009-11-04 17:28:21 -0600 (Wed, 04 Nov 2009) | 2 lines
Remove commented out code block that was unintentionally left in.
........
r7512 | sruffell | 2009-11-06 18:35:38 -0600 (Fri, 06 Nov 2009) | 1 line
wcte12xp: Remove unused flag member and make const the t1_descs.
........
r7513 | sruffell | 2009-11-06 18:35:38 -0600 (Fri, 06 Nov 2009) | 4 lines
voicebus: Remove the VB_PRINTK macro.
Unnecessarily duplicates the dev_xxx macros. Also removes the need for the
board_name member from struct voicebus.
........
r7514 | sruffell | 2009-11-06 18:35:39 -0600 (Fri, 06 Nov 2009) | 4 lines
voicebus: Remove sdi member from 'struct voicebus'
This is only used during startup so we don't need to carry it around in the
structure at all times.
........
r7515 | sruffell | 2009-11-06 18:35:40 -0600 (Fri, 06 Nov 2009) | 1 line
voicebus: Set the DMA_BIT_MASK
........
r7516 | sruffell | 2009-11-06 18:35:40 -0600 (Fri, 06 Nov 2009) | 1 line
voicebus: Use DAHDI_IRQ_SHARED instead of defining our own.
........
r7517 | sruffell | 2009-11-06 18:35:40 -0600 (Fri, 06 Nov 2009) | 24 lines
voicebus: Send 'idle' buffers when the transmit descriptor underruns.
Previously, when the host system fails to service the interrupt in a timely
fashion, the transmit descriptor ring for the voicebus card would "go empty"
since the interface wouldn't have another descriptor to read in. The driver
only knows that it went empty, not how far behind it actually was. Therefore,
the driver could just increase the latency by a millisecond and keep going
waiting for another bump.
Additionally, when the transmit descriptor actually goes empty, there are some
cases where an in process SPI transaction to one of the modules is interrupted,
which may result in corrupted module register writes on rare occassions.
This now makes it possible for the voicebus drivers to coexist with some devices
that periodically lock interrupts for longer than 25ms. Before this patch, the
latency would constantly increase until either the modules received a corrupted
frame.
This patch preconfigures all the receive descriptors to send an "idle" packet
that will be transmitted to the onboard modules when the host doesn't service
the interrupt within (latency - 2)ms. There are now two kinds of underruns,
softunderuns where the driver can detect that these idlebuffers have made it to
the TX FIFO, and the normal hard underrun where the part signals a transmit
descriptor unavailable interrupt. DAHDI-278.
........
r7518 | sruffell | 2009-11-06 18:35:41 -0600 (Fri, 06 Nov 2009) | 7 lines
voicebus: Add function to lock the latency.
Now that increases in the latency produce less undefined behavior on the SPI
busses, provide an interface for client drivers to inform the voicebus library
to not increase the latency if underruns are detected. This can speed up loads
of the driver since latency bumps do not trigger a restart of the driver
initialization. DAHDI-278.
........
r7519 | sruffell | 2009-11-06 18:35:42 -0600 (Fri, 06 Nov 2009) | 4 lines
wcte12xp: Lock latency when loading
No longer need to restart board initialization if the latency would have
increased during initialization. DAHDI-278.
........
r7520 | sruffell | 2009-11-06 18:35:42 -0600 (Fri, 06 Nov 2009) | 4 lines
wctdm24xxp: Lock latency when loading
We no longer need to retry board initialization if the latency would have
increased during the initialization. DAHDI-278
........
r7521 | sruffell | 2009-11-06 18:35:43 -0600 (Fri, 06 Nov 2009) | 4 lines
voicebus, wctdm24xxp, wcte12xp: Move a print out of the interrupt handler.
This can be handled just as well in process context and printing to a serial
console from the interrupt handler has the potential to cause long latencies.
........
r7522 | sruffell | 2009-11-06 18:35:44 -0600 (Fri, 06 Nov 2009) | 5 lines
voicebus: Add optional sysfs entry for reading a boards current latency.
This is off by default since it hasn't been tested on a full range of kernels,
but can be useful for quickly seeing differences for latencies on different
cards installed in the system.
........
r7523 | sruffell | 2009-11-06 18:35:44 -0600 (Fri, 06 Nov 2009) | 1 line
voicebus: Remove 'assert' macros and use BUG_ON/WARN_ON directly.
........
r7524 | sruffell | 2009-11-06 18:35:45 -0600 (Fri, 06 Nov 2009) | 1 line
voicebus: Be just a little more graceful if we cannot grab our interrupt line.
........
r7527 | sruffell | 2009-11-06 18:58:03 -0600 (Fri, 06 Nov 2009) | 1 line
wcte12xp: Fix up some continued strings.
........
r7528 | sruffell | 2009-11-06 18:58:03 -0600 (Fri, 06 Nov 2009) | 1 line
wct4xxp: Fix up some continued strings.
........
r7534 | sruffell | 2009-11-09 12:02:40 -0600 (Mon, 09 Nov 2009) | 1 line
wct4xxp: Only print the new debounce messages when debug is set.
........
r7535 | sruffell | 2009-11-09 12:02:41 -0600 (Mon, 09 Nov 2009) | 1 line
wcte12xp: Only print the new debounce messages when debug is set.
........
r7536 | sruffell | 2009-11-09 12:11:06 -0600 (Mon, 09 Nov 2009) | 4 lines
wcte12xp: use the dev_xxx macro for the debounce messages.
We want to know which device is reporting the debounce when there are more than
one card in the system.
........
r7549 | sruffell | 2009-11-10 09:46:18 -0600 (Tue, 10 Nov 2009) | 9 lines
wcte12xp: Export features and operations for VPMADT032.
Fixes a regression in dahdi-linux 2.2.0 where it was impossible for userspace to
reset the state of a channel in the VPM.
(issue #15724)
Patches:
mantis-15724-2.patch uploaded by sruffell (license 456)
Tested by: alecdavis
........
r7565 | sruffell | 2009-11-12 13:22:06 -0600 (Thu, 12 Nov 2009) | 7 lines
voicebus: Fix race when enabling/disabling hardware echocan.
This closes a race condition where it was possible for the driver to
believe it has enabled the VPMADT032 when in fact, it really has not.
This fixes a regression introduced in dahdi-linux 2.2.0.
(issue #15724)
........
r7566 | sruffell | 2009-11-12 13:22:06 -0600 (Thu, 12 Nov 2009) | 1 line
wctdm24xxp, wcte12xp: We no longer have any DTMF events to check for.
........
r7567 | sruffell | 2009-11-12 13:22:07 -0600 (Thu, 12 Nov 2009) | 1 line
voicebus: Remove unused curtone from 'struct vpmadt032'
........
r7568 | sruffell | 2009-11-12 13:22:07 -0600 (Thu, 12 Nov 2009) | 1 line
voicebus: Remove redundant MAX_CHANNELS_FROM_SPAN
........
r7569 | sruffell | 2009-11-12 13:22:08 -0600 (Thu, 12 Nov 2009) | 3 lines
voicebus: Use dev_xxx macro when printing vpm messages.
We also do not need the unused context member of the vpmadt032 structure.
........
r7570 | sruffell | 2009-11-12 13:22:08 -0600 (Thu, 12 Nov 2009) | 4 lines
wcte12xp: Change serial port configuration setting for hw echocan.
The wcte12xp, like the wctdm24xpp, should have the PcmOutPortA set to
SerialPortNull.
........
r7571 | sruffell | 2009-11-12 13:56:49 -0600 (Thu, 12 Nov 2009) | 1 line
kernel.h: Define 'list_replace' for kernels < 2.6.18
........
r7576 | sruffell | 2009-11-12 15:48:17 -0600 (Thu, 12 Nov 2009) | 9 lines
wcb4xxp: More hw ids for HFC-4S & HFC-8S
Solves a typo in Junghanns 8 ports card hw id & adds more hardware ids
(Beronet mainly). All tested ok in asterisk-es group.
(issue #15446)
Reported by: Odicha
Patches:
wcb4xxp dahdi-linux.patch uploaded by Odicha (license 700)
........
r7579 | sruffell | 2009-11-12 17:03:06 -0600 (Thu, 12 Nov 2009) | 1 line
wcb4xxp: Add missing comma
........
r7582 | sruffell | 2009-11-12 17:19:13 -0600 (Thu, 12 Nov 2009) | 1 line
wcte12xp, voicebus: Set the companding mode correctly on E1.
........
r7587 | tzafrir | 2009-11-15 13:22:54 -0600 (Sun, 15 Nov 2009) | 2 lines
xpp: No need for an osolete .version file
........
r7590 | tzafrir | 2009-11-15 15:29:56 -0600 (Sun, 15 Nov 2009) | 5 lines
xpp: refactor card_pri access to CAS registers
Provide some functions to access the CAS registers for E1, T1/ESF and
T1/D4. Mostly, relatively few changes.
........
r7591 | tzafrir | 2009-11-15 15:42:57 -0600 (Sun, 15 Nov 2009) | 4 lines
xpp: card_pri: force remote refresh on CAS
Send different values on alarm to make the remote party re-read state.
........
r7595 | tzafrir | 2009-11-19 06:18:03 -0600 (Thu, 19 Nov 2009) | 2 lines
xpp: rules for loading USB firmware into 1163 devices as well
........
r7601 | sruffell | 2009-11-19 10:11:20 -0600 (Thu, 19 Nov 2009) | 1 line
wctdm24xxp: Honor the alawoverride parameter when using the VPMADT032.
........
r7614 | tzafrir | 2009-11-22 02:37:25 -0600 (Sun, 22 Nov 2009) | 4 lines
xpp firmware: fix FXS indirect register reading.
xpp rev: 7498
........
r7615 | tzafrir | 2009-11-22 02:39:04 -0600 (Sun, 22 Nov 2009) | 4 lines
xpp firmware: USB firmware with support of MPP 1.4
xpp rev: 7419
........
r7622 | tzafrir | 2009-11-22 13:59:30 -0600 (Sun, 22 Nov 2009) | 5 lines
xpp: statify and line length in card_bri.c
* checkpatch.pl nudged about line lengthes.
* sparse nudged about non-static functions.
........
r7625 | tzafrir | 2009-11-22 15:17:16 -0600 (Sun, 22 Nov 2009) | 2 lines
xpp: Improved inter-Astribank drift calculation.
........
r7632 | mspiceland | 2009-11-23 13:13:17 -0600 (Mon, 23 Nov 2009) | 4 lines
Even if we are debouncing the LOS declaration, we still expect the LED to
turn red as soon as we unplug the physical cable. This impliments this on
the wcte12xp just as it already does on the wct4xxp.
........
r7638 | mattf | 2009-11-23 13:38:29 -0600 (Mon, 23 Nov 2009) | 1 line
Commit fix for problem frames being received for WCB4XXP_HDLC_BUF_LEN multiple sized frames.
........
r7639 | mattf | 2009-11-23 13:39:11 -0600 (Mon, 23 Nov 2009) | 1 line
........
r7640 | mattf | 2009-11-23 13:41:42 -0600 (Mon, 23 Nov 2009) | 1 line
Commit fix for problem frames being received for WCB4XXP_HDLC_BUF_LEN multiple sized frames.
........
Removed:
linux/team/mspiceland/dahdi-qfalc31/drivers/dahdi/xpp/.version
Modified:
linux/team/mspiceland/dahdi-qfalc31/ (props changed)
linux/team/mspiceland/dahdi-qfalc31/drivers/dahdi/voicebus/GpakCust.c
linux/team/mspiceland/dahdi-qfalc31/drivers/dahdi/voicebus/GpakCust.h
linux/team/mspiceland/dahdi-qfalc31/drivers/dahdi/voicebus/voicebus.c
linux/team/mspiceland/dahdi-qfalc31/drivers/dahdi/voicebus/voicebus.h
linux/team/mspiceland/dahdi-qfalc31/drivers/dahdi/wcb4xxp/base.c
linux/team/mspiceland/dahdi-qfalc31/drivers/dahdi/wcb4xxp/wcb4xxp.h
linux/team/mspiceland/dahdi-qfalc31/drivers/dahdi/wct4xxp/base.c
linux/team/mspiceland/dahdi-qfalc31/drivers/dahdi/wctdm24xxp/base.c
linux/team/mspiceland/dahdi-qfalc31/drivers/dahdi/wcte12xp/base.c
linux/team/mspiceland/dahdi-qfalc31/drivers/dahdi/wcte12xp/wcte12xp.h
linux/team/mspiceland/dahdi-qfalc31/drivers/dahdi/xpp/card_bri.c
linux/team/mspiceland/dahdi-qfalc31/drivers/dahdi/xpp/card_global.c
linux/team/mspiceland/dahdi-qfalc31/drivers/dahdi/xpp/card_pri.c
linux/team/mspiceland/dahdi-qfalc31/drivers/dahdi/xpp/firmwares/PIC_TYPE_1.hex
linux/team/mspiceland/dahdi-qfalc31/drivers/dahdi/xpp/firmwares/USB_FW.hex
linux/team/mspiceland/dahdi-qfalc31/drivers/dahdi/xpp/xbus-pcm.c
linux/team/mspiceland/dahdi-qfalc31/drivers/dahdi/xpp/xbus-pcm.h
linux/team/mspiceland/dahdi-qfalc31/drivers/dahdi/xpp/xbus-sysfs.c
linux/team/mspiceland/dahdi-qfalc31/drivers/dahdi/xpp/xpp.rules
linux/team/mspiceland/dahdi-qfalc31/include/dahdi/kernel.h
Propchange: linux/team/mspiceland/dahdi-qfalc31/
------------------------------------------------------------------------------
--- svnmerge-integrated (original)
+++ svnmerge-integrated Thu Dec 3 14:40:27 2009
@@ -1,1 +1,1 @@
-/linux/trunk:1-7439
+/linux/trunk:1-7661
Modified: linux/team/mspiceland/dahdi-qfalc31/drivers/dahdi/voicebus/GpakCust.c
URL: http://svnview.digium.com/svn/dahdi/linux/team/mspiceland/dahdi-qfalc31/drivers/dahdi/voicebus/GpakCust.c?view=diff&rev=7662&r1=7661&r2=7662
==============================================================================
--- linux/team/mspiceland/dahdi-qfalc31/drivers/dahdi/voicebus/GpakCust.c (original)
+++ linux/team/mspiceland/dahdi-qfalc31/drivers/dahdi/voicebus/GpakCust.c Thu Dec 3 14:40:27 2009
@@ -52,6 +52,9 @@
static rwlock_t ifacelock;
static struct vpmadt032 *ifaces[MAX_DSP_CORES];
+
+#define vpm_info(vpm, format, arg...) \
+ dev_info(&voicebus_get_pci_dev(vpm->vb)->dev , format , ## arg)
static inline struct vpmadt032 *find_iface(const unsigned short dspid)
{
@@ -212,26 +215,42 @@
return res;
}
-static int vpmadt032_enable_ec(struct vpmadt032 *vpm, int channel)
+struct change_order {
+ struct list_head node;
+ unsigned int channel;
+ struct adt_lec_params params;
+};
+
+static struct change_order *alloc_change_order(void)
+{
+ return kzalloc(sizeof(struct change_order), GFP_KERNEL);
+}
+
+static void free_change_order(struct change_order *order)
+{
+ kfree(order);
+}
+
+static int vpmadt032_enable_ec(struct vpmadt032 *vpm, int channel,
+ enum adt_companding companding)
{
int res;
GPAK_AlgControlStat_t pstatus;
GpakAlgCtrl_t control;
- control = (ADT_COMP_ALAW == vpm->desiredecstate[channel].companding) ?
- EnableALawSwCompanding :
- EnableMuLawSwCompanding;
+ control = (ADT_COMP_ALAW == companding) ? EnableALawSwCompanding :
+ EnableMuLawSwCompanding;
if (vpm->options.debug & DEBUG_ECHOCAN) {
const char *law;
law = (control == EnableMuLawSwCompanding) ? "MuLaw" : "ALaw";
- printk(KERN_DEBUG "Enabling ecan on channel: %d (%s)\n",
- channel, law);
+ vpm_info(vpm, "Enabling ecan on channel: %d (%s)\n",
+ channel, law);
}
res = gpakAlgControl(vpm->dspid, channel, control, &pstatus);
if (res) {
- printk(KERN_WARNING "Unable to set SW Companding on " \
- "channel %d (reason %d)\n", channel, res);
+ vpm_info(vpm, "Unable to set SW Companding on "
+ "channel %d (reason %d)\n", channel, res);
}
res = gpakAlgControl(vpm->dspid, channel, EnableEcanA, &pstatus);
return res;
@@ -243,16 +262,96 @@
GPAK_AlgControlStat_t pstatus;
if (vpm->options.debug & DEBUG_ECHOCAN)
- printk(KERN_DEBUG "Disabling ecan on channel: %d\n", channel);
+ vpm_info(vpm, "Disabling ecan on channel: %d\n", channel);
res = gpakAlgControl(vpm->dspid, channel, BypassSwCompanding, &pstatus);
if (res) {
- printk(KERN_WARNING "Unable to disable sw companding on " \
- "echo cancellation channel %d (reason %d)\n",
- channel, res);
+ vpm_info(vpm, "Unable to disable sw companding on "
+ "echo cancellation channel %d (reason %d)\n",
+ channel, res);
}
res = gpakAlgControl(vpm->dspid, channel, BypassEcanA, &pstatus);
return res;
+}
+
+static struct change_order *get_next_order(struct vpmadt032 *vpm)
+{
+ struct change_order *order;
+
+ spin_lock(&vpm->change_list_lock);
+ if (!list_empty(&vpm->change_list)) {
+ order = list_entry(vpm->change_list.next,
+ struct change_order, node);
+ list_del(&order->node);
+ } else {
+ order = NULL;
+ }
+ spin_unlock(&vpm->change_list_lock);
+
+ return order;
+}
+
+static int nlp_settings_changed(const struct adt_lec_params *a,
+ const struct adt_lec_params *b)
+{
+ return ((a->nlp_type != b->nlp_type) ||
+ (a->nlp_threshold != b->nlp_threshold) ||
+ (a->nlp_max_suppress != b->nlp_max_suppress));
+}
+
+static int echocan_on(const struct adt_lec_params *new,
+ const struct adt_lec_params *old)
+{
+ return ((new->tap_length != old->tap_length) &&
+ (new->tap_length > 0));
+}
+
+static int echocan_off(const struct adt_lec_params *new,
+ const struct adt_lec_params *old)
+{
+ return ((new->tap_length != old->tap_length) &&
+ (0 == new->tap_length));
+}
+
+static void update_channel_config(struct vpmadt032 *vpm, unsigned int channel,
+ struct adt_lec_params *desired)
+{
+ int res;
+ GPAK_AlgControlStat_t pstatus;
+ GPAK_ChannelConfigStat_t cstatus;
+ GPAK_TearDownChanStat_t tstatus;
+ GpakChannelConfig_t chanconfig;
+
+ if (vpm->options.debug & DEBUG_ECHOCAN) {
+ vpm_info(vpm, "Reconfiguring chan %d for nlp %d, "
+ "nlp_thresh %d, and max_supp %d\n", channel + 1,
+ desired->nlp_type, desired->nlp_threshold,
+ desired->nlp_max_suppress);
+ }
+
+ vpm->setchanconfig_from_state(vpm, channel, &chanconfig);
+
+ res = gpakTearDownChannel(vpm->dspid, channel, &tstatus);
+ if (res)
+ return;
+
+ res = gpakConfigureChannel(vpm->dspid, channel, tdmToTdm,
+ &chanconfig, &cstatus);
+ if (res)
+ return;
+
+ if (!desired->tap_length) {
+ res = gpakAlgControl(vpm->dspid, channel,
+ BypassSwCompanding, &pstatus);
+ if (res) {
+ vpm_info(vpm, "Unable to disable sw companding on "
+ "echo cancellation channel %d (reason %d)\n",
+ channel, res);
+ }
+ gpakAlgControl(vpm->dspid, channel, BypassEcanA, &pstatus);
+ }
+
+ return;
}
/**
@@ -272,97 +371,81 @@
{
struct vpmadt032 *vpm = container_of(data, struct vpmadt032, work);
#endif
- struct adt_lec_params *curstate, *desiredstate;
- int channel;
-
- /* Sweep through all the echo can channels on the VPMADT032 module,
- * looking for ones where the desired state does not match the current
- * state.
- */
- for (channel = 0; channel < vpm->options.channels; channel++) {
- GPAK_AlgControlStat_t pstatus;
- int res = 1;
- curstate = &vpm->curecstate[channel];
- desiredstate = &vpm->desiredecstate[channel];
-
- if ((desiredstate->nlp_type != curstate->nlp_type) ||
- (desiredstate->nlp_threshold != curstate->nlp_threshold) ||
- (desiredstate->nlp_max_suppress != curstate->nlp_max_suppress)) {
-
- GPAK_ChannelConfigStat_t cstatus;
- GPAK_TearDownChanStat_t tstatus;
- GpakChannelConfig_t chanconfig;
-
- if (vpm->options.debug & DEBUG_ECHOCAN)
- printk(KERN_DEBUG "Reconfiguring chan %d for nlp %d, nlp_thresh %d, and max_supp %d\n", channel + 1, vpm->desiredecstate[channel].nlp_type,
- desiredstate->nlp_threshold, desiredstate->nlp_max_suppress);
-
- vpm->setchanconfig_from_state(vpm, channel, &chanconfig);
-
- res = gpakTearDownChannel(vpm->dspid, channel, &tstatus);
- if (res)
- goto vpm_bh_out;
-
- res = gpakConfigureChannel(vpm->dspid, channel, tdmToTdm, &chanconfig, &cstatus);
- if (res)
- goto vpm_bh_out;
-
- if (!desiredstate->tap_length) {
- res = gpakAlgControl(vpm->dspid, channel, BypassSwCompanding, &pstatus);
- if (res)
- printk("Unable to disable sw companding on echo cancellation channel %d (reason %d)\n", channel, res);
- res = gpakAlgControl(vpm->dspid, channel, BypassEcanA, &pstatus);
- }
-
- } else if (desiredstate->tap_length != curstate->tap_length) {
- if (desiredstate->tap_length)
- res = vpmadt032_enable_ec(vpm, channel);
- else
- res = vpmadt032_disable_ec(vpm, channel);
- }
-vpm_bh_out:
- if (!res)
- *curstate = *desiredstate;
- }
- return;
-}
+ struct change_order *order;
+
+ while ((order = get_next_order(vpm))) {
+
+ struct adt_lec_params *old;
+ struct adt_lec_params *new;
+ unsigned int channel;
+
+ channel = order->channel;
+ BUG_ON(channel >= ARRAY_SIZE(vpm->curecstate));
+ old = &vpm->curecstate[channel];
+ new = &order->params;
+
+ if (nlp_settings_changed(new, old))
+ update_channel_config(vpm, channel, new);
+ else if (echocan_on(new, old))
+ vpmadt032_enable_ec(vpm, channel, new->companding);
+ else if (echocan_off(new, old))
+ vpmadt032_disable_ec(vpm, channel);
+
+ *old = order->params;
+ free_change_order(order);
+ }
+}
+
#include "adt_lec.c"
-static void vpmadt032_check_and_schedule_update(struct vpmadt032 *vpm, int channo)
-{
- int update;
- /* Only update the parameters if the new state of the echo canceller
- * is different than the current state. */
- update = memcmp(&vpm->curecstate[channo],
- &vpm->desiredecstate[channo],
- sizeof(vpm->curecstate[channo]));
- if (update && test_bit(VPM150M_ACTIVE, &vpm->control)) {
- /* Since updating the parameters can take a bit of time while
- * the driver sends messages to the VPMADT032 and waits for
- * their responses, we'll push the work of updating the
- * parameters to a work queue so the caller can continue to
- * proceed with setting up the call.
- */
- queue_work(vpm->wq, &vpm->work);
- }
+static void vpmadt032_check_and_schedule_update(struct vpmadt032 *vpm,
+ struct change_order *order)
+{
+ struct change_order *cur;
+ struct change_order *n;
+
+ INIT_LIST_HEAD(&order->node);
+ spin_lock(&vpm->change_list_lock);
+ list_for_each_entry_safe(cur, n, &vpm->change_list, node) {
+ if (cur->channel == order->channel) {
+ list_replace(&cur->node, &order->node);
+ free_change_order(cur);
+ break;
+ }
+ }
+ if (list_empty(&order->node))
+ list_add_tail(&order->node, &vpm->change_list);
+ spin_unlock(&vpm->change_list_lock);
+
+ queue_work(vpm->wq, &vpm->work);
}
int vpmadt032_echocan_create(struct vpmadt032 *vpm, int channo,
struct dahdi_echocanparams *ecp, struct dahdi_echocanparam *p)
{
unsigned int ret;
-
- ret = adt_lec_parse_params(&vpm->desiredecstate[channo], ecp, p);
- if (ret)
+ struct change_order *order = alloc_change_order();
+ if (!order)
+ return -ENOMEM;
+
+ memcpy(&order->params, &vpm->curecstate[channo], sizeof(order->params));
+ ret = adt_lec_parse_params(&order->params, ecp, p);
+ if (ret) {
+ free_change_order(order);
return ret;
-
- if (vpm->options.debug & DEBUG_ECHOCAN)
- printk(KERN_DEBUG "echocan: Channel is %d length %d\n", channo, ecp->tap_length);
+ }
+
+ if (vpm->options.debug & DEBUG_ECHOCAN) {
+ vpm_info(vpm, "Channel is %d length %d\n",
+ channo, ecp->tap_length);
+ }
/* The driver cannot control the number of taps on the VPMADT032
* module. Instead, it uses tap_length to enable or disable the echo
* cancellation. */
- vpm->desiredecstate[channo].tap_length = (ecp->tap_length) ? 1 : 0;
-
- vpmadt032_check_and_schedule_update(vpm, channo);
+ order->params.tap_length = (ecp->tap_length) ? 1 : 0;
+ order->params.companding = vpm->companding;
+ order->channel = channo;
+
+ vpmadt032_check_and_schedule_update(vpm, order);
return 0;
}
EXPORT_SYMBOL(vpmadt032_echocan_create);
@@ -370,15 +453,22 @@
void vpmadt032_echocan_free(struct vpmadt032 *vpm, int channo,
struct dahdi_echocan_state *ec)
{
- adt_lec_init_defaults(&vpm->desiredecstate[channo], 0);
- vpm->desiredecstate[channo].nlp_type = vpm->options.vpmnlptype;
- vpm->desiredecstate[channo].nlp_threshold = vpm->options.vpmnlpthresh;
- vpm->desiredecstate[channo].nlp_max_suppress = vpm->options.vpmnlpmaxsupp;
+ struct change_order *order;
+ order = alloc_change_order();
+ WARN_ON(!order);
+ if (!order)
+ return;
+
+ adt_lec_init_defaults(&order->params, 0);
+ order->params.nlp_type = vpm->options.vpmnlptype;
+ order->params.nlp_threshold = vpm->options.vpmnlpthresh;
+ order->params.nlp_max_suppress = vpm->options.vpmnlpmaxsupp;
+ order->channel = channo;
if (vpm->options.debug & DEBUG_ECHOCAN)
- printk(KERN_DEBUG "echocan: Channel is %d length 0\n", channo);
-
- vpmadt032_check_and_schedule_update(vpm, channo);
+ vpm_info(vpm, "Channel is %d length 0\n", channo);
+
+ vpmadt032_check_and_schedule_update(vpm, order);
}
EXPORT_SYMBOL(vpmadt032_echocan_free);
@@ -410,6 +500,8 @@
/* Init our vpmadt032 struct */
memcpy(&vpm->options, options, sizeof(*options));
spin_lock_init(&vpm->list_lock);
+ spin_lock_init(&vpm->change_list_lock);
+ INIT_LIST_HEAD(&vpm->change_list);
INIT_LIST_HEAD(&vpm->free_cmds);
INIT_LIST_HEAD(&vpm->pending_cmds);
INIT_LIST_HEAD(&vpm->active_cmds);
@@ -443,8 +535,6 @@
kfree(vpm);
printk(KERN_NOTICE "Unable to initialize another vpmadt032 modules\n");
vpm = NULL;
- } else if (vpm->options.debug & DEBUG_ECHOCAN) {
- printk(KERN_DEBUG "Setting VPMADT032 DSP ID to %d\n", vpm->dspid);
}
return vpm;
@@ -461,6 +551,9 @@
BUG_ON(!vpm->setchanconfig_from_state);
BUG_ON(!vpm->wq);
+ BUG_ON(!vb);
+
+ vpm->vb = vb;
might_sleep();
@@ -521,8 +614,9 @@
return res;
}
vpm->curpage = -1;
+
+ dev_info(&voicebus_get_pci_dev(vb)->dev, "Booting VPMADT032\n");
set_bit(VPM150M_SWRESET, &vpm->control);
-
while (test_bit(VPM150M_SWRESET, &vpm->control))
msleep(1);
@@ -561,7 +655,7 @@
p->EcanDblTalkThresh = 6;
p->EcanMaxDoubleTalkThres = 40;
p->EcanNlpThreshold = DEFAULT_NLPTHRESH;
- p->EcanNlpConv = 0;
+ p->EcanNlpConv = 18;
p->EcanNlpUnConv = 12;
p->EcanNlpMaxSuppress = DEFAULT_NLPMAXSUPP;
p->EcanCngThreshold = 43;
@@ -579,6 +673,7 @@
{
unsigned long flags;
struct vpmadt032_cmd *cmd;
+ struct change_order *order;
LIST_HEAD(local_list);
BUG_ON(!vpm);
@@ -597,6 +692,16 @@
cmd = list_entry(local_list.next, struct vpmadt032_cmd, node);
list_del(&cmd->node);
kfree(cmd);
+ }
+
+ spin_lock(&vpm->change_list_lock);
+ list_splice(&vpm->change_list, &local_list);
+ spin_unlock(&vpm->change_list_lock);
+
+ while (!list_empty(&local_list)) {
+ order = list_entry(local_list.next, struct change_order, node);
+ list_del(&order->node);
+ kfree(order);
}
BUG_ON(ifaces[vpm->dspid] != vpm);
Modified: linux/team/mspiceland/dahdi-qfalc31/drivers/dahdi/voicebus/GpakCust.h
URL: http://svnview.digium.com/svn/dahdi/linux/team/mspiceland/dahdi-qfalc31/drivers/dahdi/voicebus/GpakCust.h?view=diff&rev=7662&r1=7661&r2=7662
==============================================================================
--- linux/team/mspiceland/dahdi-qfalc31/drivers/dahdi/voicebus/GpakCust.h (original)
+++ linux/team/mspiceland/dahdi-qfalc31/drivers/dahdi/voicebus/GpakCust.h Thu Dec 3 14:40:27 2009
@@ -105,9 +105,8 @@
struct GpakChannelConfig;
-#define MAX_CHANNELS_PER_SPAN 32
struct vpmadt032 {
- void *context;
+ struct voicebus *vb;
struct work_struct work;
struct workqueue_struct *wq;
int dspid;
@@ -115,8 +114,10 @@
unsigned long control;
unsigned char curpage;
unsigned short version;
- struct adt_lec_params curecstate[MAX_CHANNELS_PER_SPAN];
- struct adt_lec_params desiredecstate[MAX_CHANNELS_PER_SPAN];
+ enum adt_companding companding;
+ struct adt_lec_params curecstate[MAX_CHANNELS];
+ spinlock_t change_list_lock;
+ struct list_head change_list;
spinlock_t list_lock;
/* Commands that are ready to be used. */
struct list_head free_cmds;
@@ -124,7 +125,6 @@
struct list_head pending_cmds;
/* Commands that are currently in progress by the VPM module */
struct list_head active_cmds;
- unsigned char curtone[MAX_CHANNELS_PER_SPAN];
struct vpmadt032_options options;
void (*setchanconfig_from_state)(struct vpmadt032 *vpm, int channel, struct GpakChannelConfig *chanconfig);
/* This must be last */
Modified: linux/team/mspiceland/dahdi-qfalc31/drivers/dahdi/voicebus/voicebus.c
URL: http://svnview.digium.com/svn/dahdi/linux/team/mspiceland/dahdi-qfalc31/drivers/dahdi/voicebus/voicebus.c?view=diff&rev=7662&r1=7661&r2=7662
==============================================================================
--- linux/team/mspiceland/dahdi-qfalc31/drivers/dahdi/voicebus/voicebus.c (original)
+++ linux/team/mspiceland/dahdi-qfalc31/drivers/dahdi/voicebus/voicebus.c Thu Dec 3 14:40:27 2009
@@ -41,8 +41,6 @@
#include "vpmadtreg.h"
#include "GpakCust.h"
-#define assert(__x__) BUG_ON(!(__x__))
-
#define INTERRUPT 0 /* Run the deferred processing in the ISR. */
#define TASKLET 1 /* Run in a tasklet. */
#define TIMER 2 /* Run in a system timer. */
@@ -56,6 +54,11 @@
#define VOICEBUS_ALLOC_FLAGS GFP_ATOMIC
#endif
+/* Define CONFIG_VOICEBUS_SYSFS to create some attributes under the pci device.
+ * This is disabled by default because it hasn't been tested on the full range
+ * of supported kernels. */
+#undef CONFIG_VOICEBUS_SYSFS
+
#if VOICEBUS_DEFERRED == TIMER
#if HZ < 1000
/* \todo Put an error message here. */
@@ -63,7 +66,7 @@
#endif
/*! The number of descriptors in both the tx and rx descriptor ring. */
-#define DRING_SIZE (1 << 5) /* Must be a power of 2 */
+#define DRING_SIZE (1 << 7) /* Must be a power of 2 */
#define DRING_MASK (DRING_SIZE-1)
/* Interrupt status' reported in SR_CSR5 */
@@ -110,10 +113,10 @@
/* In memory structure shared by the host and the adapter. */
struct voicebus_descriptor {
- u32 des0;
- u32 des1;
- u32 buffer1;
- u32 container; /* Unused */
+ volatile __le32 des0;
+ volatile __le32 des1;
+ volatile __le32 buffer1;
+ volatile __le32 container; /* Unused */
} __attribute__((packed));
struct voicebus_descriptor_list {
@@ -127,20 +130,22 @@
void *pending[DRING_SIZE];
/* PCI Bus address of the descriptor list. */
dma_addr_t desc_dma;
- /*! either DMA_FROM_DEVICE or DMA_TO_DEVICE */
- unsigned int direction;
/*! The number of buffers currently submitted to the hardware. */
atomic_t count;
/*! The number of bytes to pad each descriptor for cache alignment. */
unsigned int padding;
};
-
-/*! * \brief Represents a VoiceBus interface on a Digium telephony card.
+/**
+ * struct voicebus -
+ *
+ * @tx_idle_vbb:
+ * @tx_idle_vbb_dma_addr:
+ * @max_latency: Do not allow the driver to automatically insert more than this
+ * much latency to the tdm stream by default.
+ * @count: The number of non-idle buffers that we should be expecting.
*/
struct voicebus {
- /*! Name of this card. */
- const char *board_name;
/*! The system pci device for this VoiceBus interface. */
struct pci_dev *pdev;
/*! Protects access to card registers and this structure. You should
@@ -154,6 +159,8 @@
/*! Pool to allocate memory for the tx and rx descriptor rings. */
struct voicebus_descriptor_list rxd;
struct voicebus_descriptor_list txd;
+ void *idle_vbb;
+ dma_addr_t idle_vbb_dma_addr;
/*! Level of debugging information. 0=None, 5=Insane. */
atomic_t debuglevel;
/*! Cache of buffer objects. */
@@ -186,11 +193,17 @@
struct completion stopped_completion;
/*! Flags */
unsigned long flags;
- /* \todo see about removing this... */
- u32 sdi;
/*! Number of tx buffers to queue up before enabling interrupts. */
unsigned int min_tx_buffer_count;
+ unsigned int max_latency;
+ void *vbb_stash[DRING_SIZE];
+ unsigned int count;
};
+
+static inline void handle_transmit(struct voicebus *vb, void *vbb)
+{
+ vb->handle_transmit(vbb, vb->context);
+}
/*
* Use the following macros to lock the VoiceBus interface, and it won't
@@ -218,15 +231,13 @@
#define VBUNLOCK_FROM_DEFERRED(_vb_) spin_lock(&((_vb_)->lock))
#endif
-#define VB_PRINTK(_vb, _lvl, _fmt, _args...) \
- printk(KERN_##_lvl "%s: " _fmt, (_vb)->board_name, ## _args)
-
/* Bit definitions for struct voicebus.flags */
#define TX_UNDERRUN 1
#define RX_UNDERRUN 2
#define IN_DEFERRED_PROCESSING 3
#define STOP 4
#define STOPPED 5
+#define LATENCY_LOCKED 6
#if VOICEBUS_DEFERRED == WORKQUEUE
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 18)
@@ -257,32 +268,9 @@
#endif
#endif
-#ifdef DBG
-static inline int
-assert_in_vb_deferred(struct voicebus *vb)
-{
- assert(test_bit(IN_DEFERRED_PROCESSING, &vb->flags));
-}
-
-static inline void
-start_vb_deferred(struct voicebus *vb)
-{
- set_bit(IN_DEFERRED_PROCESSING, &vb->flags);
-}
-
-static inline void
-stop_vb_deferred(struct voicebus *vb)
-{
- clear_bit(IN_DEFERRED_PROCESSING, &vb->flags);
-}
-#else
-#define assert_in_vb_deferred(_x_) do {; } while (0)
-#define start_vb_deferred(_x_) do {; } while (0)
-#define stop_vb_deferred(_x_) do {; } while (0)
-#endif
-
static inline struct voicebus_descriptor *
-vb_descriptor(struct voicebus_descriptor_list *dl, int index)
+vb_descriptor(const struct voicebus_descriptor_list *dl,
+ const unsigned int index)
{
struct voicebus_descriptor *d;
d = (struct voicebus_descriptor *)((u8*)dl->desc +
@@ -298,7 +286,7 @@
struct voicebus_descriptor *d;
const u32 END_OF_RING = 0x02000000;
- assert(dl);
+ BUG_ON(!dl);
/*
* Add some padding to each descriptor to ensure that they are
@@ -324,16 +312,55 @@
d->des1 = des1;
}
d->des1 |= cpu_to_le32(END_OF_RING);
- dl->direction = direction;
atomic_set(&dl->count, 0);
return 0;
}
+#define OWNED(_d_) (((_d_)->des0)&OWN_BIT)
+#define SET_OWNED(_d_) do { wmb(); (_d_)->des0 |= OWN_BIT; wmb(); } while (0)
+
static int
vb_initialize_tx_descriptors(struct voicebus *vb)
{
- return vb_initialize_descriptors(
- vb, &vb->txd, 0xe4800000 | vb->framesize, DMA_TO_DEVICE);
+ int i;
+ int des1 = 0xe4800000 | vb->framesize;
+ struct voicebus_descriptor *d;
+ struct voicebus_descriptor_list *dl = &vb->txd;
+ const u32 END_OF_RING = 0x02000000;
+
+ WARN_ON(!dl);
+ WARN_ON((NULL == vb->idle_vbb) || (0 == vb->idle_vbb_dma_addr));
+
+ /*
+ * Add some padding to each descriptor to ensure that they are
+ * aligned on host system cache-line boundaries, but only for the
+ * cache-line sizes that we support.
+ *
+ */
+ if ((0x08 == vb->cache_line_size) || (0x10 == vb->cache_line_size) ||
+ (0x20 == vb->cache_line_size)) {
+ dl->padding = (vb->cache_line_size*sizeof(u32)) - sizeof(*d);
+ } else {
+ dl->padding = 0;
+ }
+
+ dl->desc = pci_alloc_consistent(vb->pdev,
+ (sizeof(*d) + dl->padding) *
+ DRING_SIZE, &dl->desc_dma);
+ if (!dl->desc)
+ return -ENOMEM;
+
+ memset(dl->desc, 0, (sizeof(*d) + dl->padding) * DRING_SIZE);
+ for (i = 0; i < DRING_SIZE; ++i) {
+ d = vb_descriptor(dl, i);
+ d->des1 = des1;
+ d->buffer1 = vb->idle_vbb_dma_addr;
+ dl->pending[i] = vb->idle_vbb;
+ SET_OWNED(d);
+ }
+ d->des1 |= cpu_to_le32(END_OF_RING);
+ atomic_set(&dl->count, 0);
+ return 0;
}
static int
@@ -358,10 +385,10 @@
*/
#define MESSAGE "%d ms is an invalid value for minumum latency. Setting to %d ms.\n"
if (DRING_SIZE < ms) {
- VB_PRINTK(vb, WARNING, MESSAGE, ms, DRING_SIZE);
+ dev_warn(&vb->pdev->dev, MESSAGE, ms, DRING_SIZE);
return -EINVAL;
} else if (VOICEBUS_DEFAULT_LATENCY > ms) {
- VB_PRINTK(vb, WARNING, MESSAGE, ms, VOICEBUS_DEFAULT_LATENCY);
+ dev_warn(&vb->pdev->dev, MESSAGE, ms, VOICEBUS_DEFAULT_LATENCY);
return -EINVAL;
}
VBLOCK(vb);
@@ -419,6 +446,36 @@
}
EXPORT_SYMBOL(voicebus_current_latency);
+/**
+ * voicebus_lock_latency() - Do not increase the latency during underruns.
+ *
+ */
+void voicebus_lock_latency(struct voicebus *vb)
+{
+ set_bit(LATENCY_LOCKED, &vb->flags);
+}
+EXPORT_SYMBOL(voicebus_lock_latency);
+
+/**
+ * voicebus_unlock_latency() - Bump up the latency during underruns.
+ *
+ */
+void voicebus_unlock_latency(struct voicebus *vb)
+{
+ clear_bit(LATENCY_LOCKED, &vb->flags);
+}
+EXPORT_SYMBOL(voicebus_unlock_latency);
+
+/**
+ * voicebus_is_latency_locked() - Return 1 if latency is currently locked.
+ *
+ */
+int voicebus_is_latency_locked(const struct voicebus *vb)
+{
+ return test_bit(LATENCY_LOCKED, &vb->flags);
+}
+EXPORT_SYMBOL(voicebus_is_latency_locked);
+
/*!
* \brief Read one of the hardware control registers without acquiring locks.
*/
@@ -460,18 +517,48 @@
}
static void
-vb_cleanup_descriptors(struct voicebus *vb, struct voicebus_descriptor_list *dl)
+vb_cleanup_tx_descriptors(struct voicebus *vb)
{
unsigned int i;
+ struct voicebus_descriptor_list *dl = &vb->txd;
struct voicebus_descriptor *d;
- assert(vb_is_stopped(vb));
+ BUG_ON(!vb_is_stopped(vb));
+
+ for (i = 0; i < DRING_SIZE; ++i) {
+ d = vb_descriptor(dl, i);
+ if (d->buffer1 && (d->buffer1 != vb->idle_vbb_dma_addr)) {
+ WARN_ON(!dl->pending[i]);
+ dma_unmap_single(&vb->pdev->dev, d->buffer1,
+ vb->framesize, DMA_TO_DEVICE);
+ voicebus_free(vb, dl->pending[i]);
+ }
+ d->buffer1 = vb->idle_vbb_dma_addr;
+ dl->pending[i] = vb->idle_vbb;
+ SET_OWNED(d);
+ }
+ /* Send out two idle buffers to start because sometimes the first buffer
+ * doesn't make it back to us. */
+ dl->head = dl->tail = 2;
+ atomic_set(&dl->count, 0);
+}
+
+static void
+vb_cleanup_rx_descriptors(struct voicebus *vb)
+{
+ unsigned int i;
+ struct voicebus_descriptor_list *dl = &vb->rxd;
+ struct voicebus_descriptor *d;
+
+ BUG_ON(!vb_is_stopped(vb));
for (i = 0; i < DRING_SIZE; ++i) {
d = vb_descriptor(dl, i);
if (d->buffer1) {
+ dma_unmap_single(&vb->pdev->dev, d->buffer1,
+ vb->framesize, DMA_FROM_DEVICE);
d->buffer1 = 0;
- assert(dl->pending[i]);
+ BUG_ON(!dl->pending[i]);
voicebus_free(vb, dl->pending[i]);
dl->pending[i] = NULL;
}
@@ -480,6 +567,15 @@
dl->head = 0;
dl->tail = 0;
atomic_set(&dl->count, 0);
+}
+
+static void vb_cleanup_descriptors(struct voicebus *vb,
+ struct voicebus_descriptor_list *dl)
+{
+ if (dl == &vb->txd)
+ vb_cleanup_tx_descriptors(vb);
+ else
+ vb_cleanup_rx_descriptors(vb);
}
static void
@@ -519,30 +615,30 @@
}
static int
-__vb_sdi_clk(struct voicebus *vb)
+__vb_sdi_clk(struct voicebus *vb, u32 *sdi)
{
unsigned int ret;
- vb->sdi &= ~CSR9_MDC;
- __vb_setctl(vb, 0x0048, vb->sdi);
+ *sdi &= ~CSR9_MDC;
+ __vb_setctl(vb, 0x0048, *sdi);
ret = __vb_getctl(vb, 0x0048);
- vb->sdi |= CSR9_MDC;
- __vb_setctl(vb, 0x0048, vb->sdi);
+ *sdi |= CSR9_MDC;
+ __vb_setctl(vb, 0x0048, *sdi);
return (ret & CSR9_MDI) ? 1 : 0;
}
static void
-__vb_sdi_sendbits(struct voicebus *vb, u32 bits, int count)
-{
- vb->sdi &= ~CSR9_MMC;
- __vb_setctl(vb, 0x0048, vb->sdi);
+__vb_sdi_sendbits(struct voicebus *vb, u32 bits, int count, u32 *sdi)
+{
+ *sdi &= ~CSR9_MMC;
+ __vb_setctl(vb, 0x0048, *sdi);
while (count--) {
if (bits & (1 << count))
- vb->sdi |= CSR9_MDO;
+ *sdi |= CSR9_MDO;
else
- vb->sdi &= ~CSR9_MDO;
-
- __vb_sdi_clk(vb);
+ *sdi &= ~CSR9_MDO;
+
+ __vb_sdi_clk(vb, sdi);
}
}
@@ -551,13 +647,14 @@
{
LOCKS_VOICEBUS;
u32 bits;
+ u32 sdi = 0;
/* Send preamble */
bits = 0xffffffff;
VBLOCK(vb);
- __vb_sdi_sendbits(vb, bits, 32);
+ __vb_sdi_sendbits(vb, bits, 32, &sdi);
bits = (0x5 << 12) | (1 << 7) | (addr << 2) | 0x2;
- __vb_sdi_sendbits(vb, bits, 16);
- __vb_sdi_sendbits(vb, val, 16);
+ __vb_sdi_sendbits(vb, bits, 16, &sdi);
+ __vb_sdi_sendbits(vb, val, 16, &sdi);
VBUNLOCK(vb);
}
@@ -566,7 +663,7 @@
{
LOCKS_VOICEBUS;
u32 reg;
- assert(vb->pdev);
+ BUG_ON(!vb->pdev);
VBLOCK(vb);
pci_read_config_dword(vb->pdev, 0x0004, ®);
reg |= 0x00000007;
@@ -620,11 +717,12 @@
pci_access = DEFAULT_PCI_ACCESS | (0x3 << 14);
break;
default:
- if (atomic_read(&vb->debuglevel))
- VB_PRINTK(vb, WARNING, "Host system set a cache size "\
[... 3932 lines stripped ...]
More information about the dahdi-commits
mailing list