Some changes to deal with interrupts before device fully attached.
authorIan Abbott <abbotti@mev.co.uk>
Thu, 18 Oct 2007 18:01:45 +0000 (18:01 +0000)
committerIan Abbott <abbotti@mev.co.uk>
Thu, 18 Oct 2007 18:01:45 +0000 (18:01 +0000)
21 files changed:
comedi/drivers/adl_pci9111.c
comedi/drivers/adl_pci9118.c
comedi/drivers/adv_pci1710.c
comedi/drivers/amplc_dio200.c
comedi/drivers/amplc_pc236.c
comedi/drivers/cb_pcidas.c
comedi/drivers/cb_pcidas64.c
comedi/drivers/das6402.c
comedi/drivers/dmm32at.c
comedi/drivers/dt2811.c
comedi/drivers/dt2814.c
comedi/drivers/dt282x.c
comedi/drivers/dt3000.c
comedi/drivers/gsc_hpdi.c
comedi/drivers/icp_multi.c
comedi/drivers/me4000.c
comedi/drivers/ni_pcidio.c
comedi/drivers/pcl711.c
comedi/drivers/pcl812.c
comedi/drivers/quatech_daqp_cs.c
comedi/drivers/rtd520.c

index 4bfbcb82e2a03ac787470fef1d94b2fdc45ea8ed..575b92075c8ee70714d64cb404863ecdd054a3c6 100644 (file)
@@ -950,13 +950,39 @@ pci9111_interrupt (int irq, void *p_device PT_REGS_ARG)
        comedi_subdevice *subdevice = dev->read_subdev;
        comedi_async *async;
        unsigned long irq_flags;
+       unsigned char intcsr;
+
+       if (!dev->attached)
+       {
+               // Ignore interrupt before device fully attached.
+               // Might not even have allocated subdevices yet!
+               return IRQ_NONE;
+       }
 
        async = subdevice->async;
 
        comedi_spin_lock_irqsave (&dev->spinlock, irq_flags);
 
