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) diff --git a/include/dahdi/kernel.h b/include/dahdi/kernel.h index 6b5f4a4..d3beabe 100644 --- a/include/dahdi/kernel.h +++ b/include/dahdi/kernel.h @@ -719,6 +719,9 @@ enum { DAHDI_FLAGBIT_LOOPED = 18, /*!< Loopback the receive data from the channel to the transmit */ DAHDI_FLAGBIT_MTP2 = 19, /*!< Repeats last message in buffer and also discards repeating messages sent to us */ DAHDI_FLAGBIT_HDLC56 = 20, /*!< Sets the given channel (if in HDLC mode) to use 56K HDLC instead of 64K */ + DAHDI_FLAGBIT_BUFEVENTS = 21, /*!< Report buffer events */ + DAHDI_FLAGBIT_TXUNDERRUN = 22, /*!< Transmit underrun condition */ + DAHDI_FLAGBIT_RXOVERRUN = 23, /*!< Receive overrun condition */ DAHDI_FLAGBIT_DEVFILE = 25, /*!< Channel has a sysfs dev file */ }; @@ -783,6 +786,9 @@ struct dahdi_count { #define DAHDI_FLAG_LOOPED DAHDI_FLAG(LOOPED) #define DAHDI_FLAG_MTP2 DAHDI_FLAG(MTP2) #define DAHDI_FLAG_HDLC56 DAHDI_FLAG(HDLC56) +#define DAHDI_FLAG_BUFEVENTS DAHDI_FLAG(BUFEVENTS) +#define DAHDI_FLAG_TXUNDERRUN DAHDI_FLAG(TXUNDERRUN) +#define DAHDI_FLAG_RXOVERRUN DAHDI_FLAG(RXOVERRUN) struct dahdi_span_ops { struct module *owner; /*!< Which module is exporting this span. */ diff --git a/include/dahdi/user.h b/include/dahdi/user.h index 1159fbf..6b666b9 100644 --- a/include/dahdi/user.h +++ b/include/dahdi/user.h @@ -448,6 +448,12 @@ enum dahdi_maint_mode { /* The echo canceler's NLP (only) was enabled */ #define DAHDI_EVENT_EC_NLP_ENABLED 28 +/* The channel's read buffer encountered an overrun condition */ +#define DAHDI_EVENT_READ_OVERRUN 29 + +/* The channel's write buffer encountered an underrun condition */ +#define DAHDI_EVENT_WRITE_UNDERRUN 30 + #define DAHDI_EVENT_PULSEDIGIT (1 << 16) /* This is OR'd with the digit received */ #define DAHDI_EVENT_DTMFDOWN (1 << 17) /* Ditto for DTMF key down event */ #define DAHDI_EVENT_DTMFUP (1 << 18) /* Ditto for DTMF key up event */ @@ -1085,6 +1091,13 @@ struct dahdi_vmwi_info { #define DAHDI_TXMIRROR _IOW(DAHDI_CODE, 104, int) #endif /* CONFIG_DAHDI_MIRROR */ +/* + Set the desired state for channel buffer event generation which is disabled + by default to allow for backwards compatibility for dumb users of channels + such as pattern utilities. + */ +#define DAHDI_BUFFER_EVENTS _IOW(DAHDI_CODE, 105, int) + /* Get current status IOCTL */ /* Defines for Radio Status (dahdi_radio_stat.radstat) bits */