[PATCH 03/18] staging: comedi: cb_pcidas: introduce cb_pcidas_ao_load_fifo()

H Hartley Sweeten hsweeten at visionengravers.com
Mon Oct 20 18:52:07 UTC 2014


Introduce a helper function to load the analog output FIFO.

This fixes a bug in cb_pcidas_ao_inttrig(). That function was writing
'num_bytes' data values to the FIFO instead of 'num_points'. This results
in twice the number of data values getting written to the FIFO.

Use comedi_buf_read_samples() read the analog output samples from the async
buffer.

Signed-off-by: H Hartley Sweeten <hsweeten at visionengravers.com>
Cc: Ian Abbott <abbotti at mev.co.uk>
Cc: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
---
 drivers/staging/comedi/drivers/cb_pcidas.c | 54 ++++++++++++------------------
 1 file changed, 22 insertions(+), 32 deletions(-)

diff --git a/drivers/staging/comedi/drivers/cb_pcidas.c b/drivers/staging/comedi/drivers/cb_pcidas.c
index e7ab6bc..a0d462f 100644
--- a/drivers/staging/comedi/drivers/cb_pcidas.c
+++ b/drivers/staging/comedi/drivers/cb_pcidas.c
@@ -1134,32 +1134,39 @@ static int cb_pcidas_cancel(struct comedi_device *dev,
 	return 0;
 }
 
+static void cb_pcidas_ao_load_fifo(struct comedi_device *dev,
+				   struct comedi_subdevice *s,
+				   unsigned int nsamples)
+{
+	struct cb_pcidas_private *devpriv = dev->private;
+	struct comedi_cmd *cmd = &s->async->cmd;
+	unsigned int nbytes;
+
+	if (cmd->stop_src == TRIG_COUNT && devpriv->ao_count < nsamples)
+		nsamples = devpriv->ao_count;
+
+	nbytes = comedi_buf_read_samples(s, devpriv->ao_buffer, nsamples);
+	nsamples = nbytes / bytes_per_sample(s);
+	if (cmd->stop_src == TRIG_COUNT)
+		devpriv->ao_count -= nsamples;
+
+	outsw(devpriv->ao_registers + DACDATA, devpriv->ao_buffer, nsamples);
+}
+
 static int cb_pcidas_ao_inttrig(struct comedi_device *dev,
 				struct comedi_subdevice *s,
 				unsigned int trig_num)
 {
 	const struct cb_pcidas_board *thisboard = dev->board_ptr;
 	struct cb_pcidas_private *devpriv = dev->private;
-	unsigned int num_bytes, num_points = thisboard->fifo_size;
 	struct comedi_async *async = s->async;
-	struct comedi_cmd *cmd = &s->async->cmd;
+	struct comedi_cmd *cmd = &async->cmd;
 	unsigned long flags;
 
 	if (trig_num != cmd->start_arg)
 		return -EINVAL;
 
-	/*  load up fifo */
-	if (cmd->stop_src == TRIG_COUNT && devpriv->ao_count < num_points)
-		num_points = devpriv->ao_count;
-
-	num_bytes = cfc_read_array_from_buffer(s, devpriv->ao_buffer,
-					       num_points * sizeof(short));
-	num_points = num_bytes / sizeof(short);
-
-	if (cmd->stop_src == TRIG_COUNT)
-		devpriv->ao_count -= num_points;
-	/*  write data to board's fifo */
-	outsw(devpriv->ao_registers + DACDATA, devpriv->ao_buffer, num_bytes);
+	cb_pcidas_ao_load_fifo(dev, s, thisboard->fifo_size);
 
 	/*  enable dac half-full and empty interrupts */
 	spin_lock_irqsave(&dev->spinlock, flags);
@@ -1275,8 +1282,6 @@ static void handle_ao_interrupt(struct comedi_device *dev, unsigned int status)
 	struct comedi_subdevice *s = dev->write_subdev;
 	struct comedi_async *async = s->async;
 	struct comedi_cmd *cmd = &async->cmd;
-	unsigned int half_fifo = thisboard->fifo_size / 2;
-	unsigned int num_points;
 	unsigned long flags;
 
 	if (status & DAEMI) {
@@ -1295,23 +1300,8 @@ static void handle_ao_interrupt(struct comedi_device *dev, unsigned int status)
 			async->events |= COMEDI_CB_EOA;
 		}
 	} else if (status & DAHFI) {
-		unsigned int num_bytes;
+		cb_pcidas_ao_load_fifo(dev, s, thisboard->fifo_size / 2);
 
-		/*  figure out how many points we are writing to fifo */
-		num_points = half_fifo;
-		if (cmd->stop_src == TRIG_COUNT &&
-		    devpriv->ao_count < num_points)
-			num_points = devpriv->ao_count;
-		num_bytes =
-		    cfc_read_array_from_buffer(s, devpriv->ao_buffer,
-					       num_points * sizeof(short));
-		num_points = num_bytes / sizeof(short);
-
-		if (cmd->stop_src == TRIG_COUNT)
-			devpriv->ao_count -= num_points;
-		/*  write data to board's fifo */
-		outsw(devpriv->ao_registers + DACDATA, devpriv->ao_buffer,
-		      num_points);
 		/*  clear half-full interrupt latch */
 		spin_lock_irqsave(&dev->spinlock, flags);
 		outw(devpriv->adc_fifo_bits | DAHFI,
-- 
2.0.3



More information about the devel mailing list