summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDoug Bailey <dbailey@digium.com>2009-01-27 15:13:52 +0000
committerDoug Bailey <dbailey@digium.com>2009-01-27 15:13:52 +0000
commit22c8d7c0cf228dec7ccc38348ab8e6c77c492bc6 (patch)
treeaf16d0d84a80f19db1ef87a6e2a5a3ec0e124106
parentb19785437da38b006e18c54cfe03e3930f0ea19c (diff)
Break VMWI ioctl calls into two separate calls to maintain old revision compatibility
(issue #14104) Reported by: alecdavis Tested by: dbailey git-svn-id: http://svn.asterisk.org/svn/dahdi/linux/trunk@5826 a0bf4364-ded3-4de4-8d8a-66a801d63aff
-rw-r--r--drivers/dahdi/wctdm.c95
-rw-r--r--drivers/dahdi/wctdm24xxp/base.c92
-rw-r--r--drivers/dahdi/wctdm24xxp/wctdm24xxp.h3
-rw-r--r--include/dahdi/user.h6
4 files changed, 114 insertions, 82 deletions
diff --git a/drivers/dahdi/wctdm.c b/drivers/dahdi/wctdm.c
index 9d43833..2859164 100644
--- a/drivers/dahdi/wctdm.c
+++ b/drivers/dahdi/wctdm.c
@@ -239,7 +239,8 @@ struct wctdm {
int palarms;
int reversepolarity; /* Reverse Line */
int mwisendtype;
- struct dahdi_vmwi_info vmwisetting;
+ struct dahdi_vmwi_info vmwisetting;
+ int vmwi_active_messages;
int vmwi_lrev:1; /* MWI Line Reversal*/
int vmwi_hvdc:1; /* MWI High Voltage DC Idle line */
int vmwi_hvac:1; /* MWI Neon High Voltage AC Idle line */
@@ -1450,6 +1451,47 @@ static int wctdm_set_hwgain(struct wctdm *wc, int card, __s32 gain, __u32 tx)
return 0;
}
+static int set_vmwi(struct wctdm * wc, int chan_idx)
+{
+ if (wc->mod[chan_idx].fxs.vmwi_active_messages){
+ wc->mod[chan_idx].fxs.vmwi_lrev = (wc->mod[chan_idx].fxs.vmwisetting.vmwi_type & DAHDI_VMWI_LREV)?1:0;
+ wc->mod[chan_idx].fxs.vmwi_hvdc = (wc->mod[chan_idx].fxs.vmwisetting.vmwi_type & DAHDI_VMWI_HVDC)?1:0;
+ wc->mod[chan_idx].fxs.vmwi_hvac = (wc->mod[chan_idx].fxs.vmwisetting.vmwi_type & DAHDI_VMWI_HVAC)?1:0;
+ } else {
+ wc->mod[chan_idx].fxs.vmwi_lrev = 0;
+ wc->mod[chan_idx].fxs.vmwi_hvdc = 0;
+ wc->mod[chan_idx].fxs.vmwi_hvac = 0;
+ }
+
+ if (debug) {
+ printk(KERN_DEBUG "Setting VMWI on channel %d, messages=%d, lrev=%d, hvdc=%d, hvac=%d\n",
+ chan_idx,
+ wc->mod[chan_idx].fxs.vmwi_active_messages,
+ wc->mod[chan_idx].fxs.vmwi_lrev,
+ wc->mod[chan_idx].fxs.vmwi_hvdc,
+ wc->mod[chan_idx].fxs.vmwi_hvac
+ );
+ }
+ if (POLARITY_XOR(chan_idx)) {
+ wc->mod[chan_idx].fxs.idletxhookstate |= 0x4;
+ /* Do not set while currently ringing or open */
+ if (wc->mod[chan_idx].fxs.lasttxhook != 0x04 &&
+ wc->mod[chan_idx ].fxs.lasttxhook != 0x00) {
+ wc->mod[chan_idx ].fxs.lasttxhook |= 0x4;
+ wctdm_setreg(wc, chan_idx, 64, wc->mod[chan_idx].fxs.lasttxhook);
+ }
+ } else {
+ wc->mod[chan_idx].fxs.idletxhookstate &= ~0x04;
+ /* Do not set while currently ringing or open */
+ if (wc->mod[chan_idx].fxs.lasttxhook != 0x04 &&
+ wc->mod[chan_idx].fxs.lasttxhook != 0x00) {
+ wc->mod[chan_idx].fxs.lasttxhook &= ~0x04;
+ wctdm_setreg(wc, chan_idx, 64, wc->mod[chan_idx].fxs.lasttxhook);
+ }
+ }
+ return 0;
+}
+
static int wctdm_init_voicedaa(struct wctdm *wc, int card, int fast, int manual, int sane)
{
unsigned char reg16=0, reg26=0, reg30=0, reg31=0;
@@ -1799,7 +1841,6 @@ static int wctdm_init_proslic(struct wctdm *wc, int card, int fast, int manual,
return 0;
}
-
static int wctdm_ioctl(struct dahdi_chan *chan, unsigned int cmd, unsigned long data)
{
struct wctdm_stats stats;
@@ -1840,48 +1881,22 @@ static int wctdm_ioctl(struct dahdi_chan *chan, unsigned int cmd, unsigned long
wc->mod[chan->chanpos - 1].fxs.lasttxhook &= ~0x04;
wctdm_setreg(wc, chan->chanpos - 1, 64, wc->mod[chan->chanpos - 1].fxs.lasttxhook);
break;
- case DAHDI_VMWI:
+ case DAHDI_VMWI_CONFIG:
if (wc->modtype[chan->chanpos - 1] != MOD_TYPE_FXS)
return -EINVAL;
if (copy_from_user(&(wc->mod[chan->chanpos - 1].fxs.vmwisetting), (__user void *) data, sizeof(wc->mod[chan->chanpos - 1].fxs.vmwisetting)))
return -EFAULT;
-
- if (wc->mod[chan->chanpos - 1].fxs.vmwisetting.messages){
- wc->mod[chan->chanpos - 1].fxs.vmwi_lrev = (wc->mod[chan->chanpos - 1].fxs.vmwisetting.vmwi_type & DAHDI_VMWI_LREV)?1:0;
- wc->mod[chan->chanpos - 1].fxs.vmwi_hvdc = (wc->mod[chan->chanpos - 1].fxs.vmwisetting.vmwi_type & DAHDI_VMWI_HVDC)?1:0;
- wc->mod[chan->chanpos - 1].fxs.vmwi_hvac = (wc->mod[chan->chanpos - 1].fxs.vmwisetting.vmwi_type & DAHDI_VMWI_HVAC)?1:0;
- } else {
- wc->mod[chan->chanpos - 1].fxs.vmwi_lrev = 0;
- wc->mod[chan->chanpos - 1].fxs.vmwi_hvdc = 0;
- wc->mod[chan->chanpos - 1].fxs.vmwi_hvac = 0;
- }
-
- if (debug) {
- printk(KERN_DEBUG "Setting VMWI on channel %d, messages=%d, lrev=%d, hvdc=%d, hvac=%d\n",
- chan->chanpos-1,
- wc->mod[chan->chanpos - 1].fxs.vmwisetting.messages,
- wc->mod[chan->chanpos - 1].fxs.vmwi_lrev,
- wc->mod[chan->chanpos - 1].fxs.vmwi_hvdc,
- wc->mod[chan->chanpos - 1].fxs.vmwi_hvac
- );
- }
- if (POLARITY_XOR(chan->chanpos -1)) {
- wc->mod[chan->chanpos -1 ].fxs.idletxhookstate |= 0x4;
- /* Do not set while currently ringing or open */
- if (wc->mod[chan->chanpos -1 ].fxs.lasttxhook != 0x04 &&
- wc->mod[chan->chanpos -1 ].fxs.lasttxhook != 0x00) {
- wc->mod[chan->chanpos -1 ].fxs.lasttxhook |= 0x4;
- wctdm_setreg(wc, chan->chanpos - 1, 64, wc->mod[chan->chanpos - 1].fxs.lasttxhook);
- }
- } else {
- wc->mod[chan->chanpos -1 ].fxs.idletxhookstate &= ~0x04;
- /* Do not set while currently ringing or open */
- if (wc->mod[chan->chanpos -1 ].fxs.lasttxhook != 0x04 &&
- wc->mod[chan->chanpos -1 ].fxs.lasttxhook != 0x00) {
- wc->mod[chan->chanpos -1 ].fxs.lasttxhook &= ~0x04;
- wctdm_setreg(wc, chan->chanpos - 1, 64, wc->mod[chan->chanpos - 1].fxs.lasttxhook);
- }
- }
+ set_vmwi(wc, chan->chanpos - 1);
+ break;
+ case DAHDI_VMWI:
+ if (wc->modtype[chan->chanpos - 1] != MOD_TYPE_FXS)
+ return -EINVAL;
+ if (get_user(x, (__user int *) data))
+ return -EFAULT;
+ if (0 > x)
+ return -EFAULT;
+ wc->mod[chan->chanpos - 1].fxs.vmwi_active_messages = x;
+ set_vmwi(wc, chan->chanpos - 1);
break;
case WCTDM_GET_STATS:
if (wc->modtype[chan->chanpos - 1] == MOD_TYPE_FXS) {
diff --git a/drivers/dahdi/wctdm24xxp/base.c b/drivers/dahdi/wctdm24xxp/base.c
index 0f87ea7..6c7fd27 100644
--- a/drivers/dahdi/wctdm24xxp/base.c
+++ b/drivers/dahdi/wctdm24xxp/base.c
@@ -87,7 +87,7 @@ static int loopcurrent = 20;
* polarity reversal for the port,
* and the state of the line reversal MWI indicator
*/
-#define POLARITY_XOR(card) ( (reversepolarity != 0) ^ (wc->mods[(card)].fxs.reversepolarity != 0) ^ (wc->mods[(card)].fxs.linereverse_mwi != 0) )
+#define POLARITY_XOR(card) ( (reversepolarity != 0) ^ (wc->mods[(card)].fxs.reversepolarity != 0) ^ (wc->mods[(card)].fxs.vmwi_linereverse != 0) )
static int reversepolarity = 0;
static alpha indirect_regs[] =
@@ -1934,6 +1934,46 @@ static int wctdm_set_hwgain(struct wctdm *wc, int card, __s32 gain, __u32 tx)
return 0;
}
+static int set_vmwi(struct wctdm *wc, int chan_idx)
+{
+ int x;
+ /* Presently only supports line reversal MWI */
+ if (wc->mods[chan_idx].fxs.vmwi_active_messages && wc->mods[chan_idx].fxs.vmwisetting.vmwi_type & DAHDI_VMWI_LREV){
+ wc->mods[chan_idx].fxs.vmwi_linereverse = 1;
+ } else {
+ wc->mods[chan_idx].fxs.vmwi_linereverse = 0;
+ }
+ /* Set line polarity for new VMWI state */
+ if (POLARITY_XOR(chan_idx)) {
+ wc->mods[chan_idx].fxs.idletxhookstate |= 0x14;
+ /* Do not set while currently ringing or open */
+ if (wc->mods[chan_idx].fxs.lasttxhook != 0x04 &&
+ wc->mods[chan_idx].fxs.lasttxhook != 0x00) {
+ wc->mods[chan_idx].fxs.lasttxhook |= 0x14;
+ wc->sethook[chan_idx] = CMD_WR(64, wc->mods[chan_idx].fxs.lasttxhook);
+ }
+ } else {
+ wc->mods[chan_idx].fxs.idletxhookstate &= ~0x04;
+ /* Do not set while currently ringing or open */
+ if (wc->mods[chan_idx].fxs.lasttxhook != 0x04 &&
+ wc->mods[chan_idx].fxs.lasttxhook != 0x00) {
+ x = wc->mods[chan_idx].fxs.lasttxhook;
+ x &= ~0x04;
+ x |= 0x10;
+ wc->mods[chan_idx].fxs.lasttxhook = x;
+ wc->sethook[chan_idx] = CMD_WR(64, wc->mods[chan_idx].fxs.lasttxhook);
+ }
+ }
+ if (debug) {
+ printk(KERN_DEBUG "Setting VMWI on channel %d, messages=%d, lrev=%d\n",
+ chan_idx,
+ wc->mods[chan_idx].fxs.vmwi_active_messages,
+ wc->mods[chan_idx].fxs.vmwi_linereverse
+ );
+ }
+ return 0;
+}
+
static int wctdm_init_voicedaa(struct wctdm *wc, int card, int fast, int manual, int sane)
{
unsigned char reg16=0, reg26=0, reg30=0, reg31=0;
@@ -2053,7 +2093,7 @@ static int wctdm_init_proslic(struct wctdm *wc, int card, int fast, int manual,
/* Initialize VMWI settings */
memset(&(wc->mods[card].fxs.vmwisetting), 0, sizeof(wc->mods[card].fxs.vmwisetting));
- wc->mods[card].fxs.linereverse_mwi = 0;
+ wc->mods[card].fxs.vmwi_linereverse = 0;
/* By default, don't send on hook */
if (!reversepolarity != !wc->mods[card].fxs.reversepolarity) {
@@ -2444,46 +2484,22 @@ static int wctdm_ioctl(struct dahdi_chan *chan, unsigned int cmd, unsigned long
/* wctdm_setreg(wc, chan->chanpos - 1, 64, wc->mods[chan->chanpos - 1].fxs.lasttxhook); */
}
break;
- case DAHDI_VMWI:
+ case DAHDI_VMWI_CONFIG:
if (wc->modtype[chan->chanpos - 1] != MOD_TYPE_FXS)
return -EINVAL;
if (copy_from_user(&(wc->mods[chan->chanpos - 1].fxs.vmwisetting), (__user void *) data, sizeof(wc->mods[chan->chanpos - 1].fxs.vmwisetting)))
return -EFAULT;
-
- if (wc->mods[chan->chanpos - 1].fxs.vmwisetting.messages && wc->mods[chan->chanpos - 1].fxs.vmwisetting.vmwi_type & DAHDI_VMWI_LREV){
- wc->mods[chan->chanpos - 1].fxs.linereverse_mwi = 1;
- } else {
- wc->mods[chan->chanpos - 1].fxs.linereverse_mwi = 0;
- }
- /* Set line polarity for new VMWI state */
- if (POLARITY_XOR(chan->chanpos -1)) {
- wc->mods[chan->chanpos -1 ].fxs.idletxhookstate |= 0x14;
- /* Do not set while currently ringing or open */
- if (wc->mods[chan->chanpos -1 ].fxs.lasttxhook != 0x04 &&
- wc->mods[chan->chanpos -1 ].fxs.lasttxhook != 0x00) {
- wc->mods[chan->chanpos -1 ].fxs.lasttxhook |= 0x14;
- wc->sethook[chan->chanpos - 1] = CMD_WR(64, wc->mods[chan->chanpos - 1].fxs.lasttxhook);
- }
- } else {
- wc->mods[chan->chanpos -1 ].fxs.idletxhookstate &= ~0x04;
- /* Do not set while currently ringing or open */
- if (wc->mods[chan->chanpos -1 ].fxs.lasttxhook != 0x04 &&
- wc->mods[chan->chanpos -1 ].fxs.lasttxhook != 0x00) {
- x = wc->mods[chan->chanpos -1 ].fxs.lasttxhook;
- x &= ~0x04;
- x |= 0x10;
- wc->mods[chan->chanpos -1 ].fxs.lasttxhook = x;
- wc->sethook[chan->chanpos - 1] = CMD_WR(64, wc->mods[chan->chanpos - 1].fxs.lasttxhook);
- }
- }
-
- if (debug) {
- printk(KERN_DEBUG "Setting VMWI on channel %d, messages=%d, lrev=%d\n",
- chan->chanpos-1,
- wc->mods[chan->chanpos - 1].fxs.vmwisetting.messages,
- wc->mods[chan->chanpos - 1].fxs.linereverse_mwi
- );
- }
+ set_vmwi(wc, chan->chanpos - 1);
+ break;
+ case DAHDI_VMWI:
+ if (wc->modtype[chan->chanpos - 1] != MOD_TYPE_FXS)
+ return -EINVAL;
+ if (get_user(x, (__user int *) data))
+ return -EFAULT;
+ if (0 > x)
+ return -EFAULT;
+ wc->mods[chan->chanpos - 1].fxs.vmwi_active_messages = x;
+ set_vmwi(wc, chan->chanpos - 1);
break;
case WCTDM_GET_STATS:
if (wc->modtype[chan->chanpos - 1] == MOD_TYPE_FXS) {
diff --git a/drivers/dahdi/wctdm24xxp/wctdm24xxp.h b/drivers/dahdi/wctdm24xxp/wctdm24xxp.h
index 86a9f95..f8da786 100644
--- a/drivers/dahdi/wctdm24xxp/wctdm24xxp.h
+++ b/drivers/dahdi/wctdm24xxp/wctdm24xxp.h
@@ -249,7 +249,8 @@ struct wctdm {
int lasttxhook; /* Bits 0-3 are written to proslic reg 64, Bit 4 indicates if the last write is pending */
int palarms;
struct dahdi_vmwi_info vmwisetting;
- int linereverse_mwi;
+ int vmwi_active_messages;
+ int vmwi_linereverse;
int reversepolarity; /* polarity reversal */
struct calregs calregs;
} fxs;
diff --git a/include/dahdi/user.h b/include/dahdi/user.h
index 8a06f5f..c6cbed3 100644
--- a/include/dahdi/user.h
+++ b/include/dahdi/user.h
@@ -970,8 +970,7 @@ struct dahdi_hwgain {
* VMWI Specification
*/
struct dahdi_vmwi_info {
- unsigned int messages; /* Number of messages pending */
- unsigned int vmwi_type;
+ unsigned int vmwi_type;
};
#define DAHDI_VMWI_LREV (1 << 0) /* Line Reversal */
@@ -982,7 +981,8 @@ struct dahdi_vmwi_info {
* VoiceMail Waiting Indication (VMWI) -- implemented by low-level driver.
* Value: number of waiting messages (hence 0: switch messages off).
*/
-#define DAHDI_VMWI _IOWR(DAHDI_CODE, 94, struct dahdi_vmwi_info)
+#define DAHDI_VMWI _IOWR(DAHDI_CODE, 94, int)
+#define DAHDI_VMWI_CONFIG _IOW(DAHDI_CODE, 95, struct dahdi_vmwi_info)
/*
* Startup or Shutdown a span