kcomedilib though.
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;
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;
}
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;
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;
continue;
}
+ comedi_buf_munge(dev, s, n);
m = copy_to_user(buf, async->prealloc_buf +
async->buf_read_ptr, n);
if(m){
async->cur_chan = 0;
async->scan_progress = 0;
async->munge_chan = 0;
+ async->munge_count = 0;
+ async->munge_ptr = 0;
async->events = 0;
}
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)
}
}
-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);
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;
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");
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;
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");
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");
static int dt282x_ao_cancel(comedi_device * dev, comedi_subdevice * s)
{
+ dt282x_disable_dma(dev);
+
devpriv->dacsr=0;
update_dacsr(0);
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))
{
count = 0;
}
- comedi_buf_munge(dev, s, count);
comedi_buf_write_free(async, count);
async->scan_progress += count;
{
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;
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);
* 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
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
async->cur_chan = 0;
async->scan_progress = 0;
async->munge_chan = 0;
+ async->munge_count = 0;
+ async->munge_ptr = 0;
async->events = 0;
}
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 */
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