[svn-commits] sruffell: linux/trunk r9884 - in /linux/trunk: drivers/dahdi/ include/dahdi/
SVN commits to the Digium repositories
svn-commits at lists.digium.com
Mon Apr 4 11:25:27 CDT 2011
Author: sruffell
Date: Mon Apr 4 11:25:23 2011
New Revision: 9884
URL: http://svnview.digium.com/svn/dahdi?view=rev&rev=9884
Log:
dahdi: Add in-hardirq versions of the dahdi_receive/transmit/ec_span.
Since cli/sti are expensive instructions, if the board drivers are
calling receive/transmit/ec_span from interrupt context all local
interrupts do not need to be disabled. The board drivers all still use
the normal dahdi_receive and dahdi_transmit. _dahdi_receive and
_dahdi_transmit are the "in-hardirq" versions of those functions.
Signed-off-by: Shaun Ruffell <sruffell at digium.com>
Acked-by: Michael Spiceland <mspiceland at digium.com>
Acked-by: Kinsey Moore <kmoore at digium.com>
Modified:
linux/trunk/drivers/dahdi/dahdi-base.c
linux/trunk/include/dahdi/kernel.h
Modified: linux/trunk/drivers/dahdi/dahdi-base.c
URL: http://svnview.digium.com/svn/dahdi/linux/trunk/drivers/dahdi/dahdi-base.c?view=diff&rev=9884&r1=9883&r2=9884
==============================================================================
--- linux/trunk/drivers/dahdi/dahdi-base.c (original)
+++ linux/trunk/drivers/dahdi/dahdi-base.c Mon Apr 4 11:25:23 2011
@@ -119,16 +119,12 @@
EXPORT_SYMBOL(__dahdi_lin2mu);
EXPORT_SYMBOL(__dahdi_lin2a);
#endif
-EXPORT_SYMBOL(dahdi_transmit);
-EXPORT_SYMBOL(dahdi_receive);
EXPORT_SYMBOL(dahdi_rbsbits);
EXPORT_SYMBOL(dahdi_qevent_nolock);
EXPORT_SYMBOL(dahdi_qevent_lock);
EXPORT_SYMBOL(dahdi_hooksig);
EXPORT_SYMBOL(dahdi_alarm_notify);
EXPORT_SYMBOL(dahdi_set_dynamic_ioctl);
-EXPORT_SYMBOL(dahdi_ec_chunk);
-EXPORT_SYMBOL(dahdi_ec_span);
EXPORT_SYMBOL(dahdi_hdlc_abort);
EXPORT_SYMBOL(dahdi_hdlc_finish);
EXPORT_SYMBOL(dahdi_hdlc_getbuf);
@@ -7635,7 +7631,8 @@
}
}
-static inline void __dahdi_ec_chunk(struct dahdi_chan *ss, unsigned char *rxchunk, const unsigned char *txchunk)
+static void
+__dahdi_ec_chunk(struct dahdi_chan *ss, u8 *rxchunk, const u8 *txchunk)
{
short rxlin, txlin;
int x;
@@ -7704,7 +7701,7 @@
}
/**
- * dahdi_ec_chunk() - process echo for a single channel
+ * _dahdi_ec_chunk() - process echo for a single channel
* @ss: DAHDI channel
* @rxchunk: chunk of audio on which to cancel echo
* @txchunk: reference chunk from the other direction
@@ -7713,14 +7710,16 @@
* audio. In order to fix it it uses the transmitted audio as a
* reference. This call updates the echo canceller for a single chunk (8
* bytes).
+ *
+ * Call with local interrupts disabled.
*/
-void dahdi_ec_chunk(struct dahdi_chan *ss, unsigned char *rxchunk, const unsigned char *txchunk)
-{
- unsigned long flags;
- spin_lock_irqsave(&ss->lock, flags);
+void _dahdi_ec_chunk(struct dahdi_chan *ss, u8 *rxchunk, const u8 *txchunk)
+{
+ spin_lock(&ss->lock);
__dahdi_ec_chunk(ss, rxchunk, txchunk);
- spin_unlock_irqrestore(&ss->lock, flags);
-}
+ spin_unlock(&ss->lock);
+}
+EXPORT_SYMBOL(_dahdi_ec_chunk);
/**
* dahdi_ec_span() - process echo for all channels in a span.
@@ -7730,11 +7729,9 @@
* span. Uses dahdi_chunk.write_chunk for the rxchunk (the chunk to fix)
* and dahdi_chan.readchunk as the txchunk (the reference chunk).
*/
-void dahdi_ec_span(struct dahdi_span *span)
+void _dahdi_ec_span(struct dahdi_span *span)
{
int x;
- unsigned long flags;
- local_irq_save(flags);
for (x = 0; x < span->channels; x++) {
if (span->chans[x]->ec_current) {
spin_lock(&span->chans[x]->lock);
@@ -7742,8 +7739,8 @@
spin_unlock(&span->chans[x]->lock);
}
}
- local_irq_restore(flags);
-}
+}
+EXPORT_SYMBOL(_dahdi_ec_span);
/* return 0 if nothing detected, 1 if lack of tone, 2 if presence of tone */
/* modifies buffer pointed to by 'amp' with notched-out values */
@@ -8710,12 +8707,9 @@
}
}
-int dahdi_transmit(struct dahdi_span *span)
-{
- unsigned long flags;
+int _dahdi_transmit(struct dahdi_span *span)
+{
unsigned int x;
-
- local_irq_save(flags);
for (x=0;x<span->channels;x++) {
struct dahdi_chan *const chan = span->chans[x];
@@ -8756,8 +8750,6 @@
spin_unlock(&chan->lock);
}
- local_irq_restore(flags);
-
if (span->mainttimer) {
span->mainttimer -= DAHDI_CHUNKSIZE;
if (span->mainttimer <= 0) {
@@ -8767,6 +8759,7 @@
}
return 0;
}
+EXPORT_SYMBOL(_dahdi_transmit);
static inline void __pseudo_rx_audio(struct dahdi_chan *chan)
{
@@ -8801,7 +8794,7 @@
#endif
/**
- * process_masterspan - Handle conferencing and timers.
+ * _process_masterspan - Handle conferencing and timers.
*
* There are three sets of conference sum accumulators. One for the current
* sample chunk (conf_sums), one for the next sample chunk (conf_sums_next), and
@@ -8837,9 +8830,8 @@
* of the next sample chunk's data (next time around the world).
*
*/
-static void process_masterspan(void)
-{
- unsigned long flags;
+static void _process_masterspan(void)
+{
int x;
struct pseudo_chan *pseudo;
struct dahdi_span *s;
@@ -8854,7 +8846,7 @@
#endif
/* Hold the chan_lock for the duration of major
activities which touch all sorts of channels */
- spin_lock_irqsave(&chan_lock, flags);
+ spin_lock(&chan_lock);
/* Process any timers */
process_timers();
@@ -8903,7 +8895,7 @@
dahdi_sync_tick(s);
}
- spin_unlock_irqrestore(&chan_lock, flags);
+ spin_unlock(&chan_lock);
}
#ifndef CONFIG_DAHDI_CORE_TIMER
@@ -8945,6 +8937,7 @@
static void coretimer_func(unsigned long param)
{
+ unsigned long flags;
unsigned long ms_since_start;
struct timespec now;
const unsigned long MAX_INTERVAL = 100000L;
@@ -8987,8 +8980,10 @@
return;
}
+ local_irq_save(flags);
while (ms_since_start > msecs_processed(&core_timer))
- process_masterspan();
+ _process_masterspan();
+ local_irq_restore(flags);
if (ms_since_start > MAX_INTERVAL) {
atomic_set(&core_timer.count, 0);
@@ -9062,16 +9057,13 @@
is_chan_dacsed(chan));
}
-int dahdi_receive(struct dahdi_span *span)
-{
- unsigned long flags;
+int _dahdi_receive(struct dahdi_span *span)
+{
unsigned int x;
#ifdef CONFIG_DAHDI_WATCHDOG
span->watchcounter--;
#endif
- local_irq_save(flags);
-
for (x = 0; x < span->channels; x++) {
struct dahdi_chan *const chan = span->chans[x];
spin_lock(&chan->lock);
@@ -9132,13 +9124,12 @@
spin_unlock(&chan->lock);
}
- local_irq_restore(flags);
-
if (span == master)
- process_masterspan();
+ _process_masterspan();
return 0;
}
+EXPORT_SYMBOL(_dahdi_receive);
MODULE_AUTHOR("Mark Spencer <markster at digium.com>");
MODULE_DESCRIPTION("DAHDI Telephony Interface");
Modified: linux/trunk/include/dahdi/kernel.h
URL: http://svnview.digium.com/svn/dahdi/linux/trunk/include/dahdi/kernel.h?view=diff&rev=9884&r1=9883&r2=9884
==============================================================================
--- linux/trunk/include/dahdi/kernel.h (original)
+++ linux/trunk/include/dahdi/kernel.h Mon Apr 4 11:25:23 2011
@@ -1048,12 +1048,32 @@
/*! \brief Unregister a dynamic driver */
void dahdi_dynamic_unregister_driver(struct dahdi_dynamic_driver *driver);
+int _dahdi_receive(struct dahdi_span *span);
+
/*! Receive on a span. The DAHDI interface will handle all the calculations for
all member channels of the span, pulling the data from the readchunk buffer */
-int dahdi_receive(struct dahdi_span *span);
+static inline int dahdi_receive(struct dahdi_span *span)
+{
+ unsigned long flags;
+ int ret;
+ local_irq_save(flags);
+ ret = _dahdi_receive(span);
+ local_irq_restore(flags);
+ return ret;
+}
+
+int _dahdi_transmit(struct dahdi_span *span);
/*! Prepare writechunk buffers on all channels for this span */
-int dahdi_transmit(struct dahdi_span *span);
+static inline int dahdi_transmit(struct dahdi_span *span)
+{
+ unsigned long flags;
+ int ret;
+ local_irq_save(flags);
+ ret = _dahdi_transmit(span);
+ local_irq_restore(flags);
+ return ret;
+}
/*! Abort the buffer currently being receive with event "event" */
void dahdi_hdlc_abort(struct dahdi_chan *ss, int event);
@@ -1122,9 +1142,26 @@
as possible. ECHO CANCELLATION IS NO LONGER AUTOMATICALLY DONE
AT THE DAHDI LEVEL. dahdi_ec_chunk will not echo cancel if it should
not be doing so. rxchunk is modified in-place */
-
-void dahdi_ec_chunk(struct dahdi_chan *chan, unsigned char *rxchunk, const unsigned char *txchunk);
-void dahdi_ec_span(struct dahdi_span *span);
+void _dahdi_ec_chunk(struct dahdi_chan *chan, unsigned char *rxchunk,
+ const unsigned char *txchunk);
+
+static inline void dahdi_ec_chunk(struct dahdi_chan *ss, unsigned char *rxchunk,
+ const unsigned char *txchunk)
+{
+ unsigned long flags;
+ local_irq_save(flags);
+ _dahdi_ec_chunk(ss, rxchunk, txchunk);
+ local_irq_restore(flags);
+}
+
+void _dahdi_ec_span(struct dahdi_span *span);
+static inline void dahdi_ec_span(struct dahdi_span *span)
+{
+ unsigned long flags;
+ local_irq_save(flags);
+ _dahdi_ec_span(span);
+ local_irq_restore(flags);
+}
extern struct file_operations *dahdi_transcode_fops;
More information about the svn-commits
mailing list