add support for comedi_poll when using mite dma, (needed to add
authorFrank Mori Hess <fmhess@speakeasy.net>
Sun, 21 Mar 2004 17:35:24 +0000 (17:35 +0000)
committerFrank Mori Hess <fmhess@speakeasy.net>
Sun, 21 Mar 2004 17:35:24 +0000 (17:35 +0000)
another spinlock to prevent races with interrupt handler).

comedi/drivers/ni_atmio.c
comedi/drivers/ni_mio_common.c
comedi/drivers/ni_mio_cs.c
comedi/drivers/ni_pcimio.c
comedi/drivers/ni_stc.h

index 8da2416d49a9e25a6d784de01a58c2638d457057..426fb28680a69e653db58427957be2af250fb4da 100644 (file)
@@ -411,7 +411,7 @@ static int ni_atmio_attach(comedi_device *dev,comedi_devconfig *it)
        int             irq;
 
        /* allocate private area */
-       if((ret = alloc_private(dev, sizeof(ni_private))) < 0)
+       if((ret = ni_alloc_private(dev)) < 0)
                return ret;
 
        iobase=it->options[0];
index 8c38e2e7dd3a6633ae7a91b522a4b8b4eb97fbea..f6a1bea8f1415e0755d7eb49aa66b0e07abba003 100644 (file)
@@ -286,20 +286,20 @@ static inline void ni_ao_win_outw( comedi_device *dev, uint16_t data, int addr )
 {
        unsigned long flags;
 
-       comedi_spin_lock_irqsave(&dev->spinlock,flags);
+       comedi_spin_lock_irqsave(&devpriv->window_lock,flags);
        ni_writew(addr,AO_Window_Address_611x);
        ni_writew(data,AO_Window_Data_611x);
-       comedi_spin_unlock_irqrestore(&dev->spinlock,flags);
+       comedi_spin_unlock_irqrestore(&devpriv->window_lock,flags);
 }
 
 static inline void ni_ao_win_outl(comedi_device *dev, uint32_t data, int addr)
 {
        unsigned long flags;
 
-       comedi_spin_lock_irqsave(&dev->spinlock,flags);
+       comedi_spin_lock_irqsave(&devpriv->window_lock,flags);
        ni_writew(addr,AO_Window_Address_611x);
        ni_writel(data,AO_Window_Data_611x);
-       comedi_spin_unlock_irqrestore(&dev->spinlock,flags);
+       comedi_spin_unlock_irqrestore(&devpriv->window_lock,flags);
 }
 
 static inline unsigned short ni_ao_win_inw( comedi_device *dev, int addr )
@@ -307,10 +307,10 @@ static inline unsigned short ni_ao_win_inw( comedi_device *dev, int addr )
        unsigned long flags;
        unsigned short data;
 
-       comedi_spin_lock_irqsave(&dev->spinlock,flags);
+       comedi_spin_lock_irqsave(&devpriv->window_lock,flags);
        ni_writew(addr, AO_Window_Address_611x);
        data = ni_readw(AO_Window_Data_611x);
-       comedi_spin_unlock_irqrestore(&dev->spinlock,flags);
+       comedi_spin_unlock_irqrestore(&devpriv->window_lock,flags);
        return data;
 }
 
