From 57a5ff6a384d03f481b8b260d74e6ef0e4dd1938 Mon Sep 17 00:00:00 2001 From: Frank Mori Hess Date: Tue, 13 Feb 2001 03:51:43 +0000 Subject: [PATCH] split asyncronous stuff off of comedi_subdevice_struct --- comedi/comedi_fops.c | 307 +++++++++++++++------------- comedi/drivers.c | 34 +-- comedi/drivers/8255.c | 4 +- comedi/drivers/adl_pci9118.c | 38 ++-- comedi/drivers/comedi_parport.c | 12 +- comedi/drivers/das16-new.c | 26 +-- comedi/drivers/das1800.c | 52 ++--- comedi/drivers/das6402.c | 10 +- comedi/drivers/das800.c | 38 ++-- comedi/drivers/dt2814.c | 4 +- comedi/drivers/dt282x.c | 44 ++-- comedi/drivers/mite.c | 10 +- comedi/drivers/ni_atmio16d.c | 38 ++-- comedi/drivers/ni_mio_common.c | 140 ++++++------- comedi/drivers/pcl812.c | 8 +- comedi/drivers/pcl818.c | 84 ++++---- comedi/drivers/skel.c | 4 +- comedi/kcomedilib/kcomedilib_main.c | 141 +++++++------ comedi/realtime/vd_dds.c | 11 +- include/linux/comedidev.h | 68 ++++-- 20 files changed, 575 insertions(+), 498 deletions(-) diff --git a/comedi/comedi_fops.c b/comedi/comedi_fops.c index 082d3ba7..273bbdd4 100644 --- a/comedi/comedi_fops.c +++ b/comedi/comedi_fops.c @@ -63,7 +63,7 @@ static int do_cmdtest_ioctl(comedi_device *dev,void *arg,void *file); 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) { @@ -155,7 +155,7 @@ static int do_devconfig_ioctl(comedi_device *dev,comedi_devconfig *arg,kdev_t mi 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()) @@ -171,72 +171,72 @@ static int do_bufconfig_ioctl(comedi_device *dev,void *arg) 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))) @@ -248,7 +248,7 @@ static int do_bufconfig_ioctl(comedi_device *dev,void *arg) /* 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; @@ -256,21 +256,22 @@ int resize_buf(comedi_device *dev, comedi_subdevice *s, unsigned int size) 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; } @@ -387,7 +388,7 @@ static int do_subdinfo_ioctl(comedi_device *dev,comedi_subdinfo *arg,void *file) ret=copy_to_user(arg,tmp,dev->n_subdevices*sizeof(comedi_subdinfo)); kfree(tmp); - + return ret?-EFAULT:0; } @@ -536,6 +537,7 @@ static int do_trig_ioctl_mode0(comedi_device *dev,comedi_subdevice *s,comedi_tri 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){ @@ -577,11 +579,11 @@ static int do_trig_ioctl_mode0(comedi_device *dev,comedi_subdevice *s,comedi_tri 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){ @@ -634,13 +636,21 @@ static int do_trig_ioctl_mode0(comedi_device *dev,comedi_subdevice *s,comedi_tri 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); @@ -668,32 +678,32 @@ static int do_trig_ioctl_modeN(comedi_device *dev,comedi_subdevice *s,comedi_tri 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; @@ -706,7 +716,7 @@ static int do_trig_ioctl_modeN(comedi_device *dev,comedi_subdevice *s,comedi_tri cleanup: do_become_nonbusy(dev,s); - + return ret; } #endif @@ -744,7 +754,7 @@ static int do_insnlist_ioctl(comedi_device *dev,void *arg,void *file) if(copy_from_user(&insnlist,arg,sizeof(comedi_insnlist))) return -EFAULT; - + if(insnlist.n_insns>=10) /* XXX */ return -EINVAL; @@ -779,7 +789,7 @@ static int do_insnlist_ioctl(comedi_device *dev,void *arg,void *file) data[0]=tv.tv_sec; data[1]=tv.tv_usec; ret=2; - + break; } case INSN_WAIT: @@ -886,6 +896,7 @@ static int do_cmd_ioctl(comedi_device *dev,void *arg,void *file) { comedi_cmd user_cmd; comedi_subdevice *s; + comedi_async *async; int ret=0; unsigned int *chanlist_saver=NULL; @@ -909,6 +920,7 @@ static int do_cmd_ioctl(comedi_device *dev,void *arg,void *file) } 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; @@ -939,36 +951,36 @@ static int do_cmd_ioctl(comedi_device *dev,void *arg,void *file) 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; @@ -981,32 +993,32 @@ static int do_cmd_ioctl(comedi_device *dev,void *arg,void *file) 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; @@ -1014,7 +1026,7 @@ static int do_cmd_ioctl(comedi_device *dev,void *arg,void *file) 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; } @@ -1033,14 +1045,14 @@ cleanup: /* COMEDI_CMDTEST command testing ioctl - + arg: pointer to cmd structure - + reads: cmd structure at arg channel/range list - + writes: modified cmd structure at arg @@ -1319,8 +1331,7 @@ static int comedi_mmap_v22(struct file * file, struct vm_area_struct *vma) { 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) @@ -1330,14 +1341,13 @@ static int comedi_mmap_v22(struct file * file, struct vm_area_struct *vma) } 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"); @@ -1345,18 +1355,18 @@ static int comedi_mmap_v22(struct file * file, struct vm_area_struct *vma) } 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; } @@ -1368,6 +1378,7 @@ static unsigned int comedi_poll_v22(struct file *file, poll_table * wait) { comedi_device *dev; comedi_subdevice *s; + comedi_async *async; unsigned int mask; dev=comedi_get_device_by_minor(MINOR(RDEV_OF_FILE(file))); @@ -1381,16 +1392,18 @@ static unsigned int comedi_poll_v22(struct file *file, poll_table * wait) 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; } @@ -1402,6 +1415,7 @@ static ssize_t comedi_write_v22(struct file *file,const char *buf,size_t nbytes, { comedi_device *dev; comedi_subdevice *s; + comedi_async *async; int n,m,count=0,retval=0; DECLARE_WAITQUEUE(wait,current); int sample_size; @@ -1416,8 +1430,9 @@ static ssize_t comedi_write_v22(struct file *file,const char *buf,size_t nbytes, 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); @@ -1433,8 +1448,8 @@ static ssize_t comedi_write_v22(struct file *file,const char *buf,size_t nbytes, 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; @@ -1454,9 +1469,9 @@ static ssize_t comedi_write_v22(struct file *file,const char *buf,size_t nbytes, 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(mbuf_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; @@ -1503,6 +1518,7 @@ static ssize_t comedi_read_v22(struct file * file,char *buf,size_t nbytes,loff_t { comedi_device *dev; comedi_subdevice *s; + comedi_async *async; int n,m,count=0,retval=0; DECLARE_WAITQUEUE(wait,current); int sample_size; @@ -1515,8 +1531,9 @@ static ssize_t comedi_read_v22(struct file * file,char *buf,size_t nbytes,loff_t 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); @@ -1545,10 +1562,10 @@ static ssize_t comedi_read_v22(struct file * file,char *buf,size_t nbytes,loff_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 @@ -1572,33 +1589,33 @@ printk("m is %d\n",m); 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; @@ -1612,6 +1629,7 @@ printk("m is %d\n",m); */ static void do_become_nonbusy(comedi_device *dev,comedi_subdevice *s) { + comedi_async *async = s->async; #if 0 printk("becoming non-busy\n"); #endif @@ -1631,16 +1649,16 @@ static void do_become_nonbusy(comedi_device *dev,comedi_subdevice *s) } 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; } @@ -1728,7 +1746,8 @@ ok: 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; @@ -1753,13 +1772,13 @@ static int comedi_close_v22(struct inode *inode,struct file *file) // 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); @@ -1905,31 +1924,31 @@ void comedi_error(comedi_device *dev,const char *s) 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 @@ -1937,7 +1956,7 @@ void comedi_event(comedi_device *dev,comedi_subdevice *s,unsigned int mask) * common, I'm not going to worry about it. */ } } - + if(mask&COMEDI_CB_EOA){ s->subdev_flags &= ~SDF_RUNNING; } diff --git a/comedi/drivers.c b/comedi/drivers.c index ee4231bb..6275ef3e 100644 --- a/comedi/drivers.c +++ b/comedi/drivers.c @@ -60,6 +60,7 @@ int comedi_device_detach(comedi_device *dev) { int i; comedi_subdevice *s; + comedi_async *async; if(!dev->attached) return 0; @@ -72,8 +73,12 @@ int comedi_device_detach(comedi_device *dev) for(i=0;in_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){ @@ -104,8 +109,6 @@ int comedi_device_attach(comedi_device *dev,comedi_devconfig *it) 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){ @@ -240,6 +243,7 @@ static void postconfig(comedi_device *dev) int i; int have_trig; comedi_subdevice *s; + comedi_async *async = NULL; for(i=0;in_subdevices;i++){ s=dev->subdevices+i; @@ -261,15 +265,14 @@ static void postconfig(comedi_device *dev) 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"); } } @@ -447,7 +450,7 @@ static int insn_emulate_bits(comedi_device *dev,comedi_subdevice *s, int ret; lsampl_t new_data[2]; unsigned int chan; - + chan = CR_CHAN(insn->chanspec); memset(&new_insn,0,sizeof(new_insn)); @@ -553,11 +556,12 @@ static int mode0_emulate_config(comedi_device *dev,comedi_subdevice *s,comedi_tr 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); diff --git a/comedi/drivers/8255.c b/comedi/drivers/8255.c index 4c96d59b..04a56adc 100644 --- a/comedi/drivers/8255.c +++ b/comedi/drivers/8255.c @@ -55,8 +55,8 @@ #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); diff --git a/comedi/drivers/adl_pci9118.c b/comedi/drivers/adl_pci9118.c index e4a73807..22f4fc82 100644 --- a/comedi/drivers/adl_pci9118.c +++ b/comedi/drivers/adl_pci9118.c @@ -263,7 +263,7 @@ static void move_block_from_dma_12bit(comedi_device *dev,comedi_subdevice *s,sam { int i,j; - j=s->cur_chan; + j=s->async->cur_chan; for(i=0;ichanlist[j]) { // data dropout! @@ -283,7 +283,7 @@ static void move_block_from_dma_12bit(comedi_device *dev,comedi_subdevice *s,sam comedi_eos(dev,s); } } - s->cur_chan=j; + s->async->cur_chan=j; } /* @@ -293,7 +293,7 @@ static void move_block_from_dma_16bit(comedi_device *dev,comedi_subdevice *s,sam { int i,j; - j=s->cur_chan; + j=s->async->cur_chan; for(i=0;i>8); // get one sample data++; dma++; @@ -305,7 +305,7 @@ static void move_block_from_dma_16bit(comedi_device *dev,comedi_subdevice *s,sam comedi_eos(dev,s); } } - s->cur_chan=j; + s->async->cur_chan=j; } /* @@ -361,21 +361,21 @@ static void interrupt_pci9118_ai_dma(int irq, void *d, struct pt_regs *regs) 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) @@ -461,7 +461,7 @@ static int pci9118_ai_docmd_and_mode(int mode, comedi_device * dev, comedi_subde 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; @@ -610,7 +610,7 @@ static int pci9118_ai_mode1(comedi_device * dev, comedi_subdevice * s, comedi_tr /* ============================================================================== */ -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); } @@ -1010,7 +1010,7 @@ static int pci9118_ai_cmdtest(comedi_device *dev,comedi_subdevice *s,comedi_cmd */ 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; @@ -1187,7 +1187,7 @@ int pci9118_ai_cancel(comedi_device * dev, comedi_subdevice * s) 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; @@ -1357,8 +1357,8 @@ static int pci9118_attach(comedi_device *dev,comedi_devconfig *it) 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; } diff --git a/comedi/drivers/comedi_parport.c b/comedi/drivers/comedi_parport.c index 4fbfafe6..e60a6d8a 100644 --- a/comedi/drivers/comedi_parport.c +++ b/comedi/drivers/comedi_parport.c @@ -215,11 +215,11 @@ static void parport_interrupt(int irq,void *d,struct pt_regs *regs) 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); } @@ -287,7 +287,7 @@ static int parport_attach(comedi_device *dev,comedi_devconfig *it) 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; diff --git a/comedi/drivers/das16-new.c b/comedi/drivers/das16-new.c index fb1a9c01..ae67387b 100644 --- a/comedi/drivers/das16-new.c +++ b/comedi/drivers/das16-new.c @@ -538,7 +538,7 @@ static int das16_cmd_test(comedi_device *dev,comedi_subdevice *s, comedi_cmd *cm 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; @@ -692,10 +692,10 @@ static void das16_interrupt(int irq, void *d, struct pt_regs *regs) 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;icur_chanlist_len;++i) { + for(i=0;iasync->cur_chanlist_len;++i) { if(i) { /* performing multiple conversions */ outb(0x00, dev->iobase+DAS16_TRIG); /* force a conversion */ @@ -711,18 +711,18 @@ static void das16_interrupt(int irq, void *d, struct pt_regs *regs) 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 */ @@ -1054,8 +1054,8 @@ static int das16_attach(comedi_device *dev, comedi_devconfig *it) 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; @@ -1078,7 +1078,7 @@ static int das16_attach(comedi_device *dev, comedi_devconfig *it) 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; } diff --git a/comedi/drivers/das1800.c b/comedi/drivers/das1800.c index 385849bd..a6257473 100644 --- a/comedi/drivers/das1800.c +++ b/comedi/drivers/das1800.c @@ -660,8 +660,8 @@ static int das1800_attach(comedi_device *dev, comedi_devconfig *it) 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) @@ -1085,20 +1085,20 @@ static void das1800_handle_fifo_not_empty(comedi_device *dev, comedi_subdevice * /* 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) @@ -1293,13 +1293,13 @@ static int das1800_ai_do_cmd(comedi_device *dev, comedi_subdevice *s) 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 */ @@ -1309,25 +1309,25 @@ static int das1800_ai_do_cmd(comedi_device *dev, comedi_subdevice *s) * 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"); @@ -1346,7 +1346,7 @@ static int das1800_ai_do_cmd(comedi_device *dev, comedi_subdevice *s) // 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"); @@ -1362,19 +1362,19 @@ static int das1800_ai_do_cmd(comedi_device *dev, comedi_subdevice *s) // 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 @@ -1393,13 +1393,13 @@ static int das1800_ai_do_cmd(comedi_device *dev, comedi_subdevice *s) // 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; diff --git a/comedi/drivers/das6402.c b/comedi/drivers/das6402.c index c54de414..21669594 100644 --- a/comedi/drivers/das6402.c +++ b/comedi/drivers/das6402.c @@ -164,7 +164,7 @@ static void intr_handler(int irq,void *d,struct pt_regs *regs) 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 @@ -199,16 +199,16 @@ static void das6402_ai_fifo_dregs(comedi_device *dev,comedi_subdevice *s) 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;iiobase+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); } diff --git a/comedi/drivers/das800.c b/comedi/drivers/das800.c index dc6d0c8f..b0e68ade 100644 --- a/comedi/drivers/das800.c +++ b/comedi/drivers/das800.c @@ -364,7 +364,8 @@ static void das800_interrupt(int irq, void *d, struct pt_regs *regs) 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; @@ -390,20 +391,20 @@ static void das800_interrupt(int irq, void *d, struct pt_regs *regs) 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 */ @@ -501,8 +502,8 @@ static int das800_attach(comedi_device *dev, comedi_devconfig *it) 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; @@ -697,6 +698,7 @@ static int das800_ai_do_cmd(comedi_device *dev, comedi_subdevice *s) int startChan, endChan, scan, gain; int conv_bits; unsigned long irq_flags; + comedi_async *async = s->async; if(!dev->irq) { @@ -707,8 +709,8 @@ static int das800_ai_do_cmd(comedi_device *dev, comedi_subdevice *s) 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); @@ -717,16 +719,16 @@ static int das800_ai_do_cmd(comedi_device *dev, comedi_subdevice *s) 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: @@ -742,14 +744,14 @@ static int das800_ai_do_cmd(comedi_device *dev, comedi_subdevice *s) */ 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"); diff --git a/comedi/drivers/dt2814.c b/comedi/drivers/dt2814.c index 88287026..dc0b96fe 100644 --- a/comedi/drivers/dt2814.c +++ b/comedi/drivers/dt2814.c @@ -223,7 +223,7 @@ static int dt2814_ai_cmdtest(comedi_device *dev,comedi_subdevice *s, 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; @@ -318,8 +318,8 @@ static int dt2814_attach(comedi_device *dev,comedi_devconfig *it) 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 */ diff --git a/comedi/drivers/dt282x.c b/comedi/drivers/dt282x.c index b5b976b7..1e99d0e2 100644 --- a/comedi/drivers/dt282x.c +++ b/comedi/drivers/dt282x.c @@ -381,43 +381,43 @@ static void copy_to_buf(comedi_device *dev,comedi_subdevice *s,void *buf,unsigne 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; } @@ -608,7 +608,7 @@ static void dt282x_interrupt(int irq, void *d, struct pt_regs *regs) 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){ @@ -799,7 +799,7 @@ static int dt282x_ai_cmdtest(comedi_device * dev, comedi_subdevice * s,comedi_cm 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); @@ -1195,7 +1195,7 @@ static int dt282x_ao_cmd(comedi_device *dev,comedi_subdevice *s) { 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); @@ -1470,7 +1470,7 @@ static int dt282x_attach(comedi_device * dev, comedi_devconfig * it) 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); @@ -1493,9 +1493,9 @@ static int dt282x_attach(comedi_device * dev, comedi_devconfig * it) 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; diff --git a/comedi/drivers/mite.c b/comedi/drivers/mite.c index dcb9cf6a..a5b1d407 100644 --- a/comedi/drivers/mite.c +++ b/comedi/drivers/mite.c @@ -251,11 +251,11 @@ void mite_dma_prep(struct mite_struct *mite,comedi_subdevice *s) int chor,chcr,mcr,dcr,lkcr; for(i=0;iprealloc_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; diff --git a/comedi/drivers/ni_atmio16d.c b/comedi/drivers/ni_atmio16d.c index 5455cb9c..5328f5c3 100644 --- a/comedi/drivers/ni_atmio16d.c +++ b/comedi/drivers/ni_atmio16d.c @@ -260,17 +260,17 @@ static void atmio16d_interrupt(int irq, void *d, struct pt_regs *regs) // 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); } } @@ -303,7 +303,7 @@ static int atmio16d_ai_cmdtest(comedi_device *dev, comedi_subdevice *s, comedi_c 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 && @@ -313,8 +313,8 @@ static int atmio16d_ai_cmdtest(comedi_device *dev, comedi_subdevice *s, comedi_c cmd->stop_src!=TRIG_NONE)err++; if(err)return 2; - - + + /* step 3: make sure arguments are trivially compatible */ if(cmd->start_arg!=0){ @@ -337,13 +337,13 @@ static int atmio16d_ai_cmdtest(comedi_device *dev, comedi_subdevice *s, comedi_c } #endif } - + if(cmd->convert_arg<10000){ cmd->convert_arg=10000; err++; } - - + + #if 0 if(cmd->convert_arg>SLOWEST_TIMER){ cmd->convert_arg=SLOWEST_TIMER; @@ -371,18 +371,18 @@ static int atmio16d_ai_cmdtest(comedi_device *dev, comedi_subdevice *s, comedi_c 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) { @@ -765,9 +765,9 @@ static int atmio16d_attach(comedi_device * dev, comedi_devconfig * it) 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; diff --git a/comedi/drivers/ni_mio_common.c b/comedi/drivers/ni_mio_common.c index ce748ff7..23b8bcd4 100644 --- a/comedi/drivers/ni_mio_common.c +++ b/comedi/drivers/ni_mio_common.c @@ -351,19 +351,19 @@ static void ni_ai_fifo_read(comedi_device *dev,comedi_subdevice *s, unsigned int mask; mask=(1<cur_chan; + j=s->async->cur_chan; for(i=0;iai_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 @@ -423,24 +423,24 @@ static void ni_handle_fifo_half_full(comedi_device *dev) 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); } @@ -462,13 +462,13 @@ static void ni_handle_fifo_dregs(comedi_device *dev) */ mask=(1<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;icur_chan=j; + s->async->cur_chan=j; return; } d=ni_readw(ADC_FIFO_Data_Register); @@ -476,15 +476,15 @@ static void ni_handle_fifo_dregs(comedi_device *dev) 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); } @@ -596,14 +596,14 @@ static int ni_ai_mode0(comedi_device *dev,comedi_subdevice *s,comedi_trig *it) 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;chann_chan;chan++){ ni_load_channelgain_list(dev,1,it->chanlist+chan,(it->flags&TRIG_DITHER)==TRIG_DITHER); #if 0 @@ -615,7 +615,7 @@ static int ni_ai_mode0(comedi_device *dev,comedi_subdevice *s,comedi_trig *it) 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;ichanspec,(insn->flags&TRIG_DITHER)==TRIG_DITHER); ni_load_channelgain_list(dev,1,&insn->chanspec,0); @@ -696,7 +696,7 @@ static void ni_load_channelgain_list(comedi_device *dev,unsigned int n_chan,unsi }else{ devpriv->changain_state=0; } - + win_out(1,Configuration_Memory_Clear); sign=1<<(boardtype.adbits-1); @@ -704,7 +704,7 @@ static void ni_load_channelgain_list(comedi_device *dev,unsigned int n_chan,unsi 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; @@ -882,7 +882,7 @@ static int ni_ai_cmdtest(comedi_device *dev,comedi_subdevice *s,comedi_cmd *cmd) 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; @@ -906,7 +906,7 @@ static int ni_ai_cmd(comedi_device *dev,comedi_subdevice *s) 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); @@ -918,7 +918,7 @@ devpriv->n_left = 0; /* 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); @@ -947,11 +947,11 @@ devpriv->n_left = 1; 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| @@ -1032,7 +1032,7 @@ devpriv->n_left = 1; 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{ @@ -1069,7 +1069,7 @@ devpriv->n_left = 1; /* 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 */ @@ -1106,7 +1106,7 @@ static int ni_ai_mode2(comedi_device *dev,comedi_subdevice *s,comedi_trig *it) 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); @@ -1121,21 +1121,21 @@ static int ni_ai_mode2(comedi_device *dev,comedi_subdevice *s,comedi_trig *it) 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| @@ -1176,7 +1176,7 @@ static int ni_ai_mode2(comedi_device *dev,comedi_subdevice *s,comedi_trig *it) 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{ @@ -1211,7 +1211,7 @@ static int ni_ai_mode2(comedi_device *dev,comedi_subdevice *s,comedi_trig *it) } #ifdef PCIDMA -#if 0 +#if 0 Strobes_Register AI_AO_Select_Register Interrupt_B_Enable_Register MSC_Pass_thru @@ -1228,7 +1228,7 @@ rt_printk("end config\n"); #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); @@ -1259,7 +1259,7 @@ static int ni_ai_mode4(comedi_device *dev,comedi_subdevice *s,comedi_trig *it) 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); @@ -1274,27 +1274,27 @@ static int ni_ai_mode4(comedi_device *dev,comedi_subdevice *s,comedi_trig *it) 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); @@ -1329,7 +1329,7 @@ static int ni_ai_mode4(comedi_device *dev,comedi_subdevice *s,comedi_trig *it) /* 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{ @@ -1363,7 +1363,7 @@ static int ni_ai_mode4(comedi_device *dev,comedi_subdevice *s,comedi_trig *it) /* XXX start polling if necessary */ } - + /* end configuration */ win_out(AI_Configuration_End,Joint_Reset_Register); @@ -1410,21 +1410,21 @@ static int ni_ao_fifo_half_empty(comedi_device *dev,comedi_subdevice *s) { 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); @@ -1439,14 +1439,14 @@ static int ni_ao_prep_fifo(comedi_device *dev,comedi_subdevice *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; } @@ -1471,7 +1471,7 @@ static int ni_ao_insn_write(comedi_device *dev,comedi_subdevice *s, chan=CR_CHAN(insn->chanspec); conf=chan<<8; - + /* XXX check range with current range in flaglist[chan] */ /* should update calibration if range changes (ick) */ @@ -1480,7 +1480,7 @@ static int ni_ao_insn_write(comedi_device *dev,comedi_subdevice *s, 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 */ @@ -1498,7 +1498,7 @@ static int ni_ao_insn_write(comedi_device *dev,comedi_subdevice *s, if(((range&1)==0) || !boardtype.ao_unipolar) dat^=(1<<(boardtype.aobits-1)); - + ni_writew(dat,(chan)? DAC1_Direct_Data : DAC0_Direct_Data); return 1; @@ -1506,7 +1506,7 @@ static int ni_ao_insn_write(comedi_device *dev,comedi_subdevice *s, 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; @@ -2038,8 +2038,8 @@ static int ni_E_init(comedi_device *dev,comedi_devconfig *it) /* 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; @@ -2056,12 +2056,12 @@ static int ni_E_init(comedi_device *dev,comedi_devconfig *it) 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; diff --git a/comedi/drivers/pcl812.c b/comedi/drivers/pcl812.c index e7766b00..8ad035ec 100644 --- a/comedi/drivers/pcl812.c +++ b/comedi/drivers/pcl812.c @@ -345,11 +345,11 @@ static void interrupt_pcl812_ai_mode13_int(int irq, void *d, struct pt_regs *reg 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; @@ -366,8 +366,8 @@ static void interrupt_pcl812_ai_mode13_int(int irq, void *d, struct pt_regs *reg 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); } diff --git a/comedi/drivers/pcl818.c b/comedi/drivers/pcl818.c index 999f2307..049bd6b3 100644 --- a/comedi/drivers/pcl818.c +++ b/comedi/drivers/pcl818.c @@ -451,47 +451,47 @@ conv_finish: 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 @@ -521,8 +521,8 @@ static void interrupt_pcl818_ai_mode13_dma(int irq, void *d, struct pt_regs *reg 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; @@ -532,29 +532,29 @@ static void interrupt_pcl818_ai_mode13_dma(int irq, void *d, struct pt_regs *reg 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; @@ -564,7 +564,7 @@ static void interrupt_pcl818_ai_mode13_dma_rtc(int irq, void *d, struct pt_regs 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); @@ -583,7 +583,7 @@ static void interrupt_pcl818_ai_mode13_dma_rtc(int irq, void *d, struct pt_regs 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! @@ -594,9 +594,9 @@ static void interrupt_pcl818_ai_mode13_dma_rtc(int irq, void *d, struct pt_regs return; } //rt_printk("r %ld ",ofs_dats); - + bufptr=devpriv->last_top_dma; - + for (i=0; iact_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]); @@ -604,12 +604,12 @@ static void interrupt_pcl818_ai_mode13_dma_rtc(int irq, void *d, struct pt_regs 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; @@ -619,22 +619,22 @@ static void interrupt_pcl818_ai_mode13_dma_rtc(int irq, void *d, struct pt_regs 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; @@ -647,16 +647,16 @@ static void interrupt_pcl818_ai_mode13_dma_rtc(int irq, void *d, struct pt_regs } -/* +/* ============================================================================== 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); @@ -674,10 +674,10 @@ static void interrupt_pcl818_ai_mode13_fifo(int irq, void *d, struct pt_regs *re comedi_error_done(dev,s); return; } - + if (lo&2) { len=512; } else { len=0; } - + for (i=0;iiobase + PCL818_FI_DATALO); if ((lo & 0xf)!=devpriv->act_chanlist[devpriv->act_chanlist_pos]) { // dropout! @@ -688,8 +688,8 @@ static void interrupt_pcl818_ai_mode13_fifo(int irq, void *d, struct pt_regs *re } 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; @@ -699,8 +699,8 @@ static void interrupt_pcl818_ai_mode13_fifo(int irq, void *d, struct pt_regs *re 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); } diff --git a/comedi/drivers/skel.c b/comedi/drivers/skel.c index 0fedfa11..2711ca21 100644 --- a/comedi/drivers/skel.c +++ b/comedi/drivers/skel.c @@ -215,7 +215,7 @@ static int skel_attach(comedi_device *dev,comedi_devconfig *it) 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; @@ -225,7 +225,7 @@ static int skel_attach(comedi_device *dev,comedi_devconfig *it) 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; diff --git a/comedi/kcomedilib/kcomedilib_main.c b/comedi/kcomedilib/kcomedilib_main.c index 176fff80..fd694ec9 100644 --- a/comedi/kcomedilib/kcomedilib_main.c +++ b/comedi/kcomedilib/kcomedilib_main.c @@ -186,7 +186,7 @@ unsigned int comedi_get_subdevice_flags(unsigned int minor,unsigned int subdevic 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; @@ -315,7 +315,7 @@ int comedi_get_krange(unsigned int minor,unsigned int subdevice,unsigned int cha return -EINVAL; } memcpy(krange,lr->range+range,sizeof(comedi_krange)); - + return 0; } @@ -326,11 +326,15 @@ unsigned int comedi_get_buf_head_pos(unsigned int minor,unsigned int subdevice) { 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; } /* @@ -340,13 +344,15 @@ int comedi_set_user_int_count(unsigned int minor,unsigned int subdevice,unsigned { 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; } @@ -354,22 +360,27 @@ int comedi_command(unsigned int minor,comedi_cmd *cmd) { 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; @@ -380,13 +391,13 @@ int comedi_command(unsigned int minor,comedi_cmd *cmd) 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); } @@ -399,21 +410,24 @@ int comedi_command_test(unsigned int minor,comedi_cmd *cmd) 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 @@ -437,17 +451,20 @@ int comedi_trigger(unsigned int minor,unsigned int subdev,comedi_trig *it) 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); } @@ -469,11 +486,11 @@ static int comedi_trig_ioctl_mode0(comedi_device *dev,comedi_subdevice *s,comedi 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; @@ -490,9 +507,9 @@ static int comedi_trig_ioctl_mode0(comedi_device *dev,comedi_subdevice *s,comedi } 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"); } @@ -506,6 +523,7 @@ cleanup: 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) @@ -521,15 +539,18 @@ static int comedi_trig_ioctl_modeN(comedi_device *dev,comedi_subdevice *s,comedi 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; @@ -552,9 +573,9 @@ static int comedi_trig_ioctl_modeN(comedi_device *dev,comedi_subdevice *s,comedi } s->cur_trig=*it; - + ret=s->trig[it->mode](dev,s,it); - + if(ret==0)return 0; cleanup: @@ -681,7 +702,7 @@ error: arg: subdevice number - + reads: none @@ -756,33 +777,35 @@ int comedi_unlock(unsigned int minor,unsigned int subdev) 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); } @@ -792,13 +815,13 @@ int comedi_unlock(unsigned int minor,unsigned int subdev) /* COMEDI_CANCEL cancel acquisition ioctl - + arg: subdevice number - + reads: nothing - + writes: nothing @@ -849,18 +872,20 @@ int comedi_register_callback(unsigned int minor,unsigned int subdev, { 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; @@ -870,13 +895,13 @@ int comedi_register_callback(unsigned int minor,unsigned int subdev, 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; diff --git a/comedi/realtime/vd_dds.c b/comedi/realtime/vd_dds.c index aaf946e1..ae17bc4d 100644 --- a/comedi/realtime/vd_dds.c +++ b/comedi/realtime/vd_dds.c @@ -94,13 +94,13 @@ static void dds_interrupt(int irq,void *d,struct pt_regs * regs) 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); } @@ -243,6 +243,7 @@ int dds_attach(comedi_device *dev,comedi_devconfig *it) 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; diff --git a/include/linux/comedidev.h b/include/linux/comedidev.h index 90ffa444..239943e8 100644 --- a/include/linux/comedidev.h +++ b/include/linux/comedidev.h @@ -56,6 +56,7 @@ #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; @@ -68,39 +69,42 @@ struct comedi_subdevice_struct{ 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 @@ -117,11 +121,33 @@ struct comedi_subdevice_struct{ 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{ @@ -164,10 +190,10 @@ struct comedi_device_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; }; -- 2.26.2