Fixed devinfo ioctl for subdevice files (/dev/comediN_subM). Made
authorFrank Mori Hess <fmhess@speakeasy.net>
Mon, 16 Jul 2007 14:59:13 +0000 (14:59 +0000)
committerFrank Mori Hess <fmhess@speakeasy.net>
Mon, 16 Jul 2007 14:59:13 +0000 (14:59 +0000)
comedi subdevice type defines into an enum.

comedi/comedi_fops.c
comedi/drivers.c
include/linux/comedi.h
include/linux/comedidev.h

index 4498b7c20207cc7df99fa51ecfa3c6171ba6aed4..03ba84814ae95024b31ccf0469995d66b8693fde 100644 (file)
@@ -64,7 +64,7 @@ spinlock_t big_comedi_lock; /* Dynamic initialization */
 
 static int do_devconfig_ioctl(comedi_device *dev,comedi_devconfig *arg);
 static int do_bufconfig_ioctl(comedi_device *dev,void *arg);
-static int do_devinfo_ioctl(comedi_device *dev,comedi_devinfo *arg);
+static int do_devinfo_ioctl(comedi_device *dev,comedi_devinfo *arg, struct file *file);
 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);
@@ -104,7 +104,7 @@ static int comedi_ioctl(struct inode * inode,struct file * file,
        case COMEDI_BUFCONFIG:
                return do_bufconfig_ioctl(dev,(void*)arg);
        case COMEDI_DEVINFO:
-               return do_devinfo_ioctl(dev,(void *)arg);
+               return do_devinfo_ioctl(dev,(void *)arg, file);
        case COMEDI_SUBDINFO:
                return do_subdinfo_ioctl(dev,(void *)arg,file);
        case COMEDI_CHANINFO:
@@ -297,9 +297,12 @@ copyback:
                devinfo structure
 
 */
-static int do_devinfo_ioctl(comedi_device *dev,comedi_devinfo *arg)
+static int do_devinfo_ioctl(comedi_device *dev, comedi_devinfo *arg, struct file *file)
 {
        comedi_devinfo devinfo;
+       const unsigned minor = iminor(file->f_dentry->d_inode);
+       comedi_subdevice *read_subdev = comedi_get_read_subdevice(dev, minor);
+       comedi_subdevice *write_subdev = comedi_get_write_subdevice(dev, minor);
 
        memset(&devinfo,0,sizeof(devinfo));
 
@@ -309,13 +312,13 @@ static int do_devinfo_ioctl(comedi_device *dev,comedi_devinfo *arg)
        memcpy(devinfo.driver_name,dev->driver->driver_name,COMEDI_NAMELEN);
        memcpy(devinfo.board_name,dev->board_name,COMEDI_NAMELEN);
 
-       if(dev->read_subdev){
-               devinfo.read_subdevice = dev->read_subdev - dev->subdevices;
+       if(read_subdev){
+               devinfo.read_subdevice = read_subdev - dev->subdevices;
        }else{
                devinfo.read_subdevice = -1;
        }
-       if(dev->write_subdev){
-               devinfo.write_subdevice = dev->write_subdev - dev->subdevices;
+       if(write_subdev){
+               devinfo.write_subdevice = write_subdev - dev->subdevices;
        }else{
                devinfo.write_subdevice = -1;
        }
@@ -1283,15 +1286,14 @@ static int comedi_mmap(struct file * file, struct vm_area_struct *vma)
                DPRINTK("no driver configured on comedi%i\n", dev->minor);
                return -ENODEV;
        }
-       s = comedi_get_subdevice_by_minor(minor);
-       if(s == NULL)
-       {       if(vma->vm_flags & VM_WRITE){
-                       s = dev->write_subdev;
-               }else{
-                       s = dev->read_subdev;
-               }
-               if(s == NULL) return -EINVAL;
+       if(vma->vm_flags & VM_WRITE)
+       {
+               s = comedi_get_write_subdevice(dev, minor);
+       }else
+       {
+               s = comedi_get_read_subdevice(dev, minor);
        }
+       if(s == NULL) return -EINVAL;
        async = s->async;
        if(async==NULL){
                return -EINVAL;
@@ -1381,10 +1383,9 @@ static ssize_t comedi_write(struct file *file,const char *buf,size_t nbytes,loff
                return -ENODEV;
        }
 
-       s = comedi_get_subdevice_by_minor(minor);
+       s = comedi_get_write_subdevice(dev, minor);
        if(s == NULL)
-               s = dev->write_subdev;
-       if(s == NULL || s->async == NULL || (s->subdev_flags & SDF_CMD_WRITE) == 0) return -EIO;
+               return -EIO;
        async = s->async;
 
        if(!nbytes)return 0;
@@ -1469,10 +1470,8 @@ static ssize_t comedi_read(struct file * file,char *buf,size_t nbytes,loff_t *of
                return -ENODEV;
        }
 
-       s = comedi_get_subdevice_by_minor(minor);
-       if(s == NULL)
-               s = dev->read_subdev;
-       if(s == NULL || s->async == NULL || (s->subdev_flags & SDF_CMD_READ) == 0) return -EIO;
+       s = comedi_get_read_subdevice(dev, minor);
+       if(s == NULL) return -EIO;
        async = s->async;
        if(!nbytes)return 0;
 
index 49997aac155c68718a2b1b2093a8788e913dfc4a..8dd1c77025c2e6efcd117d925173f7fb6ca8b9c9 100644 (file)
@@ -265,6 +265,8 @@ static int postconfig(comedi_device *dev)
                        unsigned minor;
                        dev_t devt;
 
+                       BUG_ON((s->subdev_flags & (SDF_CMD_READ | SDF_CMD_WRITE)) == 0);
+
                        async = kmalloc(sizeof(comedi_async), GFP_KERNEL);
                        if(async == NULL)
                        {
index c89febdfde5047f2c1ded1f9ff347a3af8cf48d6..9bc0cf9342b352e8d11cfe0e765b53fd563ce60d 100644 (file)
@@ -202,18 +202,21 @@ typedef unsigned short sampl_t;
 
 /* subdevice types */
 
-#define COMEDI_SUBD_UNUSED              0      /* unused */
-#define COMEDI_SUBD_AI                  1      /* analog input */
-#define COMEDI_SUBD_AO                  2      /* analog output */
-#define COMEDI_SUBD_DI                  3      /* digital input */
-#define COMEDI_SUBD_DO                  4      /* digital output */
-#define COMEDI_SUBD_DIO                 5      /* digital input/output */
-#define COMEDI_SUBD_COUNTER             6      /* counter */
-#define COMEDI_SUBD_TIMER               7      /* timer */
-#define COMEDI_SUBD_MEMORY              8      /* memory, EEPROM, DPRAM */
-#define COMEDI_SUBD_CALIB               9      /* calibration DACs */
-#define COMEDI_SUBD_PROC                10     /* processor, DSP */
-#define COMEDI_SUBD_SERIAL              11     /* serial IO */
+enum comedi_subdevice_type
+{
+       COMEDI_SUBD_UNUSED,     /* unused by driver */
+       COMEDI_SUBD_AI, /* analog input */
+       COMEDI_SUBD_AO, /* analog output */
+       COMEDI_SUBD_DI, /* digital input */
+       COMEDI_SUBD_DO, /* digital output */
+       COMEDI_SUBD_DIO,        /* digital input/output */
+       COMEDI_SUBD_COUNTER,    /* counter */
+       COMEDI_SUBD_TIMER,      /* timer */
+       COMEDI_SUBD_MEMORY,     /* memory, EEPROM, DPRAM */
+       COMEDI_SUBD_CALIB,      /* calibration DACs */
+       COMEDI_SUBD_PROC,       /* processor, DSP */
+       COMEDI_SUBD_SERIAL      /* serial IO */
+};
 
 /* configuration instructions */
 
index 0c232981b112fdc3f19bfbd5b6ae3df3cd770f44..ea29b5ee3fab32c5714043f543d438623fca27ee 100644 (file)
@@ -304,6 +304,30 @@ static inline comedi_subdevice * comedi_get_subdevice_by_minor(unsigned minor)
        return dev->subdevices + subdevice_index;
 }
 
+static inline comedi_subdevice* comedi_get_read_subdevice(comedi_device *dev, unsigned minor)
+{
+       comedi_subdevice *read_subdev = comedi_get_subdevice_by_minor(minor);
+       if(read_subdev == NULL)
+       {
+               read_subdev = dev->read_subdev;
+       }
+       if(read_subdev == NULL || read_subdev->async == NULL || (read_subdev->subdev_flags & SDF_CMD_READ) == 0)
+               return NULL;
+       return read_subdev;
+}
+
+static inline comedi_subdevice* comedi_get_write_subdevice(comedi_device *dev, unsigned minor)
+{
+       comedi_subdevice *write_subdev = comedi_get_subdevice_by_minor(minor);
+       if(write_subdev == NULL)
+       {
+               write_subdev = dev->write_subdev;
+       }
+       if(write_subdev == NULL || write_subdev->async == NULL || (write_subdev->subdev_flags & SDF_CMD_WRITE) == 0)
+               return NULL;
+       return write_subdev;
+}
+
 static inline unsigned comedi_construct_minor_for_subdevice(comedi_device *dev, unsigned subdevice_index)
 {
        unsigned minor = 0;