From e9558d499b9aa340130ed6bfefa07ccc306f6d56 Mon Sep 17 00:00:00 2001 From: Shaun Ruffell Date: Wed, 9 Feb 2011 18:57:53 +0000 Subject: [PATCH] wctdm24xxp: Remove the wctdm_regs structure from the stack in wctdm_ioctl. Drops the size of the wctdm_ioctl stack from 524 to 204 bytes. Signed-off-by: Shaun Ruffell git-svn-id: http://svn.asterisk.org/svn/dahdi/linux/trunk@9748 a0bf4364-ded3-4de4-8d8a-66a801d63aff --- drivers/dahdi/wctdm24xxp/base.c | 60 ++++++++++++++++++++++++--------- 1 file changed, 44 insertions(+), 16 deletions(-) diff --git a/drivers/dahdi/wctdm24xxp/base.c b/drivers/dahdi/wctdm24xxp/base.c index cf61adf..8153a35 100644 --- a/drivers/dahdi/wctdm24xxp/base.c +++ b/drivers/dahdi/wctdm24xxp/base.c @@ -3000,11 +3000,36 @@ static void qrv_dosetup(struct dahdi_chan *chan,struct wctdm *wc) return; } +static void wctdm24xxp_get_fxs_regs(struct wctdm *wc, struct dahdi_chan *chan, + struct wctdm_regs *regs) +{ + int x; + for (x = 0; x < NUM_INDIRECT_REGS; x++) + regs->indirect[x] = wctdm_proslic_getreg_indirect(wc, + chan->chanpos - 1, x); + for (x = 0; x < NUM_REGS; x++) + regs->direct[x] = wctdm_getreg(wc, chan->chanpos - 1, x); +} + +static void wctdm24xxp_get_fxo_regs(struct wctdm *wc, struct dahdi_chan *chan, + struct wctdm_regs *regs) +{ + int x; + for (x = 0; x < NUM_FXO_REGS; x++) + regs->direct[x] = wctdm_getreg(wc, chan->chanpos - 1, x); +} + +static void wctdm24xxp_get_qrv_regs(struct wctdm *wc, struct dahdi_chan *chan, + struct wctdm_regs *regs) +{ + int x; + for (x = 0; x < 0x32; x++) + regs->direct[x] = wctdm_getreg(wc, chan->chanpos - 1, x); +} static int wctdm_ioctl(struct dahdi_chan *chan, unsigned int cmd, unsigned long data) { struct wctdm_stats stats; - struct wctdm_regs regs; struct wctdm_regop regop; struct wctdm_echo_coefs echoregs; struct dahdi_hwgain hwgain; @@ -3086,23 +3111,26 @@ static int wctdm_ioctl(struct dahdi_chan *chan, unsigned int cmd, unsigned long return -EFAULT; break; case WCTDM_GET_REGS: - if (wc->modtype[chan->chanpos - 1] == MOD_TYPE_FXS) { - for (x=0;xchanpos -1, x); - for (x=0;xchanpos - 1, x); - } else if (wc->modtype[chan->chanpos - 1] == MOD_TYPE_QRV) { - memset(®s, 0, sizeof(regs)); - for (x=0;x<0x32;x++) - regs.direct[x] = wctdm_getreg(wc, chan->chanpos - 1, x); - } else { - memset(®s, 0, sizeof(regs)); - for (x=0;xchanpos - 1, x); - } - if (copy_to_user((__user void *)data, ®s, sizeof(regs))) + { + struct wctdm_regs *regs = kzalloc(sizeof(*regs), GFP_KERNEL); + if (!regs) + return -ENOMEM; + + if (wc->modtype[chan->chanpos - 1] == MOD_TYPE_FXS) + wctdm24xxp_get_fxs_regs(wc, chan, regs); + else if (wc->modtype[chan->chanpos - 1] == MOD_TYPE_QRV) + wctdm24xxp_get_qrv_regs(wc, chan, regs); + else + wctdm24xxp_get_fxo_regs(wc, chan, regs); + + if (copy_to_user((__user void *)data, regs, sizeof(*regs))) { + kfree(regs); return -EFAULT; + } + + kfree(regs); break; + } case WCTDM_SET_REG: if (copy_from_user(®op, (__user void *) data, sizeof(regop))) return -EFAULT;