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
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
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)) {
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
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
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)) {
devpriv->valid=1;
- pci1710_reset(dev);
-
return 0;
}
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
outb(cur_enabled, subpriv->iobase);
}
- if (subpriv->active) {
+ if (s->async && subpriv->active) {
/*
* The command is still active.
*
}
comedi_spin_unlock_irqrestore(&subpriv->spinlock, flags);
- if (oldevents != s->async->events) {
+ if (s->async && (oldevents != s->async->events)) {
comedi_event(dev, s);
}
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);
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 ))
{
if(dev->attached == 0)
{
- comedi_error(dev, "premature interrupt");
+ return IRQ_NONE;
}
async = s->async;
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 ))
{
dev->irq = pcidev->irq;
printk(" irq %u\n", dev->irq);
- init_plx9080(dev);
- init_stc_registers( dev );
retval = setup_subdevices(dev);
if(retval < 0)
{
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;
}
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);
#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);
s->async->events |= COMEDI_SB_EOA;
}
comedi_event(dev, s);
+ return IRQ_HANDLED;
}
#endif
{
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);
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);
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);
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;
}
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 ) )
printk(" irq %u\n", dev->irq);
- init_plx9080(dev);
-
// alocate pci dma buffers
for( i = 0; i < NUM_DMA_BUFFERS; i++ )
{
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 );
{
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
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)) {
devpriv->valid = 1;
- icp_multi_reset(dev);
-
#ifdef ICP_MULTI_EXTDEBUG
printk("icp multi EDBG: END: icp_multi_attach(...)\n");
#endif
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;
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);
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);
{
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); };
}
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;
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");
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) {
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);
}
u16 fifoStatus;
comedi_subdevice *s = dev->subdevices + 0; /* analog in subdevice */
+ if (!dev->attached) {
+ return IRQ_NONE;
+ }
+
devpriv->intCount++; /* DEBUG statistics */
fifoStatus = RtdFifoStatus (dev);