static int do_insnlist_ioctl(comedi_device *dev,void *arg,void *file);
static void do_become_nonbusy(comedi_device *dev,comedi_subdevice *s);
-int resize_buf(comedi_device *dev,comedi_subdevice *s, unsigned int size);
+int resize_buf(comedi_device *dev,comedi_async *s, unsigned int size);
static int comedi_ioctl(struct inode * inode,struct file * file,unsigned int cmd,unsigned long arg)
{
static int do_bufconfig_ioctl(comedi_device *dev,void *arg)
{
comedi_bufconfig bc;
- comedi_subdevice *rsd=NULL, *wsd=NULL;
+ comedi_async *rasync = NULL, *wasync = NULL;
int ret;
if(!suser())
if(copy_from_user(&bc,arg,sizeof(comedi_bufconfig)))
return -EFAULT;
- if(dev->read_subdev >= 0)
- rsd = &dev->subdevices[dev->read_subdev];
- if(dev->write_subdev >= 0)
- wsd = &dev->subdevices[dev->write_subdev];
+ if(dev->read_subdev)
+ rasync = dev->read_subdev->async;
+ if(dev->write_subdev)
+ wasync = dev->write_subdev->async;
if(bc.read_size){
- if(rsd == NULL)
+ if(rasync == NULL)
{
DPRINTK("device has no read subdevice, buffer resize failed\n");
return -ENODEV;
}
- if(rsd->busy)
+ if(rasync->subdev->busy)
return -EBUSY;
- if(rsd->mmap_count){
+ if(rasync->mmap_count){
DPRINTK("read subdevice is mmapped, cannot resize buffer\n");
return -EBUSY;
}
- if(!rsd->prealloc_buf)
+ if(!rasync->prealloc_buf)
return -EINVAL;
}
if(bc.write_size){
- if(wsd == NULL)
+ if(wasync == NULL)
{
DPRINTK("device has no write subdevice, buffer resize failed\n");
return -ENODEV;
}
- if(wsd->busy)
+ if(wasync->subdev->busy)
return -EBUSY;
- if(wsd->mmap_count){
+ if(wasync->mmap_count){
DPRINTK("write subdevice is mmapped, cannot resize buffer\n");
return -EBUSY;
}
- if(!wsd->prealloc_buf)
+ if(!wasync->prealloc_buf)
return -EINVAL;
}
// resize buffers
if(bc.read_size){
- ret = resize_buf(dev,rsd,bc.read_size);
+ ret = resize_buf(dev,rasync,bc.read_size);
if(ret < 0)
return ret;
- DPRINTK("comedi%i read buffer resized to %i bytes\n", dev->minor, rsd->prealloc_bufsz);
+ DPRINTK("comedi%i read buffer resized to %i bytes\n", dev->minor, rasync->prealloc_bufsz);
}
if(bc.write_size){
- ret = resize_buf(dev,wsd,bc.write_size);
+ ret = resize_buf(dev,wasync,bc.write_size);
if(ret < 0)
return ret;
- DPRINTK("comedi%i write buffer resized to %i bytes\n", dev->minor, wsd->prealloc_bufsz);
+ DPRINTK("comedi%i write buffer resized to %i bytes\n", dev->minor, wasync->prealloc_bufsz);
}
// write back buffer sizes
- if(rsd){
- bc.read_size = rsd->prealloc_bufsz;
+ if(rasync){
+ bc.read_size = rasync->prealloc_bufsz;
} else bc.read_size = 0;
- if(wsd){
- bc.write_size = wsd->prealloc_bufsz;
+ if(wasync){
+ bc.write_size = wasync->prealloc_bufsz;
} else bc.write_size = 0;
if(copy_to_user(arg,&bc,sizeof(comedi_bufconfig)))
/* utility function that resizes the prealloc_buf for
* a subdevice
*/
-int resize_buf(comedi_device *dev, comedi_subdevice *s, unsigned int size)
+int resize_buf(comedi_device *dev, comedi_async *async, unsigned int size)
{
void *old_buf;
size = ((size + PAGE_SIZE - 1) / PAGE_SIZE) * PAGE_SIZE;
// if no change is required, do nothing
- if(s->prealloc_buf && s->prealloc_bufsz){
- if(s->prealloc_bufsz == size)
- return 0;
+ if(async->prealloc_buf && async->prealloc_bufsz &&
+ async->prealloc_bufsz == size)
+ {
+ return 0;
}
- old_buf = s->prealloc_buf;
- s->prealloc_buf = rvmalloc(size);
+ old_buf = async->prealloc_buf;
+ async->prealloc_buf = rvmalloc(size);
// restore old buffer on error
- if(s->prealloc_buf == 0){
- s->prealloc_buf = old_buf;
+ if(async->prealloc_buf == NULL){
+ async->prealloc_buf = old_buf;
return -ENOMEM;
}
- rvfree(old_buf, s->prealloc_bufsz);
- s->prealloc_bufsz = size;
+ rvfree(old_buf, async->prealloc_bufsz);
+ async->prealloc_bufsz = size;
return 0;
}
ret=copy_to_user(arg,tmp,dev->n_subdevices*sizeof(comedi_subdinfo));
kfree(tmp);
-
+
return ret?-EFAULT:0;
}
int reading;
int bufsz;
int ret=0,i;
+ comedi_async *async = s->async;
/* make sure channel/gain list isn't too long */
if(user_trig->n_chan > s->len_chanlist){
goto cleanup;
}
- s->buf_int_ptr=0;
- s->buf_int_count=0;
+ async->buf_int_ptr=0;
+ async->buf_int_count=0;
if(s->subdev_flags & SDF_READABLE){
- s->buf_user_ptr=0;
- s->buf_user_count=0;
+ async->buf_user_ptr=0;
+ async->buf_user_count=0;
}
if(s->subdev_flags & SDF_WRITEABLE){
cleanup:
do_become_nonbusy(dev,s);
-
+
return ret;
}
static int do_trig_ioctl_modeN(comedi_device *dev,comedi_subdevice *s,comedi_trig *user_trig)
{
int ret=0;
+ comedi_async *async = s->async;
+
+ if(async == NULL)
+ {
+ DPRINTK("subdevice has no buffer, trig failed\n");
+ return -ENODEV;
+ goto cleanup;
+ }
if(s->cur_trig.mode>=5 || s->trig[s->cur_trig.mode]==NULL){
DPRINTK("bad mode %d\n",s->cur_trig.mode);
ret = -EFAULT;
goto cleanup;
}
-
+
/* make sure each element in channel/gain list is valid */
if((ret=check_chanlist(s,s->cur_trig.n_chan,s->cur_trig.chanlist))<0){
DPRINTK("bad chanlist\n");
goto cleanup;
}
- if(!s->prealloc_buf){
- printk("comedi: bug: s->prealloc_buf=NULL\n");
+ if(!s->async->prealloc_buf){
+ printk("comedi: bug: s->async->prealloc_buf==NULL\n");
}
- s->cur_trig.data=s->prealloc_buf;
- s->cur_trig.data_len=s->prealloc_bufsz;
+ s->cur_trig.data=async->prealloc_buf;
+ s->cur_trig.data_len=async->prealloc_bufsz;
- s->buf_int_ptr=0;
- s->buf_int_count=0;
+ async->buf_int_ptr=0;
+ async->buf_int_count=0;
if(s->subdev_flags & SDF_READABLE){
- s->buf_user_ptr=0;
- s->buf_user_count=0;
+ async->buf_user_ptr=0;
+ async->buf_user_count=0;
}
- s->cur_chan=0;
- s->cur_chanlist_len=s->cur_trig.n_chan;
+ async->cur_chan=0;
+ async->cur_chanlist_len=s->cur_trig.n_chan;
- s->cb_mask=COMEDI_CB_EOA|COMEDI_CB_BLOCK|COMEDI_CB_ERROR;
+ async->cb_mask=COMEDI_CB_EOA|COMEDI_CB_BLOCK|COMEDI_CB_ERROR;
if(s->cur_trig.flags & TRIG_WAKE_EOS){
- s->cb_mask|=COMEDI_CB_EOS;
+ async->cb_mask|=COMEDI_CB_EOS;
}
s->runflags=SRF_USER;
cleanup:
do_become_nonbusy(dev,s);
-
+
return ret;
}
#endif
if(copy_from_user(&insnlist,arg,sizeof(comedi_insnlist)))
return -EFAULT;
-
+
if(insnlist.n_insns>=10) /* XXX */
return -EINVAL;
data[0]=tv.tv_sec;
data[1]=tv.tv_usec;
ret=2;
-
+
break;
}
case INSN_WAIT:
{
comedi_cmd user_cmd;
comedi_subdevice *s;
+ comedi_async *async;
int ret=0;
unsigned int *chanlist_saver=NULL;
}
s=dev->subdevices+user_cmd.subdev;
+ async = s->async;
if(s->type==COMEDI_SUBD_UNUSED){
DPRINTK("%d not valid subdevice\n",user_cmd.subdev);
return -EIO;
goto cleanup;
}
- s->cmd=user_cmd;
- s->cmd.chanlist=NULL;
- s->cmd.data=NULL;
+ async->cmd=user_cmd;
+ async->cmd.chanlist=NULL;
+ async->cmd.data=NULL;
/* load channel/gain list */
/* we should have this already allocated */
- s->cmd.chanlist=kmalloc(s->cmd.chanlist_len*sizeof(int),GFP_KERNEL);
- if(!s->cmd.chanlist){
+ async->cmd.chanlist=kmalloc(async->cmd.chanlist_len*sizeof(int),GFP_KERNEL);
+ if(!async->cmd.chanlist){
DPRINTK("allocation failed\n");
ret = -ENOMEM;
goto cleanup;
}
- if(copy_from_user(s->cmd.chanlist,user_cmd.chanlist,s->cmd.chanlist_len*sizeof(int))){
+ if(copy_from_user(async->cmd.chanlist,user_cmd.chanlist,async->cmd.chanlist_len*sizeof(int))){
DPRINTK("fault reading chanlist\n");
ret = -EFAULT;
goto cleanup;
}
/* make sure each element in channel/gain list is valid */
- if((ret=check_chanlist(s,s->cmd.chanlist_len,s->cmd.chanlist))<0){
+ if((ret=check_chanlist(s,async->cmd.chanlist_len,async->cmd.chanlist))<0){
DPRINTK("bad chanlist\n");
goto cleanup;
}
- ret=s->do_cmdtest(dev,s,&s->cmd);
+ ret=s->do_cmdtest(dev,s,&async->cmd);
- if(s->cmd.flags&TRIG_BOGUS || ret){
+ if(async->cmd.flags&TRIG_BOGUS || ret){
DPRINTK("test returned %d\n",ret);
- user_cmd=s->cmd;
+ user_cmd=async->cmd;
// restore chanlist pointer before copying back
user_cmd.chanlist = chanlist_saver;
user_cmd.data = NULL;
goto cleanup;
}
- if(!s->prealloc_bufsz){
+ if(!async->prealloc_bufsz){
ret=-ENOMEM;
DPRINTK("no buffer (?)\n");
goto cleanup;
}
- s->cmd.data = s->prealloc_buf;
- s->cmd.data_len=s->prealloc_bufsz;
+ async->cmd.data = async->prealloc_buf;
+ async->cmd.data_len=async->prealloc_bufsz;
#ifdef CONFIG_COMEDI_MODE_CORE
- s->cur_trig.data=s->prealloc_buf; /* XXX */
- s->cur_trig.data_len=s->prealloc_bufsz;
+ s->cur_trig.data=async->prealloc_buf; /* XXX */
+ s->cur_trig.data_len=async->prealloc_bufsz;
#endif
- s->buf_int_ptr=0;
- s->buf_int_count=0;
+ async->buf_int_ptr=0;
+ async->buf_int_count=0;
if(s->subdev_flags & SDF_READABLE){
- s->buf_user_ptr=0;
- s->buf_user_count=0;
+ async->buf_user_ptr=0;
+ async->buf_user_count=0;
}
- s->cur_chan = 0;
- s->cur_chanlist_len = s->cmd.chanlist_len;
+ async->cur_chan = 0;
+ async->cur_chanlist_len = async->cmd.chanlist_len;
- s->cb_mask = COMEDI_CB_EOA|COMEDI_CB_BLOCK|COMEDI_CB_ERROR;
- if(s->cmd.flags & TRIG_WAKE_EOS){
- s->cb_mask |= COMEDI_CB_EOS;
+ async->cb_mask = COMEDI_CB_EOA|COMEDI_CB_BLOCK|COMEDI_CB_ERROR;
+ if(async->cmd.flags & TRIG_WAKE_EOS){
+ async->cb_mask |= COMEDI_CB_EOS;
}
s->runflags=SRF_USER;
s->subdev_flags|=SDF_RUNNING;
#ifdef CONFIG_COMEDI_RT
- if(s->cmd.flags&TRIG_RT){
+ if(async->cmd.flags&TRIG_RT){
comedi_switch_to_rt(dev);
s->runflags |= SRF_RT;
}
/*
COMEDI_CMDTEST
command testing ioctl
-
+
arg:
pointer to cmd structure
-
+
reads:
cmd structure at arg
channel/range list
-
+
writes:
modified cmd structure at arg
{
kdev_t minor=MINOR(RDEV_OF_FILE(file));
comedi_device *dev=comedi_get_device_by_minor(minor);
- comedi_subdevice *s;
- int subdev;
+ comedi_async *async = NULL;
struct comedi_file_private *cfp;
if(!dev->attached)
}
if(vma->vm_flags & VM_WRITE){
- subdev=dev->write_subdev;
+ async=dev->write_subdev->async;
}else{
- subdev=dev->read_subdev;
+ async=dev->read_subdev->async;
}
- if(subdev<0){
+ if(async==NULL){
return -EINVAL;
}
- s=dev->subdevices+subdev;
if(VM_OFFSET(vma) != 0){
DPRINTK("comedi: mmap() offset must be 0.\n");
}
cfp = (struct comedi_file_private*) file->private_data;
- if(subdev == dev->read_subdev)
+ if(async == dev->read_subdev->async)
cfp->read_mmap_count++;
- else if(subdev == dev->write_subdev)
+ else if(async == dev->write_subdev->async)
cfp->write_mmap_count++;
- rvmmap(s->prealloc_buf,s->prealloc_bufsz,vma);
+ rvmmap(async->prealloc_buf,async->prealloc_bufsz,vma);
//vma->vm_file = file;
//vma->vm_ops = &comedi_vm_ops;
//file_atomic_inc(&file->f_count);
- s->mmap_count++;
+ async->mmap_count++;
return 0;
}
{
comedi_device *dev;
comedi_subdevice *s;
+ comedi_async *async;
unsigned int mask;
dev=comedi_get_device_by_minor(MINOR(RDEV_OF_FILE(file)));
poll_wait(file, &dev->read_wait, wait);
poll_wait(file, &dev->write_wait, wait);
mask = 0;
- if(dev->read_subdev>=0){
- s=dev->subdevices+dev->read_subdev;
+ if(dev->read_subdev){
+ s = dev->read_subdev;
+ async = s->async;
if(!(s->subdev_flags&SDF_RUNNING) ||
- (s->buf_user_count < s->buf_int_count))
+ (async->buf_user_count < async->buf_int_count))
mask |= POLLIN | POLLRDNORM;
}
- if(dev->write_subdev>=0){
- s=dev->subdevices+dev->write_subdev;
+ if(dev->write_subdev){
+ s = dev->write_subdev;
+ async = s->async;
if((!s->subdev_flags&SDF_RUNNING) ||
- (s->buf_user_count < s->buf_int_count + s->prealloc_bufsz))
+ (async->buf_user_count < async->buf_int_count + async->prealloc_bufsz))
mask |= POLLOUT | POLLWRNORM;
}
{
comedi_device *dev;
comedi_subdevice *s;
+ comedi_async *async;
int n,m,count=0,retval=0;
DECLARE_WAITQUEUE(wait,current);
int sample_size;
return -ENODEV;
}
- if(dev->write_subdev<0)return -EIO;
- s=dev->subdevices+dev->write_subdev;
+ if(dev->write_subdev == NULL)return -EIO;
+ s = dev->write_subdev;
+ async = s->async;
if(s->subdev_flags&SDF_LSAMPL){
sample_size=sizeof(lsampl_t);
return -EIO;
if(!s->busy){
- buf_ptr=s->prealloc_buf;
- buf_len=s->prealloc_bufsz;
+ buf_ptr=async->prealloc_buf;
+ buf_len=async->prealloc_bufsz;
}else{
if(s->busy != file)
return -EACCES;
n=nbytes;
- m=buf_len-(s->buf_user_count-s->buf_int_count);
- if(s->buf_user_ptr+m > buf_len){
- m=buf_len - s->buf_user_ptr;
+ m=buf_len-(async->buf_user_count-async->buf_int_count);
+ if(async->buf_user_ptr+m > buf_len){
+ m=buf_len - async->buf_user_ptr;
}
if(m<n)n=m;
schedule();
continue;
}
- m=copy_from_user(buf_ptr+s->buf_user_ptr,buf,n);
+ m=copy_from_user(buf_ptr+async->buf_user_ptr,buf,n);
if(m) retval=-EFAULT;
n-=m;
count+=n;
nbytes-=n;
- s->buf_user_ptr+=n;
- s->buf_user_count+=n;
+ async->buf_user_ptr+=n;
+ async->buf_user_count+=n;
- if(s->buf_user_ptr>=buf_len ){
- s->buf_user_ptr=0;
+ if(async->buf_user_ptr>=buf_len ){
+ async->buf_user_ptr=0;
}
buf+=n;
{
comedi_device *dev;
comedi_subdevice *s;
+ comedi_async *async;
int n,m,count=0,retval=0;
DECLARE_WAITQUEUE(wait,current);
int sample_size;
return -ENODEV;
}
- if(dev->read_subdev<0)return -EIO;
- s=dev->subdevices+dev->read_subdev;
+ s = dev->read_subdev;
+ if(s == NULL)return -EIO;
+ async = s->async;
if(s->subdev_flags&SDF_LSAMPL){
sample_size=sizeof(lsampl_t);
n=nbytes;
- m=s->buf_int_count-s->buf_user_count;
+ m=async->buf_int_count-async->buf_user_count;
- if(s->buf_user_ptr+m > s->cur_trig.data_len){ /* XXX MODE */
- m=s->cur_trig.data_len - s->buf_user_ptr;
+ if(async->buf_user_ptr+m > s->cur_trig.data_len){ /* XXX MODE */
+ m=s->cur_trig.data_len - async->buf_user_ptr;
#if 0
printk("m is %d\n",m);
#endif
schedule();
continue;
}
- m=copy_to_user(buf,((void *)(s->cur_trig.data))+s->buf_user_ptr,n);
+ m=copy_to_user(buf,((void *)(s->cur_trig.data))+async->buf_user_ptr,n);
if(m) retval=-EFAULT;
n-=m;
// check for buffer overrun
- if(s->buf_int_count - s->buf_user_count > s->cur_trig.data_len){ /* XXX MODE */
- s->buf_user_count = s->buf_int_count;
- s->buf_user_ptr = s->buf_int_ptr;
+ if(async->buf_int_count - async->buf_user_count > s->cur_trig.data_len){ /* XXX MODE */
+ async->buf_user_count = async->buf_int_count;
+ async->buf_user_ptr = async->buf_int_ptr;
retval=-EINVAL;
- do_cancel_ioctl(dev, dev->read_subdev, file);
+ do_cancel(dev, async->subdev);
DPRINTK("buffer overrun\n");
break;
}
count+=n;
nbytes-=n;
- s->buf_user_ptr+=n;
- s->buf_user_count+=n;
+ async->buf_user_ptr+=n;
+ async->buf_user_count+=n;
- if(s->buf_user_ptr>=s->cur_trig.data_len ){
- s->buf_user_ptr=0;
+ if(async->buf_user_ptr>=s->cur_trig.data_len ){
+ async->buf_user_ptr=0;
}
buf+=n;
break; /* makes device work like a pipe */
}
- if(!(s->subdev_flags&SDF_RUNNING) && s->buf_int_count-s->buf_user_count==0){
+ if(!(s->subdev_flags&SDF_RUNNING) && async->buf_int_count-async->buf_user_count==0){
do_become_nonbusy(dev,s);
}
current->state=TASK_RUNNING;
*/
static void do_become_nonbusy(comedi_device *dev,comedi_subdevice *s)
{
+ comedi_async *async = s->async;
#if 0
printk("becoming non-busy\n");
#endif
}
if(s->cur_trig.data){
- if(s->cur_trig.data != s->prealloc_buf)
+ if(async == NULL || s->cur_trig.data != async->prealloc_buf)
kfree(s->cur_trig.data);
s->cur_trig.data=NULL;
}
- s->buf_user_ptr=0;
- s->buf_int_ptr=0;
- s->buf_user_count=0;
- s->buf_int_count=0;
+ async->buf_user_ptr=0;
+ async->buf_int_ptr=0;
+ async->buf_user_count=0;
+ async->buf_int_count=0;
s->busy=NULL;
}
static int comedi_close_v22(struct inode *inode,struct file *file)
{
comedi_device *dev=comedi_get_device_by_minor(MINOR(inode->i_rdev));
- comedi_subdevice *s=NULL;
+ comedi_subdevice *s = NULL;
+ comedi_async *async = NULL;
struct comedi_file_private *cfp = (struct comedi_file_private*) file->private_data;
int i;
// decrement mmap_counts
if(cfp->read_mmap_count)
{
- s = dev->subdevices + dev->read_subdev;
- s->mmap_count -= cfp->read_mmap_count;
+ async = dev->read_subdev->async;
+ async->mmap_count -= cfp->read_mmap_count;
}
if(cfp->write_mmap_count)
{
- s = dev->subdevices + dev->write_subdev;
- s->mmap_count -= cfp->write_mmap_count;
+ async = dev->write_subdev->async;
+ async->mmap_count -= cfp->write_mmap_count;
}
kfree(cfp);
void comedi_event(comedi_device *dev,comedi_subdevice *s,unsigned int mask)
{
+ comedi_async *async = s->async;
+
//DPRINTK("comedi_event %x\n",mask);
- if(s->cb_mask&mask){
+ if(async->cb_mask&mask){
if(s->runflags&SRF_USER){
- unsigned int subdev;
- subdev = s - dev->subdevices;
if(dev->rt){
#ifdef CONFIG_COMEDI_RT
// pend wake up
- if(subdev==dev->read_subdev)
+ if(s==dev->read_subdev)
comedi_rt_pend_wakeup(&dev->read_wait);
- if(subdev==dev->write_subdev)
+ if(s==dev->write_subdev)
comedi_rt_pend_wakeup(&dev->write_wait);
#else
printk("BUG: comedi_event() code unreachable\n");
#endif
}else{
- if(subdev==dev->read_subdev)
+ if(s==dev->read_subdev)
wake_up_interruptible(&dev->read_wait);
- if(subdev==dev->write_subdev)
+ if(s==dev->write_subdev)
wake_up_interruptible(&dev->write_wait);
}
}else{
- if(s->cb_func)s->cb_func(mask,s->cb_arg);
+ if(async->cb_func)async->cb_func(mask,async->cb_arg);
/* XXX bug here. If subdevice A is rt, and
* subdevice B tries to callback to a normal
* linux kernel function, it will be at the
* common, I'm not going to worry about it. */
}
}
-
+
if(mask&COMEDI_CB_EOA){
s->subdev_flags &= ~SDF_RUNNING;
}
{
int i;
comedi_subdevice *s;
+ comedi_async *async;
if(!dev->attached)
return 0;
for(i=0;i<dev->n_subdevices;i++){
s=dev->subdevices+i;
- if(s->prealloc_buf)
- rvfree(s->prealloc_buf,s->prealloc_bufsz);
+ if(s->async)
+ {
+ async = s->async;
+ rvfree(async->prealloc_buf,async->prealloc_bufsz);
+ kfree(async);
+ }
}
if(dev->driver){
memset(dev,0,sizeof(dev));
dev->minor=minor;
dev->use_count = use_count;
- dev->read_subdev=-1;
- dev->write_subdev=-1;
for(driv=comedi_drivers;driv;driv=driv->next){
if(driv->register_boards && driv->num_boards){
int i;
int have_trig;
comedi_subdevice *s;
+ comedi_async *async = NULL;
for(i=0;i<dev->n_subdevices;i++){
s=dev->subdevices+i;
s->trig[4]=command_trig;
}
if(s->do_cmd || have_trig){
- s->prealloc_bufsz=1024*128;
- }else{
- s->prealloc_bufsz=0;
- }
-
- if(s->prealloc_bufsz){
+ async = kmalloc(sizeof(comedi_async), GFP_KERNEL);
+ memset(async, 0, sizeof(comedi_async));
+ s->async = async;
+ async->subdev = s;
+ async->prealloc_bufsz=1024*128;
/* XXX */
- s->prealloc_buf=rvmalloc(s->prealloc_bufsz);
- if(!s->prealloc_buf){
+ async->prealloc_buf=rvmalloc(async->prealloc_bufsz);
+ if(!async->prealloc_buf){
printk("ENOMEM\n");
}
}
int ret;
lsampl_t new_data[2];
unsigned int chan;
-
+
chan = CR_CHAN(insn->chanspec);
memset(&new_insn,0,sizeof(new_insn));
static int command_trig(comedi_device *dev,comedi_subdevice *s,comedi_trig *it)
{
int ret;
+ comedi_async *async = s->async;
- ret=mode_to_command(&s->cmd,it);
+ ret=mode_to_command(&async->cmd,it);
if(ret)return ret;
- ret=s->do_cmdtest(dev,s,&s->cmd);
+ ret=s->do_cmdtest(dev,s,&async->cmd);
if(ret)return -EINVAL;
ret=s->do_cmd(dev,s);
#define CR_A_MODE(a) ((a)<<5)
#define CR_CW 0x80
-#define CALLBACK_ARG ((void *)(s->cb_arg))
-#define CALLBACK_FUNC ((int (*)(int,int,int,void *))(s->cb_func))
+#define CALLBACK_ARG ((void *)(s->async->cb_arg))
+#define CALLBACK_FUNC ((int (*)(int,int,int,void *))(s->async->cb_func))
static int dev_8255_attach(comedi_device * dev, comedi_devconfig * it);
static int dev_8255_detach(comedi_device * dev);
{
int i,j;
- j=s->cur_chan;
+ j=s->async->cur_chan;
for(i=0;i<n;i++){
#ifdef PCL9118_PARANOIDCHECK
if ((*dma & 0x0f00)!=devpriv->chanlist[j]) { // data dropout!
comedi_eos(dev,s);
}
}
- s->cur_chan=j;
+ s->async->cur_chan=j;
}
/*
{
int i,j;
- j=s->cur_chan;
+ j=s->async->cur_chan;
for(i=0;i<n;i++){
*data=((*dma & 0xff)<<8)|((*dma & 0xff00)>>8); // get one sample
data++; dma++;
comedi_eos(dev,s);
}
}
- s->cur_chan=j;
+ s->async->cur_chan=j;
}
/*
ptr=(sampl_t *)devpriv->dmabuf_virt[devpriv->dma_actbuf];
- if(s->buf_int_ptr+samplesinbuf*sizeof(sampl_t)>=devpriv->ai1234_data_len){
- m=(devpriv->ai1234_data_len-s->buf_int_ptr)/sizeof(sampl_t);
- if (this_board->ai_maxdata==0xfff) { move_block_from_dma_12bit(dev,s,(void *)ptr,((void *)(s->cur_trig.data))+s->buf_int_ptr,m); }
- else { move_block_from_dma_16bit(dev,s,(void *)ptr,((void *)(s->cur_trig.data))+s->buf_int_ptr,m); }
- s->buf_int_count+=m*sizeof(sampl_t);
+ if(s->async->buf_int_ptr+samplesinbuf*sizeof(sampl_t)>=devpriv->ai1234_data_len){
+ m=(devpriv->ai1234_data_len-s->async->buf_int_ptr)/sizeof(sampl_t);
+ if (this_board->ai_maxdata==0xfff) { move_block_from_dma_12bit(dev,s,(void *)ptr,((void *)(s->cur_trig.data))+s->async->buf_int_ptr,m); }
+ else { move_block_from_dma_16bit(dev,s,(void *)ptr,((void *)(s->cur_trig.data))+s->async->buf_int_ptr,m); }
+ s->async->buf_int_count+=m*sizeof(sampl_t);
ptr+=m*sizeof(sampl_t);
samplesinbuf-=m;
- s->buf_int_ptr=0;
+ s->async->buf_int_ptr=0;
comedi_eobuf(dev,s);
}
- if (this_board->ai_maxdata==0xfff) { move_block_from_dma_12bit(dev,s,(void *)ptr,((void *)(s->cur_trig.data))+s->buf_int_ptr,samplesinbuf); }
- else { move_block_from_dma_16bit(dev,s,(void *)ptr,((void *)(s->cur_trig.data))+s->buf_int_ptr,samplesinbuf); }
- s->buf_int_count+=samplesinbuf*sizeof(sampl_t);
- s->buf_int_ptr+=samplesinbuf*sizeof(sampl_t);
+ if (this_board->ai_maxdata==0xfff) { move_block_from_dma_12bit(dev,s,(void *)ptr,((void *)(s->cur_trig.data))+s->async->buf_int_ptr,samplesinbuf); }
+ else { move_block_from_dma_16bit(dev,s,(void *)ptr,((void *)(s->cur_trig.data))+s->async->buf_int_ptr,samplesinbuf); }
+ s->async->buf_int_count+=samplesinbuf*sizeof(sampl_t);
+ s->async->buf_int_ptr+=samplesinbuf*sizeof(sampl_t);
if (!devpriv->neverending_ai)
inl(dev->iobase+PCI9118_ADSTAT); // flush A/D status register
devpriv->ai1234_act_scan=0;
- s->cur_chan=0;
+ s->async->cur_chan=0;
devpriv->ai1234_buf_ptr=0;
devpriv->neverending_ai=0;
/*
==============================================================================
*/
-static int pci9118_ai_mode2(comedi_device * dev, comedi_subdevice * s, comedi_trig * it)
+static int pci9118_ai_mode2(comedi_device * dev, comedi_subdevice * s, comedi_trig * it)
{
return pci9118_ai_mode1234(2, dev, s, it);
}
*/
static int pci9118_ai_cmd(comedi_device *dev,comedi_subdevice *s)
{
- comedi_cmd *cmd=&s->cmd;
+ comedi_cmd *cmd=&s->async->cmd;
devpriv->ai1234_flags=cmd->flags;
devpriv->ai1234_n_chan=cmd->chanlist_len;
devpriv->ai_do=0;
devpriv->ai1234_act_scan=0;
- s->cur_chan=0;
+ s->async->cur_chan=0;
devpriv->ai1234_buf_ptr=0;
devpriv->neverending_ai=0;
devpriv->ai4_status=0;
if((ret=alloc_subdevices(dev))<0)
return ret;
- dev->read_subdev = 0;
s = dev->subdevices + 0;
+ dev->read_subdev = s;
s->type = COMEDI_SUBD_AI;
s->subdev_flags = SDF_READABLE|SDF_RT|SDF_COMMON|SDF_GROUND|SDF_DIFF;
if (devpriv->usemux) { s->n_chan = devpriv->usemux; }
return;
}
- *(sampl_t *)(((void *)s->cur_trig.data)+s->buf_int_ptr)=0;
- s->buf_int_ptr+=sizeof(sampl_t);
- s->buf_int_count+=sizeof(sampl_t);
- if(s->buf_int_ptr>=s->cur_trig.data_len){
- s->buf_int_ptr=0;
+ *(sampl_t *)(((void *)s->cur_trig.data)+s->async->buf_int_ptr)=0;
+ s->async->buf_int_ptr+=sizeof(sampl_t);
+ s->async->buf_int_count+=sizeof(sampl_t);
+ if(s->async->buf_int_ptr>=s->cur_trig.data_len){
+ s->async->buf_int_ptr=0;
comedi_eobuf(dev,s);
}
s->insn_bits = parport_insn_c;
s=dev->subdevices+3;
- dev->read_subdev=3;
+ dev->read_subdev=s;
if(irq){
s->type=COMEDI_SUBD_DI;
s->subdev_flags=SDF_READABLE;
static int das16_cmd_exec(comedi_device *dev,comedi_subdevice *s)
{
- comedi_cmd *cmd = &s->cmd;
+ comedi_cmd *cmd = &s->async->cmd;
char byte;
float freq;
if(devpriv->cmd_go) { /* Are we supposed to be here? */
/* check for missed conversions */
- // if( CR_CHAN(s->cur_chanlist[0]) != inb() )
+ // if( CR_CHAN(s->async->cur_chanlist[0]) != inb() )
// printk("Channel MUX sync error\n");
- for(i=0;i<s->cur_chanlist_len;++i) {
+ for(i=0;i<s->async->cur_chanlist_len;++i) {
if(i) { /* performing multiple conversions */
outb(0x00, dev->iobase+DAS16_TRIG); /* force a conversion */
msb = inb(dev->iobase+DAS16_AI_MSB);
/* all this just to put data into a buffer! */
- *(sampl_t *)(((void *)s->cur_trig.data)+s->buf_int_ptr) =
+ *(sampl_t *)(((void *)s->cur_trig.data)+s->async->buf_int_ptr) =
(lsb>>4) + (msb<<4);
-
- s->buf_int_ptr += sizeof(sampl_t);
- s->buf_int_count += sizeof(sampl_t);
-
- if(s->buf_int_ptr >= s->cur_trig.data_len) { /* buffer rollover */
- s->buf_int_ptr = 0;
+
+ s->async->buf_int_ptr += sizeof(sampl_t);
+ s->async->buf_int_count += sizeof(sampl_t);
+
+ if(s->async->buf_int_ptr >= s->cur_trig.data_len) { /* buffer rollover */
+ s->async->buf_int_ptr = 0;
comedi_eobuf(dev, s);
}
- if( !(s->cmd.flags&TRIG_WAKE_EOS) )
+ if( !(s->async->cmd.flags&TRIG_WAKE_EOS) )
comedi_bufcheck(dev, s); /* wakeup user's read() */
if(--devpriv->adc_count <= 0) { /* end of acquisition */
printk(" ( no irq )\n");
}
- dev->read_subdev=0;
s=dev->subdevices+0;
+ dev->read_subdev=s;
/* ai */
if(thisboard->ai){
s->type = COMEDI_SUBD_AI;
s->do_cmdtest = das16_cmd_test;
s->do_cmd = das16_cmd_exec;
s->cancel = das16_cancel;
- s->cmd.flags |= TRIG_WAKE_EOS;
+ s->async->cmd.flags |= TRIG_WAKE_EOS;
}else{
s->type=COMEDI_SUBD_UNUSED;
}
return -ENOMEM;
/* analog input subdevice */
- dev->read_subdev = 0;
s = dev->subdevices + 0;
+ dev->read_subdev = s;
s->type = COMEDI_SUBD_AI;
s->subdev_flags = SDF_READABLE | SDF_DIFF | SDF_GROUND;
if(thisboard->common)
/* utility function used by das1800 interrupt service routines */
inline void write_to_buffer(comedi_device *dev, comedi_subdevice *s, sampl_t data_point)
{
- if(s->buf_int_ptr >= s->prealloc_bufsz )
+ if(s->async->buf_int_ptr >= s->async->prealloc_bufsz )
{
- s->buf_int_ptr = 0;
+ s->async->buf_int_ptr = 0;
comedi_eobuf(dev, s);
}
- *((sampl_t *)((void *)s->prealloc_buf + s->buf_int_ptr)) = data_point;
- s->cur_chan++;
- if(s->cur_chan >= s->cur_chanlist_len)
+ *((sampl_t *)((void *)s->async->prealloc_buf + s->async->buf_int_ptr)) = data_point;
+ s->async->cur_chan++;
+ if(s->async->cur_chan >= s->async->cur_chanlist_len)
{
- s->cur_chan = 0;
+ s->async->cur_chan = 0;
comedi_eos(dev, s);
}
- s->buf_int_count += sizeof(sampl_t);
- s->buf_int_ptr += sizeof(sampl_t);
+ s->async->buf_int_count += sizeof(sampl_t);
+ s->async->buf_int_ptr += sizeof(sampl_t);
}
void disable_das1800(comedi_device *dev)
disable_das1800(dev);
- n = s->cmd.chanlist_len;
+ n = s->async->cmd.chanlist_len;
outb(QRAM, dev->iobase + DAS1800_SELECT); /* select QRAM for baseAddress + 0x0 */
outb(n - 1, dev->iobase + DAS1800_QRAM_ADDRESS); /*set QRAM address start */
for(i = 0; i < n; i++) /* make channel / gain list */
{
/* mask off unipolar/bipolar bit from range */
- chan_range = CR_CHAN(s->cmd.chanlist[i]) | ((CR_RANGE(s->cmd.chanlist[i]) & 0x3) << 8);
+ chan_range = CR_CHAN(s->async->cmd.chanlist[i]) | ((CR_RANGE(s->async->cmd.chanlist[i]) & 0x3) << 8);
outw(chan_range, dev->iobase + DAS1800_QRAM);
}
outb(n - 1, dev->iobase + DAS1800_QRAM_ADDRESS); /*finish write to QRAM */
* set clock source to internal or external, select analog reference,
* select unipolar / bipolar
*/
- aref = CR_AREF(s->cmd.chanlist[0]);
+ aref = CR_AREF(s->async->cmd.chanlist[0]);
conv_flags = UQEN;
if(aref != AREF_DIFF)
conv_flags |= SD;
if(aref == AREF_COMMON)
conv_flags |= CMEN;
/* if a unipolar range was selected */
- if(CR_RANGE(s->cmd.chanlist[0]) & 0x4)
+ if(CR_RANGE(s->async->cmd.chanlist[0]) & 0x4)
conv_flags |= UB;
- switch(s->cmd.scan_begin_src)
+ switch(s->async->cmd.scan_begin_src)
{
case TRIG_FOLLOW: // not in burst mode
- switch(s->cmd.convert_src)
+ switch(s->async->cmd.convert_src)
{
case TRIG_TIMER:
/* trig on cascaded counters */
conv_flags |= IPCLK;
/* set conversion frequency */
- i8253_cascade_ns_to_timer_2div(TIMER_BASE, &(devpriv->divisor1), &(devpriv->divisor2), &(s->cmd.convert_arg), s->cmd.flags & TRIG_ROUND_MASK);
+ i8253_cascade_ns_to_timer_2div(TIMER_BASE, &(devpriv->divisor1), &(devpriv->divisor2), &(s->async->cmd.convert_arg), s->async->cmd.flags & TRIG_ROUND_MASK);
if(das1800_set_frequency(dev) < 0)
{
comedi_error(dev, "Error setting up counters");
// burst mode with internal pacer clock
conv_flags |= BMDE | IPCLK;
/* set conversion frequency */
- i8253_cascade_ns_to_timer_2div(TIMER_BASE, &(devpriv->divisor1), &(devpriv->divisor2), &(s->cmd.scan_begin_arg), s->cmd.flags & TRIG_ROUND_MASK);
+ i8253_cascade_ns_to_timer_2div(TIMER_BASE, &(devpriv->divisor1), &(devpriv->divisor2), &(s->async->cmd.scan_begin_arg), s->async->cmd.flags & TRIG_ROUND_MASK);
if(das1800_set_frequency(dev) < 0)
{
comedi_error(dev, "Error setting up counters");
// set conversion rate and length for burst mode
if(conv_flags & BMDE)
{
- s->cmd.convert_arg = burst_convert_arg(s->cmd.convert_arg, s->cmd.flags & TRIG_ROUND_MASK);
- outb(s->cmd.convert_arg / 1000 - 1, dev->iobase + DAS1800_BURST_RATE);
- outb(s->cmd.chanlist_len - 1, dev->iobase + DAS1800_BURST_LENGTH);
+ s->async->cmd.convert_arg = burst_convert_arg(s->async->cmd.convert_arg, s->async->cmd.flags & TRIG_ROUND_MASK);
+ outb(s->async->cmd.convert_arg / 1000 - 1, dev->iobase + DAS1800_BURST_RATE);
+ outb(s->async->cmd.chanlist_len - 1, dev->iobase + DAS1800_BURST_LENGTH);
}
- switch(s->cmd.stop_src)
+ switch(s->async->cmd.stop_src)
{
case TRIG_COUNT:
- devpriv->count = s->cmd.stop_arg * s->cmd.chanlist_len;
+ devpriv->count = s->async->cmd.stop_arg * s->async->cmd.chanlist_len;
devpriv->forever = 0;
/* set interrupt mode */
// if they want just a few points
- if(s->cmd.stop_arg < HALF_FIFO)
+ if(s->async->cmd.stop_arg < HALF_FIFO)
devpriv->irq_dma_bits &= ~FIMD; // interrupt fifo not empty
else
devpriv->irq_dma_bits |= FIMD; //interrupt fifo half full
// enable fifo
control_a = FFEN;
- if(s->cmd.stop_src == TRIG_EXT)
+ if(s->async->cmd.stop_src == TRIG_EXT)
{
control_a |= ATEN;
// load counter 0 in mode 0
- das1800_load_counter(dev, 0, s->cmd.stop_arg & 0xffff, 0);
+ das1800_load_counter(dev, 0, s->async->cmd.stop_arg & 0xffff, 0);
}
- switch(s->cmd.start_src)
+ switch(s->async->cmd.start_src)
{
case TRIG_EXT:
control_a |= TGEN | CGSL;
das6402_ai_fifo_dregs(dev,s);
- if(s->buf_int_count >= devpriv->ai_bytes_to_read){
+ if(s->async->buf_int_count >= devpriv->ai_bytes_to_read){
outw_p(SCANL,dev->iobase+2); /* clears the fifo */
outb(0x07,dev->iobase+8); /* clears all flip-flops */
#ifdef DEBUG
data=((void *)s->cur_trig.data);
while(1){
- n=(s->cur_trig.data_len-s->buf_int_ptr)/sizeof(sampl_t);
+ n=(s->cur_trig.data_len-s->async->buf_int_ptr)/sizeof(sampl_t);
for(i=0;i<n;i++){
if(!(inb(dev->iobase+8)&0x01))
return;
*data=inw(dev->iobase);
data++;
- s->buf_int_ptr+=sizeof(sampl_t);
- s->buf_int_count+=sizeof(sampl_t);
+ s->async->buf_int_ptr+=sizeof(sampl_t);
+ s->async->buf_int_count+=sizeof(sampl_t);
}
- s->buf_int_ptr=0;
+ s->async->buf_int_ptr=0;
data=s->cur_trig.data;
comedi_eobuf(dev,s);
}
short i; /* loop index */
sampl_t dataPoint;
comedi_device *dev = d;
- comedi_subdevice *s = dev->subdevices + dev->read_subdev; /* analog input subdevice */
+ comedi_subdevice *s = dev->read_subdev; /* analog input subdevice */
+ comedi_async *async = s->async;
int status;
unsigned long irq_flags;
if(devpriv->count > 0 || devpriv->forever == 1)
{
/* write data point to buffer */
- if(s->buf_int_ptr >= s->prealloc_bufsz )
+ if(async->buf_int_ptr >= async->prealloc_bufsz )
{
- s->buf_int_ptr = 0;
+ async->buf_int_ptr = 0;
comedi_eobuf(dev, s);
}
- *((sampl_t *)((void *)s->prealloc_buf + s->buf_int_ptr)) = dataPoint;
- s->cur_chan++;
- if( s->cur_chan >= s->cur_chanlist_len )
+ *((sampl_t *)((void *)async->prealloc_buf + async->buf_int_ptr)) = dataPoint;
+ async->cur_chan++;
+ if( async->cur_chan >= async->cur_chanlist_len )
{
- s->cur_chan = 0;
+ async->cur_chan = 0;
comedi_eos(dev, s);
}
- s->buf_int_count += sizeof(sampl_t);
- s->buf_int_ptr += sizeof(sampl_t);
+ async->buf_int_count += sizeof(sampl_t);
+ async->buf_int_ptr += sizeof(sampl_t);
if(devpriv->count > 0) devpriv->count--;
}
/* read 16 bits from dev->iobase and dev->iobase + 1 */
return -ENOMEM;
/* analog input subdevice */
- dev->read_subdev = 0;
s = dev->subdevices + 0;
+ dev->read_subdev = s;
s->type = COMEDI_SUBD_AI;
s->subdev_flags = SDF_READABLE;
s->n_chan = 8;
int startChan, endChan, scan, gain;
int conv_bits;
unsigned long irq_flags;
+ comedi_async *async = s->async;
if(!dev->irq)
{
disable_das800(dev);
/* set channel scan limits */
- startChan = CR_CHAN(s->cmd.chanlist[0]);
- endChan = (startChan + s->cmd.chanlist_len - 1) % 8;
+ startChan = CR_CHAN(async->cmd.chanlist[0]);
+ endChan = (startChan + async->cmd.chanlist_len - 1) % 8;
scan = (endChan << 3) | startChan;
comedi_spin_lock_irqsave(&devpriv->spinlock, irq_flags);
comedi_spin_unlock_irqrestore(&devpriv->spinlock, irq_flags);
/* set gain */
- gain = CR_RANGE(s->cmd.chanlist[0]);
+ gain = CR_RANGE(async->cmd.chanlist[0]);
if( gain > 0)
gain += 0x7;
gain &= 0xf;
outb(gain, dev->iobase + DAS800_GAIN);
- switch(s->cmd.stop_src)
+ switch(async->cmd.stop_src)
{
case TRIG_COUNT:
- devpriv->count = s->cmd.stop_arg * s->cmd.chanlist_len;
+ devpriv->count = async->cmd.stop_arg * async->cmd.chanlist_len;
devpriv->forever = 0;
break;
case TRIG_NONE:
*/
conv_bits = 0;
conv_bits |= EACS | IEOC;
- if(s->cmd.start_src == TRIG_EXT)
+ if(async->cmd.start_src == TRIG_EXT)
conv_bits |= DTEN;
- switch(s->cmd.convert_src)
+ switch(async->cmd.convert_src)
{
case TRIG_TIMER:
conv_bits |= CASC | ITE;
/* set conversion frequency */
- i8253_cascade_ns_to_timer_2div(TIMER_BASE, &(devpriv->divisor1), &(devpriv->divisor2), &(s->cmd.convert_arg), s->cmd.flags & TRIG_ROUND_MASK);
+ i8253_cascade_ns_to_timer_2div(TIMER_BASE, &(devpriv->divisor1), &(devpriv->divisor2), &(async->cmd.convert_arg), async->cmd.flags & TRIG_ROUND_MASK);
if(das800_set_frequency(dev) < 0)
{
comedi_error(dev, "Error setting up counters");
static int dt2814_ai_cmd(comedi_device *dev,comedi_subdevice *s)
{
- comedi_cmd *cmd = &s->cmd;
+ comedi_cmd *cmd = &s->async->cmd;
int chan;
int trigvar;
if((ret=alloc_private(dev,sizeof(dt2814_private)))<0)
return ret;
- dev->read_subdev = 0;
s=dev->subdevices+0;
+ dev->read_subdev = s;
s->type=COMEDI_SUBD_AI;
s->subdev_flags=SDF_READABLE;
s->n_chan=16; /* XXX */
unsigned int n;
n=n_bytes;
- if(s->buf_int_ptr+n >= s->cur_trig.data_len){
- n=s->cur_trig.data_len-s->buf_int_ptr;
- memcpy(((void *)(s->cur_trig.data))+s->buf_int_ptr,buf,n);
+ if(s->async->buf_int_ptr+n >= s->cur_trig.data_len){
+ n=s->cur_trig.data_len-s->async->buf_int_ptr;
+ memcpy(((void *)(s->cur_trig.data))+s->async->buf_int_ptr,buf,n);
buf+=n;
- s->buf_int_count+=n;
- s->buf_int_ptr=0;
+ s->async->buf_int_count+=n;
+ s->async->buf_int_ptr=0;
n=n_bytes-n;
}
- memcpy(((void *)(s->cur_trig.data))+s->buf_int_ptr,buf,n);
+ memcpy(((void *)(s->cur_trig.data))+s->async->buf_int_ptr,buf,n);
buf+=n;
- s->buf_int_count+=n;
- s->buf_int_ptr+=n;
+ s->async->buf_int_count+=n;
+ s->async->buf_int_ptr+=n;
}
static int copy_from_buf(comedi_device *dev,comedi_subdevice *s,void *buf,unsigned int n_bytes)
{
unsigned int n,m;
- n=s->buf_int_count-s->buf_user_count;
+ n=s->async->buf_int_count-s->async->buf_user_count;
if(n==0)return 0;
if(n>n_bytes)
n=n_bytes;
n_bytes=n;
- if(s->buf_int_ptr+n >= s->cur_trig.data_len){
- m=s->cur_trig.data_len-s->buf_int_ptr;
- memcpy(buf,((void *)(s->cur_trig.data))+s->buf_int_ptr,m);
+ if(s->async->buf_int_ptr+n >= s->cur_trig.data_len){
+ m=s->cur_trig.data_len-s->async->buf_int_ptr;
+ memcpy(buf,((void *)(s->cur_trig.data))+s->async->buf_int_ptr,m);
buf+=m;
- s->buf_int_count+=m;
- s->buf_int_ptr=0;
+ s->async->buf_int_count+=m;
+ s->async->buf_int_ptr=0;
n-=m;
}
- memcpy(buf,((void *)(s->cur_trig.data))+s->buf_int_ptr,n);
- s->buf_int_count+=n;
- s->buf_int_ptr+=n;
+ memcpy(buf,((void *)(s->cur_trig.data))+s->async->buf_int_ptr,n);
+ s->async->buf_int_count+=n;
+ s->async->buf_int_ptr+=n;
return n_bytes;
}
if(devpriv->ad_2scomp){
data^=1<<(boardtype.adbits-1);
}
- s->cur_trig.data[s->buf_int_ptr++]=data;
+ s->cur_trig.data[s->async->buf_int_ptr++]=data;
devpriv->nread--;
if(!devpriv->nread){
static int dt282x_ai_cmd(comedi_device * dev, comedi_subdevice * s)
{
- comedi_cmd *cmd=&s->cmd;
+ comedi_cmd *cmd=&s->async->cmd;
int timer;
timer=dt282x_ns_to_timer(&cmd->convert_arg,TRIG_ROUND_NEAREST);
{
int size;
int timer;
- comedi_cmd *cmd=&s->cmd;
+ comedi_cmd *cmd=&s->async->cmd;
devpriv->supcsr = DT2821_ERRINTEN | DT2821_DS1 | DT2821_DDMA;
update_supcsr(DT2821_CLRDMADNE | DT2821_BUFFB | DT2821_DACINIT);
s=dev->subdevices+0;
- dev->read_subdev=0;
+ dev->read_subdev=s;
/* ai subdevice */
s->type=COMEDI_SUBD_AI;
s->subdev_flags=SDF_READABLE|((it->options[opt_diff])?SDF_DIFF:SDF_COMMON);
s++;
if((s->n_chan=boardtype.dachan)){
- dev->write_subdev=1;
/* ao subsystem */
s->type=COMEDI_SUBD_AO;
+ dev->write_subdev=s;
s->subdev_flags=SDF_WRITEABLE;
#ifdef CONFIG_COMEDI_MODE0
s->trig[0]=dt282x_ao;
int chor,chcr,mcr,dcr,lkcr;
for(i=0;i<MITE_RING_SIZE;i++){
- n=s->prealloc_bufsz-s->buf_int_ptr;
- n=mite_kvmem_segment_load(mite,i,((void *)s->cur_trig.data)+s->buf_int_ptr,n);
- s->buf_int_ptr+=n;
- if(s->buf_int_ptr>=s->prealloc_bufsz)
- s->buf_int_ptr=0;
+ n=s->async->prealloc_bufsz-s->async->buf_int_ptr;
+ n=mite_kvmem_segment_load(mite,i,((void *)s->cur_trig.data)+s->async->buf_int_ptr,n);
+ s->async->buf_int_ptr+=n;
+ if(s->async->buf_int_ptr>=s->async->prealloc_bufsz)
+ s->async->buf_int_ptr=0;
}
chor = CHOR_DMARESET | CHOR_FRESET;
// printk("atmio16d_interrupt!\n");
- *(sampl_t *)(((void *)s->cur_trig.data)+s->buf_int_ptr) = inw(dev->iobase+AD_FIFO_REG);
- s->buf_int_ptr += sizeof(sampl_t);
- s->buf_int_count += sizeof(sampl_t);
-
- if((++s->cur_chan) >= s->cur_chanlist_len) { /* one scan done */
- s->cur_chan = 0;
+ *(sampl_t *)(((void *)s->cur_trig.data)+s->async->buf_int_ptr) = inw(dev->iobase+AD_FIFO_REG);
+ s->async->buf_int_ptr += sizeof(sampl_t);
+ s->async->buf_int_count += sizeof(sampl_t);
+
+ if((++s->async->cur_chan) >= s->async->cur_chanlist_len) { /* one scan done */
+ s->async->cur_chan = 0;
comedi_eos(dev, s);
}
- if (s->buf_int_ptr >= s->cur_trig.data_len) { /* buffer rollover */
- s->buf_int_ptr = 0;
+ if (s->async->buf_int_ptr >= s->cur_trig.data_len) { /* buffer rollover */
+ s->async->buf_int_ptr = 0;
comedi_eobuf(dev, s);
}
}
if(!cmd->stop_src && tmp!=cmd->stop_src)err++;
if(err)return 1;
-
+
/* step 2: make sure trigger sources are unique and mutually compatible */
/* note that mutual compatiblity is not an issue here */
if(cmd->scan_begin_src!=TRIG_FOLLOW &&
cmd->stop_src!=TRIG_NONE)err++;
if(err)return 2;
-
-
+
+
/* step 3: make sure arguments are trivially compatible */
if(cmd->start_arg!=0){
}
#endif
}
-
+
if(cmd->convert_arg<10000){
cmd->convert_arg=10000;
err++;
}
-
-
+
+
#if 0
if(cmd->convert_arg>SLOWEST_TIMER){
cmd->convert_arg=SLOWEST_TIMER;
static int atmio16d_ai_cmd(comedi_device *dev, comedi_subdevice *s)
{
- comedi_cmd *cmd = &s->cmd;
+ comedi_cmd *cmd = &s->async->cmd;
unsigned int timer, base_clock;
unsigned int sample_count, tmp, chan, gain;
int i;
-#ifdef DEBUG1
+#ifdef DEBUG1
printk("atmio16d_ai_cmd\n");
#endif
/* This is slowly becoming a working command interface. *
* It is still uber-experimental */
-
+
reset_counters(dev);
- s->cur_chan = 0;
+ s->async->cur_chan = 0;
/* check if scanning multiple channels */
if(cmd->chanlist_len < 2) {
devpriv->dac1_coding = it->options[12];
- dev->read_subdev = 0;
/* setup sub-devices */
s=dev->subdevices+0;
+ dev->read_subdev = s;
/* ai subdevice */
s->type=COMEDI_SUBD_AI;
s->subdev_flags=SDF_READABLE;
unsigned int mask;
mask=(1<<boardtype.adbits)-1;
- j=s->cur_chan;
+ j=s->async->cur_chan;
for(i=0;i<n;i++){
d=ni_readw(ADC_FIFO_Data_Register);
d^=devpriv->ai_xorlist[j];
d&=mask;
data[i]=d;
j++;
- if(j>=s->cur_chanlist_len){
+ if(j>=s->async->cur_chanlist_len){
j=0;
//s->event_mask |= COMEDI_CB_EOS;
}
}
- s->cur_chan=j;
+ s->async->cur_chan=j;
}
#ifdef TRY_DMA
ignore them.
*/
-
+
n=boardtype.ai_fifo_depth/2;
/* this makes the assumption that the buffer length is
greater than the half-fifo depth. */
- if(s->buf_int_ptr+n*sizeof(sampl_t)>=s->cur_trig.data_len){
- m=(s->cur_trig.data_len-s->buf_int_ptr)/sizeof(sampl_t);
- ni_ai_fifo_read(dev,s,((void *)(s->cur_trig.data))+s->buf_int_ptr,m);
- s->buf_int_count+=m*sizeof(sampl_t);
+ if(s->async->buf_int_ptr+n*sizeof(sampl_t)>=s->cur_trig.data_len){
+ m=(s->cur_trig.data_len-s->async->buf_int_ptr)/sizeof(sampl_t);
+ ni_ai_fifo_read(dev,s,((void *)(s->cur_trig.data))+s->async->buf_int_ptr,m);
+ s->async->buf_int_count+=m*sizeof(sampl_t);
n-=m;
- s->buf_int_ptr=0;
+ s->async->buf_int_ptr=0;
comedi_eobuf(dev,s);
}
- ni_ai_fifo_read(dev,s,((void *)(s->cur_trig.data))+s->buf_int_ptr,n);
- s->buf_int_count+=n*sizeof(sampl_t);
- s->buf_int_ptr+=n*sizeof(sampl_t);
+ ni_ai_fifo_read(dev,s,((void *)(s->cur_trig.data))+s->async->buf_int_ptr,n);
+ s->async->buf_int_count+=n*sizeof(sampl_t);
+ s->async->buf_int_ptr+=n*sizeof(sampl_t);
comedi_bufcheck(dev,s);
}
*/
mask=(1<<boardtype.adbits)-1;
- j=s->cur_chan;
- data=((void *)s->cur_trig.data)+s->buf_int_ptr;
+ j=s->async->cur_chan;
+ data=((void *)s->cur_trig.data)+s->async->buf_int_ptr;
while(1){
- n=(s->cur_trig.data_len-s->buf_int_ptr)/sizeof(sampl_t);
+ n=(s->cur_trig.data_len-s->async->buf_int_ptr)/sizeof(sampl_t);
for(i=0;i<n;i++){
if(ni_readw(AI_Status_1)&AI_FIFO_Empty_St){
- s->cur_chan=j;
+ s->async->cur_chan=j;
return;
}
d=ni_readw(ADC_FIFO_Data_Register);
d&=mask;
*data=d;
j++;
- if(j>=s->cur_chanlist_len){
+ if(j>=s->async->cur_chanlist_len){
j=0;
//s->event_mask |= COMEDI_CB_EOS;
}
data++;
- s->buf_int_ptr+=sizeof(sampl_t);
- s->buf_int_count+=sizeof(sampl_t);
+ s->async->buf_int_ptr+=sizeof(sampl_t);
+ s->async->buf_int_count+=sizeof(sampl_t);
}
- s->buf_int_ptr=0;
+ s->async->buf_int_ptr=0;
data=s->cur_trig.data;
comedi_eobuf(dev,s);
}
int i;
int chan;
int wsave;
-
+
wsave=win_save();
win_out(1,ADC_FIFO_Clear);
/* interrupt on errors */
win_out(0x0020,Interrupt_A_Enable_Register) ;
-
+
for(chan=0;chan<it->n_chan;chan++){
ni_load_channelgain_list(dev,1,it->chanlist+chan,(it->flags&TRIG_DITHER)==TRIG_DITHER);
#if 0
win_out(1,AI_Command_1_Register);
-
+
/* I don't know how long it takes to access the bus,
so shorter loops might cause timeouts */
for(i=0;i<NI_TIMEOUT;i++){
int i,n;
int wsave;
unsigned int mask,sign;
-
+
wsave=win_save();
win_out(1,ADC_FIFO_Clear);
/* interrupt on errors */
win_out(0x0020,Interrupt_A_Enable_Register) ;
-
+
//ni_load_channelgain_list(dev,1,&insn->chanspec,(insn->flags&TRIG_DITHER)==TRIG_DITHER);
ni_load_channelgain_list(dev,1,&insn->chanspec,0);
}else{
devpriv->changain_state=0;
}
-
+
win_out(1,Configuration_Memory_Clear);
sign=1<<(boardtype.adbits-1);
chan=CR_CHAN(list[i]);
range=CR_RANGE(list[i]);
aref=CR_AREF(list[i]);
-
+
/* fix the external/internal range differences */
range=ni_gainlkup[boardtype.gainlkup][range];
devpriv->ai_xorlist[i]=(range<8)?sign:0;
static int ni_ai_cmd(comedi_device *dev,comedi_subdevice *s)
{
int wsave;
- comedi_cmd *cmd=&s->cmd;
+ comedi_cmd *cmd=&s->async->cmd;
int timer;
int mode1=0; /* mode1 is needed for both stop and convert */
int mode2=0;
mode1 |= AI_Start_Stop | AI_Mode_1_Reserved | AI_Trigger_Once;
win_out(mode1,AI_Mode_1_Register);
-
+
/* load SC (Scan Count) */
win_out(AI_SC_Load,AI_Command_1_Register);
/* stage number of scans */
win_out(0,AI_SC_Load_A_Registers);
win_out(0,AI_SC_Load_A_Registers+1);
-
+
mode1 |= AI_Start_Stop | AI_Mode_1_Reserved | AI_Continuous;
win_out(mode1,AI_Mode_1_Register);
AI_START_STOP_Select_Register:
AI_START_Polarity=0 (?) rising edge
AI_START_Edge=1 edge triggered
- AI_START_Sync=1 (?)
+ AI_START_Sync=1 (?)
AI_START_Select=0 SI_TC
AI_STOP_Polarity=0 rising edge
AI_STOP_Edge=0 level
- AI_STOP_Sync=1
+ AI_STOP_Sync=1
AI_STOP_Select=19 external pin (configuration mem)
*/
win_out(AI_START_Edge|AI_START_Sync|
AI_Error_Interrupt_Enable|
AI_SC_TC_Interrupt_Enable;
- if(s->cb_mask&COMEDI_CB_EOS){
+ if(s->async->cb_mask&COMEDI_CB_EOS){
/* wake on end-of-scan */
devpriv->aimode=AIMODE_SCAN;
}else{
/* end configuration */
win_out(AI_Configuration_End,Joint_Reset_Register);
-
+
switch(cmd->scan_begin_src){
case TRIG_TIMER:
/* AI_SI2_Arm, AI_SI_Arm, AI_DIV_Arm, AI_SC_Arm */
trigvar1 = ni_ns_to_timer(&it->trigvar1,TRIG_ROUND_NEAREST);
ni_load_channelgain_list(dev,it->n_chan,it->chanlist,(it->flags&TRIG_DITHER)==TRIG_DITHER);
-
+
/* start configuration */
win_out(AI_Configuration_Start,Joint_Reset_Register);
win_out((it->n-1)&0xffff,AI_SC_Load_A_Registers+1);
win_out(0x000d,AI_Mode_1_Register);
}
-
+
/* load SC (Scan Count) */
win_out(0x20,AI_Command_1_Register);
-
+
/*
AI_SI_Special_Trigger_Delay=0
AI_Pre_Trigger=0
AI_START_STOP_Select_Register:
AI_START_Polarity=0 (?) rising edge
AI_START_Edge=1 edge triggered
- AI_START_Sync=1 (?)
+ AI_START_Sync=1 (?)
AI_START_Select=0 SI_TC
AI_STOP_Polarity=0 rising edge
AI_STOP_Edge=0 level
- AI_STOP_Sync=1
+ AI_STOP_Sync=1
AI_STOP_Select=19 external pin (configuration mem)
*/
win_out(AI_START_Edge|AI_START_Sync|
AI_SC_TC_Interrupt_Enable;
//bits|=Pass_Thru_0_Interrupt_Enable;
- if(s->cb_mask&COMEDI_CB_EOS){
+ if(s->async->cb_mask&COMEDI_CB_EOS){
/* wake on end-of-scan */
devpriv->aimode=AIMODE_SCAN;
}else{
}
#ifdef PCIDMA
-#if 0
+#if 0
Strobes_Register
AI_AO_Select_Register
Interrupt_B_Enable_Register MSC_Pass_thru
#endif
/* end configuration */
win_out(AI_Configuration_End,Joint_Reset_Register);
-
+
/* AI_SI2_Arm, AI_SI_Arm, AI_DIV_Arm, AI_SC_Arm */
win_out(0x1540,AI_Command_1_Register);
trigvar1 = ni_ns_to_timer(&it->trigvar1,TRIG_ROUND_NEAREST);
ni_load_channelgain_list(dev,it->n_chan,it->chanlist,(it->flags&TRIG_DITHER)==TRIG_DITHER);
-
+
/* start configuration */
win_out(AI_Configuration_Start,Joint_Reset_Register);
win_out((it->n-1)&0xffff,AI_SC_Load_A_Registers+1);
win_out(0x000d,AI_Mode_1_Register);
}
-
+
/* load SC (Scan Count) */
win_out(0x20,AI_Command_1_Register);
-
+
/*
AI_SI_Special_Trigger_Delay=0
AI_Pre_Trigger=0
AI_START_STOP_Select_Register:
AI_START_Polarity=0 (?) rising edge
AI_START_Edge=1 edge triggered
- AI_START_Sync=1 (?)
+ AI_START_Sync=1 (?)
AI_START_Select=1 PFI0
AI_STOP_Polarity=0 rising edge
AI_STOP_Edge=0 level
- AI_STOP_Sync=1
+ AI_STOP_Sync=1
AI_STOP_Select=19 external pin (configuration mem)
*/
win_out(AI_START_Edge|AI_START_Sync|AI_START_Select(1)|
AI_STOP_Select(19)|AI_STOP_Sync,
AI_START_STOP_Select_Register);
-
+
#if 0
win_out((it->trigvar>>16),AI_SI_Load_A_Registers);
win_out((it->trigvar&0xffff),AI_SI_Load_A_Registers+1);
/* interrupt on FIFO, errors, SC_TC */
bits=0x00a1;
- if(s->cb_mask&COMEDI_CB_EOS){
+ if(s->async->cb_mask&COMEDI_CB_EOS){
/* wake on end-of-scan */
devpriv->aimode=AIMODE_SCAN;
}else{
/* XXX start polling if necessary */
}
-
+
/* end configuration */
win_out(AI_Configuration_End,Joint_Reset_Register);
{
int n,m;
- n=(s->buf_int_count-s->buf_user_count)/sizeof(sampl_t);
+ n=(s->async->buf_int_count-s->async->buf_user_count)/sizeof(sampl_t);
if(n==0)return 0;
if(n>boardtype.ao_fifo_depth/2)
n=boardtype.ao_fifo_depth/2;
- if(s->buf_int_ptr+n*sizeof(sampl_t)>s->cur_trig.data_len){
- m=(s->cur_trig.data_len-s->buf_int_ptr)/sizeof(sampl_t);
- ni_ao_fifo_load(dev,s,((void *)(s->cur_trig.data))+s->buf_int_ptr,m);
- s->buf_int_count+=m*sizeof(sampl_t);
- s->buf_int_ptr=0;
+ if(s->async->buf_int_ptr+n*sizeof(sampl_t)>s->cur_trig.data_len){
+ m=(s->cur_trig.data_len-s->async->buf_int_ptr)/sizeof(sampl_t);
+ ni_ao_fifo_load(dev,s,((void *)(s->cur_trig.data))+s->async->buf_int_ptr,m);
+ s->async->buf_int_count+=m*sizeof(sampl_t);
+ s->async->buf_int_ptr=0;
n-=m;
}
- ni_ao_fifo_load(dev,s,((void *)(s->cur_trig.data))+s->buf_int_ptr,n);
- s->buf_int_count+=n*sizeof(sampl_t);
- s->buf_int_ptr+=n*sizeof(sampl_t);
+ ni_ao_fifo_load(dev,s,((void *)(s->cur_trig.data))+s->async->buf_int_ptr,n);
+ s->async->buf_int_count+=n*sizeof(sampl_t);
+ s->async->buf_int_ptr+=n*sizeof(sampl_t);
comedi_bufcheck(dev,s);
win_out(0,DAC_FIFO_Clear);
/* load some data */
- n=(s->buf_int_count-s->buf_user_count)/sizeof(sampl_t);
+ n=(s->async->buf_int_count-s->async->buf_user_count)/sizeof(sampl_t);
if(n==0)return 0;
if(n>boardtype.ao_fifo_depth)
n=boardtype.ao_fifo_depth;
- ni_ao_fifo_load(dev,s,((void *)(s->cur_trig.data))+s->buf_int_ptr,n);
- s->buf_int_count+=n*sizeof(sampl_t);
- s->buf_int_ptr+=n*sizeof(sampl_t);
+ ni_ao_fifo_load(dev,s,((void *)(s->cur_trig.data))+s->async->buf_int_ptr,n);
+ s->async->buf_int_count+=n*sizeof(sampl_t);
+ s->async->buf_int_ptr+=n*sizeof(sampl_t);
return n;
}
chan=CR_CHAN(insn->chanspec);
conf=chan<<8;
-
+
/* XXX check range with current range in flaglist[chan] */
/* should update calibration if range changes (ick) */
conf |= (range&1)^1;
}
conf |= (range&2)<<1;
-
+
#if 0
/* XXX oops. forgot flags in insn! */
/* not all boards can deglitch, but this shouldn't hurt */
if(((range&1)==0) || !boardtype.ao_unipolar)
dat^=(1<<(boardtype.aobits-1));
-
+
ni_writew(dat,(chan)? DAC1_Direct_Data : DAC0_Direct_Data);
return 1;
static int ni_ao_cmd(comedi_device *dev,comedi_subdevice *s)
{
- comedi_cmd *cmd = &s->cmd;
+ comedi_cmd *cmd = &s->async->cmd;
unsigned int conf;
unsigned int chan;
unsigned int range;
/* analog input subdevice */
- dev->read_subdev=0;
s=dev->subdevices+0;
+ dev->read_subdev=s;
s->type=COMEDI_SUBD_AI;
s->subdev_flags=SDF_READABLE|SDF_RT|SDF_GROUND|SDF_COMMON|SDF_DIFF|SDF_OTHER;
s->subdev_flags|=SDF_DITHER;
s->do_cmdtest=ni_ai_cmdtest;
s->do_cmd=ni_ai_cmd;
s->cancel=ni_ai_reset;
-
+
/* analog output subdevice */
/* XXX what about boards without ao? */
- dev->write_subdev=1;
s=dev->subdevices+1;
+ dev->write_subdev=s;
if(boardtype.n_aochan){
s->type=COMEDI_SUBD_AO;
s->subdev_flags=SDF_WRITEABLE|SDF_RT|SDF_DEGLITCH|SDF_GROUND|SDF_OTHER;
conv_finish:
- s->cur_trig.data[s->buf_int_ptr++] = ((hi << 8) | inb(dev->iobase + PCL812_AD_LO)) & 0xfff;
+ s->cur_trig.data[s->async->buf_int_ptr++] = ((hi << 8) | inb(dev->iobase + PCL812_AD_LO)) & 0xfff;
outb(0, dev->iobase + PCL812_CLRINT); /* clear INT request */
- s->buf_int_count += sizeof(sampl_t);
+ s->async->buf_int_count += sizeof(sampl_t);
if ((++devpriv->int13_act_chan) >= s->cur_trig.n_chan) { /* one scan done */
devpriv->int13_act_chan = 0;
outb(CR_CHAN(s->cur_trig.chanlist[devpriv->int13_act_chan]), dev->iobase + PCL812_MUX); /* select next channel */
}
- if (s->buf_int_ptr >= s->cur_trig.data_len) { /* buffer rollover */
- s->buf_int_ptr = 0;
+ if (s->async->buf_int_ptr >= s->cur_trig.data_len) { /* buffer rollover */
+ s->async->buf_int_ptr = 0;
//devpriv->int13_act_ptr=0;
comedi_eobuf(dev, s);
}
comedi_error_done(dev,s);
return;
}
- s->buf_int_ptr+=sizeof(sampl_t);
- s->buf_int_count+=sizeof(sampl_t);
+ s->async->buf_int_ptr+=sizeof(sampl_t);
+ s->async->buf_int_count+=sizeof(sampl_t);
if (++devpriv->act_chanlist_pos>=devpriv->act_chanlist_len) devpriv->act_chanlist_pos=0;
if ((++devpriv->int13_act_chan)>=s->cur_trig.n_chan) { /* one scan done */
devpriv->int13_act_chan=0;
- if (s->cur_trig.flags & TRIG_WAKE_EOS) { comedi_eos(dev,s); }
+ if (s->cur_trig.flags & TRIG_WAKE_EOS) { comedi_eos(dev,s); }
else { comedi_bufcheck(dev,s); }
// rt_printk("E");
devpriv->int13_act_scan++;
}
- if (s->buf_int_ptr>=s->cur_trig.data_len) { /* buffer rollover */
- s->buf_int_ptr=0;
+ if (s->async->buf_int_ptr>=s->cur_trig.data_len) { /* buffer rollover */
+ s->async->buf_int_ptr=0;
devpriv->buf_ptr=0;
//printk("B ");
- comedi_eobuf(dev,s);
+ comedi_eobuf(dev,s);
}
if (!devpriv->neverending_ai)
if ( devpriv->int13_act_scan>=s->cur_trig.n ) { /* all data sampled */
pcl818_ai_cancel(dev,s);
- comedi_done(dev,s);
+ comedi_done(dev,s);
return;
}
}
-/*
+/*
==============================================================================
analog input dma mode 1 & 3, 818 cards
*/
-static void interrupt_pcl818_ai_mode13_dma(int irq, void *d, struct pt_regs *regs)
+static void interrupt_pcl818_ai_mode13_dma(int irq, void *d, struct pt_regs *regs)
{
comedi_device *dev = d;
comedi_subdevice *s = dev->subdevices + 0;
int i,len,bufptr;
unsigned long flags;
sampl_t *ptr;
-
+
disable_dma(devpriv->dma);
devpriv->next_dma_buf=1-devpriv->next_dma_buf;
if ((devpriv->dma_runs_to_end)>-1) { // switch dma bufs
s->cur_trig.data[devpriv->buf_ptr++]=ptr[bufptr++] >> 4; // get one sample
- s->buf_int_ptr+=sizeof(sampl_t);
- s->buf_int_count+=sizeof(sampl_t);
+ s->async->buf_int_ptr+=sizeof(sampl_t);
+ s->async->buf_int_count+=sizeof(sampl_t);
devpriv->act_chanlist_pos++;
if (devpriv->act_chanlist_pos>=devpriv->act_chanlist_len) devpriv->act_chanlist_pos=0;
devpriv->int13_act_scan++;
}
- if (s->buf_int_ptr>=s->cur_trig.data_len) { /* buffer rollover */
- s->buf_int_ptr=0;
+ if (s->async->buf_int_ptr>=s->cur_trig.data_len) { /* buffer rollover */
+ s->async->buf_int_ptr=0;
devpriv->buf_ptr=0;
- comedi_eobuf(dev,s);
+ comedi_eobuf(dev,s);
}
if (!devpriv->neverending_ai)
if ( devpriv->int13_act_scan>=s->cur_trig.n ) { /* all data sampled */
pcl818_ai_cancel(dev,s);
- comedi_done(dev,s);
- // printk("done int ai13 dma\n");
+ comedi_done(dev,s);
+ // printk("done int ai13 dma\n");
return;
}
}
-
+
if (len>0) comedi_bufcheck(dev,s);
}
-/*
+/*
==============================================================================
analog input dma mode 1 & 3 over RTC, 818 cards
*/
-static void interrupt_pcl818_ai_mode13_dma_rtc(int irq, void *d, struct pt_regs *regs)
+static void interrupt_pcl818_ai_mode13_dma_rtc(int irq, void *d, struct pt_regs *regs)
{
comedi_device *dev = d;
comedi_subdevice *s = dev->subdevices + 0;
sampl_t *dmabuf=(sampl_t *)devpriv->dmabuf[0];
//outb(2,0x378);
- switch(devpriv->int818_mode) {
+ switch(devpriv->int818_mode) {
case INT_TYPE_AI1_DMA_RTC:
case INT_TYPE_AI3_DMA_RTC:
tmp = (CMOS_READ(RTC_INTR_FLAGS) & 0xF0);
if (ofs_dats<0) ofs_dats=(devpriv->dmasamplsize)+ofs_dats;
if (!ofs_dats) return; // exit=no new samples from last call
// obsluz data
- i=devpriv->last_top_dma-1;
+ i=devpriv->last_top_dma-1;
i&=(devpriv->dmasamplsize-1);
if (dmabuf[i]!=MAGIC_DMA_WORD) { // DMA overflow!
return;
}
//rt_printk("r %ld ",ofs_dats);
-
+
bufptr=devpriv->last_top_dma;
-
+
for (i=0; i<ofs_dats; i++) {
if ((dmabuf[bufptr] & 0xf)!=devpriv->act_chanlist[devpriv->act_chanlist_pos]) { // dropout!
rt_printk("comedi: A/D mode1/3 DMA - channel dropout %d!=%d !\n",(dmabuf[bufptr] & 0xf),devpriv->act_chanlist[devpriv->act_chanlist_pos]);
comedi_error_done(dev,s);
return;
}
-
+
s->cur_trig.data[devpriv->buf_ptr++]=dmabuf[bufptr++] >> 4; // get one sample
bufptr&=(devpriv->dmasamplsize-1);
- s->buf_int_ptr+=sizeof(sampl_t);
- s->buf_int_count+=sizeof(sampl_t);
+ s->async->buf_int_ptr+=sizeof(sampl_t);
+ s->async->buf_int_count+=sizeof(sampl_t);
devpriv->act_chanlist_pos++;
if (devpriv->act_chanlist_pos>=devpriv->act_chanlist_len) devpriv->act_chanlist_pos=0;
devpriv->int13_act_scan++;
}
- if (s->buf_int_ptr>=s->cur_trig.data_len) { /* buffer rollover */
- s->buf_int_ptr=0;
+ if (s->async->buf_int_ptr>=s->cur_trig.data_len) { /* buffer rollover */
+ s->async->buf_int_ptr=0;
devpriv->buf_ptr=0;
- comedi_eobuf(dev,s);
+ comedi_eobuf(dev,s);
}
if (!devpriv->neverending_ai)
if ( devpriv->int13_act_scan>=s->cur_trig.n ) { /* all data sampled */
pcl818_ai_cancel(dev,s);
- comedi_done(dev,s);
- //printk("done int ai13 dma\n");
+ comedi_done(dev,s);
+ //printk("done int ai13 dma\n");
return;
}
}
- devpriv->last_top_dma=bufptr;
+ devpriv->last_top_dma=bufptr;
bufptr--;
bufptr&=(devpriv->dmasamplsize-1);
dmabuf[bufptr]=MAGIC_DMA_WORD;
}
-/*
+/*
==============================================================================
analog input interrupt mode 1 & 3, 818HD/HG cards
*/
-static void interrupt_pcl818_ai_mode13_fifo(int irq, void *d, struct pt_regs *regs)
+static void interrupt_pcl818_ai_mode13_fifo(int irq, void *d, struct pt_regs *regs)
{
comedi_device *dev = d;
comedi_subdevice *s = dev->subdevices + 0;
int i,len,lo;
-
+
outb(0, dev->iobase + PCL818_FI_INTCLR); // clear fifo int request
lo=inb(dev->iobase + PCL818_FI_STATUS);
comedi_error_done(dev,s);
return;
}
-
+
if (lo&2) { len=512; }
else { len=0; }
-
+
for (i=0;i<len;i++) {
lo=inb(dev->iobase + PCL818_FI_DATALO);
if ((lo & 0xf)!=devpriv->act_chanlist[devpriv->act_chanlist_pos]) { // dropout!
}
s->cur_trig.data[devpriv->buf_ptr++]=(lo >> 4)|(inb(dev->iobase + PCL818_FI_DATAHI) << 4); // get one sample
- s->buf_int_ptr+=sizeof(sampl_t);
- s->buf_int_count+=sizeof(sampl_t);
+ s->async->buf_int_ptr+=sizeof(sampl_t);
+ s->async->buf_int_count+=sizeof(sampl_t);
devpriv->act_chanlist_pos++;
if (devpriv->act_chanlist_pos>=devpriv->act_chanlist_len) devpriv->act_chanlist_pos=0;
devpriv->int13_act_scan++;
}
- if (s->buf_int_ptr>=s->cur_trig.data_len) { /* buffer rollover */
- s->buf_int_ptr=0;
+ if (s->async->buf_int_ptr>=s->cur_trig.data_len) { /* buffer rollover */
+ s->async->buf_int_ptr=0;
devpriv->buf_ptr=0;
comedi_eobuf(dev,s);
}
return -ENOMEM;
s=dev->subdevices+0;
- dev->read_subdev=0;
+ //dev->read_subdev=s;
/* analog input subdevice */
s->type=COMEDI_SUBD_AI;
s->subdev_flags=SDF_READABLE;
s->insn_read = &skel_ai_rinsn;
//s->do_cmd = &skel_ai_cmd;
s->do_cmdtest = &skel_ai_cmdtest;
-
+
s=dev->subdevices+1;
/* analog output subdevice */
s->type=COMEDI_SUBD_AO;
comedi_device *dev;
comedi_subdevice *s;
- if (minor_to_subdev(minor,subdevice,&dev,&s)!=0)
+ if (minor_to_subdev(minor,subdevice,&dev,&s)!=0)
return 0;
return s->subdev_flags;
return -EINVAL;
}
memcpy(krange,lr->range+range,sizeof(comedi_krange));
-
+
return 0;
}
{
comedi_device *dev;
comedi_subdevice *s;
+ comedi_async *async;
- if (minor_to_subdev(minor,subdevice,&dev,&s)!=0)
+ if (minor_to_subdev(minor,subdevice,&dev,&s)!=0)
return 0;
-
- return s->buf_int_count;
+
+ async = s->async;
+ if(async == NULL) return 0;
+
+ return async->buf_int_count;
}
/*
{
comedi_device *dev;
comedi_subdevice *s;
+ comedi_async *async;
int ret;
- if ((ret=minor_to_subdev(minor,subdevice,&dev,&s))!=0)
+ if ((ret=minor_to_subdev(minor,subdevice,&dev,&s))!=0)
return ret;
-
- s->buf_user_count=buf_user_count;
-
+
+ async = s->async;
+ async->buf_user_count = buf_user_count;
+
return 0;
}
{
comedi_device *dev;
comedi_subdevice *s;
+ comedi_async *async;
int ret;
if((ret=minor_to_dev(minor,&dev))<0)
return ret;
-
+
if(cmd->subdev>=dev->n_subdevices)
return -ENODEV;
s=dev->subdevices+cmd->subdev;
+ async = s->async;
if(s->type==COMEDI_SUBD_UNUSED)
return -EIO;
-
- s->cb_mask = COMEDI_CB_EOA|COMEDI_CB_BLOCK|COMEDI_CB_ERROR;
- s->cb_mask |= COMEDI_CB_EOS;
- s->cmd=*cmd;
+ if(async == NULL)
+ return -ENODEV;
+
+ async->cb_mask = COMEDI_CB_EOA|COMEDI_CB_BLOCK|COMEDI_CB_ERROR;
+ async->cb_mask |= COMEDI_CB_EOS;
+
+ async->cmd=*cmd;
#if 0
s->runflags=0;
s->subdev_flags |= SDF_RUNNING;
- s->buf_user_ptr=0;
- s->buf_user_count=0;
- s->buf_int_ptr=0;
- s->buf_int_count=0;
+ async->buf_user_ptr=0;
+ async->buf_user_count=0;
+ async->buf_int_ptr=0;
+ async->buf_int_count=0;
- s->cur_trig.data_len = s->cmd.data_len;
- s->cur_trig.data = s->cmd.data;
+ s->cur_trig.data_len = async->cmd.data_len;
+ s->cur_trig.data = async->cmd.data;
return s->do_cmd(dev,s);
}
if((ret=minor_to_dev(minor,&dev))<0)
return ret;
-
+
if(cmd->subdev>=dev->n_subdevices)
return -ENODEV;
s=dev->subdevices+cmd->subdev;
if(s->type==COMEDI_SUBD_UNUSED)
return -EIO;
-
+
+ if(s->async == NULL)
+ return -ENODEV;
+
return s->do_cmdtest(dev,s,cmd);
}
/*
COMEDI_TRIG
trigger ioctl
-
+
arg:
pointer to trig structure
if((ret=minor_to_dev(minor,&dev))<0)
return ret;
-
+
if(it->subdev>=dev->n_subdevices)
return -ENODEV;
s=dev->subdevices+it->subdev;
if(s->type==COMEDI_SUBD_UNUSED)
return -EIO;
-
+
if(it->mode==0)
return comedi_trig_ioctl_mode0(dev,s,it);
-
+
+ if(s->async == NULL)
+ return -ENODEV;
+
return comedi_trig_ioctl_modeN(dev,s,it);
}
ret = -EINVAL;
goto cleanup;
}
-
+
/* make sure each element in channel/gain list is valid */
if((ret=check_chanlist(s,it->n_chan,it->chanlist))<0)
goto cleanup;
-
+
if(it->data==NULL){
ret=-EINVAL;
goto cleanup;
}
s->cur_trig=*it;
-
+
ret=s->trig[0](dev,s,it);
-
+
if(ret>it->n*it->n_chan){
rt_printk("comedi: (bug) trig returned too many samples\n");
}
static int comedi_trig_ioctl_modeN(comedi_device *dev,comedi_subdevice *s,comedi_trig *it)
{
int ret=0;
+ comedi_async *async = s->async;
/* are we locked? (ioctl lock) */
if(s->lock && s->lock!=&rtcomedi_lock_semaphore)
ret = -EINVAL;
goto cleanup;
}
-
+
+ if(async == NULL)
+ return -ENODEV;
+
/* make sure each element in channel/gain list is valid */
if((ret=check_chanlist(s,it->n_chan,it->chanlist))<0)
goto cleanup;
-
- s->buf_user_ptr=0;
- s->buf_user_count=0;
- s->buf_int_ptr=0;
- s->buf_int_count=0;
+
+ async->buf_user_ptr=0;
+ async->buf_user_count=0;
+ async->buf_int_ptr=0;
+ async->buf_int_count=0;
if(it->data==NULL){
ret=-EINVAL;
}
s->cur_trig=*it;
-
+
ret=s->trig[it->mode](dev,s,it);
-
+
if(ret==0)return 0;
cleanup:
arg:
subdevice number
-
+
reads:
none
int ret=0;
comedi_subdevice *s;
comedi_device *dev;
+ comedi_async *async;
if(rtcomedi_lock_semaphore)
return -EBUSY;
-
+
if((ret=minor_to_dev(minor,&dev))<0)
return ret;
-
+
if(subdev>=dev->n_subdevices)
return -EINVAL;
s=dev->subdevices+subdev;
-
+ async = s->async;
+
if(s->busy)
return -EBUSY;
if(s->lock && s->lock!=&rtcomedi_lock_semaphore)
return -EACCES;
-
+
if(s->do_unlock)
s->do_unlock(dev,s);
if(s->lock==&rtcomedi_lock_semaphore){
s->lock=NULL;
- s->cb_mask=0;
- s->cb_func=NULL;
- s->cb_arg=NULL;
-
+ async->cb_mask=0;
+ async->cb_func=NULL;
+ async->cb_arg=NULL;
+
__MOD_DEC_USE_COUNT(dev->driver->module);
}
/*
COMEDI_CANCEL
cancel acquisition ioctl
-
+
arg:
subdevice number
-
+
reads:
nothing
-
+
writes:
nothing
{
comedi_device *dev;
comedi_subdevice *s;
+ comedi_async *async;
int ret;
if((ret=minor_to_dev(minor,&dev))<0)
return ret;
-
+
if(subdev>=dev->n_subdevices)
return -ENODEV;
s=dev->subdevices+subdev;
+ async = s->async;
if(s->type==COMEDI_SUBD_UNUSED)
return -EIO;
-
+
/* are we locked? (ioctl lock) */
if(s->lock && s->lock!=&rtcomedi_lock_semaphore)
return -EACCES;
return -EBUSY;
if(!mask){
- s->cb_mask=0;
- s->cb_func=NULL;
- s->cb_arg=NULL;
+ async->cb_mask=0;
+ async->cb_func=NULL;
+ async->cb_arg=NULL;
}else{
- s->cb_mask=mask;
- s->cb_func=cb;
- s->cb_arg=arg;
+ async->cb_mask=mask;
+ async->cb_func=cb;
+ async->cb_arg=arg;
}
return 0;
static inline void buf_add(comedi_device *dev,comedi_subdevice *s,sampl_t x)
{
- *(sampl_t *)(((void *)(s->cur_trig.data))+s->buf_int_ptr)=x&0xfff;
- s->buf_int_ptr+=sizeof(sampl_t);
- if(s->buf_int_ptr>=s->cur_trig.data_len){
- s->buf_int_ptr=0;
+ *(sampl_t *)(((void *)(s->cur_trig.data))+s->async->buf_int_ptr)=x&0xfff;
+ s->async->buf_int_ptr+=sizeof(sampl_t);
+ if(s->async->buf_int_ptr>=s->cur_trig.data_len){
+ s->async->buf_int_ptr=0;
comedi_eobuf(dev,s);
}
- s->buf_int_count+=sizeof(sampl_t);
+ s->async->buf_int_count+=sizeof(sampl_t);
}
devpriv->s=devpriv->dev->subdevices+devpriv->subd;
s=dev->subdevices+0;
+ dev->read_subdev=s;
s->type=COMEDI_SUBD_AO;
s->subdev_flags=SDF_READABLE;
s->n_chan=devpriv->s->n_chan;
#endif
typedef struct comedi_device_struct comedi_device;
typedef struct comedi_subdevice_struct comedi_subdevice;
+typedef struct comedi_async_struct comedi_async;
typedef struct comedi_driver_struct comedi_driver;
typedef struct comedi_lrange_struct comedi_lrange;
void *private;
- void *prealloc_buf; /* pre-allocated buffer */
- unsigned int prealloc_bufsz; /* buffer size, in bytes */
- unsigned int mmap_count; /* current number of mmaps of prealloc_buf */
+// asyncronous specific stuff has been moved to comedi_async_struct
+// void *prealloc_buf; /* pre-allocated buffer */
+// unsigned int prealloc_bufsz; /* buffer size, in bytes */
+// unsigned int mmap_count; /* current number of mmaps of prealloc_buf */
+ comedi_async *async;
void *lock;
void *busy;
unsigned int runflags;
-
+
int io_bits;
-
+
lsampl_t maxdata; /* if maxdata==0, use list */
lsampl_t *maxdata_list; /* list is channel specific */
-
+
unsigned int flags;
unsigned int *flaglist;
comedi_lrange *range_table;
comedi_lrange **range_table_list;
-
+
unsigned int *chanlist; /* driver-owned chanlist (not used) */
-
+
#ifdef CONFIG_COMEDI_MODE_CORE
comedi_trig cur_trig; /* current trig structure */
#endif
- comedi_cmd cmd;
-
- volatile unsigned int buf_int_ptr; /* buffer marker for interrupt */
- unsigned int buf_user_ptr; /* buffer marker for read() and write() */
- volatile unsigned int buf_int_count; /* byte count for interrupt */
- unsigned int buf_user_count; /* byte count for read() and write() */
- unsigned int cur_chan; /* useless channel marker for interrupt */
- unsigned int cur_chanlist_len;
-
+// asyncronous specific stuff has been moved to comedi_async_struct
+// comedi_cmd cmd;
+
+// volatile unsigned int buf_int_ptr; /* buffer marker for interrupt */
+// unsigned int buf_user_ptr; /* buffer marker for read() and write() */
+// volatile unsigned int buf_int_count; /* byte count for interrupt */
+// unsigned int buf_user_count; /* byte count for read() and write() */
+// unsigned int cur_chan; /* useless channel marker for interrupt */
+// unsigned int cur_chanlist_len;
+
#ifdef CONFIG_COMEDI_MODE_CORE
int (*trig[5])(comedi_device *,comedi_subdevice *,comedi_trig *);
#endif
int (*do_lock)(comedi_device *,comedi_subdevice *);
int (*do_unlock)(comedi_device *,comedi_subdevice *);
+// asyncronous specific stuff has been moved to comedi_async_struct
+// unsigned int cb_mask;
+// int (*cb_func)(unsigned int flags,void *);
+// void *cb_arg;
+
+ unsigned int state;
+};
+
+struct comedi_async_struct{
+ comedi_subdevice *subdev; /* the subdevice this buffer is associated with */
+
+ void *prealloc_buf; /* pre-allocated buffer */
+ unsigned int prealloc_bufsz; /* buffer size, in bytes */
+ unsigned int mmap_count; /* current number of mmaps of prealloc_buf */
+ volatile unsigned int buf_int_ptr; /* buffer marker for interrupt */
+ unsigned int buf_user_ptr; /* buffer marker for read() and write() */
+ volatile unsigned int buf_int_count; /* byte count for interrupt */
+ unsigned int buf_user_count; /* byte count for read() and write() */
+ unsigned int cur_chan; /* useless channel marker for interrupt */
+ unsigned int cur_chanlist_len;
+
+ comedi_cmd cmd;
+
+ // callback stuff
unsigned int cb_mask;
int (*cb_func)(unsigned int flags,void *);
void *cb_arg;
-
- unsigned int state;
};
struct comedi_driver_struct{
int iosize;
int irq;
- int read_subdev;
+ comedi_subdevice *read_subdev;
wait_queue_head_t read_wait;
- int write_subdev;
+ comedi_subdevice *write_subdev;
wait_queue_head_t write_wait;
};