staging: comedi: cb_pcidas: introduce cb_pcidas_ao_load_fifo()
authorH Hartley Sweeten <hsweeten@visionengravers.com>
Wed, 22 Oct 2014 21:36:36 +0000 (14:36 -0700)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 29 Oct 2014 08:01:19 +0000 (16:01 +0800)
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@visionengravers.com>
Reviewed-by: Ian Abbott <abbotti@mev.co.uk>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/staging/comedi/drivers/cb_pcidas.c

index e7ab6bc..a0d462f 100644 (file)
@@ -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,