[PATCH 20/66] staging: comedi: pcl818: factor out the common "dropout" detect code
H Hartley Sweeten
hsweeten at visionengravers.com
Fri Feb 28 23:24:09 UTC 2014
The DMA, FIFO, and EOC interrupt handlers all have common code that
checks for channel dropout when running an async command.
Factor this common code into a helper function.
Only return the sample if the channel is valid. The EOC handler was
previously returning the value then checking for channel dropout.
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/pcl818.c | 71 ++++++++++++++++++---------------
1 file changed, 38 insertions(+), 33 deletions(-)
diff --git a/drivers/staging/comedi/drivers/pcl818.c b/drivers/staging/comedi/drivers/pcl818.c
index 506a9cc..c28671f 100644
--- a/drivers/staging/comedi/drivers/pcl818.c
+++ b/drivers/staging/comedi/drivers/pcl818.c
@@ -555,6 +555,28 @@ static int pcl818_do_insn_bits(struct comedi_device *dev,
return insn->n;
}
+static bool pcl818_ai_dropout(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ unsigned int chan)
+{
+ struct pcl818_private *devpriv = dev->private;
+ unsigned int expected_chan;
+
+ expected_chan = devpriv->act_chanlist[devpriv->act_chanlist_pos];
+ if (chan != expected_chan) {
+ dev_dbg(dev->class_dev,
+ "A/D mode1/3 %s - channel dropout %d!=%d !\n",
+ (devpriv->dma) ? "DMA" :
+ (devpriv->usefifo) ? "FIFO" : "IRQ",
+ chan, expected_chan);
+ s->cancel(dev, s);
+ s->async->events |= COMEDI_CB_EOA | COMEDI_CB_ERROR;
+ comedi_event(dev, s);
+ return true;
+ }
+ return false;
+}
+
static bool pcl818_ai_next_chan(struct comedi_device *dev,
struct comedi_subdevice *s)
{
@@ -588,9 +610,9 @@ static bool pcl818_ai_next_chan(struct comedi_device *dev,
static irqreturn_t interrupt_pcl818_ai_mode13_int(int irq, void *d)
{
struct comedi_device *dev = d;
- struct pcl818_private *devpriv = dev->private;
struct comedi_subdevice *s = dev->read_subdev;
unsigned int chan;
+ unsigned int val;
if (pcl818_ai_eoc(dev, s, NULL, 0)) {
outb(0, dev->iobase + PCL818_STATUS); /* clear INT request */
@@ -601,19 +623,13 @@ static irqreturn_t interrupt_pcl818_ai_mode13_int(int irq, void *d)
return IRQ_HANDLED;
}
- comedi_buf_put(s->async, pcl818_ai_get_sample(dev, s, &chan));
+ val = pcl818_ai_get_sample(dev, s, &chan);
outb(0, dev->iobase + PCL818_CLRINT); /* clear INT request */
- if (chan != devpriv->act_chanlist[devpriv->act_chanlist_pos]) {
- dev_dbg(dev->class_dev,
- "A/D mode1/3 IRQ - channel dropout %x!=%x !\n",
- chan,
- devpriv->act_chanlist[devpriv->act_chanlist_pos]);
- s->cancel(dev, s);
- s->async->events |= COMEDI_CB_EOA | COMEDI_CB_ERROR;
- comedi_event(dev, s);
+ if (pcl818_ai_dropout(dev, s, chan))
return IRQ_HANDLED;
- }
+
+ comedi_buf_put(s->async, val);
if (!pcl818_ai_next_chan(dev, s))
return IRQ_HANDLED;
@@ -627,8 +643,10 @@ static irqreturn_t interrupt_pcl818_ai_mode13_dma(int irq, void *d)
struct comedi_device *dev = d;
struct pcl818_private *devpriv = dev->private;
struct comedi_subdevice *s = dev->read_subdev;
- int i, len, bufptr;
unsigned short *ptr;
+ unsigned int chan;
+ unsigned int val;
+ int i, len, bufptr;
pcl818_ai_setup_next_dma(dev, s);
@@ -639,19 +657,14 @@ static irqreturn_t interrupt_pcl818_ai_mode13_dma(int irq, void *d)
bufptr = 0;
for (i = 0; i < len; i++) {
- if ((ptr[bufptr] & 0xf) != devpriv->act_chanlist[devpriv->act_chanlist_pos]) { /* dropout! */
- dev_dbg(dev->class_dev,
- "A/D mode1/3 DMA - channel dropout %d(card)!=%d(chanlist) at %d !\n",
- (ptr[bufptr] & 0xf),
- devpriv->act_chanlist[devpriv->act_chanlist_pos],
- devpriv->act_chanlist_pos);
- s->cancel(dev, s);
- s->async->events |= COMEDI_CB_EOA | COMEDI_CB_ERROR;
- comedi_event(dev, s);
+ val = ptr[bufptr++];
+ chan = val & 0xf;
+ val = (val >> 4) & s->maxdata;
+
+ if (pcl818_ai_dropout(dev, s, chan))
return IRQ_HANDLED;
- }
- comedi_buf_put(s->async, ptr[bufptr++] >> 4); /* get one sample */
+ comedi_buf_put(s->async, val);
if (!pcl818_ai_next_chan(dev, s))
return IRQ_HANDLED;
@@ -665,7 +678,6 @@ static irqreturn_t interrupt_pcl818_ai_mode13_dma(int irq, void *d)
static irqreturn_t interrupt_pcl818_ai_mode13_fifo(int irq, void *d)
{
struct comedi_device *dev = d;
- struct pcl818_private *devpriv = dev->private;
struct comedi_subdevice *s = dev->read_subdev;
unsigned int status;
unsigned int chan;
@@ -699,16 +711,9 @@ static irqreturn_t interrupt_pcl818_ai_mode13_fifo(int irq, void *d)
for (i = 0; i < len; i++) {
val = pcl818_ai_get_fifo_sample(dev, s, &chan);
- if (chan != devpriv->act_chanlist[devpriv->act_chanlist_pos]) {
- dev_dbg(dev->class_dev,
- "A/D mode1/3 FIFO - channel dropout %d!=%d !\n",
- chan,
- devpriv->act_chanlist[devpriv->act_chanlist_pos]);
- s->cancel(dev, s);
- s->async->events |= COMEDI_CB_EOA | COMEDI_CB_ERROR;
- comedi_event(dev, s);
+
+ if (pcl818_ai_dropout(dev, s, chan))
return IRQ_HANDLED;
- }
comedi_buf_put(s->async, val);
--
1.8.5.2
More information about the devel
mailing list