insn support
authorDavid Schleef <ds@schleef.org>
Wed, 11 Oct 2000 01:08:05 +0000 (01:08 +0000)
committerDavid Schleef <ds@schleef.org>
Wed, 11 Oct 2000 01:08:05 +0000 (01:08 +0000)
comedi/kcomedilib/data.c
comedi/kcomedilib/dio.c
comedi/kcomedilib/kcomedilib_main.c

index 3ee3603ae56ea8b2516285db0ed18b989d9db274..10442bd1c91da558c8afe379fdf8af4016146b7a 100644 (file)
 #include <asm/uaccess.h>
 #endif
 
+#define USE_INSN
 
 extern volatile int rtcomedi_lock_semaphore;
 
 int comedi_data_write(unsigned int dev,unsigned int subdev,unsigned int chan,
        unsigned int range,unsigned int aref,lsampl_t data)
 {
+#ifdef USE_INSN
+       comedi_insn insn;
+       
+       memset(&insn,0,sizeof(insn));
+       insn.insn = INSN_WRITE;
+       insn.n = 1;
+       insn.data = &data;
+       insn.subdev = subdev;
+       insn.chanspec = CR_PACK(chan,range,aref);
+
+       return comedi_do_insn(dev,&insn);
+#else
        comedi_trig cmd;
        sampl_t sdata = data;
 
@@ -61,11 +74,24 @@ int comedi_data_write(unsigned int dev,unsigned int subdev,unsigned int chan,
        cmd.chanlist = &chan;
 
        return comedi_trig_ioctl(dev,subdev,&cmd);
+#endif
 }
 
 int comedi_data_read(unsigned int dev,unsigned int subdev,unsigned int chan,
        unsigned int range,unsigned int aref,lsampl_t *data)
 {
+#ifdef USE_INSN
+       comedi_insn insn;
+       
+       memset(&insn,0,sizeof(insn));
+       insn.insn = INSN_READ;
+       insn.n = 1;
+       insn.data = data;
+       insn.subdev = subdev;
+       insn.chanspec = CR_PACK(chan,range,aref);
+
+       return comedi_do_insn(dev,&insn);
+#else
        comedi_trig cmd;
        int ret;
        sampl_t sdata;
@@ -87,5 +113,6 @@ int comedi_data_read(unsigned int dev,unsigned int subdev,unsigned int chan,
        *data = sdata;
 
        return ret;
+#endif
 }
 
index e1be35f74f85f7316f05b44204bb09e2d65ac63b..d22bca9684718998eca414221eabcb04981d9549 100644 (file)
 #include <asm/uaccess.h>
 #endif
 
+#define USE_INSN
 
 extern volatile int rtcomedi_lock_semaphore;
 
 int comedi_dio_config(unsigned int dev,unsigned int subdev,unsigned int chan,
        unsigned int io)
 {
+#if 0
+       comedi_insn insn;
+
+       memset(&insn,0,sizeof(insn));
+       insn.insn = INSN_CONFIG;
+       insn.n = 1;
+       insn.data = &io;
+       insn.subdev = subdev;
+       insn.chanspec = CR_PACK(chan,0,0);
+
+       return comedi_do_insn(dev,&insn);
+#else
        comedi_trig cmd;
        sampl_t sdata = io;
 
@@ -60,11 +73,24 @@ int comedi_dio_config(unsigned int dev,unsigned int subdev,unsigned int chan,
        cmd.chanlist = &chan;
 
        return comedi_trig_ioctl(dev,subdev,&cmd);
+#endif
 }
 
 int comedi_dio_read(unsigned int dev,unsigned int subdev,unsigned int chan,
        unsigned int *val)
 {
+#ifdef USE_INSN
+       comedi_insn insn;
+
+       memset(&insn,0,sizeof(insn));
+       insn.insn = INSN_READ;
+       insn.n = 1;
+       insn.data = val;
+       insn.subdev = subdev;
+       insn.chanspec = CR_PACK(chan,0,0);
+
+       return comedi_do_insn(dev,&insn);
+#else
        comedi_trig cmd;
        sampl_t sdata;
        int ret;
@@ -83,11 +109,24 @@ int comedi_dio_read(unsigned int dev,unsigned int subdev,unsigned int chan,
        *val = sdata;
 
        return ret;
+#endif
 }
 
 int comedi_dio_write(unsigned int dev,unsigned int subdev,unsigned int chan,
        unsigned int val)
 {
+#ifdef USE_INSN
+       comedi_insn insn;
+
+       memset(&insn,0,sizeof(insn));
+       insn.insn = INSN_WRITE;
+       insn.n = 1;
+       insn.data = &val;
+       insn.subdev = subdev;
+       insn.chanspec = CR_PACK(chan,0,0);
+
+       return comedi_do_insn(dev,&insn);
+#else
        comedi_trig cmd;
        sampl_t sdata=val;
        int ret;
@@ -105,11 +144,32 @@ int comedi_dio_write(unsigned int dev,unsigned int subdev,unsigned int chan,
        ret = comedi_trig_ioctl(dev,subdev,&cmd);
 
        return ret;
+#endif
 }
 
 int comedi_dio_bitfield(unsigned int minor,unsigned int subdev,unsigned int mask,
        unsigned int *bits)
 {
+#ifdef USE_INSN
+       comedi_insn insn;
+       lsampl_t data[2];
+       int ret;
+
+       memset(&insn,0,sizeof(insn));
+       insn.insn = INSN_BITS;
+       insn.n = 2;
+       insn.data = data;
+       insn.subdev = subdev;
+
+       data[0] = mask;
+       data[1] = *bits;
+
+       ret = comedi_do_insn(minor,&insn);
+
+       *bits = data[1];
+
+       return ret;
+#else
        int ret;
        unsigned int i,n_chan;
        unsigned int m,bit;
@@ -133,6 +193,7 @@ int comedi_dio_bitfield(unsigned int minor,unsigned int subdev,unsigned int mask
        }
 
        return (int)n_chan;
+#endif
 }
 
 
index 0f0ae3cbc586ff2e5c099b16f989e087440c3b2d..fe7b5b853899515ace355255b00f7f937fd26972 100644 (file)
@@ -527,6 +527,97 @@ int __comedi_trig_ioctl(unsigned int minor,unsigned int subdev,comedi_trig *it)
        return ret;
 }
 
+/*
+ *     COMEDI_INSN
+ *     perform an instruction
+ */
+int comedi_do_insn(unsigned int minor,comedi_insn *insn)
+{
+       comedi_device *dev;
+       comedi_subdevice *s;
+       int ret=0;
+
+       dev=comedi_get_device_by_minor(minor);
+
+       if(insn->insn&INSN_MASK_SPECIAL){
+               switch(insn->insn){
+               case INSN_GTOD:
+               {
+                       struct timeval tv;
+                       lsampl_t data[2];
+
+                       do_gettimeofday(&tv);
+                       data[0] = tv.tv_sec;
+                       data[1] = tv.tv_usec;
+                       ret = 2;
+
+                       break;
+               }
+               case INSN_WAIT:
+                       if(insn->n<1 || insn->data[0]>=100){
+                               ret = -EINVAL;
+                               break;
+                       }
+                       udelay(insn->data[0]);
+                       ret=1;
+                       break;
+               default:
+                       ret = -EINVAL;
+               }
+       }else{
+               /* a subdevice instruction */
+               if(insn->subdev>=dev->n_subdevices){
+                       ret = -EINVAL;
+                       goto error;
+               }
+               s = dev->subdevices+insn->subdev;
+
+               if(s->type==COMEDI_SUBD_UNUSED){
+                       rt_printk("%d not useable subdevice\n",insn->subdev);
+                       goto error;
+               }
+
+               /* XXX check lock */
+
+               if((ret=check_chanlist(s,1,&insn->chanspec))<0){
+                       rt_printk("bad chanspec\n");
+                       goto error;
+               }
+
+               if(s->busy){
+                       ret = -EBUSY;
+                       goto error;
+               }
+               s->busy = (void *)&rtcomedi_lock_semaphore;
+
+               switch(insn->insn){
+                       case INSN_READ:
+                               ret = s->insn_read(dev,s,insn,insn->data);
+                               break;
+                       case INSN_WRITE:
+                               ret = s->insn_read(dev,s,insn,insn->data);
+                               break;
+                       case INSN_BITS:
+                               ret = s->insn_read(dev,s,insn,insn->data);
+                               break;
+                       default:
+                               ret=-EINVAL;
+                               break;
+               }
+
+               s->busy = NULL;
+       }
+       if(ret<0)goto error;
+       if(ret!=insn->n){
+               rt_printk("BUG: result of insn != insn.n\n");
+               ret = -EINVAL;
+               goto error;
+       }
+error:
+       
+       return ret;
+}
+
 /*
        COMEDI_LOCK
        lock subdevice