Fully support munging in core. Still need to check munging for
authorFrank Mori Hess <fmhess@speakeasy.net>
Mon, 15 Sep 2003 21:33:53 +0000 (21:33 +0000)
committerFrank Mori Hess <fmhess@speakeasy.net>
Mon, 15 Sep 2003 21:33:53 +0000 (21:33 +0000)
kcomedilib though.

comedi/comedi_fops.c
comedi/drivers.c
comedi/drivers/comedi_fc.c
comedi/drivers/dt282x.c
comedi/drivers/ni_labpc.c
comedi/drivers/ni_mio_common.c
comedi/drivers/rti800.c
comedi/kcomedilib/kcomedilib_main.c
include/linux/comedidev.h

index 49559716f20c015fa7bb3e25195d949527a319e5..e4f40f2bc88bf3369417d6b9d3d2603b2ab98b21 100644 (file)
@@ -505,15 +505,20 @@ static int do_bufinfo_ioctl(comedi_device *dev,void *arg)
 
        if(bi.bytes_written && s==dev->write_subdev){
                bi.bytes_written = comedi_buf_write_alloc( async, bi.bytes_written );
-               comedi_buf_munge(dev, s, bi.bytes_written);
+               comedi_buf_munge(dev, s, async->buf_write_alloc_count - async->munge_count);
                comedi_buf_write_free(async, bi.bytes_written);
        }
 
        if(s==dev->read_subdev){
+               unsigned int n_munge_bytes;
+
                bi.buf_int_count = async->buf_write_count;
                bi.buf_int_ptr = async->buf_write_ptr;
                bi.buf_user_count = async->buf_read_count;
                bi.buf_user_ptr = async->buf_read_ptr;
+
+               n_munge_bytes = bi.buf_int_count - s->async->munge_count;
+               comedi_buf_munge(dev, s, n_munge_bytes);
        }else{
                bi.buf_int_count = async->buf_read_count;
                bi.buf_int_ptr = async->buf_read_ptr;
@@ -1334,7 +1339,7 @@ static unsigned int comedi_poll_v22(struct file *file, poll_table * wait)
                s = dev->read_subdev;
                async = s->async;
                if(!s->busy
-                  || comedi_buf_read_n_available(async)>0
+                  || comedi_buf_read_n_available(s)>0
                   || !(s->subdev_flags&SDF_RUNNING)){
                        mask |= POLLIN | POLLRDNORM;
                }
@@ -1423,7 +1428,7 @@ static ssize_t comedi_write_v22(struct file *file,const char *buf,size_t nbytes,
                        n -= m;
                        retval = -EFAULT;
                }
-               comedi_buf_munge(dev, s, n);
+               comedi_buf_munge(dev, s, async->buf_write_alloc_count - async->munge_count);
                comedi_buf_write_free(async, n);
 
                count+=n;
@@ -1473,7 +1478,7 @@ static ssize_t comedi_read_v22(struct file * file,char *buf,size_t nbytes,loff_t
 
                n=nbytes;
 
-               m = comedi_buf_read_n_available(async);
+               m = comedi_buf_read_n_available(s);
 //printk("%d available\n",m);
                if(async->buf_read_ptr + m > async->prealloc_bufsz){
                        m = async->prealloc_bufsz - async->buf_read_ptr;
@@ -1503,6 +1508,7 @@ static ssize_t comedi_read_v22(struct file * file,char *buf,size_t nbytes,loff_t
                        continue;
                }
 
+               comedi_buf_munge(dev, s, n);
                m = copy_to_user(buf, async->prealloc_buf +
                        async->buf_read_ptr, n);
                if(m){
@@ -1897,6 +1903,8 @@ static void init_async_buf( comedi_async *async )
        async->cur_chan = 0;
        async->scan_progress = 0;
        async->munge_chan = 0;
+       async->munge_count = 0;
+       async->munge_ptr = 0;
 
        async->events = 0;
 }
index 526258c22504690b1800dc11d31c6ae5307b4661..4a016aa8b6c47f1e4aa784dacdb50c4c5665e144 100644 (file)
@@ -459,38 +459,48 @@ int comedi_buf_alloc(comedi_device *dev, comedi_subdevice *s,
        return 0;
 }
 
-// munging is applied to data right before comedi_buf_write_free()
-void comedi_buf_munge( comedi_device *dev, comedi_subdevice *s,
+/* munging is applied to data by core as it passes between user
+ * and kernel space */
+unsigned int comedi_buf_munge( comedi_device *dev, comedi_subdevice *s,
        unsigned int num_bytes )
 {
-       unsigned int offset = s->async->buf_write_ptr;
+       unsigned int count = 0;
 
        if( s->munge == NULL || ( s->async->cmd.flags & CMDF_RAWDATA ) )
-               return;
+               return count;
 
-       while( num_bytes )
+       /* don't munge partial samples */
+       num_bytes -= num_bytes % bytes_per_sample(s);
+       while( count < num_bytes )
        {
                unsigned int block_size;
 
-               block_size = num_bytes;
-               if( (int)(offset + block_size - s->async->prealloc_bufsz) > 0 )
-                       block_size = s->async->prealloc_bufsz - offset;
+               block_size = num_bytes - count;
+               if( (int)(s->async->munge_ptr + block_size - s->async->prealloc_bufsz) > 0 )
+                       block_size = s->async->prealloc_bufsz - s->async->munge_ptr;
 
-               s->munge( dev, s, s->async->prealloc_buf + offset,
+               s->munge( dev, s, s->async->prealloc_buf + s->async->munge_ptr,
                        block_size, s->async->munge_chan );
 
                s->async->munge_chan += block_size / bytes_per_sample( s );
                s->async->munge_chan %= s->async->cmd.chanlist_len;
-               num_bytes -= block_size;
-               offset = 0;
+               s->async->munge_count += block_size;
+               s->async->munge_ptr += block_size;
+               s->async->munge_ptr %= s->async->prealloc_bufsz;
+               count += block_size;
        }
+       return count;
 }
 
-unsigned int comedi_buf_write_n_available(comedi_async *async)
+unsigned int comedi_buf_write_n_available(comedi_subdevice *s)
 {
+       comedi_async *async=s->async;
        unsigned int free_end = async->buf_read_count + async->prealloc_bufsz;
+       unsigned int nbytes;
 
-       return free_end - async->buf_write_alloc_count;
+       nbytes = free_end - async->buf_write_alloc_count;
+       nbytes -= nbytes % bytes_per_sample(s);
+       return nbytes;
 }
 
 unsigned int comedi_buf_write_alloc(comedi_async *async, unsigned int nbytes)
@@ -592,16 +602,27 @@ void comedi_buf_memcpy_from(comedi_async *async, unsigned int offset,
        }
 }
 
-unsigned int comedi_buf_read_n_available(comedi_async *async)
+static inline unsigned int _comedi_buf_read_n_available(comedi_async *async)
+{
+       return async->buf_write_count - async->buf_read_count;
+}
+
+unsigned int comedi_buf_read_n_available(comedi_subdevice *s)
 {
-       unsigned int read_end = async->buf_write_count;
+       comedi_async *async = s->async;
+       unsigned int nbytes;
 
-       return read_end - async->buf_read_count;
+       if(async == NULL)
+               return 0;
+
+       nbytes = _comedi_buf_read_n_available(async);
+       nbytes -= nbytes % bytes_per_sample(s);
+       return nbytes;
 }
 
 int comedi_buf_get(comedi_async *async, sampl_t *x)
 {
-       unsigned int n = comedi_buf_read_n_available(async);
+       unsigned int n = _comedi_buf_read_n_available(async);
 
        if(n<sizeof(sampl_t))return 0;
        *x = *(sampl_t *)(async->prealloc_buf + async->buf_read_ptr);
index b8e8a95f0da331c3a96783ed913030edee10e0e8..fc0cedb89df2ce59dff4ae296c824da4f543b868 100644 (file)
@@ -90,7 +90,7 @@ unsigned int cfc_read_array_from_buffer( comedi_subdevice *subd, void *data,
 
        if( num_bytes == 0 ) return 0;
 
-       bytes_available = comedi_buf_read_n_available( async );
+       bytes_available = comedi_buf_read_n_available(subd);
        if( bytes_available < num_bytes )
        {
                num_bytes = bytes_available;
index e72234f33c3cd85b77ee46f813a8b9b197bfec09..01e179d40e33c813eaf2f9189ff157c0736efb08 100644 (file)
@@ -457,7 +457,7 @@ static void dt282x_ao_dma_interrupt(comedi_device * dev)
 
        devpriv->current_dma_index=1-i;
 
-       size = comedi_buf_read_n_available(s->async);
+       size = comedi_buf_read_n_available(s);
        if(size>devpriv->dma_maxsize)size=devpriv->dma_maxsize;
        if( size == 0){
                rt_printk("dt282x: AO underrun\n");
@@ -597,8 +597,7 @@ static irqreturn_t dt282x_interrupt(int irq, void *d, struct pt_regs *regs)
                handled = 1;
        }
        if (adcsr & DT2821_ADERR) {
-               if(devpriv->nread != 0 )
-               {
+               if(devpriv->nread != 0 ){
                        comedi_error(dev, "A/D error");
                        dt282x_ai_cancel(dev,s);
                        s->async->events |= COMEDI_CB_ERROR;
@@ -1050,7 +1049,7 @@ static int dt282x_ao_inttrig(comedi_device *dev,comedi_subdevice *s,
 
        if(x!=0)return -EINVAL;
 
-       size = comedi_buf_read_n_available(s->async);
+       size = comedi_buf_read_n_available(s);
        if(size>devpriv->dma_maxsize)size=devpriv->dma_maxsize;
        if( size == 0){
                rt_printk("dt282x: AO underrun\n");
@@ -1060,7 +1059,7 @@ static int dt282x_ao_inttrig(comedi_device *dev,comedi_subdevice *s,
        comedi_buf_read_free(s->async, size);
        prep_ao_dma(dev,0,size);
 
-       size = comedi_buf_read_n_available(s->async);
+       size = comedi_buf_read_n_available(s);
        if(size>devpriv->dma_maxsize)size=devpriv->dma_maxsize;
        if( size == 0){
                rt_printk("dt282x: AO underrun\n");
@@ -1110,6 +1109,8 @@ static int dt282x_ao_cmd(comedi_device *dev,comedi_subdevice *s)
 
 static int dt282x_ao_cancel(comedi_device * dev, comedi_subdevice * s)
 {
+       dt282x_disable_dma(dev);
+
        devpriv->dacsr=0;
        update_dacsr(0);
 
index 285ea5f5d9042e4a8deb970c19053d366fbb3de4..39cb88c7c239b54bd26a895fb08199cd5de7cee2 100644 (file)
@@ -520,12 +520,7 @@ int labpc_common_attach( comedi_device *dev, unsigned long iobase,
        if(irq)
        {
                isr_flags = 0;
-               if((thisboard->bustype == pci_bustype)
-#if 0
-                               // I'm fairly sure the daqcard-1200 interrupt cannot be shared
-                               || (thisboard->bustype == pcmcia_bustype)
-#endif
-                               )
+               if(thisboard->bustype == pci_bustype)
                        isr_flags |= SA_SHIRQ;
                if(comedi_request_irq( irq, labpc_interrupt, isr_flags, driver_labpc.driver_name, dev))
                {
index c0b9c46a375ddcba54aaf0f3c58c3f01f37c71c8..b1f87d25f02c18254df211082be44c18b3e7f21b 100644 (file)
@@ -361,7 +361,6 @@ static void ni_sync_ai_dma(struct mite_struct *mite, comedi_device *dev)
                count = 0;
        }
 
-       comedi_buf_munge(dev, s, count);
        comedi_buf_write_free(async, count);
 
        async->scan_progress += count;
@@ -807,7 +806,7 @@ static int ni_ao_fifo_half_empty(comedi_device *dev,comedi_subdevice *s)
 {
        int n;
 
-       n = comedi_buf_read_n_available(s->async);
+       n = comedi_buf_read_n_available(s);
        if(n==0){
                s->async->events |= COMEDI_CB_OVERFLOW;
                return 0;
@@ -832,7 +831,7 @@ static int ni_ao_prep_fifo(comedi_device *dev,comedi_subdevice *s)
        win_out(0,DAC_FIFO_Clear);
 
        /* load some data */
-       n = comedi_buf_read_n_available(s->async);
+       n = comedi_buf_read_n_available(s);
        if(n==0)return 0;
 
        n /= sizeof(sampl_t);
@@ -1236,7 +1235,7 @@ static int ni_ai_insn_read(comedi_device *dev,comedi_subdevice *s,comedi_insn *i
  * they have multiple A/D converters.  Register level documentation is
  * not written down for these boards, other than what is here.  If you
  * have any questions, ask Tim Ousley.
- * From the driver side, it is only the configuration memory that is a
+ * From the driver side, the configuration memory is a
  * little different.
  * Configuration Memory Low:
  *   bits 15-9: same
index af8065186d3c29a53b727425c9404388b284d069..c0512cd897dbbb3f834df0c65025cb6fcd1b8fe1 100644 (file)
@@ -186,7 +186,7 @@ static int rti800_ai_insn_read(comedi_device *dev,comedi_subdevice *s,
 
        outb(chan | (gain << 5), dev->iobase + RTI800_MUXGAIN);
 
-       /* without a delay here, you the RTI_OVERRUN bit
+       /* without a delay here, the RTI_OVERRUN bit
         * gets set, and you will have an error.  Not
         * sure if this is a long enough delay though.
         * comedi_udelay( gaindelay[ gain ] ) definitely
index 6678b2aade12648f04e6ef07209f70921121c508..98fa98ed747eb53070c161d5c0b62dcbfd6d6776 100644 (file)
@@ -128,6 +128,8 @@ static void init_async_buf( comedi_async *async )
        async->cur_chan = 0;
        async->scan_progress = 0;
        async->munge_chan = 0;
+       async->munge_count = 0;
+       async->munge_ptr = 0;
        async->events = 0;
 }
 
index f649a277dd5794ddfb496b964324bd0ca6ba9c2c..d49fd3969db3f74e55276d4016cebb8b9498a431 100644 (file)
@@ -164,6 +164,10 @@ struct comedi_async_struct{
        unsigned int scan_progress;
        /* keeps track of where we are in chanlist as for munging */
        unsigned int munge_chan;
+       /* number of bytes that have been munged */
+       unsigned int munge_count;
+       /* buffer marker for munging */
+       unsigned int munge_ptr;
 
        unsigned int    events;         /* events that have occurred */
 
@@ -350,17 +354,17 @@ static inline unsigned int bytes_per_sample( const comedi_subdevice *subd )
 int comedi_buf_put(comedi_async *async, sampl_t x);
 int comedi_buf_get(comedi_async *async, sampl_t *x);
 
-unsigned int comedi_buf_write_n_available(comedi_async *async);
+unsigned int comedi_buf_write_n_available(comedi_subdevice *s);
 unsigned int comedi_buf_write_alloc(comedi_async *async, unsigned int nbytes);
 unsigned int comedi_buf_write_alloc_strict(comedi_async *async, unsigned int nbytes);
 void comedi_buf_write_free(comedi_async *async, unsigned int nbytes);
 void comedi_buf_read_free(comedi_async *async, unsigned int nbytes);
-unsigned int comedi_buf_read_n_available(comedi_async *async);
+unsigned int comedi_buf_read_n_available(comedi_subdevice *s);
 void comedi_buf_memcpy_to( comedi_async *async, unsigned int offset, const void *source,
        unsigned int num_bytes );
 void comedi_buf_memcpy_from( comedi_async *async, unsigned int offset, void *destination,
        unsigned int num_bytes );
-void comedi_buf_munge( comedi_device *dev, comedi_subdevice *s,
+unsigned int comedi_buf_munge( comedi_device *dev, comedi_subdevice *s,
        unsigned int num_bytes );
 
 //#ifdef CONFIG_COMEDI_RT