[PATCH 1/3] staging: comedi: cb_pcidas64: Use insn->n in AO insn_write handler

Ian Abbott abbotti at mev.co.uk
Tue Oct 30 14:17:11 UTC 2018


The `insn_write` handler for the AO subdevice (`ao_winsn()` currently
ignores `insn->n` (the number of samples to write) and assumes a single
sample is to be written.  But `insn->n` could be 0, meaning no samples
should be written, in which case `data[0]` is invalid.

Follow the usual Comedi guidelines and change `ao_winsn()` to write the
specified number of samples.  This fixes the assumption that `data[0]`
is valid.

Signed-off-by: Ian Abbott <abbotti at mev.co.uk>
---
 drivers/staging/comedi/drivers/cb_pcidas64.c | 32 ++++++++++++--------
 1 file changed, 19 insertions(+), 13 deletions(-)

diff --git a/drivers/staging/comedi/drivers/cb_pcidas64.c b/drivers/staging/comedi/drivers/cb_pcidas64.c
index 631a703b345d..44e5aaf8bae5 100644
--- a/drivers/staging/comedi/drivers/cb_pcidas64.c
+++ b/drivers/staging/comedi/drivers/cb_pcidas64.c
@@ -3097,8 +3097,10 @@ static int ao_winsn(struct comedi_device *dev, struct comedi_subdevice *s,
 {
 	const struct pcidas64_board *board = dev->board_ptr;
 	struct pcidas64_private *devpriv = dev->private;
-	int chan = CR_CHAN(insn->chanspec);
-	int range = CR_RANGE(insn->chanspec);
+	unsigned int chan = CR_CHAN(insn->chanspec);
+	unsigned int range = CR_RANGE(insn->chanspec);
+	unsigned int val = s->readback[chan];
+	unsigned int i;
 
 	/* do some initializing */
 	writew(0, devpriv->main_iobase + DAC_CONTROL0_REG);
@@ -3108,20 +3110,24 @@ static int ao_winsn(struct comedi_device *dev, struct comedi_subdevice *s,
 	writew(devpriv->dac_control1_bits,
 	       devpriv->main_iobase + DAC_CONTROL1_REG);
 
-	/* write to channel */
-	if (board->layout == LAYOUT_4020) {
-		writew(data[0] & 0xff,
-		       devpriv->main_iobase + dac_lsb_4020_reg(chan));
-		writew((data[0] >> 8) & 0xf,
-		       devpriv->main_iobase + dac_msb_4020_reg(chan));
-	} else {
-		writew(data[0], devpriv->main_iobase + dac_convert_reg(chan));
+	for (i = 0; i < insn->n; i++) {
+		/* write to channel */
+		val = data[i];
+		if (board->layout == LAYOUT_4020) {
+			writew(val & 0xff,
+			       devpriv->main_iobase + dac_lsb_4020_reg(chan));
+			writew((val >> 8) & 0xf,
+			       devpriv->main_iobase + dac_msb_4020_reg(chan));
+		} else {
+			writew(val,
+			       devpriv->main_iobase + dac_convert_reg(chan));
+		}
 	}
 
-	/* remember output value */
-	s->readback[chan] = data[0];
+	/* remember last output value */
+	s->readback[chan] = val;
 
-	return 1;
+	return insn->n;
 }
 
 static void set_dac_control0_reg(struct comedi_device *dev,
-- 
2.19.1



More information about the devel mailing list