-       if ((inb (dev_private->lcr_io_base + PLX9050_REGISTER_INTERRUPT_CONTROL) &
-            PLX9050_LINTI1_STATUS) != 0)
+       // Check if we are source of interrupt
+       intcsr = inb (dev_private->lcr_io_base + PLX9050_REGISTER_INTERRUPT_CONTROL);
+       if (!(((intcsr & PLX9050_PCI_INTERRUPT_ENABLE) != 0) &&
+                               (((intcsr & (PLX9050_LINTI1_ENABLE |
+                                            PLX9050_LINTI1_STATUS)) ==
+                                 (PLX9050_LINTI1_ENABLE |
+                                  PLX9050_LINTI1_STATUS)) ||
+                                ((intcsr & (PLX9050_LINTI2_ENABLE |
+                                            PLX9050_LINTI2_STATUS)) ==
+                                 (PLX9050_LINTI2_ENABLE |
+                                  PLX9050_LINTI2_STATUS)))))
+       {
+               // Not the source of the interrupt.
+               // (N.B. not using PLX9050_SOFTWARE_INTERRUPT)
+               comedi_spin_unlock_irqrestore (&dev->spinlock, irq_flags);
+               return IRQ_NONE;
+       }
+
+       if ((intcsr & (PLX9050_LINTI1_ENABLE | PLX9050_LINTI1_STATUS)) ==
+                       (PLX9050_LINTI1_ENABLE | PLX9050_LINTI1_STATUS))
        {
                // Interrupt comes from fifo_half-full signal
 
index fe081c1827fc58f0fb78d823a39891ae5ec95365..f2b56880ad9ac05147c760057903e9cbb0a92803 100644 (file)
@@ -645,6 +645,9 @@ static irqreturn_t interrupt_pci9118(int irq, void *d PT_REGS_ARG)
        comedi_device *dev = d;
        unsigned int    int_daq=0,int_amcc,int_adstat;
 
+       if (!dev->attached)
+               return IRQ_NONE;        // not fully initialized
+
        int_daq=inl(dev->iobase+PCI9118_INTSRC) & 0xf;          // get IRQ reasons from card
        int_amcc=inl(devpriv->iobase_a+AMCC_OP_REG_INTCSR);     // get INT register from AMCC chip
 
@@ -1749,6 +1752,8 @@ static int pci9118_attach(comedi_device *dev,comedi_devconfig *it)
        devpriv->pcidev=pcidev;
        devpriv->iobase_a=iobase_a;
 
+       pci9118_reset(dev);
+
        if (it->options[3]&2) irq=0; // user don't want use IRQ
        if (irq>0)  {
                if (comedi_request_irq(irq, interrupt_pci9118, IRQF_SHARED, "ADLink PCI-9118", dev)) {
@@ -1869,8 +1874,6 @@ static int pci9118_attach(comedi_device *dev,comedi_devconfig *it)
        s->io_bits=0xf;         /* all bits output */
        s->insn_bits=pci9118_insn_bits_do;
 
-       pci9118_reset(dev);
-
        devpriv->valid=1;
        devpriv->i8254_osc_base=250;    // 250ns=4MHz
        devpriv->ai_maskharderr=0x10a;  // default measure crash condition
index d2ca49afd412d2207213283635ca39f144aef9d2..5e7e1c13669c120e7682798fe06eb4aca4882d1a 100644 (file)
@@ -720,6 +720,9 @@ static irqreturn_t interrupt_service_pci1710(int irq, void *d PT_REGS_ARG)
        comedi_device *dev = d;
 
        DPRINTK("adv_pci1710 EDBG: BGN: interrupt_service_pci1710(%d,...)\n",irq);
+       if (!dev->attached)     // is device attached?
+               return IRQ_NONE; // no, exit
+
        if (!(inw(dev->iobase + PCI171x_STATUS) & Status_IRQ))  // is this interrupt from our board?
                return IRQ_NONE; // no, exit
 
@@ -1299,6 +1302,8 @@ static int pci1710_attach(comedi_device *dev,comedi_devconfig *it)
                return ret;
        }
 
+       pci1710_reset(dev);
+
        if (this_board->have_irq) {
                if (irq)  {
                        if (comedi_request_irq(irq, interrupt_service_pci1710, IRQF_SHARED, "Advantech PCI-1710", dev)) {
@@ -1404,8 +1409,6 @@ static int pci1710_attach(comedi_device *dev,comedi_devconfig *it)
 
        devpriv->valid=1;
 
-       pci1710_reset(dev);
-
        return 0;
 }
 
index 137347f7b6a947bc297e9ad854ff7db27542510e..a443950c8d7c4b5ecbf1070a9c74b24d4b58d969 100644 (file)
@@ -654,7 +654,7 @@ dio200_handle_read_intr(comedi_device *dev, comedi_subdevice *s)
        triggered = 0;
 
        comedi_spin_lock_irqsave(&subpriv->spinlock, flags);
-       oldevents = s->async->events;
+       oldevents = s->async ? s->async->events : 0;
        if (subpriv->has_int_sce) {
                /*
                 * Collect interrupt sources that have triggered and disable
@@ -693,7 +693,7 @@ dio200_handle_read_intr(comedi_device *dev, comedi_subdevice *s)
                        outb(cur_enabled, subpriv->iobase);
                }
 
-               if (subpriv->active) {
+               if (s->async && subpriv->active) {
                        /*
                         * The command is still active.
                         *
@@ -740,7 +740,7 @@ dio200_handle_read_intr(comedi_device *dev, comedi_subdevice *s)
        }
        comedi_spin_unlock_irqrestore(&subpriv->spinlock, flags);
 
-       if (oldevents != s->async->events) {
+       if (s->async && (oldevents != s->async->events)) {
                comedi_event(dev, s);
        }
 
index 65701e398b2e54734f06f458caa4b3b40a5d93a2..0814cc431351148bce0db7ea1f74c4486ca6e7a1 100644 (file)
@@ -558,7 +558,7 @@ static irqreturn_t pc236_interrupt(int irq,void *d PT_REGS_ARG)
        int handled;
 
        handled = pc236_intr_check(dev);
-       if (handled) {
+       if (dev->attached && handled) {
                comedi_buf_put(s->async,0);
                s->async->events |= COMEDI_CB_BLOCK | COMEDI_CB_EOS;
                comedi_event(dev, s);
index 28f155be21d04739ad2b0fe1b4b975106714d507..9f9e83e9e4ca3a8d773f60fec6dd78827a76423e 100644 (file)
@@ -584,6 +584,9 @@ found:
                devpriv->ao_registers = pci_resource_start(devpriv->pci_dev, AO_BADRINDEX);
        }
 
+       // disable and clear interrupts on amcc s5933
+       outl(INTCSR_INBOX_INTR_STATUS, devpriv->s5933_config + AMCC_OP_REG_INTCSR);
+
        // get irq
        if(comedi_request_irq(devpriv->pci_dev->irq, cb_pcidas_interrupt, IRQF_SHARED, "cb_pcidas", dev ))
        {
@@ -1505,7 +1508,7 @@ static irqreturn_t cb_pcidas_interrupt(int irq, void *d PT_REGS_ARG)
 
        if(dev->attached == 0)
        {
-               comedi_error(dev, "premature interrupt");
+               return IRQ_NONE;
        }
 
        async = s->async;
index 42b38d37ab52125d36488c4c612407c66049999c..1271614cc8b49f6b9663b99d210f2dd37a32dc54 100644 (file)
@@ -1749,6 +1749,8 @@ static int attach(comedi_device *dev, comedi_devconfig *it)
 
        priv(dev)->hw_revision = hw_revision( dev, readw(priv(dev)->main_iobase + HW_STATUS_REG ) );
        printk(" stc hardware revision %i\n", priv(dev)->hw_revision);
+       init_plx9080(dev);
+       init_stc_registers( dev );
        // get irq
        if(comedi_request_irq(pcidev->irq, handle_interrupt, IRQF_SHARED, "cb_pcidas64", dev ))
        {
@@ -1758,8 +1760,6 @@ static int attach(comedi_device *dev, comedi_devconfig *it)
        dev->irq = pcidev->irq;
        printk(" irq %u\n", dev->irq);
 
-       init_plx9080(dev);
-       init_stc_registers( dev );
        retval = setup_subdevices(dev);
        if(retval < 0)
        {
index 879a364e58da1a1885800e3ce2d117fac6a43651..c9ffb5cd2231c9d5c6d3432f98847d49fc2d1a5c 100644 (file)
@@ -158,7 +158,7 @@ static irqreturn_t intr_handler(int irq,void *d PT_REGS_ARG)
        comedi_device *dev=d;
        comedi_subdevice *s=dev->subdevices;
 
-       if (devpriv->das6402_ignoreirq){
+       if (!dev->attached || devpriv->das6402_ignoreirq){
                printk("das6402: BUG: spurious interrupt\n");
                return IRQ_HANDLED;
        }
index 58af13ce6d3ca16e451233b61400b1d79fec58e6..730bdb554249f35bf318491004ead93b99d47049 100644 (file)
@@ -843,12 +843,19 @@ static irqreturn_t dmm32at_isr(int irq,void *d PT_REGS_ARG){
        unsigned short msb, lsb;
        int i;
        comedi_device *dev=d;
-        comedi_subdevice *s=dev->read_subdev;
-       comedi_cmd *cmd = &s->async->cmd;
+
+       if (!dev->attached)
+       {
+               comedi_error(dev, "spurious interrupt");
+               return IRQ_HANDLED;
+       }
 
        intstat = dmm_inb(dev,DMM32AT_INTCLOCK);
 
        if(intstat & DMM32AT_ADINT){
+               comedi_subdevice *s=dev->read_subdev;
+               comedi_cmd *cmd = &s->async->cmd;
+
                for(i=0;i<cmd->chanlist_len;i++){
                        /* read data */
                        lsb = dmm_inb(dev,DMM32AT_AILSB);
index df464ea7a994c124cb84ba481e1fa07688b575c0..90510350b179492e4bbb649d8f3b74ae02ab53cf 100644 (file)
@@ -255,12 +255,18 @@ static const comedi_lrange *dac_range_types[] =
 #define DT2811_TIMEOUT 5
 
 #if 0
-static void dt2811_interrupt(int irq, void *d PT_REGS_ARG)
+static irqreturn_t dt2811_interrupt(int irq, void *d PT_REGS_ARG)
 {
        int lo, hi;
        int data;
        comedi_device *dev = d;
 
+       if (!dev->attached)
+       {
+               comedi_error(dev, "spurious interrupt");
+               return IRQ_HANDLED;
+       }
+
        lo = inb(dev->iobase + DT2811_ADDATLO);
        hi = inb(dev->iobase + DT2811_ADDATHI);
 
@@ -271,6 +277,7 @@ static void dt2811_interrupt(int irq, void *d PT_REGS_ARG)
                s->async->events |= COMEDI_SB_EOA;
        }
        comedi_event(dev, s);
+       return IRQ_HANDLED;
 }
 #endif
 
index 88b5c54e078d3ae3914e1c1505a86c6495c1ef93..d41f157ca37b5d3096ce49a858d63969b4480783 100644 (file)
@@ -336,9 +336,17 @@ static irqreturn_t dt2814_interrupt(int irq,void *d PT_REGS_ARG)
 {
        int lo,hi;
        comedi_device *dev=d;
-       comedi_subdevice *s = dev->subdevices + 0;
+       comedi_subdevice *s;
        int data;
 
+       if (!dev->attached)
+       {
+               comedi_error(dev, "spurious interrupt");
+               return IRQ_HANDLED;
+       }
+
+       s = dev->subdevices + 0;
+
        hi=inb(dev->iobase+DT2814_DATA);
        lo=inb(dev->iobase+DT2814_DATA);
 
index c04737f72b64d632da26b31e3a332ea3aa31b28c..42454ec5f930ee09544ea3bb593085fb6cba1484 100644 (file)
@@ -578,11 +578,19 @@ static int prep_ao_dma(comedi_device * dev,int dma_index,int n)
 static irqreturn_t dt282x_interrupt(int irq, void *d PT_REGS_ARG)
 {
        comedi_device *dev = d;
-       comedi_subdevice *s = dev->subdevices+0;
-       comedi_subdevice *s_ao = dev->subdevices+1;
+       comedi_subdevice *s;
+       comedi_subdevice *s_ao;
        unsigned int supcsr, adcsr, dacsr;
        int handled = 0;
 
+       if (!dev->attached)
+       {
+               comedi_error(dev, "spurious interrupt");
+               return IRQ_HANDLED;
+       }
+
+       s = dev->subdevices+0;
+       s_ao = dev->subdevices+1;
        adcsr = inw(dev->iobase + DT2821_ADCSR);
        dacsr = inw(dev->iobase + DT2821_DACSR);
        supcsr = inw(dev->iobase + DT2821_SUPCSR);
index 7ca33c1eada8cdc0e45ab33ace994e2d0f635910..aab9e58e7393b28452a3edeb4a865a5e95fdd261 100644 (file)
@@ -333,14 +333,24 @@ static void dt3k_writesingle(comedi_device *dev,unsigned int subsys,
 
 static int debug_n_ints = 0;
 
+// FIXME! Assumes shared interrupt is for this card.
+// What's this debug_n_ints stuff? Obviously needs some work...
 static irqreturn_t dt3k_interrupt(int irq, void *d PT_REGS_ARG)
 {
        comedi_device *dev = d;
-       comedi_subdevice *s = dev->subdevices + 0;
+       comedi_subdevice *s;
        unsigned int status;
 
+       if (!dev->attached)
+       {
+               return IRQ_NONE;
+       }
+
+       s = dev->subdevices + 0;
        status = readw(devpriv->io_addr+DPR_Intr_Flag);
+#ifdef DEBUG
        debug_intr_flags(status);
+#endif
 
        if(status & DT3000_ADFULL){
                dt3k_ai_empty_fifo(dev,s);
index 2f0ed26c7e6f490378bd56809f8c2e72d2ece59a..d26a8339b7024b6b26bfeb9a264772f5513fe216 100644 (file)
@@ -470,10 +470,11 @@ static int init_hpdi( comedi_device *dev )
        priv(dev)->rx_fifo_size = fifo_size( readl( priv(dev)->hpdi_iobase +
                RX_FIFO_SIZE_REG ) );
 
+       writel( 0, priv(dev)->hpdi_iobase + INTERRUPT_CONTROL_REG );
+
        // enable interrupts
        plx_intcsr_bits = ICS_AERR | ICS_PERR | ICS_PIE | ICS_PLIE | ICS_PAIE | ICS_LIE | ICS_DMA0_E;
        writel( plx_intcsr_bits, priv(dev)->plx9080_iobase + PLX_INTRCS_REG );
-       writel( 0, priv(dev)->hpdi_iobase + INTERRUPT_CONTROL_REG );
 
        return 0;
 }
@@ -609,6 +610,8 @@ static int hpdi_attach(comedi_device *dev, comedi_devconfig *it)
        DEBUG_PRINT(" plx9080 remapped to 0x%p\n", priv(dev)->plx9080_iobase);
        DEBUG_PRINT(" hpdi remapped to 0x%p\n", priv(dev)->hpdi_iobase);
 
+       init_plx9080(dev);
+
        // get irq
        if( comedi_request_irq( pcidev->irq, handle_interrupt, IRQF_SHARED, driver_hpdi.driver_name,
                 dev ) )
@@ -620,8 +623,6 @@ static int hpdi_attach(comedi_device *dev, comedi_devconfig *it)
 
        printk(" irq %u\n", dev->irq);
 
-       init_plx9080(dev);
-
        // alocate pci dma buffers
        for( i = 0; i < NUM_DMA_BUFFERS; i++ )
        {
@@ -928,7 +929,17 @@ static irqreturn_t handle_interrupt(int irq, void *d PT_REGS_ARG)
        uint8_t dma0_status, dma1_status;
        unsigned long flags;
 
+       if (!dev->attached)
+       {
+               return IRQ_NONE;
+       }
+
        plx_status = readl( priv(dev)->plx9080_iobase + PLX_INTRCS_REG );
+       if( ( plx_status & ( ICS_DMA0_A | ICS_DMA1_A | ICS_LIA ) ) == 0 )
+       {
+               return IRQ_NONE;
+       }
+
        hpdi_intr_status = readl( priv(dev)->hpdi_iobase + INTERRUPT_STATUS_REG );
        hpdi_board_status = readl( priv(dev)->hpdi_iobase + BOARD_STATUS_REG );
 
@@ -938,9 +949,6 @@ static irqreturn_t handle_interrupt(int irq, void *d PT_REGS_ARG)
        {
                DEBUG_PRINT("hpdi: intr status 0x%x, ", hpdi_intr_status);
                writel( hpdi_intr_status, priv(dev)->hpdi_iobase + INTERRUPT_STATUS_REG );
-       }else if( ( plx_status & ( ICS_DMA0_A | ICS_DMA1_A | ICS_LIA ) ) == 0 )
-       {
-               return IRQ_NONE;
        }
 
        // spin lock makes sure noone else changes plx dma control reg
index a8a140fb671755457a784c87d2d27ef6c493e59f..ae27abbe3301c7f4c0455e0178138741c1d3b9f8 100644 (file)
@@ -926,6 +926,8 @@ static int icp_multi_attach(comedi_device *dev,comedi_devconfig *it)
                return ret;
        }
 
+       icp_multi_reset(dev);
+
        if (this_board->have_irq) {
                if (irq)  {
                        if (comedi_request_irq(irq, interrupt_service_icp_multi, IRQF_SHARED, "Inova Icp Multi", dev)) {
@@ -1017,8 +1019,6 @@ static int icp_multi_attach(comedi_device *dev,comedi_devconfig *it)
 
        devpriv->valid = 1;
 
-       icp_multi_reset(dev);
-
 #ifdef ICP_MULTI_EXTDEBUG
        printk("icp multi EDBG: END: icp_multi_attach(...)\n");
 #endif
index d54653dcb9f5befc8472a37a5d3b704f7ef2884e..aa586436b8d3c820597ff44ef44a446d8cc10b9a 100644 (file)
@@ -1685,6 +1685,11 @@ static irqreturn_t me4000_ai_isr(int irq, void *dev_id PT_REGS_ARG){
 
     ISR_PDEBUG("me4000_ai_isr() is executed\n");
 
+    if(!dev->attached){
+           ISR_PDEBUG("me4000_ai_isr() premature interrupt\n");
+           return IRQ_NONE;
+    }
+
     /* Reset all events */
     s->async->events = 0;
 
index ab57a78283b66b5cc134dab9bd78eecb34106943..a95abef8f6de3c86ca0eee996b19adccc7adfe12 100644 (file)
@@ -494,15 +494,15 @@ static irqreturn_t nidio_interrupt(int irq, void *d PT_REGS_ARG)
        unsigned int m_status = 0;
        unsigned long irq_flags;
 
-       status = readb(devpriv->mite->daq_io_addr+Interrupt_And_Window_Status);
-       flags = readb(devpriv->mite->daq_io_addr+Group_1_Flags);
-
        //interrupcions parasites
        if(dev->attached == 0){
-               comedi_error(dev,"premature interrupt");
-               async->events |= COMEDI_CB_ERROR|COMEDI_CB_EOA;
+               // assume it's from another card
+               return IRQ_NONE;
        }
 
+       status = readb(devpriv->mite->daq_io_addr+Interrupt_And_Window_Status);
+       flags = readb(devpriv->mite->daq_io_addr+Group_1_Flags);
+
        DPRINTK("ni_pcidio_interrupt: status=0x%02x,flags=0x%02x\n",
                status,flags);
        ni_pcidio_print_flags(flags);
index e461c030cb481806b4ae81d97dce6e3d10ed3362..54f961e8a80d44713c5fed50cd2d21b24c28de1e 100644 (file)
@@ -186,12 +186,18 @@ static irqreturn_t pcl711_interrupt(int irq, void *d PT_REGS_ARG)
        comedi_device *dev = d;
        comedi_subdevice *s = dev->subdevices + 0;
 
+       if (!dev->attached) {
+               comedi_error(dev, "spurious interrupt");
+               return IRQ_HANDLED;
+       }
+
        hi = inb(dev->iobase + PCL711_AD_HI);
        lo = inb(dev->iobase + PCL711_AD_LO);
        outb(0, dev->iobase + PCL711_CLRINTR);
 
        data = (hi << 8) | lo;
 
+       /* FIXME! Nothing else sets ntrig! */
        if (!(--devpriv->ntrig)) {
                if (this_board->is_8112) {
                        outb(1, dev->iobase + PCL711_MODE);
index 190995942ed8addd1f6942c28d0b6a59d71c8b42..d23930dc7470b4d536f87b2188680d48e5991464 100644 (file)
@@ -977,6 +977,10 @@ static irqreturn_t interrupt_pcl812(int irq, void *d PT_REGS_ARG)
 {
        comedi_device *dev = d;
 
+       if (!dev->attached) {
+               comedi_error(dev, "spurious interrupt");
+               return IRQ_HANDLED;
+       }
        if (devpriv->ai_dma) { return interrupt_pcl812_ai_dma(irq, d); }
                        else { return interrupt_pcl812_ai_int(irq, d); };
 }
index 4e9cc6594ac6cc9358b09afc3f85a0af87d0f5f8..0b5db681cca30e93e19b6c3491a23e2c0f4f5f1a 100644 (file)
@@ -269,8 +269,8 @@ static int daqp_ai_cancel(comedi_device *dev, comedi_subdevice *s)
 static void daqp_interrupt(int irq, void * dev_id PT_REGS_ARG)
 {
        local_info_t *local = (local_info_t *)dev_id;
-       comedi_device *dev = local->dev;
-       comedi_subdevice *s = local->s;
+       comedi_device *dev;
+       comedi_subdevice *s;
        int loop_limit = 10000;
        int status;
 
@@ -280,12 +280,20 @@ static void daqp_interrupt(int irq, void * dev_id PT_REGS_ARG)
                return;
        }
 
+       dev = local->dev;
        if (dev == NULL) {
                printk(KERN_WARNING
                       "daqp_interrupt(): NULL comedi_device.\n");
                return;
        }
 
+       if (!dev->attached) {
+               printk(KERN_WARNING
+                      "daqp_interrupt(): comedi_device not yet attached.\n");
+               return;
+       }
+
+       s = local->s;
        if (s == NULL) {
                printk(KERN_WARNING
                       "daqp_interrupt(): NULL comedi_subdevice.\n");
index 5e8f23d6333cb1cbbf52aa56688ecea03d2e5ffc..7fd11aeae83d5042c42e7feddcb5d328a9ed2626 100644 (file)
@@ -922,6 +922,27 @@ static int rtd_attach (
     s->n_chan=3;
     s->maxdata=0xffff;
 
+                                       /* initialize board, per RTD spec */
+                                       /* also, initialize shadow registers */
+    RtdResetBoard (dev);
+    comedi_udelay (100);                       /* needed? */
+    RtdPlxInterruptWrite (dev, 0);
+    RtdInterruptMask (dev,0);          /* and sets shadow */
+    RtdInterruptClearMask (dev,~0);    /* and sets shadow */
+    RtdInterruptClear(dev);            /* clears bits set by mask */
+    RtdInterruptOverrunClear(dev);
+    RtdClearCGT (dev);
+    RtdAdcClearFifo (dev);
+    RtdDacClearFifo (dev,0);
+    RtdDacClearFifo (dev,1);
+                                       /* clear digital IO fifo*/
+    RtdDioStatusWrite (dev, 0);                /* safe state, set shadow */
+    RtdUtcCtrlPut (dev, 0, 0x30);      /* safe state, set shadow */
+    RtdUtcCtrlPut (dev, 1, 0x30);      /* safe state, set shadow */
+    RtdUtcCtrlPut (dev, 2, 0x30);      /* safe state, set shadow */
+    RtdUtcCtrlPut (dev, 3, 0);         /* safe state, set shadow */
+    /* TODO: set user out source ??? */
+
        /* check if our interrupt is available and get it */
        if((ret=comedi_request_irq (devpriv->pci_dev->irq, rtd_interrupt,
                IRQF_SHARED, "rtd520", dev)) < 0) {
@@ -994,26 +1015,6 @@ static int rtd_attach (
     printk("\n");                      /* end configuration line */
 #endif /* USE_DMA */
 
-                                       /* initialize board, per RTD spec */
-                                       /* also, initialize shadow registers */
-    RtdResetBoard (dev);
-    comedi_udelay (100);                       /* needed? */
-    RtdInterruptMask (dev,0);          /* and sets shadow */
-    RtdInterruptClearMask (dev,~0);    /* and sets shadow */
-    RtdInterruptClear(dev);            /* clears bits set by mask */
-    RtdInterruptOverrunClear(dev);
-    RtdClearCGT (dev);
-    RtdAdcClearFifo (dev);
-    RtdDacClearFifo (dev,0);
-    RtdDacClearFifo (dev,1);
-                                       /* clear digital IO fifo*/
-    RtdDioStatusWrite (dev, 0);                /* safe state, set shadow */
-    RtdUtcCtrlPut (dev, 0, 0x30);      /* safe state, set shadow */
-    RtdUtcCtrlPut (dev, 1, 0x30);      /* safe state, set shadow */
-    RtdUtcCtrlPut (dev, 2, 0x30);      /* safe state, set shadow */
-    RtdUtcCtrlPut (dev, 3, 0);         /* safe state, set shadow */
-    /* TODO: set user out source ??? */
-
     if (dev->irq) {                    /* enable plx9080 interrupts */
        RtdPlxInterruptWrite (dev, ICS_PIE | ICS_PLIE);
     }
@@ -1509,6 +1510,10 @@ static irqreturn_t rtd_interrupt (
        u16 fifoStatus;
        comedi_subdevice *s = dev->subdevices + 0; /* analog in subdevice */
 
+       if (!dev->attached) {
+               return IRQ_NONE;
+       }
+
        devpriv->intCount++;            /* DEBUG statistics */
 
        fifoStatus = RtdFifoStatus (dev);