From 6283775e6712a14a8a3d233dd62ae2b98f432b43 Mon Sep 17 00:00:00 2001 From: David Schleef Date: Tue, 9 Jul 2002 00:31:41 +0000 Subject: [PATCH] Move buffer inlines to comedi/drivers.c. Rewrite as consistent primitives. Change buf_dirty_count to buf_free_count. --- comedi/comedi_fops.c | 76 ++++----- comedi/comedi_ksyms.c | 4 + comedi/drivers.c | 244 ++++++++++++++++++++++++++++ comedi/drivers/adl_pci9118.c | 5 +- comedi/drivers/ni_mio_common.c | 14 +- comedi/kcomedilib/kcomedilib_main.c | 2 +- include/linux/comedidev.h | 231 ++++---------------------- 7 files changed, 319 insertions(+), 257 deletions(-) diff --git a/comedi/comedi_fops.c b/comedi/comedi_fops.c index d53a7ff8..d11226c6 100644 --- a/comedi/comedi_fops.c +++ b/comedi/comedi_fops.c @@ -1312,7 +1312,6 @@ static ssize_t comedi_write_v22(struct file *file,const char *buf,size_t nbytes, comedi_async *async; int n,m,count=0,retval=0; DECLARE_WAITQUEUE(wait,current); - int sample_size; dev=comedi_get_device_by_minor(MINOR(RDEV_OF_FILE(file))); @@ -1326,14 +1325,6 @@ static ssize_t comedi_write_v22(struct file *file,const char *buf,size_t nbytes, s = dev->write_subdev; async = s->async; - if(s->subdev_flags&SDF_LSAMPL){ - sample_size=sizeof(lsampl_t); - }else{ - sample_size=sizeof(sampl_t); - } - if(nbytes%sample_size) - nbytes-=nbytes%sample_size; - if(!nbytes)return 0; if(!s->busy) @@ -1348,9 +1339,11 @@ static ssize_t comedi_write_v22(struct file *file,const char *buf,size_t nbytes, n=nbytes; - m = async->data_len + async->buf_read_count - async->buf_write_count; - if( async->buf_write_ptr + m > async->data_len ) + m = n; + if(async->buf_write_ptr + m > async->data_len){ m = async->data_len - async->buf_write_ptr; + } + m = comedi_buf_write_alloc(async, m); if(m < n) n = m; @@ -1375,13 +1368,13 @@ static ssize_t comedi_write_v22(struct file *file,const char *buf,size_t nbytes, schedule(); continue; } - m = 0; - if( write_to_async_buffer( async, buf, n, 1 ) ) - { - m = n; + + m = copy_from_user(async->prealloc_buf + async->buf_write_ptr, + buf, n); + if(m){ + n -= m; retval = -EFAULT; } - n-=m; count+=n; nbytes-=n; @@ -1403,7 +1396,6 @@ static ssize_t comedi_read_v22(struct file * file,char *buf,size_t nbytes,loff_t comedi_async *async; int n,m,count=0,retval=0; DECLARE_WAITQUEUE(wait,current); - int sample_size; dev=comedi_get_device_by_minor(MINOR(RDEV_OF_FILE(file))); @@ -1417,14 +1409,6 @@ static ssize_t comedi_read_v22(struct file * file,char *buf,size_t nbytes,loff_t if(s == NULL)return -EIO; async = s->async; - if(s->subdev_flags&SDF_LSAMPL){ - sample_size=sizeof(lsampl_t); - }else{ - sample_size=sizeof(sampl_t); - } - if(nbytes%sample_size) - nbytes-=nbytes%sample_size; - if(!nbytes)return 0; if(!s->busy) @@ -1439,13 +1423,12 @@ static ssize_t comedi_read_v22(struct file * file,char *buf,size_t nbytes,loff_t n=nbytes; - m = async->buf_write_count - async->buf_read_count; - if( m > async->data_len ) - m = async->data_len; - -#if 0 -printk("m is %d\n",m); -#endif + m = comedi_buf_read_n_available(async); +//printk("%d available\n",m); + if(async->buf_read_ptr + m > async->prealloc_bufsz){ + m = async->prealloc_bufsz - async->buf_read_ptr; + } +//printk("%d contiguous\n",m); if(mread_subdev); - DPRINTK("buffer overflow\n"); - break; + m = copy_to_user(buf, async->prealloc_buf + + async->buf_read_ptr, n); + if(m){ + n -= m; + retval = -EFAULT; } + comedi_buf_read_free(async, n); + count+=n; nbytes-=n; @@ -1803,6 +1780,8 @@ void comedi_event(comedi_device *dev,comedi_subdevice *s, unsigned int mask) mask = s->async->events; s->async->events = 0; + mask |= COMEDI_CB_BLOCK; + //DPRINTK("comedi_event %x\n",mask); if( (s->subdev_flags & SDF_RUNNING) == 0) @@ -1853,10 +1832,11 @@ void comedi_event(comedi_device *dev,comedi_subdevice *s, unsigned int mask) static void init_async_buf( comedi_async *async ) { - async->buf_read_count = 0; + async->buf_free_count = 0; async->buf_write_count = 0; - async->buf_dirty_count = 0; - async->buf_read_ptr = 0; + async->buf_read_count = 0; + async->buf_write_ptr = 0; + async->buf_read_ptr = 0; } diff --git a/comedi/comedi_ksyms.c b/comedi/comedi_ksyms.c index 46681172..08e7438f 100644 --- a/comedi/comedi_ksyms.c +++ b/comedi/comedi_ksyms.c @@ -64,6 +64,10 @@ EXPORT_SYMBOL(comedi_devices); EXPORT_SYMBOL(big_comedi_lock); EXPORT_SYMBOL(check_chanlist); +EXPORT_SYMBOL(comedi_buf_put); +EXPORT_SYMBOL(comedi_buf_get); +EXPORT_SYMBOL(comedi_buf_read_n_available); + #endif diff --git a/comedi/drivers.c b/comedi/drivers.c index 0a752541..13854775 100644 --- a/comedi/drivers.c +++ b/comedi/drivers.c @@ -391,3 +391,247 @@ static int buf_alloc(comedi_device *dev, comedi_subdevice *s, return 0; } + + +#if 0 +int write_to_async_buffer( comedi_async *async, const void *array, + unsigned int num_bytes, unsigned int from_user_space ) +{ + async->buf_dirty_count += num_bytes; + while( num_bytes ) + { + unsigned int block_size; + + block_size = num_bytes; + if( async->buf_write_ptr + block_size > async->data_len) + block_size = async->data_len - async->buf_write_ptr; + + if( from_user_space ) + { + if( copy_from_user( async->data + async->buf_write_ptr, array, block_size ) ) + return -EFAULT; + }else + memcpy( async->data + async->buf_write_ptr, array, block_size ); + + array += block_size; + num_bytes -= block_size; + async->buf_write_count += block_size; + async->buf_write_ptr += block_size; + if( async->buf_write_ptr == async->data_len ) + { + async->buf_write_ptr = 0; + } + } + + return 0; +} + +int read_from_async_buffer( comedi_async *async, void *destination, + unsigned int num_bytes, unsigned int from_user_space ) +{ + unsigned int bytes_available = async->buf_write_count - async->buf_read_count; + unsigned int remaining = bytes_available; + + if( bytes_available == 0 ) return -EAGAIN; + + while( remaining ) + { + unsigned int block_size; + + block_size = remaining; + if( async->buf_read_ptr + block_size > async->data_len ) + block_size = async->data_len - async->buf_read_ptr; + + if( from_user_space ) + { + if( copy_to_user( destination, async->data + async->buf_read_ptr, block_size ) ) + return -EFAULT; + }else + memcpy( destination, async->data + async->buf_read_ptr, block_size ); + + destination += block_size; + remaining -= block_size; + async->buf_read_ptr += block_size; + if( async->buf_read_ptr == async->data_len ) + { + async->buf_read_ptr = 0; + } + } + // check if buffer has overrun + if( async->buf_dirty_count - async->buf_read_count > async->data_len ) + return -EIO; + async->buf_read_count += bytes_available; + + return bytes_available - remaining; +} + +/* Writes an array of data points to comedi's buffer, used for input. + * Can be more efficient than putting comedi_buf_put() in a loop. */ +void __comedi_buf_put_array(comedi_async *async, void* array, + unsigned int num_bytes, unsigned int bytes_per_sample ) +{ + if( async->buf_write_ptr + num_bytes >= async->data_len ) + { + async->events |= COMEDI_CB_EOBUF; + } + + write_to_async_buffer( async, array, num_bytes, 0 ); + + async->cur_chan += num_bytes / bytes_per_sample; + if( async->cur_chan >= async->cmd.chanlist_len ) + { + async->cur_chan %= async->cmd.chanlist_len; + async->events |= COMEDI_CB_EOS; + } + async->events |= COMEDI_CB_BLOCK; +} + +void comedi_buf_put_array(comedi_async *async, sampl_t *array, + unsigned int num_samples ) +{ + __comedi_buf_put_array( async, array, num_samples * sizeof( sampl_t ), sizeof( sampl_t ) ); +} + +void comedi_buf_put_long_array(comedi_async *async, lsampl_t *array, + unsigned int num_samples ) +{ + __comedi_buf_put_array( async, array, num_samples * sizeof( lsampl_t ), sizeof( lsampl_t ) ); +} + +/* writes a data point to comedi's buffer, used for input */ +void comedi_buf_put(comedi_async *async, sampl_t x) +{ + comedi_buf_put_array( async, &x, 1 ); +} + +/* writes a long data point to comedi's buffer, used for input */ +void comedi_buf_put_long(comedi_async *async, lsampl_t x) +{ + comedi_buf_put_long_array( async, &x, 1 ); +} + +/* Reads a data point from comedi's buffer, used for output. + * returns negative value on error. */ +int comedi_buf_get_array(comedi_async *async, sampl_t *array, unsigned int num_samples) +{ + unsigned int num_bytes = num_samples * sizeof( sampl_t ); + int retval; + unsigned int read_ptr = async->buf_read_ptr; + + retval = read_from_async_buffer( async, array, num_bytes, 0 ); + + if( retval < 0 ) + { + async->events |= COMEDI_CB_ERROR; + return retval; + } + + num_bytes = retval; + num_samples = retval / sizeof( sampl_t ); + + if( read_ptr + num_bytes >= async->data_len) + { + async->events |= COMEDI_CB_EOBUF; + } + + async->cur_chan += num_samples; + if( async->cur_chan >= async->cmd.chanlist_len) + { + async->cur_chan %= async->cmd.chanlist_len; + async->events |= COMEDI_CB_EOS; + } + + async->events |= COMEDI_CB_BLOCK; + + return retval / sizeof( sampl_t ); +} + +/* Reads a data point from comedi's buffer, used for output. + * returns negative value on error. */ +int comedi_buf_get(comedi_async *async, sampl_t *x) +{ + return comedi_buf_get_array(async, x, 1); +} +#endif + + +/* begin ds */ + +unsigned int comedi_buf_write_alloc(comedi_async *async, unsigned int nbytes) +{ + unsigned int free_end = async->buf_read_count + async->prealloc_bufsz; + + if((int)(async->buf_free_count + nbytes - free_end) > 0){ + nbytes = free_end - async->buf_free_count; + } + + async->buf_free_count += nbytes; + + return nbytes; +} + +unsigned int comedi_buf_write_alloc_strict(comedi_async *async, + unsigned int nbytes) +{ + unsigned int free_end = async->buf_read_count + async->prealloc_bufsz; + + if((int)(async->buf_free_count + nbytes - free_end) > 0){ + nbytes = 0; + } + + async->buf_free_count += nbytes; + + return nbytes; +} + +/* transfers control of a chunk from writer to reader */ +void comedi_buf_write_free(comedi_async *async, unsigned int nbytes) +{ + async->buf_write_count += nbytes; + async->buf_write_ptr += nbytes; + if(async->buf_write_ptr >= async->prealloc_bufsz){ + async->buf_write_ptr -= async->prealloc_bufsz; + async->events |= COMEDI_CB_EOBUF; + } +} + +/* transfers control of a chunk from reader to free area */ +void comedi_buf_read_free(comedi_async *async, unsigned int nbytes) +{ + async->buf_read_count += nbytes; + async->buf_read_ptr += nbytes; + if(async->buf_read_ptr >= async->prealloc_bufsz){ + async->buf_read_ptr -= async->prealloc_bufsz; + } +} + +unsigned int comedi_buf_read_n_available(comedi_async *async) +{ + unsigned int read_end = async->buf_write_count; + + return read_end - async->buf_read_count; +} + +int comedi_buf_get(comedi_async *async, sampl_t *x) +{ + unsigned int n = comedi_buf_read_n_available(async); + + if(nprealloc_buf + async->buf_read_ptr); + comedi_buf_read_free(async, sizeof(sampl_t)); + return 1; +} + +int comedi_buf_put(comedi_async *async, sampl_t x) +{ + unsigned int n = comedi_buf_write_alloc_strict(async, sizeof(sampl_t)); + + if(nevents |= COMEDI_CB_ERROR; + return 0; + } + *(sampl_t *)(async->prealloc_buf + async->buf_write_ptr) = x; + comedi_buf_write_free(async, sizeof(sampl_t)); + return 1; +} + diff --git a/comedi/drivers/adl_pci9118.c b/comedi/drivers/adl_pci9118.c index 5fbfcfc7..8c53d379 100644 --- a/comedi/drivers/adl_pci9118.c +++ b/comedi/drivers/adl_pci9118.c @@ -681,7 +681,7 @@ static int move_block_from_dma_12bit_32b(comedi_device *dev, comedi_subdevice *s } #endif sampl=((sampl & 0xfff0)<<12)|((sampl & 0xfff00000)>>20); - comedi_buf_put_long( s->async, sampl ); + comedi_buf_put( s->async, sampl ); } sp+=cc<<1; if (cc>=chans) { @@ -731,7 +731,8 @@ static int move_block_from_dma_16bit_32b(comedi_device *dev, comedi_subdevice *s for (;cc>16))^0x80008000; - comedi_buf_put_long( s->async, sampl ); + /* XXX broken */ + comedi_buf_put( s->async, sampl ); } sp+=cc<<1; if (cc>=chans) { diff --git a/comedi/drivers/ni_mio_common.c b/comedi/drivers/ni_mio_common.c index 312f7356..7ba3b430 100644 --- a/comedi/drivers/ni_mio_common.c +++ b/comedi/drivers/ni_mio_common.c @@ -346,7 +346,7 @@ static void ni_E_interrupt(int irq,void *d,struct pt_regs * regs) #ifdef PCIDMA static void mite_handle_a_linkc(struct mite_struct *mite, comedi_device *dev) { - unsigned int count; + int count; comedi_subdevice *s = dev->subdevices + 0; comedi_async *async = s->async; @@ -357,8 +357,6 @@ static void mite_handle_a_linkc(struct mite_struct *mite, comedi_device *dev) printk("BUG: too many samples in interrupt (%d)\n",count); return; } - // XXX buf_dirty_count should really be incremented earlier... - async->buf_dirty_count += count; async->buf_write_count += count; if(async->cmd.flags & CMDF_RAWDATA){ @@ -665,7 +663,7 @@ static void ni_ai_fifo_read(comedi_device *dev,comedi_subdevice *s, for(i=0;iai_xorlist[ async->cur_chan ]; - comedi_buf_put( async, d ); + comedi_buf_put(async, d); } } @@ -708,16 +706,16 @@ static void ni_handle_fifo_dregs(comedi_device *dev) /* This may get the hi/lo data in the wrong order */ data = (dl>>16) + devpriv->ai_xorlist[async->cur_chan]; - comedi_buf_put( s->async, data ); + comedi_buf_put(s->async, data); data = (dl&0xffff) + devpriv->ai_xorlist[async->cur_chan]; - comedi_buf_put( s->async, data ); + comedi_buf_put(s->async, data); } /* Check if there's a single sample stuck in the FIFO */ if(ni_readb(Status_611x)&0x80){ dl=ni_readl(ADC_FIFO_Data_611x); data = (dl&0xffff) + devpriv->ai_xorlist[async->cur_chan]; - comedi_buf_put( s->async, data ); + comedi_buf_put(s->async, data); } }else{ while(1){ @@ -728,7 +726,7 @@ static void ni_handle_fifo_dregs(comedi_device *dev) } data=ni_readw(ADC_FIFO_Data_Register); data+=devpriv->ai_xorlist[async->cur_chan]; - comedi_buf_put( s->async, data ); + comedi_buf_put(s->async, data); } } } diff --git a/comedi/kcomedilib/kcomedilib_main.c b/comedi/kcomedilib/kcomedilib_main.c index 45d79ba8..d7627558 100644 --- a/comedi/kcomedilib/kcomedilib_main.c +++ b/comedi/kcomedilib/kcomedilib_main.c @@ -121,7 +121,7 @@ static void init_async_buf( comedi_async *async ) { async->buf_read_count = 0; async->buf_write_count = 0; - async->buf_dirty_count = 0; + async->buf_free_count = 0; async->buf_read_ptr = 0; async->buf_write_ptr = 0; } diff --git a/include/linux/comedidev.h b/include/linux/comedidev.h index 2e1311a1..1de7834c 100644 --- a/include/linux/comedidev.h +++ b/include/linux/comedidev.h @@ -131,27 +131,13 @@ struct comedi_async_struct{ unsigned int max_bufsize; /* maximum buffer size, bytes */ unsigned int mmap_count; /* current number of mmaps of prealloc_buf */ - /* To avoid races and provide reliable overrun detection, read / writes - * to buffer should make use of the read_from_async_buffer() and - * write_to_async_buffer() functions and proceed - * as follows: - * - * Writing: - * 1) if appropriate, check space in buffer, using read/write count members - * 2) call write_to_async_buffer() - * Reading: - * 1) if appropriate, check how much data is in buffer, using read/write - * count members - * 2) call read_from_async_buffer() - * 3) if appropriate, check return value for buffer overrun - * - * Note: there should be exactly one reader and one writer - */ - unsigned int buf_write_ptr; /* buffer marker for writer */ - unsigned int buf_read_ptr; /* buffer marker for reader */ + volatile unsigned int buf_free_count; /* byte count for free space */ volatile unsigned int buf_write_count; /* byte count for writer (write completed) */ - volatile unsigned int buf_dirty_count; /* byte count for writer (write in progress) */ - volatile unsigned int buf_read_count; /* byte count for reader */ + volatile unsigned int buf_read_count; /* byte count for reader */ + + unsigned int buf_write_ptr; /* buffer marker for writer */ + unsigned int buf_read_ptr; /* buffer marker for reader */ + unsigned int cur_chan; /* useless channel marker for interrupt */ void *data; @@ -177,10 +163,10 @@ struct comedi_driver_struct{ int (*attach)(comedi_device *,comedi_devconfig *); int (*detach)(comedi_device *); - // number of elements in board_name and board_id arrays + /* number of elements in board_name and board_id arrays */ unsigned int num_names; void *board_name; - // offset in bytes from one board name pointer to the next + /* offset in bytes from one board name pointer to the next */ int offset; }; @@ -190,7 +176,6 @@ struct comedi_device_struct{ void *private; kdev_t minor; char *board_name; - //int board; const void * board_ptr; int attached; int rt; @@ -264,10 +249,10 @@ static inline void comedi_proc_init(void) {} static inline void comedi_proc_cleanup(void) {} #endif -// subdevice runflags +/* subdevice runflags */ #define SRF_USER 0x00000001 #define SRF_RT 0x00000002 -// indicates an COMEDI_CB_ERROR event has occurred since the last command was started +/* indicates an COMEDI_CB_ERROR event has occurred since the last command was started */ #define SRF_ERROR 0x00000004 /* @@ -325,180 +310,30 @@ static inline int alloc_private(comedi_device *dev,int size) return 0; } -/* To avoid races and provide reliable overrun detection, read / writes -* to buffer should proceed generally as follows: -* Writing: -* 1) if appropriate, check space in buffer, using read/write count members -* 2) increment dirty count -* 3) write data to buffer -* 4) increment write count -* 5) keep track of where to write with write ptr -* Reading: -* 1) read data from buffer, using read/write count members to determine how much -* 3) if appropriate, check for overrun using read/dirty count members -* 4) increment read count -* 2) keep track of where to read with read ptr -* -* Note: there should be exactly one reader and one writer -*/ -static inline int write_to_async_buffer( comedi_async *async, const void *array, - unsigned int num_bytes, unsigned int from_user_space ) -{ - async->buf_dirty_count += num_bytes; - while( num_bytes ) - { - unsigned int block_size; - - block_size = num_bytes; - if( async->buf_write_ptr + block_size > async->data_len) - block_size = async->data_len - async->buf_write_ptr; - - if( from_user_space ) - { - if( copy_from_user( async->data + async->buf_write_ptr, array, block_size ) ) - return -EFAULT; - }else - memcpy( async->data + async->buf_write_ptr, array, block_size ); - - array += block_size; - num_bytes -= block_size; - async->buf_write_count += block_size; - async->buf_write_ptr += block_size; - if( async->buf_write_ptr == async->data_len ) - { - async->buf_write_ptr = 0; - } - } - - return 0; -} - -static inline int read_from_async_buffer( comedi_async *async, void *destination, - unsigned int num_bytes, unsigned int from_user_space ) -{ - unsigned int bytes_available = async->buf_write_count - async->buf_read_count; - unsigned int remaining = bytes_available; - - if( bytes_available == 0 ) return -EAGAIN; - - while( remaining ) - { - unsigned int block_size; - - block_size = remaining; - if( async->buf_read_ptr + block_size > async->data_len ) - block_size = async->data_len - async->buf_read_ptr; - - if( from_user_space ) - { - if( copy_to_user( destination, async->data + async->buf_read_ptr, block_size ) ) - return -EFAULT; - }else - memcpy( destination, async->data + async->buf_read_ptr, block_size ); - - destination += block_size; - remaining -= block_size; - async->buf_read_ptr += block_size; - if( async->buf_read_ptr == async->data_len ) - { - async->buf_read_ptr = 0; - } - } - // check if buffer has overrun - if( async->buf_dirty_count - async->buf_read_count > async->data_len ) - return -EIO; - async->buf_read_count += bytes_available; - - return bytes_available - remaining; -} - -/* Writes an array of data points to comedi's buffer, used for input. - * Can be more efficient than putting comedi_buf_put() in a loop. */ -static inline void __comedi_buf_put_array(comedi_async *async, void* array, - unsigned int num_bytes, unsigned int bytes_per_sample ) -{ - if( async->buf_write_ptr + num_bytes >= async->data_len ) - { - async->events |= COMEDI_CB_EOBUF; - } - - write_to_async_buffer( async, array, num_bytes, 0 ); - - async->cur_chan += num_bytes / bytes_per_sample; - if( async->cur_chan >= async->cmd.chanlist_len ) - { - async->cur_chan %= async->cmd.chanlist_len; - async->events |= COMEDI_CB_EOS; - } - async->events |= COMEDI_CB_BLOCK; -} - -static inline void comedi_buf_put_array(comedi_async *async, sampl_t *array, - unsigned int num_samples ) -{ - __comedi_buf_put_array( async, array, num_samples * sizeof( sampl_t ), sizeof( sampl_t ) ); -} - -static inline void comedi_buf_put_long_array(comedi_async *async, lsampl_t *array, - unsigned int num_samples ) -{ - __comedi_buf_put_array( async, array, num_samples * sizeof( lsampl_t ), sizeof( lsampl_t ) ); -} - -// writes a data point to comedi's buffer, used for input -static inline void comedi_buf_put(comedi_async *async, sampl_t x) -{ - comedi_buf_put_array( async, &x, 1 ); -} - -// writes a long data point to comedi's buffer, used for input -static inline void comedi_buf_put_long(comedi_async *async, lsampl_t x) -{ - comedi_buf_put_long_array( async, &x, 1 ); -} - -/* Reads a data point from comedi's buffer, used for output. - * returns negative value on error. */ -static inline int comedi_buf_get_array(comedi_async *async, sampl_t *array, unsigned int num_samples) -{ - unsigned int num_bytes = num_samples * sizeof( sampl_t ); - int retval; - unsigned int read_ptr = async->buf_read_ptr; - - retval = read_from_async_buffer( async, array, num_bytes, 0 ); - - if( retval < 0 ) - { - async->events |= COMEDI_CB_ERROR; - return retval; - } - - num_bytes = retval; - num_samples = retval / sizeof( sampl_t ); - - if( read_ptr + num_bytes >= async->data_len) - { - async->events |= COMEDI_CB_EOBUF; - } - - async->cur_chan += num_samples; - if( async->cur_chan >= async->cmd.chanlist_len) - { - async->cur_chan %= async->cmd.chanlist_len; - async->events |= COMEDI_CB_EOS; - } - - async->events |= COMEDI_CB_BLOCK; - - return retval / sizeof( sampl_t ); -} +#if 0 +int write_to_async_buffer( comedi_async *async, const void *array, + unsigned int num_bytes, unsigned int from_user_space ); +int read_from_async_buffer( comedi_async *async, void *destination, + unsigned int num_bytes, unsigned int from_user_space ); +void __comedi_buf_put_array(comedi_async *async, void* array, + unsigned int num_bytes, unsigned int bytes_per_sample ); +void comedi_buf_put_array(comedi_async *async, sampl_t *array, + unsigned int num_samples ); +void comedi_buf_put_long_array(comedi_async *async, lsampl_t *array, + unsigned int num_samples ); +#endif +int comedi_buf_put(comedi_async *async, sampl_t x); +#if 0 +void comedi_buf_put_long(comedi_async *async, lsampl_t x); +int comedi_buf_get_array(comedi_async *async, sampl_t *array, unsigned int num_samples); +#endif +int comedi_buf_get(comedi_async *async, sampl_t *x); -/* Reads a data point from comedi's buffer, used for output. - * returns negative value on error. */ -static inline int comedi_buf_get(comedi_async *async, sampl_t *x) -{ - return comedi_buf_get_array( async, x, 1); -} +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); //#ifdef CONFIG_COMEDI_RT -- 2.26.2