fixed null dereference that occured when interrupt was handled before driver was...
authorFrank Mori Hess <fmhess@speakeasy.net>
Sat, 5 May 2001 00:51:22 +0000 (00:51 +0000)
committerFrank Mori Hess <fmhess@speakeasy.net>
Sat, 5 May 2001 00:51:22 +0000 (00:51 +0000)
comedi/drivers/das800.c

index 5a10a52624606954398bff3858684351b240bf67..9c26d7c6805b46cc760ea57571ff8185b0780d84 100644 (file)
@@ -319,16 +319,21 @@ static void das800_interrupt(int irq, void *d, struct pt_regs *regs)
        sampl_t dataPoint;
        comedi_device *dev = d;
        comedi_subdevice *s = dev->read_subdev; /* analog input subdevice */
-       comedi_async *async = s->async;
+       comedi_async *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 interupt was not generated by board or driver not attached, quit */
        if(!(status & IRQ) || !(dev->attached))
                return;
 
+       /* wait until here to initialize async, since we will get null dereference
+        * if interrupt occurs before driver is fully attached!
+        */
+       async = s->async;
+
        // if hardware conversions are not enabled, then quit
        comedi_spin_lock_irqsave(&dev->spinlock, irq_flags);
        outb(CONTROL1, dev->iobase + DAS800_GAIN);      /* select base address + 7 to be STATUS2 register */
@@ -348,6 +353,7 @@ static void das800_interrupt(int irq, void *d, struct pt_regs *regs)
        {
                if( dataPoint & FIFO_OVF )
                {
+                       comedi_spin_unlock_irqrestore(&dev->spinlock, irq_flags);
                        comedi_error(dev, "DAS800 FIFO overflow");
                        das800_cancel(dev, dev->subdevices + 0);
                        comedi_error_done(dev, s);
@@ -423,6 +429,10 @@ static int das800_attach(comedi_device *dev, comedi_devconfig *it)
        }
        printk("\n");
 
+       /* allocate and initialize dev->private */
+       if(alloc_private(dev, sizeof(das800_private)) < 0)
+               return -ENOMEM;
+
        if(iobase == 0)
        {
                printk("io base address required for das800\n");
@@ -464,10 +474,6 @@ static int das800_attach(comedi_device *dev, comedi_devconfig *it)
 
        dev->board_name = thisboard->name;
 
-       /* allocate and initialize dev->private */
-       if(alloc_private(dev, sizeof(das800_private)) < 0)
-               return -ENOMEM;
-
        dev->n_subdevices = 3;
        if(alloc_subdevices(dev) < 0)
                return -ENOMEM;