dma_start_sync(dev, 0);
}
+static unsigned int cb_pcidas64_ao_fill_buffer(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ unsigned short *dest,
+ unsigned int max_bytes)
+{
+ struct pcidas64_private *devpriv = dev->private;
+ struct comedi_cmd *cmd = &s->async->cmd;
+ unsigned int nsamples = max_bytes / bytes_per_sample(s);
+ unsigned int actual_bytes;
+
+ if (cmd->stop_src == TRIG_COUNT && devpriv->ao_count < nsamples)
+ nsamples = devpriv->ao_count;
+
+ actual_bytes = comedi_buf_read_samples(s, dest, nsamples);
+ nsamples = actual_bytes / bytes_per_sample(s);
+ if (cmd->stop_src == TRIG_COUNT)
+ devpriv->ao_count -= nsamples;
+
+ return nsamples;
+}
+
static unsigned int load_ao_dma_buffer(struct comedi_device *dev,
const struct comedi_cmd *cmd)
{
struct pcidas64_private *devpriv = dev->private;
- unsigned int num_bytes, buffer_index, prev_buffer_index;
+ struct comedi_subdevice *s = dev->write_subdev;
+ unsigned int buffer_index = devpriv->ao_dma_index;
+ unsigned int prev_buffer_index = prev_ao_dma_index(dev);
+ unsigned int nsamples;
+ unsigned int nbytes;
unsigned int next_bits;
- buffer_index = devpriv->ao_dma_index;
- prev_buffer_index = prev_ao_dma_index(dev);
-
- num_bytes = comedi_buf_read_n_available(dev->write_subdev);
- if (num_bytes > DMA_BUFFER_SIZE)
- num_bytes = DMA_BUFFER_SIZE;
- if (cmd->stop_src == TRIG_COUNT && num_bytes > devpriv->ao_count)
- num_bytes = devpriv->ao_count;
- num_bytes -= num_bytes % bytes_in_sample;
-
- if (num_bytes == 0)
+ nsamples = cb_pcidas64_ao_fill_buffer(dev, s,
+ devpriv->ao_buffer[buffer_index],
+ DMA_BUFFER_SIZE);
+ if (nsamples == 0)
return 0;
- num_bytes = cfc_read_array_from_buffer(dev->write_subdev,
- devpriv->
- ao_buffer[buffer_index],
- num_bytes);
- devpriv->ao_dma_desc[buffer_index].transfer_size =
- cpu_to_le32(num_bytes);
+ nbytes = nsamples * bytes_per_sample(s);
+ devpriv->ao_dma_desc[buffer_index].transfer_size = cpu_to_le32(nbytes);
/* set end of chain bit so we catch underruns */
next_bits = le32_to_cpu(devpriv->ao_dma_desc[buffer_index].next);
next_bits |= PLX_END_OF_CHAIN_BIT;
devpriv->ao_dma_desc[prev_buffer_index].next = cpu_to_le32(next_bits);
devpriv->ao_dma_index = (buffer_index + 1) % AO_DMA_RING_COUNT;
- devpriv->ao_count -= num_bytes;
- return num_bytes;
+ return nbytes;
}
static void load_ao_dma(struct comedi_device *dev, const struct comedi_cmd *cmd)
static int prep_ao_dma(struct comedi_device *dev, const struct comedi_cmd *cmd)
{
struct pcidas64_private *devpriv = dev->private;
- unsigned int num_bytes;
+ struct comedi_subdevice *s = dev->write_subdev;
+ unsigned int nsamples;
+ unsigned int nbytes;
int i;
/* clear queue pointer too, since external queue has
writew(0, devpriv->main_iobase + ADC_QUEUE_CLEAR_REG);
writew(0, devpriv->main_iobase + DAC_BUFFER_CLEAR_REG);
- num_bytes = (DAC_FIFO_SIZE / 2) * bytes_in_sample;
- if (cmd->stop_src == TRIG_COUNT &&
- num_bytes / bytes_in_sample > devpriv->ao_count)
- num_bytes = devpriv->ao_count * bytes_in_sample;
- num_bytes = cfc_read_array_from_buffer(dev->write_subdev,
- devpriv->ao_bounce_buffer,
- num_bytes);
- for (i = 0; i < num_bytes / bytes_in_sample; i++) {
+ nsamples = cb_pcidas64_ao_fill_buffer(dev, s,
+ devpriv->ao_bounce_buffer,
+ DAC_FIFO_SIZE);
+ if (nsamples == 0)
+ return -1;
+
+ for (i = 0; i < nsamples; i++) {
writew(devpriv->ao_bounce_buffer[i],
devpriv->main_iobase + DAC_FIFO_REG);
}
- devpriv->ao_count -= num_bytes / bytes_in_sample;
+
if (cmd->stop_src == TRIG_COUNT && devpriv->ao_count == 0)
return 0;
- num_bytes = load_ao_dma_buffer(dev, cmd);
- if (num_bytes == 0)
+
+ nbytes = load_ao_dma_buffer(dev, cmd);
+ if (nbytes == 0)
return -1;
load_ao_dma(dev, cmd);