@@ -328,14 +328,14 @@ static inline void ni_set_bits(comedi_device *dev, int reg, int bits, int value)
 {
        unsigned long flags;
 
-       comedi_spin_lock_irqsave( &dev->spinlock, flags );
+       comedi_spin_lock_irqsave( &devpriv->window_lock, flags );
        switch (reg){
                case Interrupt_A_Enable_Register:
                        if(value)
                                devpriv->int_a_enable_reg |= bits;
                        else
                                devpriv->int_a_enable_reg &= ~bits;
-                       comedi_spin_unlock_irqrestore( &dev->spinlock, flags );
+                       comedi_spin_unlock_irqrestore( &devpriv->window_lock, flags );
                        win_out(devpriv->int_a_enable_reg,Interrupt_A_Enable_Register);
                        break;
                case Interrupt_B_Enable_Register:
@@ -343,7 +343,7 @@ static inline void ni_set_bits(comedi_device *dev, int reg, int bits, int value)
                                devpriv->int_b_enable_reg |= bits;
                        else
                                devpriv->int_b_enable_reg &= ~bits;
-                       comedi_spin_unlock_irqrestore( &dev->spinlock, flags );
+                       comedi_spin_unlock_irqrestore( &devpriv->window_lock, flags );
                        win_out(devpriv->int_b_enable_reg,Interrupt_B_Enable_Register);
                        break;
                case IO_Bidirection_Pin_Register:
@@ -351,13 +351,13 @@ static inline void ni_set_bits(comedi_device *dev, int reg, int bits, int value)
                                devpriv->io_bidirection_pin_reg |= bits;
                        else
                                devpriv->io_bidirection_pin_reg &= ~bits;
-                       comedi_spin_unlock_irqrestore( &dev->spinlock, flags );
+                       comedi_spin_unlock_irqrestore( &devpriv->window_lock, flags );
                        win_out(devpriv->io_bidirection_pin_reg,IO_Bidirection_Pin_Register);
                        break;
                default:
                        printk("Warning ni_set_bits() called with invalid arguments\n");
                        printk("reg is %d\n",reg);
-                       comedi_spin_unlock_irqrestore( &dev->spinlock, flags );
+                       comedi_spin_unlock_irqrestore( &devpriv->window_lock, flags );
                        break;
        }
 }
@@ -1149,16 +1149,20 @@ static int ni_ai_reset(comedi_device *dev,comedi_subdevice *s)
 
 static int ni_ai_poll(comedi_device *dev,comedi_subdevice *s)
 {
+       unsigned long flags;
+       int count;
+
+       // lock to avoid race with interrupt handler
+       comedi_spin_lock_irqsave(&dev->spinlock, flags);
 #ifndef PCIDMA
        ni_handle_fifo_dregs(dev);
-
-       //comedi_event(dev,s,s->async->events);
-
-       return s->async->buf_write_count - s->async->buf_read_count;
 #else
-       /* XXX we don't support this yet. */
-       return -EINVAL;
+       ni_sync_ai_dma(devpriv->mite, dev);
 #endif
+       count = s->async->buf_write_count - s->async->buf_read_count;
+       comedi_spin_unlock_irqrestore(&dev->spinlock, flags);
+
+       return count;
 }
 
 
@@ -2631,6 +2635,18 @@ static void init_ao_67xx(comedi_device *dev, comedi_subdevice *s)
                ni_ao_win_outw(dev, AO_Channel(i) | 0x0, AO_Configuration_2_67xx);
 }
 
+static int ni_alloc_private(comedi_device *dev)
+{
+       int ret;
+
+       ret = alloc_private(dev, sizeof(ni_private));
+       if(ret < 0) return ret;
+
+       spin_lock_init(&devpriv->window_lock);
+
+       return 0;
+};
+
 static int ni_E_init(comedi_device *dev,comedi_devconfig *it)
 {
        comedi_subdevice *s;
index c25855f662e6a5ebeac119d4862a559b58c55aed..06c0ac062329b02abafe161ce22448e92be436ab 100644 (file)
@@ -553,7 +553,7 @@ static int mio_cs_attach(comedi_device *dev,comedi_devconfig *it)
        }
        
        /* allocate private area */
-       if((ret=alloc_private(dev,sizeof(ni_private)))<0)
+       if((ret=ni_alloc_private(dev))<0)
                return ret;
        
        if( (ret=ni_E_init(dev,it))<0 ){
index 19ae2c8f47ac4c8646f26cbd9ebba4b8a661a1db..a15daf29959edeeac0c8963c6f3d480b910945a3 100644 (file)
@@ -742,7 +742,7 @@ static int pcimio_attach(comedi_device *dev,comedi_devconfig *it)
 
        printk("comedi%d: ni_pcimio:",dev->minor);
 
-       ret=alloc_private(dev,sizeof(ni_private));
+       ret=ni_alloc_private(dev);
        if(ret<0)return ret;
 
        ret=pcimio_find_device(dev,it->options[0],it->options[1]);
index a2332fbbc34fc2f881974045a22d36498e0b9f71..e2b2f6bf01e8f7005e5469da0280238826e35440 100644 (file)
@@ -805,6 +805,7 @@ static ni_board ni_boards[];
        int blocksize;                                          \
        int n_left;                                             \
        unsigned int ai_calib_source;                           \
+       spinlock_t window_lock; \
                                                                \
        int changain_state;                                     \
        unsigned int changain_spec;                             \