From: H Hartley Sweeten Date: Mon, 14 Jul 2014 19:06:58 +0000 (-0700) Subject: staging: comedi: ni_65xx: fix ni_65xx_intr_insn_config() X-Git-Tag: v3.17-rc1~123^2~705 X-Git-Url: https://git.karo-electronics.de/?a=commitdiff_plain;h=b3e33cd3f83fcb4415a1014a1c8b11c621900ae8;p=karo-tx-linux.git staging: comedi: ni_65xx: fix ni_65xx_intr_insn_config() Refactor this function to follow the standard (*insn_config) form. Add a sanity check of the number of data parameters (insn->n). Currently the core does not check INSN_CONFIG_CHANGE_NOTIFY. Fix the writes to the rise/fall edge enable registers. The macro expects a "port" value not the port offset value. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- diff --git a/drivers/staging/comedi/drivers/ni_65xx.c b/drivers/staging/comedi/drivers/ni_65xx.c index 517dbc6f7395..742d3cdcd898 100644 --- a/drivers/staging/comedi/drivers/ni_65xx.c +++ b/drivers/staging/comedi/drivers/ni_65xx.c @@ -508,22 +508,41 @@ static int ni_65xx_intr_insn_config(struct comedi_device *dev, { struct ni_65xx_private *devpriv = dev->private; - if (insn->n < 1) - return -EINVAL; - if (data[0] != INSN_CONFIG_CHANGE_NOTIFY) - return -EINVAL; + switch (data[0]) { + case INSN_CONFIG_CHANGE_NOTIFY: + /* add instruction to check_insn_config_length() */ + if (insn->n != 3) + return -EINVAL; - writeb(data[1], devpriv->mmio + NI_65XX_RISE_EDGE_ENA_REG(0)); - writeb(data[1] >> 8, devpriv->mmio + NI_65XX_RISE_EDGE_ENA_REG(0x10)); - writeb(data[1] >> 16, devpriv->mmio + NI_65XX_RISE_EDGE_ENA_REG(0x20)); - writeb(data[1] >> 24, devpriv->mmio + NI_65XX_RISE_EDGE_ENA_REG(0x30)); + /* + * This only works for the first 4 ports (32 channels)! + */ - writeb(data[2], devpriv->mmio + NI_65XX_FALL_EDGE_ENA_REG(0)); - writeb(data[2] >> 8, devpriv->mmio + NI_65XX_FALL_EDGE_ENA_REG(0x10)); - writeb(data[2] >> 16, devpriv->mmio + NI_65XX_FALL_EDGE_ENA_REG(0x20)); - writeb(data[2] >> 24, devpriv->mmio + NI_65XX_FALL_EDGE_ENA_REG(0x30)); + /* set the channels to monitor for rising edges */ + writeb(data[1] & 0xff, + devpriv->mmio + NI_65XX_RISE_EDGE_ENA_REG(0)); + writeb((data[1] >> 8) & 0xff, + devpriv->mmio + NI_65XX_RISE_EDGE_ENA_REG(1)); + writeb((data[1] >> 16) & 0xff, + devpriv->mmio + NI_65XX_RISE_EDGE_ENA_REG(2)); + writeb((data[1] >> 24) & 0xff, + devpriv->mmio + NI_65XX_RISE_EDGE_ENA_REG(3)); + + /* set the channels to monitor for falling edges */ + writeb(data[2] & 0xff, + devpriv->mmio + NI_65XX_FALL_EDGE_ENA_REG(0)); + writeb((data[2] >> 8) & 0xff, + devpriv->mmio + NI_65XX_FALL_EDGE_ENA_REG(1)); + writeb((data[2] >> 16) & 0xff, + devpriv->mmio + NI_65XX_FALL_EDGE_ENA_REG(2)); + writeb((data[2] >> 24) & 0xff, + devpriv->mmio + NI_65XX_FALL_EDGE_ENA_REG(3)); + break; + default: + return -EINVAL; + } - return 2; + return insn->n; } /* ripped from mite.h and mite_setup2() to avoid mite dependancy */