diff options
author | Doug Bailey <dbailey@digium.com> | 2009-01-27 15:13:52 +0000 |
---|---|---|
committer | Doug Bailey <dbailey@digium.com> | 2009-01-27 15:13:52 +0000 |
commit | 22c8d7c0cf228dec7ccc38348ab8e6c77c492bc6 (patch) | |
tree | af16d0d84a80f19db1ef87a6e2a5a3ec0e124106 | |
parent | b19785437da38b006e18c54cfe03e3930f0ea19c (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.c | 95 | ||||
-rw-r--r-- | drivers/dahdi/wctdm24xxp/base.c | 92 | ||||
-rw-r--r-- | drivers/dahdi/wctdm24xxp/wctdm24xxp.h | 3 | ||||
-rw-r--r-- | include/dahdi/user.h | 6 |
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 |