Moved trig-related code from comedi_fops.c to trig.c
authorDavid Schleef <ds@schleef.org>
Sun, 27 May 2001 23:13:15 +0000 (23:13 +0000)
committerDavid Schleef <ds@schleef.org>
Sun, 27 May 2001 23:13:15 +0000 (23:13 +0000)
comedi/comedi_fops.c
comedi/trig.c

index 2196bc39c73f919df8444199ef69ea043caced8d..76227cfe1db1bf8d9fd61fd2ebfb1bee3652a4f9 100644 (file)
@@ -53,9 +53,6 @@ static int do_devinfo_ioctl(comedi_device *dev,comedi_devinfo *arg);
 static int do_subdinfo_ioctl(comedi_device *dev,comedi_subdinfo *arg,void *file);
 static int do_chaninfo_ioctl(comedi_device *dev,comedi_chaninfo *arg);
 static int do_bufinfo_ioctl(comedi_device *dev,void *arg);
-#ifdef CONFIG_COMEDI_TRIG
-static int do_trig_ioctl(comedi_device *dev,void *arg,void *file);
-#endif
 static int do_cmd_ioctl(comedi_device *dev,void *arg,void *file);
 static int do_lock_ioctl(comedi_device *dev,unsigned int arg,void * file);
 static int do_unlock_ioctl(comedi_device *dev,unsigned int arg,void * file);
@@ -64,7 +61,12 @@ 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 int do_poll_ioctl(comedi_device *dev,unsigned int subd,void *file);
 
-static void do_become_nonbusy(comedi_device *dev,comedi_subdevice *s);
+#ifdef CONFIG_COMEDI_TRIG
+/* moved to trig.c */
+int do_trig_ioctl(comedi_device *dev,void *arg,void *file);
+#endif
+
+void do_become_nonbusy(comedi_device *dev,comedi_subdevice *s);
 int resize_buf(comedi_device *dev,comedi_async *s, unsigned int size);
 static int do_cancel(comedi_device *dev,comedi_subdevice *s);
 
@@ -530,275 +532,6 @@ copyback:
        return 0;
 }
 
