From: Frank Mori Hess Date: Mon, 16 Jul 2007 14:59:13 +0000 (+0000) Subject: Fixed devinfo ioctl for subdevice files (/dev/comediN_subM). Made X-Git-Tag: r0_7_74~49 X-Git-Url: http://git.tremily.us/?a=commitdiff_plain;h=4bd4ef55c09f87c9a015b0bb9dbec50c1a9119a7;p=comedi.git Fixed devinfo ioctl for subdevice files (/dev/comediN_subM). Made comedi subdevice type defines into an enum. --- diff --git a/comedi/comedi_fops.c b/comedi/comedi_fops.c index 4498b7c2..03ba8481 100644 --- a/comedi/comedi_fops.c +++ b/comedi/comedi_fops.c @@ -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; diff --git a/comedi/drivers.c b/comedi/drivers.c index 49997aac..8dd1c770 100644 --- a/comedi/drivers.c +++ b/comedi/drivers.c @@ -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) { diff --git a/include/linux/comedi.h b/include/linux/comedi.h index c89febdf..9bc0cf93 100644 --- a/include/linux/comedi.h +++ b/include/linux/comedi.h @@ -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 */ diff --git a/include/linux/comedidev.h b/include/linux/comedidev.h index 0c232981..ea29b5ee 100644 --- a/include/linux/comedidev.h +++ b/include/linux/comedidev.h @@ -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;