summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorKinsey Moore <kmoore@digium.com>2011-04-15 16:16:19 +0000
committerKinsey Moore <kmoore@digium.com>2011-04-15 16:16:19 +0000
commite381a17fb7190696984eca6b8707fb53d671e812 (patch)
treee3bd0ebb343d23b917e04a90b4ce942eda43ee82 /drivers
parent71d2abf65876e5f84db4efb191325bcbc7eaa975 (diff)
dahdi: Add capability to generate events on buffer underruns and overruns
Add BUFFEVENTS and individual buffer event channel flags so that DAHDI can notify userspace processes when it is dropping data. This can be useful when trouble shooting fax problems since DAHDI currently silently discards data becasuse of scheduling latency. With this change, Asterisk could log an event as opposed to just leaving it up to the tone detectors to figure out there was some unexpected phase shift. Acked-by: Shaun Ruffell <sruffell@digium.com> (original patch by Matt Fredrickson) git-svn-id: http://svn.asterisk.org/svn/dahdi/linux/trunk@9905 a0bf4364-ded3-4de4-8d8a-66a801d63aff
Diffstat (limited to 'drivers')
-rw-r--r--drivers/dahdi/dahdi-base.c29
1 files changed, 29 insertions, 0 deletions
diff --git a/drivers/dahdi/dahdi-base.c b/drivers/dahdi/dahdi-base.c
index d9b8408..5c57b2c 100644
--- a/drivers/dahdi/dahdi-base.c
+++ b/drivers/dahdi/dahdi-base.c
@@ -6278,6 +6278,13 @@ static int dahdi_chan_ioctl(struct file *file, unsigned int cmd, unsigned long d
}
break;
#endif
+ case DAHDI_BUFFER_EVENTS:
+ if (get_user(j, (int __user *)data) != -EFAULT && j)
+ set_bit(DAHDI_FLAGBIT_BUFEVENTS, &chan->flags);
+ else
+ clear_bit(DAHDI_FLAGBIT_BUFEVENTS, &chan->flags);
+
+ break;
default:
return dahdi_chanandpseudo_ioctl(file, cmd, data);
}
@@ -7060,6 +7067,7 @@ static inline void __dahdi_getbuf_chunk(struct dahdi_chan *ss, unsigned char *tx
int getlin;
/* How many bytes we need to process */
int bytes = DAHDI_CHUNKSIZE, left;
+ bool needtxunderrun = false;
int x;
/* Let's pick something to transmit. First source to
@@ -7201,13 +7209,25 @@ out in the later versions, and is put back now. */
} else {
memset(txb, 0xFF, bytes);
}
+ needtxunderrun += bytes;
bytes = 0;
} else {
memset(txb, DAHDI_LIN2X(0, ms), bytes); /* Lastly we use silence on telephony channels */
+ needtxunderrun += bytes;
bytes = 0;
}
}
+ if (needtxunderrun) {
+ if (!test_bit(DAHDI_FLAGBIT_TXUNDERRUN, &ms->flags)) {
+ if (test_bit(DAHDI_FLAGBIT_BUFEVENTS, &ms->flags))
+ __qevent(ms, DAHDI_EVENT_WRITE_UNDERRUN);
+ set_bit(DAHDI_FLAGBIT_TXUNDERRUN, &ms->flags);
+ }
+ } else {
+ clear_bit(DAHDI_FLAGBIT_TXUNDERRUN, &ms->flags);
+ }
+
#ifdef CONFIG_DAHDI_MIRROR
if (ss->txmirror) {
spin_lock(&ss->txmirror->lock);
@@ -8383,6 +8403,15 @@ that the waitqueue is empty. */
#endif
}
+ if (bytes) {
+ if (!test_bit(DAHDI_FLAGBIT_RXOVERRUN, &ms->flags)) {
+ if (test_bit(DAHDI_FLAGBIT_BUFEVENTS, &ms->flags))
+ __qevent(ms, DAHDI_EVENT_READ_OVERRUN);
+ set_bit(DAHDI_FLAGBIT_RXOVERRUN, &ms->flags);
+ }
+ } else {
+ clear_bit(DAHDI_FLAGBIT_RXOVERRUN, &ms->flags);
+ }
}
static inline void __dahdi_putbuf_chunk(struct dahdi_chan *ss, unsigned char *rxb)