-#ifdef CONFIG_COMEDI_TRIG
-/*
-       COMEDI_TRIG
-       trigger ioctl
-       
-       arg:
-               pointer to trig structure
-       
-       reads:
-               trig structure at arg
-               channel/range list
-       
-       writes:
-               modified trig structure at arg
-               data list
-
-       this function is too complicated
-*/
-static int do_trig_ioctl_mode0(comedi_device *dev,comedi_subdevice *s,comedi_trig *user_trig);
-static int do_trig_ioctl_modeN(comedi_device *dev,comedi_subdevice *s,comedi_trig *user_trig);
-static int do_trig_ioctl(comedi_device *dev,void *arg,void *file)
-{
-       comedi_trig user_trig;
-       comedi_subdevice *s;
-
-#if 0
-DPRINTK("entering do_trig_ioctl()\n");
-#endif
-       if(copy_from_user(&user_trig,arg,sizeof(comedi_trig))){
-               DPRINTK("bad trig address\n");
-               return -EFAULT;
-       }
-
-#if 0
-       /* this appears to be the only way to check if we are allowed
-          to write to an area. */
-       if(copy_to_user(arg,&user_trig,sizeof(comedi_trig)))
-               return -EFAULT;
-#endif
-
-       if(user_trig.subdev>=dev->n_subdevices){
-               DPRINTK("%d no such subdevice\n",user_trig.subdev);
-               return -ENODEV;
-       }
-
-       s=dev->subdevices+user_trig.subdev;
-       if(s->type==COMEDI_SUBD_UNUSED){
-               DPRINTK("%d not useable subdevice\n",user_trig.subdev);
-               return -EIO;
-       }
-
-       /* are we locked? (ioctl lock) */
-       if(s->lock && s->lock!=file){
-               DPRINTK("device locked\n");
-               return -EACCES;
-       }
-
-       /* are we busy? */
-       if(s->busy){
-               DPRINTK("device busy\n");
-               return -EBUSY;
-       }
-       s->busy=file;
-
-       s->cur_trig=user_trig;
-       s->cur_trig.chanlist=NULL;
-       s->cur_trig.data=NULL;
-
-       if(user_trig.mode == 0){
-               return do_trig_ioctl_mode0(dev,s,&user_trig);
-       }else{
-               return do_trig_ioctl_modeN(dev,s,&user_trig);
-       }
-}
-
-static int do_trig_ioctl_mode0(comedi_device *dev,comedi_subdevice *s,comedi_trig *user_trig)
-{
-       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){
-               DPRINTK("channel/gain list too long %d > %d\n",user_trig->n_chan,s->len_chanlist);
-               ret = -EINVAL;
-               goto cleanup;
-       }
-
-       /* load channel/gain list */
-       s->cur_trig.chanlist=kmalloc(s->cur_trig.n_chan*sizeof(int),GFP_KERNEL);
-       if(!s->cur_trig.chanlist){
-               DPRINTK("allocation failed\n");
-               ret = -ENOMEM;
-               goto cleanup;
-       }
-
-       if(copy_from_user(s->cur_trig.chanlist,user_trig->chanlist,s->cur_trig.n_chan*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->cur_trig.n_chan,s->cur_trig.chanlist))<0){
-               DPRINTK("bad chanlist\n");
-               goto cleanup;
-       }
-
-       /* allocate temporary buffer */
-       if(s->subdev_flags&SDF_LSAMPL){
-               bufsz=s->cur_trig.n*s->cur_trig.n_chan*sizeof(lsampl_t);
-       }else{
-               bufsz=s->cur_trig.n*s->cur_trig.n_chan*sizeof(sampl_t);
-       }
-
-       if(!(s->cur_trig.data=kmalloc(bufsz,GFP_KERNEL))){
-               DPRINTK("failed to allocate buffer\n");
-               ret=-ENOMEM;
-               goto cleanup;
-       }
-
-// this stuff isn't used in mode0
-//     async->buf_int_ptr=0;
-//     async->buf_int_count=0;
-//     if(s->subdev_flags & SDF_READABLE){
-//             async->buf_user_ptr=0;
-//             async->buf_user_count=0;
-//     }
-
-       if(s->subdev_flags & SDF_WRITEABLE){
-               if(s->subdev_flags & SDF_READABLE){
-                       /* bidirectional, so we defer to trig structure */
-                       if(user_trig->flags&TRIG_WRITE){
-                               reading=0;
-                       }else{
-                               reading=1;
-                       }
-               }else{
-                       reading=0;
-               }
-       }else{
-               /* subdev is read-only */
-               reading=1;
-       }
-       if(!reading && user_trig->data){
-               if(s->subdev_flags&SDF_LSAMPL){
-                       i=s->cur_trig.n*s->cur_trig.n_chan*sizeof(lsampl_t);
-               }else{
-                       i=s->cur_trig.n*s->cur_trig.n_chan*sizeof(sampl_t);
-               }
-               if(copy_from_user(s->cur_trig.data,user_trig->data,i)){
-                       DPRINTK("bad address %p,%p (%d)\n",s->cur_trig.data,user_trig->data,i);
-                       ret=-EFAULT;
-                       goto cleanup;
-               }
-       }
-
-       ret=s->trig[0](dev,s,&s->cur_trig);
-
-       if(ret<0)goto cleanup;
-
-       if(s->subdev_flags&SDF_LSAMPL){
-               i=ret*sizeof(lsampl_t);
-       }else{
-               i=ret*sizeof(sampl_t);
-       }
-       if(i>bufsz){
-               printk("comedi: (bug) trig returned too many samples\n");
-               i=bufsz;
-       }
-       if(reading){
-               if(copy_to_user(user_trig->data,s->cur_trig.data,i)){
-                       ret=-EFAULT;
-                       goto cleanup;
-               }
-       }
-cleanup:
-
-       s->busy=NULL;
-       //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=-EINVAL;
-               goto cleanup;
-       }
-
-       /* make sure channel/gain list isn't too long */
-       if(user_trig->n_chan > s->len_chanlist){
-               DPRINTK("channel/gain list too long %d > %d\n",user_trig->n_chan,s->len_chanlist);
-               ret = -EINVAL;
-               goto cleanup;
-       }
-
-       /* load channel/gain list */
-       s->cur_trig.chanlist=kmalloc(s->cur_trig.n_chan*sizeof(int),GFP_KERNEL);
-       if(!s->cur_trig.chanlist){
-               DPRINTK("allocation failed\n");
-               ret = -ENOMEM;
-               goto cleanup;
-       }
-
-       if(copy_from_user(s->cur_trig.chanlist,user_trig->chanlist,s->cur_trig.n_chan*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->cur_trig.n_chan,s->cur_trig.chanlist))<0){
-               DPRINTK("bad chanlist\n");
-               goto cleanup;
-       }
-
-       if(!s->async->prealloc_buf){
-               printk("comedi: bug: s->async->prealloc_buf==NULL\n");
-       }
-
-//     s->cur_trig.data=async->prealloc_buf;
-//     s->cur_trig.data_len=async->prealloc_bufsz;
-       async->data=async->prealloc_buf;
-       async->data_len=async->prealloc_bufsz;
-
-       async->buf_int_ptr=0;
-       async->buf_int_count=0;
-       if(s->subdev_flags & SDF_READABLE){
-               async->buf_user_ptr=0;
-               async->buf_user_count=0;
-       }
-
-       async->cur_chan=0;
-       async->cur_chanlist_len=s->cur_trig.n_chan;
-
-       async->cb_mask=COMEDI_CB_EOA|COMEDI_CB_BLOCK|COMEDI_CB_ERROR;
-       if(s->cur_trig.flags & TRIG_WAKE_EOS){
-               async->cb_mask|=COMEDI_CB_EOS;
-       }
-
-       s->runflags=SRF_USER;
-
-       s->subdev_flags|=SDF_RUNNING;
-
-       ret=s->trig[s->cur_trig.mode](dev,s,&s->cur_trig);
-
-       if(ret==0)return 0;
-
-cleanup:
-       do_become_nonbusy(dev,s);
-
-       return ret;
-}
-#endif
-
 
 /*
  *     COMEDI_INSNLIST
@@ -1711,7 +1444,7 @@ printk("m is %d\n",m);
 /*
    This function restores a subdevice to an idle state.
  */
