From b3559cb1aa5f863e1ce9b94b518be7ddf6680e45 Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Wed, 20 Jan 2010 13:04:46 +0000 Subject: [PATCH] Staging: comedi: pcl818: Correct AI scan counting and channel checks For AI commands, the scan counter should be updated after every scan. It was being updated after every sample except for DMA mode where it was being updated after every repeated segment of the channel list. Also AI commands with multiple channels were being terminated with an error prematurely except in DMA mode. This was because the driver was comparing channel numbers received from the hardware (combined with the sample value) with the expected channel numbers to check for a "channel dropout". This test was failing incorrectly because the driver was not keeping the current position within the (repeated segment of the) channel list up to date. Signed-off-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/pcl818.c | 31 +++++++++++++++++++++++++++---- 1 file changed, 27 insertions(+), 4 deletions(-) diff --git a/drivers/staging/comedi/drivers/pcl818.c b/drivers/staging/comedi/drivers/pcl818.c index d048101..40ac293 100644 --- a/drivers/staging/comedi/drivers/pcl818.c +++ b/drivers/staging/comedi/drivers/pcl818.c @@ -557,8 +557,14 @@ conv_finish: comedi_event(dev, s); return IRQ_HANDLED; } - if (s->async->cur_chan == 0) { + devpriv->act_chanlist_pos++; + if (devpriv->act_chanlist_pos >= devpriv->act_chanlist_len) { + devpriv->act_chanlist_pos = 0; + } + s->async->cur_chan++; + if (s->async->cur_chan >= devpriv->ai_n_chan) { /* printk("E"); */ + s->async->cur_chan = 0; devpriv->ai_act_scan--; } @@ -627,9 +633,13 @@ static irqreturn_t interrupt_pcl818_ai_mode13_dma(int irq, void *d) devpriv->act_chanlist_pos++; if (devpriv->act_chanlist_pos >= devpriv->act_chanlist_len) { - devpriv->ai_act_scan--; devpriv->act_chanlist_pos = 0; } + s->async->cur_chan++; + if (s->async->cur_chan >= devpriv->ai_n_chan) { + s->async->cur_chan = 0; + devpriv->ai_act_scan--; + } if (!devpriv->neverending_ai) if (devpriv->ai_act_scan == 0) { /* all data sampled */ @@ -717,7 +727,14 @@ static irqreturn_t interrupt_pcl818_ai_mode13_dma_rtc(int irq, void *d) comedi_buf_put(s->async, dmabuf[bufptr++] >> 4); /* get one sample */ bufptr &= (devpriv->dmasamplsize - 1); - if (s->async->cur_chan == 0) { + devpriv->act_chanlist_pos++; + if (devpriv->act_chanlist_pos >= + devpriv->act_chanlist_len) { + devpriv->act_chanlist_pos = 0; + } + s->async->cur_chan++; + if (s->async->cur_chan >= devpriv->ai_n_chan) { + s->async->cur_chan = 0; devpriv->ai_act_scan--; } @@ -796,7 +813,13 @@ static irqreturn_t interrupt_pcl818_ai_mode13_fifo(int irq, void *d) comedi_buf_put(s->async, (lo >> 4) | (inb(dev->iobase + PCL818_FI_DATAHI) << 4)); /* get one sample */ - if (s->async->cur_chan == 0) { + devpriv->act_chanlist_pos++; + if (devpriv->act_chanlist_pos >= devpriv->act_chanlist_len) { + devpriv->act_chanlist_pos = 0; + } + s->async->cur_chan++; + if (s->async->cur_chan >= devpriv->ai_n_chan) { + s->async->cur_chan = 0; devpriv->ai_act_scan--; } -- 2.7.4