fixed problem with spurious interrupts occuring when hardware conversions were disabled
authorFrank Mori Hess <fmhess@speakeasy.net>
Sat, 24 Mar 2001 00:07:24 +0000 (00:07 +0000)
committerFrank Mori Hess <fmhess@speakeasy.net>
Sat, 24 Mar 2001 00:07:24 +0000 (00:07 +0000)
comedi/drivers/das800.c

index 6142c845e6fac509da90a05ceac5ac9ebb1555cd..b0f5c40976c6c481d0b83e5cf11b8a245e6ed229 100644 (file)
@@ -321,16 +321,26 @@ static void das800_interrupt(int irq, void *d, struct pt_regs *regs)
        comedi_async *async = s->async;
        int status;
        unsigned long irq_flags;
+       static const int max_loops = 256;
 
        status = inb(dev->iobase + DAS800_STATUS);
        /* if interupt was not generated by board, quit */
        if(!(status & IRQ) || !(dev->attached))
                return;
+
+       // if hardware conversions are not enabled, then quit
+       comedi_spin_lock_irqsave(&devpriv->spinlock, irq_flags);
+       outb(CONTROL1, dev->iobase + DAS800_GAIN);      /* select base address + 7 to be STATUS2 register */
+       status = inb(dev->iobase + DAS800_STATUS2) & STATUS2_HCEN;
+       comedi_spin_unlock_irqrestore(&devpriv->spinlock, irq_flags);
+       if(status == 0)
+               return;
+
   /* read 16 bits from dev->iobase and dev->iobase + 1 */
        dataPoint = inb(dev->iobase + DAS800_LSB);
        dataPoint += inb(dev->iobase + DAS800_MSB) << 8;
        /* loop while card's fifo is not empty (and make sure loop terminates by limiting to 256 iterations) */
-       for(i = 0; (dataPoint & FIFO_EMPTY) == 0 && i < 256; i++)
+       for(i = 0; (dataPoint & FIFO_EMPTY) == 0 && i < max_loops; i++)
        {
                if( dataPoint & FIFO_OVF )
                {
@@ -364,6 +374,8 @@ static void das800_interrupt(int irq, void *d, struct pt_regs *regs)
                dataPoint = inb(dev->iobase + DAS800_LSB);
                dataPoint += inb(dev->iobase + DAS800_MSB) << 8;
        }
+       if(i == max_loops)
+               comedi_error(dev, "possible problem with loop in interrupt handler");
 
        /* check for overflow on last data point */
        if( dataPoint & FIFO_OVF )
@@ -377,7 +389,7 @@ static void das800_interrupt(int irq, void *d, struct pt_regs *regs)
        if(devpriv->count > 0 || devpriv->forever == 1)
        {
                /* Re-enable card's interrupt */
-               comedi_spin_lock_irqsave(&devpriv->spinlock, irq_flags);  // spin lock makes indirect addressing SMP safe
+               comedi_spin_lock_irqsave(&devpriv->spinlock, irq_flags);
                outb(CONTROL1, dev->iobase + DAS800_GAIN);      /* select dev->iobase + 2 to be control register 1 */
                outb(CONTROL1_INTE | devpriv->do_bits, dev->iobase + DAS800_CONTROL1);
                comedi_spin_unlock_irqrestore(&devpriv->spinlock, irq_flags);