summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorH Hartley Sweeten <hsweeten@visionengravers.com>2015-01-14 17:05:11 (GMT)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2015-01-17 22:32:55 (GMT)
commit296e3f1816dbdb5f1c3213386756e362263b17b5 (patch)
tree3b89bbd562e90338bfbb00535f4d6f69b810abed
parentcf0438c9c3da2f243961561d1e3742519b2eeb3d (diff)
downloadlinux-296e3f1816dbdb5f1c3213386756e362263b17b5.tar.xz
staging: comedi: pcl818: simplify the dma->size calculations
Currently this driver determines the number of DMA "runs" needed and the size of the "last" DMA transfer in order to perform a command. As long as there are more "runs" required, the dma->size is set to the buffer maxsize. On the last "run" the buffer is set to the "last" size. Refactor the driver to use the comedi core helpers to determine the DMA size based on the buffer maxsize and the number of samples remaining in the command. This allows removing the 'dma_runs_to_end' and 'last_dma_run' mamebers from the private data. Also remove the 'ai_data_len' member which is set but never used. 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>
-rw-r--r--drivers/staging/comedi/drivers/pcl818.c58
1 files changed, 27 insertions, 31 deletions
diff --git a/drivers/staging/comedi/drivers/pcl818.c b/drivers/staging/comedi/drivers/pcl818.c
index 1c95819..fa7b4e2 100644
--- a/drivers/staging/comedi/drivers/pcl818.c
+++ b/drivers/staging/comedi/drivers/pcl818.c
@@ -304,14 +304,11 @@ static const struct pcl818_board boardtypes[] = {
struct pcl818_private {
struct comedi_isadma *dma;
- long dma_runs_to_end; /* how many we must permorm DMA transfer to end of record */
- unsigned long last_dma_run; /* how many bytes we must transfer on last DMA page */
unsigned int ns_min; /* manimal allowed delay between samples (in us) for actual card */
int i8253_osc_base; /* 1/frequency of on board oscilator in ns */
unsigned int act_chanlist[16]; /* MUX setting for actual AI operations */
unsigned int act_chanlist_len; /* how long is actual MUX list */
unsigned int act_chanlist_pos; /* actual position in MUX list */
- unsigned int ai_data_len; /* len of data buffer */
unsigned int divisor1;
unsigned int divisor2;
unsigned int usefifo:1;
@@ -340,48 +337,49 @@ static void pcl818_ai_setup_dma(struct comedi_device *dev,
struct pcl818_private *devpriv = dev->private;
struct comedi_isadma *dma = devpriv->dma;
struct comedi_isadma_desc *desc = &dma->desc[0];
- struct comedi_cmd *cmd = &s->async->cmd;
+ unsigned int nsamples;
comedi_isadma_disable(dma->chan);
- if (cmd->stop_src == TRIG_COUNT) {
- desc->size = cmd->stop_arg * comedi_bytes_per_scan(s);
- devpriv->dma_runs_to_end = desc->size / desc->maxsize;
- devpriv->last_dma_run = desc->size % desc->maxsize;
- devpriv->dma_runs_to_end--;
- if (devpriv->dma_runs_to_end >= 0)
- desc->size = desc->maxsize;
- } else {
- desc->size = desc->maxsize;
- }
dma->cur_dma = 0;
+ /*
+ * Determine dma size based on the buffer maxsize and the number of
+ * samples remaining in the command.
+ */
+ nsamples = comedi_bytes_to_samples(s, desc->maxsize);
+ nsamples = comedi_nsamples_left(s, nsamples);
+ desc->size = comedi_samples_to_bytes(s, nsamples);
comedi_isadma_program(desc);
}
static void pcl818_ai_setup_next_dma(struct comedi_device *dev,
- struct comedi_subdevice *s)
+ struct comedi_subdevice *s,
+ unsigned int unread_samples)
{
struct pcl818_private *devpriv = dev->private;
- struct comedi_cmd *cmd = &s->async->cmd;
struct comedi_isadma *dma = devpriv->dma;
+ struct comedi_isadma_desc *desc;
+ unsigned int max_samples;
+ unsigned int nsamples;
comedi_isadma_disable(dma->chan);
- dma->cur_dma = 1 - dma->cur_dma;
-
- /* switch dma bufs if still running */
- if (devpriv->dma_runs_to_end > -1 || cmd->stop_src == TRIG_NONE) {
- struct comedi_isadma_desc *desc = &dma->desc[dma->cur_dma];
-
- if (devpriv->dma_runs_to_end || cmd->stop_src == TRIG_NONE)
- desc->size = desc->maxsize;
- else
- desc->size = devpriv->last_dma_run;
+ dma->cur_dma = 1 - dma->cur_dma;
+ desc = &dma->desc[dma->cur_dma];
+
+ /*
+ * Determine dma size based on the buffer maxsize plus the number of
+ * unread samples and the number of samples remaining in the command.
+ */
+ max_samples = comedi_bytes_to_samples(s, desc->maxsize);
+ nsamples = max_samples + unread_samples;
+ nsamples = comedi_nsamples_left(s, nsamples);
+ if (nsamples > unread_samples) {
+ nsamples -= unread_samples;
+ desc->size = comedi_samples_to_bytes(s, nsamples);
comedi_isadma_program(desc);
}
-
- devpriv->dma_runs_to_end--;
}
static void pcl818_ai_set_chan_range(struct comedi_device *dev,
@@ -556,7 +554,7 @@ static void pcl818_handle_dma(struct comedi_device *dev,
unsigned int val;
int i;
- pcl818_ai_setup_next_dma(dev, s);
+ pcl818_ai_setup_next_dma(dev, s, nsamples);
for (i = 0; i < nsamples; i++) {
val = ptr[i];
@@ -806,11 +804,9 @@ static int pcl818_ai_cmd(struct comedi_device *dev,
return -EINVAL;
pcl818_ai_setup_chanlist(dev, cmd->chanlist, seglen);
- devpriv->ai_data_len = s->async->prealloc_bufsz;
devpriv->ai_cmd_running = 1;
devpriv->ai_cmd_canceled = 0;
devpriv->act_chanlist_pos = 0;
- devpriv->dma_runs_to_end = 0;
if (cmd->convert_src == TRIG_TIMER)
ctrl |= PCL818_CTRL_PACER_TRIG;