From 46966119a193333f6392d652026012e0f5447ef7 Mon Sep 17 00:00:00 2001 From: Frank Mori Hess Date: Mon, 15 Sep 2003 21:33:53 +0000 Subject: [PATCH] Fully support munging in core. Still need to check munging for kcomedilib though. --- comedi/comedi_fops.c | 16 ++++++--- comedi/drivers.c | 55 ++++++++++++++++++++--------- comedi/drivers/comedi_fc.c | 2 +- comedi/drivers/dt282x.c | 11 +++--- comedi/drivers/ni_labpc.c | 7 +--- comedi/drivers/ni_mio_common.c | 7 ++-- comedi/drivers/rti800.c | 2 +- comedi/kcomedilib/kcomedilib_main.c | 2 ++ include/linux/comedidev.h | 10 ++++-- 9 files changed, 71 insertions(+), 41 deletions(-) diff --git a/comedi/comedi_fops.c b/comedi/comedi_fops.c index 49559716..e4f40f2b 100644 --- a/comedi/comedi_fops.c +++ b/comedi/comedi_fops.c @@ -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; } diff --git a/comedi/drivers.c b/comedi/drivers.c index 526258c2..4a016aa8 100644 --- a/comedi/drivers.c +++ b/comedi/drivers.c @@ -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(nprealloc_buf + async->buf_read_ptr); diff --git a/comedi/drivers/comedi_fc.c b/comedi/drivers/comedi_fc.c index b8e8a95f..fc0cedb8 100644 --- a/comedi/drivers/comedi_fc.c +++ b/comedi/drivers/comedi_fc.c @@ -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; diff --git a/comedi/drivers/dt282x.c b/comedi/drivers/dt282x.c index e72234f3..01e179d4 100644 --- a/comedi/drivers/dt282x.c +++ b/comedi/drivers/dt282x.c @@ -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); diff --git a/comedi/drivers/ni_labpc.c b/comedi/drivers/ni_labpc.c index 285ea5f5..39cb88c7 100644 --- a/comedi/drivers/ni_labpc.c +++ b/comedi/drivers/ni_labpc.c @@ -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)) { diff --git a/comedi/drivers/ni_mio_common.c b/comedi/drivers/ni_mio_common.c index c0b9c46a..b1f87d25 100644 --- a/comedi/drivers/ni_mio_common.c +++ b/comedi/drivers/ni_mio_common.c @@ -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 diff --git a/comedi/drivers/rti800.c b/comedi/drivers/rti800.c index af806518..c0512cd8 100644 --- a/comedi/drivers/rti800.c +++ b/comedi/drivers/rti800.c @@ -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 diff --git a/comedi/kcomedilib/kcomedilib_main.c b/comedi/kcomedilib/kcomedilib_main.c index 6678b2aa..98fa98ed 100644 --- a/comedi/kcomedilib/kcomedilib_main.c +++ b/comedi/kcomedilib/kcomedilib_main.c @@ -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; } diff --git a/include/linux/comedidev.h b/include/linux/comedidev.h index f649a277..d49fd396 100644 --- a/include/linux/comedidev.h +++ b/include/linux/comedidev.h @@ -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 -- 2.26.2