changes to bufconfig structure
authorDavid Schleef <ds@schleef.org>
Thu, 1 Mar 2001 22:25:38 +0000 (22:25 +0000)
committerDavid Schleef <ds@schleef.org>
Thu, 1 Mar 2001 22:25:38 +0000 (22:25 +0000)
comedi/comedi_fops.c
comedi/drivers.c
include/linux/comedi.h
include/linux/comedidev.h

index 1773c2d1aae378fdecf165ddd59a13913f1e36db..42f8d760016f0967d253a6dfc5d103c17b020eb6 100644 (file)
@@ -157,12 +157,10 @@ 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_async *rasync = NULL, *wasync = NULL;
+       comedi_async *async;
+       comedi_subdevice *s;
        int ret;
 
-       if(!suser())
-               return -EPERM;
-
        // perform sanity checks
        if(!dev->attached)
        {
@@ -173,74 +171,52 @@ 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)
-               rasync = dev->read_subdev->async;
-       if(dev->write_subdev)
-               wasync = dev->write_subdev->async;
-
-       if(bc.read_size){
-               if(rasync == NULL)
-               {
-                       DPRINTK("device has no read subdevice, buffer resize failed\n");
-                       return -ENODEV;
-               }
+       if(bc.subdevice>=dev->n_subdevices)
+               return -EINVAL;
+       
+       s=dev->subdevices+bc.subdevice;
+       async=s->async;
 
-               if(dev->read_subdev->busy)
-                       return -EBUSY;
+       if(!async){
+               DPRINTK("subdevice does not have async capability\n");
+               bc.size = 0;
+               bc.maximum_size = 0;
+               goto copyback;
+       }
 
-               if(rasync->mmap_count){
-                       DPRINTK("read subdevice is mmapped, cannot resize buffer\n");
-                       return -EBUSY;
-               }
+       if(bc.maximum_size){
+               if(!suser())return -EPERM;
 
-               if(!rasync->prealloc_buf)
-                       return -EINVAL;
+               async->max_bufsize = bc.maximum_size;
        }
-       if(bc.write_size){
-               if(wasync == NULL)
-               {
-                       DPRINTK("device has no write subdevice, buffer resize failed\n");
-                       return -ENODEV;
-               }
 
-               if(dev->write_subdev->busy)
-                       return -EBUSY;
+       if(bc.size){
+               if(bc.size > async->max_bufsize)
+                       return -EPERM;
 
-               if(wasync->mmap_count){
-                       DPRINTK("write subdevice is mmapped, cannot resize buffer\n");
+               if(s->busy)return -EBUSY;
+
+               if(async->mmap_count){
+                       DPRINTK("read subdevice is mmapped, cannot resize buffer\n");
                        return -EBUSY;
                }
 
-               if(!wasync->prealloc_buf)
+               if(!async->prealloc_buf)
                        return -EINVAL;
-       }
-
-       // resize buffers
-       if(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, rasync->prealloc_bufsz);
-       }
-       if(bc.write_size){
-               ret = resize_buf(dev,wasync,bc.write_size);
+               ret = resize_buf(dev,async,bc.size);
 
                if(ret < 0)
                        return ret;
 
-               DPRINTK("comedi%i write buffer resized to %i bytes\n", dev->minor, wasync->prealloc_bufsz);
+               DPRINTK("comedi%i subd %d buffer resized to %i bytes\n",
+                       dev->minor, bc.subdevice, async->prealloc_bufsz);
        }
 
-       // write back buffer sizes
-       if(rasync){
-               bc.read_size = rasync->prealloc_bufsz;
-       } else bc.read_size = 0;
-       if(wasync){
-               bc.write_size = wasync->prealloc_bufsz;
-       } else bc.write_size = 0;
+       bc.size = async->prealloc_bufsz;
+       bc.maximum_size = async->max_bufsize;
 
+copyback:
        if(copy_to_user(arg,&bc,sizeof(comedi_bufconfig)))
                return -EFAULT;
 
@@ -296,14 +272,26 @@ static int do_devinfo_ioctl(comedi_device *dev,comedi_devinfo *arg)
 {
        comedi_devinfo devinfo;
        
+       memset(&devinfo,0,sizeof(devinfo));
        
        /* fill devinfo structure */
        devinfo.version_code=COMEDI_VERSION_CODE;
        devinfo.n_subdevs=dev->n_subdevices;
        memcpy(devinfo.driver_name,dev->driver->driver_name,COMEDI_NAMELEN);
        memcpy(devinfo.board_name,dev->board_name,COMEDI_NAMELEN);
-       memcpy(devinfo.options,dev->options,COMEDI_NDEVCONFOPTS*sizeof(int));
-       
+
+       if(dev->read_subdev){
+               devinfo.read_subdevice = (dev->read_subdev - dev->subdevices)/
+                       sizeof(comedi_subdevice);
+       }else{
+               devinfo.read_subdevice = -1;
+       }
+       if(dev->write_subdev){
+               devinfo.write_subdevice = (dev->write_subdev - dev->subdevices)/
+                       sizeof(comedi_subdevice);
+       }else{
+               devinfo.write_subdevice = -1;
+       }
 
        if(copy_to_user(arg,&devinfo,sizeof(comedi_devinfo)))
                return -EFAULT;
@@ -385,6 +373,8 @@ static int do_subdinfo_ioctl(comedi_device *dev,comedi_subdinfo *arg,void *file)
                if(s->trig[4])
                        us->subd_flags |= SDF_MODE4;
 #endif
+               if(s->do_cmd)
+                       us->subd_flags |= SDF_CMD;
        }
        
        ret=copy_to_user(arg,tmp,dev->n_subdevices*sizeof(comedi_subdinfo));
@@ -924,12 +914,13 @@ 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;
        }
 
-       if(!s->do_cmd){
+       if(!s->do_cmd || !s->async){
                DPRINTK("subdevice does not support commands\n");
                return -EIO;
        }
@@ -1395,17 +1386,17 @@ 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){
+       if(dev->read_subdev && dev->read_subdev->async){
                s = dev->read_subdev;
                async = s->async;
                if(!(s->subdev_flags&SDF_RUNNING) ||
                   (async->buf_user_count < async->buf_int_count))
                        mask |= POLLIN | POLLRDNORM;
        }
-       if(dev->write_subdev){
+       if(dev->write_subdev && dev->write_subdev->async){
                s = dev->write_subdev;
                async = s->async;
-               if((!s->subdev_flags&SDF_RUNNING) ||
+               if(!(s->subdev_flags&SDF_RUNNING) ||
                   (async->buf_user_count < async->buf_int_count + async->prealloc_bufsz))
                        mask |= POLLOUT | POLLWRNORM;
        }
index 2c731af0d17254fc6b5b43796f942a4a91edb461..4a4fc44e5f9622068850402dacfa8677fe168d43 100644 (file)
@@ -297,7 +297,7 @@ static int postconfig(comedi_device *dev)
                        s->trig[4]=command_trig;
                }
                if(s->do_cmd || have_trig){
-      async = kmalloc(sizeof(comedi_async), GFP_KERNEL);
+                       async = kmalloc(sizeof(comedi_async), GFP_KERNEL);
                        if(async == NULL)
                        {
                                printk("failed to allocate async struct\n");
@@ -305,7 +305,8 @@ static int postconfig(comedi_device *dev)
                        }
                        memset(async, 0, sizeof(comedi_async));
                        s->async = async;
-                       async->prealloc_bufsz=1024*128;
+                       async->max_bufsize=64*1024;
+                       async->prealloc_bufsz=16*1024;
                        async->prealloc_buf=rvmalloc(async->prealloc_bufsz);
                        if(!async->prealloc_buf){
                                printk("ENOMEM\n");
index 7a7db09e74b0cbeaefde53b57c60afa58223afa4..a4e1915fae5250e1ca27a3b9edb8c85e023b6dc3 100644 (file)
@@ -119,6 +119,7 @@ typedef unsigned short sampl_t;
 #define SDF_MODE2      0x0200          /* can do mode 2 */
 #define SDF_MODE3      0x0400          /* can do mode 3 */
 #define SDF_MODE4      0x0800          /* can do mode 4 */
+#define SDF_CMD                0x1000          /* can do commands */
 
 #define SDF_READABLE   0x00010000      /* subdevice can be read (e.g. analog input) */
 #define SDF_WRITEABLE  0x00020000      /* subdevice can be written (e.g. analog output) */
@@ -277,7 +278,9 @@ struct comedi_devinfo_struct{
        unsigned int n_subdevs;
        char driver_name[COMEDI_NAMELEN];
        char board_name[COMEDI_NAMELEN];
-       int options[COMEDI_NDEVCONFOPTS];
+       int read_subdevice;
+       int write_subdevice;
+       int unused[30];
 };
 
 struct comedi_devconfig_struct{
@@ -286,9 +289,13 @@ struct comedi_devconfig_struct{
 };
 
 struct comedi_bufconfig_struct{
-       unsigned int read_size; /* read buffer size in bytes */
-       unsigned int write_size;        /* write buffer size in bytes */
-       unsigned int unused[5];
+       unsigned int subdevice;
+       unsigned int flags;
+
+       unsigned int maximum_size;
+       unsigned int size;
+
+       unsigned int unused[4];
 };
 
 /* range stuff */
index eaca056a0d2c245c7f3d17053da97a9f5c404778..9f5a03306084ef9fbe7860945a9a2e6251f1c895 100644 (file)
@@ -132,6 +132,7 @@ struct comedi_subdevice_struct{
 struct comedi_async_struct{
        void            *prealloc_buf;          /* pre-allocated buffer */
        unsigned int    prealloc_bufsz;         /* buffer size, in bytes */
+       unsigned int    max_bufsize;            /* maximum buffer size, 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() */