-static void do_become_nonbusy(comedi_device *dev,comedi_subdevice *s)
+void do_become_nonbusy(comedi_device *dev,comedi_subdevice *s)
 {
        comedi_async *async = s->async;
 #if 0
index 65c94df740c4840c587ed70e7d496807041bdaca..b741c2401a0f2da96b5937f4a0cf54f49b07fc65 100644 (file)
@@ -35,6 +35,7 @@
 #include <linux/ioport.h>
 #include <linux/mm.h>
 #include <linux/malloc.h>
+#include <asm/uaccess.h>
 #include <asm/io.h>
 
 int command_trig(comedi_device *dev,comedi_subdevice *s,comedi_trig *it);
@@ -42,7 +43,274 @@ int mode_to_command(comedi_cmd *cmd,comedi_trig *it);
 int mode0_emulate(comedi_device *dev,comedi_subdevice *s,comedi_trig *trig);
 int mode0_emulate_config(comedi_device *dev,comedi_subdevice *s,comedi_trig *trig);
 
+void do_become_nonbusy(comedi_device *dev, comedi_subdevice *s);
 
+/*
+       COMEDI_TRIG
+       trigger ioctl
+       
+       arg:
+               pointer to trig structure
+       
+       reads:
+               trig structure at arg
+               channel/range list
+       
+       writes:
+               modified trig structure at arg
+               data list
+
+       this function is too complicated
+*/
+static int do_trig_ioctl_mode0(comedi_device *dev,comedi_subdevice *s,comedi_trig *user_trig);
+static int do_trig_ioctl_modeN(comedi_device *dev,comedi_subdevice *s,comedi_trig *user_trig);
+int do_trig_ioctl(comedi_device *dev,void *arg,void *file)
+{
+       comedi_trig user_trig;
+       comedi_subdevice *s;
+
+#if 0
+DPRINTK("entering do_trig_ioctl()\n");
+#endif
+       if(copy_from_user(&user_trig,arg,sizeof(comedi_trig))){
+               DPRINTK("bad trig address\n");
+               return -EFAULT;
+       }
+
+#if 0
+       /* this appears to be the only way to check if we are allowed
+          to write to an area. */
+       if(copy_to_user(arg,&user_trig,sizeof(comedi_trig)))
+               return -EFAULT;
+#endif
+
+       if(user_trig.subdev>=dev->n_subdevices){
+               DPRINTK("%d no such subdevice\n",user_trig.subdev);
+               return -ENODEV;
+       }
+
+       s=dev->subdevices+user_trig.subdev;
+       if(s->type==COMEDI_SUBD_UNUSED){
+               DPRINTK("%d not useable subdevice\n",user_trig.subdev);
+               return -EIO;
+       }
+
+       /* are we locked? (ioctl lock) */
+       if(s->lock && s->lock!=file){
+               DPRINTK("device locked\n");
+               return -EACCES;
+       }
+
+       /* are we busy? */
+       if(s->busy){
+               DPRINTK("device busy\n");
+               return -EBUSY;
+       }
+       s->busy=file;
+
+       s->cur_trig=user_trig;
+       s->cur_trig.chanlist=NULL;
+       s->cur_trig.data=NULL;
+
+       if(user_trig.mode == 0){
+               return do_trig_ioctl_mode0(dev,s,&user_trig);
+       }else{
+               return do_trig_ioctl_modeN(dev,s,&user_trig);
+       }
+}
+
+static int do_trig_ioctl_mode0(comedi_device *dev,comedi_subdevice *s,comedi_trig *user_trig)
+{
+       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){
+               DPRINTK("channel/gain list too long %d > %d\n",user_trig->n_chan,s->len_chanlist);
+               ret = -EINVAL;
+               goto cleanup;
+       }
+
+       /* load channel/gain list */
+       s->cur_trig.chanlist=kmalloc(s->cur_trig.n_chan*sizeof(int),GFP_KERNEL);
+       if(!s->cur_trig.chanlist){
+               DPRINTK("allocation failed\n");
+               ret = -ENOMEM;
+               goto cleanup;
+       }
+
+       if(copy_from_user(s->cur_trig.chanlist,user_trig->chanlist,s->cur_trig.n_chan*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->cur_trig.n_chan,s->cur_trig.chanlist))<0){
+               DPRINTK("bad chanlist\n");
+               goto cleanup;
+       }
+
+       /* allocate temporary buffer */
+       if(s->subdev_flags&SDF_LSAMPL){
+               bufsz=s->cur_trig.n*s->cur_trig.n_chan*sizeof(lsampl_t);
+       }else{
+               bufsz=s->cur_trig.n*s->cur_trig.n_chan*sizeof(sampl_t);
+       }
+
+       if(!(s->cur_trig.data=kmalloc(bufsz,GFP_KERNEL))){
+               DPRINTK("failed to allocate buffer\n");
+               ret=-ENOMEM;
+               goto cleanup;
+       }
+
+// this stuff isn't used in mode0
+//     async->buf_int_ptr=0;
+//     async->buf_int_count=0;
+//     if(s->subdev_flags & SDF_READABLE){
+//             async->buf_user_ptr=0;
+//             async->buf_user_count=0;
+//     }
+
+       if(s->subdev_flags & SDF_WRITEABLE){
+               if(s->subdev_flags & SDF_READABLE){
+                       /* bidirectional, so we defer to trig structure */
+                       if(user_trig->flags&TRIG_WRITE){
+                               reading=0;
+                       }else{
+                               reading=1;
+                       }
+               }else{
+                       reading=0;
+               }
+       }else{
+               /* subdev is read-only */
+               reading=1;
+       }
+       if(!reading && user_trig->data){
+               if(s->subdev_flags&SDF_LSAMPL){
+                       i=s->cur_trig.n*s->cur_trig.n_chan*sizeof(lsampl_t);
+               }else{
+                       i=s->cur_trig.n*s->cur_trig.n_chan*sizeof(sampl_t);
+               }
+               if(copy_from_user(s->cur_trig.data,user_trig->data,i)){
+                       DPRINTK("bad address %p,%p (%d)\n",s->cur_trig.data,user_trig->data,i);
+                       ret=-EFAULT;
+                       goto cleanup;
+               }
+       }
+
+       ret=s->trig[0](dev,s,&s->cur_trig);
+
+       if(ret<0)goto cleanup;
+
+       if(s->subdev_flags&SDF_LSAMPL){
+               i=ret*sizeof(lsampl_t);
+       }else{
+               i=ret*sizeof(sampl_t);
+       }
+       if(i>bufsz){
+               printk("comedi: (bug) trig returned too many samples\n");
+               i=bufsz;
+       }
+       if(reading){
+               if(copy_to_user(user_trig->data,s->cur_trig.data,i)){
+                       ret=-EFAULT;
+                       goto cleanup;
+               }
+       }
+cleanup:
+
+       s->busy=NULL;
+       //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=-EINVAL;
+               goto cleanup;
+       }
+
+       /* make sure channel/gain list isn't too long */
+       if(user_trig->n_chan > s->len_chanlist){
+               DPRINTK("channel/gain list too long %d > %d\n",user_trig->n_chan,s->len_chanlist);
+               ret = -EINVAL;
+               goto cleanup;
+       }
+
+       /* load channel/gain list */
+       s->cur_trig.chanlist=kmalloc(s->cur_trig.n_chan*sizeof(int),GFP_KERNEL);
+       if(!s->cur_trig.chanlist){
+               DPRINTK("allocation failed\n");
+               ret = -ENOMEM;
+               goto cleanup;
+       }
+
+       if(copy_from_user(s->cur_trig.chanlist,user_trig->chanlist,s->cur_trig.n_chan*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->cur_trig.n_chan,s->cur_trig.chanlist))<0){
+               DPRINTK("bad chanlist\n");
+               goto cleanup;
+       }
+
+       if(!s->async->prealloc_buf){
+               printk("comedi: bug: s->async->prealloc_buf==NULL\n");
+       }
+
+//     s->cur_trig.data=async->prealloc_buf;
+//     s->cur_trig.data_len=async->prealloc_bufsz;
+       async->data=async->prealloc_buf;
+       async->data_len=async->prealloc_bufsz;
+
+       async->buf_int_ptr=0;
+       async->buf_int_count=0;
+       if(s->subdev_flags & SDF_READABLE){
+               async->buf_user_ptr=0;
+               async->buf_user_count=0;
+       }
+
+       async->cur_chan=0;
+       async->cur_chanlist_len=s->cur_trig.n_chan;
+
+       async->cb_mask=COMEDI_CB_EOA|COMEDI_CB_BLOCK|COMEDI_CB_ERROR;
+       if(s->cur_trig.flags & TRIG_WAKE_EOS){
+               async->cb_mask|=COMEDI_CB_EOS;
+       }
+
+       s->runflags=SRF_USER;
+
+       s->subdev_flags|=SDF_RUNNING;
+
+       ret=s->trig[s->cur_trig.mode](dev,s,&s->cur_trig);
+
+       if(ret==0)return 0;
+
+cleanup:
+       do_become_nonbusy(dev,s);
+
+       return ret;
+}
 
 int mode0_emulate(comedi_device *dev,comedi_subdevice *s,comedi_trig *trig)
 {