From: Frank Mori Hess Date: Wed, 15 Nov 2006 21:25:28 +0000 (+0000) Subject: Added support for generating a seperate device file for each X-Git-Tag: r0_7_74~155 X-Git-Url: http://git.tremily.us/?a=commitdiff_plain;h=14b55728c85b77fa4dba9c5b16d045bba72439d5;p=comedi.git Added support for generating a seperate device file for each subdevice that supports commands. Subdevices need to indicate which directions they support commands in with the new subdevice flags SDF_CMD_READ and SDF_CMD_WRITE. Breaks compatibility with 2.4 kernels. Currently, only 8-bit minor numbers are used, limiting the maximum subdevice to 15. This should be easily changeable once more distros support 20-bit minor numbers. --- diff --git a/comedi/comedi_fops.c b/comedi/comedi_fops.c index 0bc54ee1..8385d09f 100644 --- a/comedi/comedi_fops.c +++ b/comedi/comedi_fops.c @@ -24,6 +24,8 @@ #undef DEBUG #define __NO_VERSION__ +#include "comedi_fops.h" + #include #include #include @@ -40,8 +42,8 @@ #include #include #include - #include +#include #include #include @@ -60,7 +62,7 @@ module_param(comedi_debug, int, 0644); comedi_device *comedi_devices; spinlock_t big_comedi_lock; /* Dynamic initialization */ -static int do_devconfig_ioctl(comedi_device *dev,comedi_devconfig *arg,unsigned int minor); +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_subdinfo_ioctl(comedi_device *dev,comedi_subdinfo *arg,void *file); @@ -82,19 +84,19 @@ static int comedi_fasync (int fd, struct file *file, int on); static void init_async_buf( comedi_async *async ); static int comedi_ioctl(struct inode * inode,struct file * file, - unsigned int cmd,unsigned long arg) + unsigned int cmd, unsigned long arg) { - unsigned int minor=MINOR(inode->i_rdev); - comedi_device *dev=comedi_get_device_by_minor(minor); + const unsigned minor = iminor(inode); + comedi_device *dev = comedi_get_device_by_minor(minor); /* Device config is special, because it must work on * an unconfigured device. */ if(cmd==COMEDI_DEVCONFIG){ - return do_devconfig_ioctl(dev,(void *)arg,minor); + return do_devconfig_ioctl(dev,(void *)arg); } if(!dev->attached){ - DPRINTK("no driver configured on /dev/comedi%i\n", minor); + DPRINTK("no driver configured on /dev/comedi%i\n", dev->minor); return -ENODEV; } @@ -147,7 +149,7 @@ static int comedi_ioctl(struct inode * inode,struct file * file, writes: none */ -static int do_devconfig_ioctl(comedi_device *dev,comedi_devconfig *arg, unsigned int minor) +static int do_devconfig_ioctl(comedi_device *dev, comedi_devconfig *arg) { comedi_devconfig it; int ret; @@ -269,7 +271,7 @@ static int do_bufconfig_ioctl(comedi_device *dev,void *arg) } DPRINTK("comedi%i subd %d buffer resized to %i bytes\n", - MINOR(dev->devt), bc.subdevice, async->prealloc_bufsz); + dev->minor, bc.subdevice, async->prealloc_bufsz); } bc.size = async->prealloc_bufsz; @@ -366,7 +368,7 @@ static int do_subdinfo_ioctl(comedi_device *dev,comedi_subdinfo *arg,void *file) us->len_chanlist = s->len_chanlist; us->maxdata = s->maxdata; if(s->range_table){ - us->range_type = (MINOR(dev->devt) << 28) | (i << 24) | (0 << 16) | + us->range_type = (dev->minor << 28) | (i << 24) | (0 << 16) | (s->range_table->length); }else{ us->range_type = 0; /* XXX */ @@ -447,7 +449,7 @@ static int do_chaninfo_ioctl(comedi_device *dev,comedi_chaninfo *arg) for(i=0;in_chan;i++){ int x; - x=(MINOR(dev->devt) << 28) | (it.subdev << 24) | (i << 16) | + x=(dev->minor << 28) | (it.subdev << 24) | (i << 16) | (s->range_table_list[i]->length); put_user(x,it.rangelist+i); } @@ -484,10 +486,8 @@ static int do_bufinfo_ioctl(comedi_device *dev,void *arg) if(bi.subdevice >= dev->n_subdevices || bi.subdevice < 0) return -EINVAL; - s=dev->subdevices + bi.subdevice; - async=s->async; - - if(s!=dev->read_subdev && s!=dev->write_subdev)return -EINVAL; + s = dev->subdevices + bi.subdevice; + async = s->async; if(!async){ DPRINTK("subdevice does not have async capability\n"); @@ -498,7 +498,7 @@ static int do_bufinfo_ioctl(comedi_device *dev,void *arg) goto copyback; } - if(bi.bytes_read && s==dev->read_subdev){ + if(bi.bytes_read && (s->subdev_flags & SDF_CMD_READ)){ comedi_buf_read_free(async, bi.bytes_read); if(!(s->subdev_flags&SDF_RUNNING) && @@ -508,7 +508,7 @@ static int do_bufinfo_ioctl(comedi_device *dev,void *arg) } } - if(bi.bytes_written && s==dev->write_subdev){ + if(bi.bytes_written && (s->subdev_flags & SDF_CMD_WRITE)){ bi.bytes_written = comedi_buf_write_alloc( async, bi.bytes_written ); comedi_buf_munge(dev, s, async->buf_write_alloc_count - async->munge_count); comedi_buf_write_free(async, bi.bytes_written); @@ -518,9 +518,10 @@ static int do_bufinfo_ioctl(comedi_device *dev,void *arg) bi.buf_write_ptr = async->buf_write_ptr; bi.buf_read_count = async->buf_read_count; bi.buf_read_ptr = async->buf_read_ptr; - if(s==dev->read_subdev){ + /* FIXME this will bug if we ever have a subdevice that supports both read and write commands. + We need a flag saying which direction the current command is going (CMDF_WRITE?) */ + if((s->subdev_flags & SDF_CMD_READ)){ unsigned int n_munge_bytes; - n_munge_bytes = bi.buf_write_count - s->async->munge_count; comedi_buf_munge(dev, s, n_munge_bytes); } @@ -1261,8 +1262,6 @@ static int do_cancel(comedi_device *dev,comedi_subdevice *s) } -#define RDEV_OF_FILE(x) ((x)->f_dentry->d_inode->i_rdev) - void comedi_unmap(struct vm_area_struct *area) { comedi_async *async; @@ -1278,7 +1277,7 @@ static struct vm_operations_struct comedi_vm_ops={ static int comedi_mmap(struct file * file, struct vm_area_struct *vma) { - unsigned int minor = MINOR(RDEV_OF_FILE(file)); + const unsigned minor = iminor(file->f_dentry->d_inode); comedi_device *dev = comedi_get_device_by_minor(minor); comedi_async *async = NULL; unsigned long start = vma->vm_start; @@ -1288,15 +1287,19 @@ static int comedi_mmap(struct file * file, struct vm_area_struct *vma) if(!dev->attached) { - DPRINTK("no driver configured on comedi%i\n", minor); + DPRINTK("no driver configured on comedi%i\n", dev->minor); return -ENODEV; } - - if(vma->vm_flags & VM_WRITE){ - async=dev->write_subdev->async; - }else{ - async=dev->read_subdev->async; + comedi_subdevice *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; } + async = s->async; if(async==NULL){ return -EINVAL; } @@ -1332,16 +1335,15 @@ static int comedi_mmap(struct file * file, struct vm_area_struct *vma) static unsigned int comedi_poll(struct file *file, poll_table * wait) { - comedi_device *dev; comedi_subdevice *s; comedi_async *async; unsigned int mask; - - dev=comedi_get_device_by_minor(MINOR(RDEV_OF_FILE(file))); + const unsigned minor = iminor(file->f_dentry->d_inode); + comedi_device *dev = comedi_get_device_by_minor(minor); if(!dev->attached) { - DPRINTK("no driver configured on comedi%i\n", MINOR(dev->devt)); + DPRINTK("no driver configured on comedi%i\n", dev->minor); return -ENODEV; } @@ -1377,17 +1379,19 @@ static ssize_t comedi_write(struct file *file,const char *buf,size_t nbytes,loff comedi_async *async; int n,m,count=0,retval=0; DECLARE_WAITQUEUE(wait,current); - - dev=comedi_get_device_by_minor(MINOR(RDEV_OF_FILE(file))); + const unsigned minor = iminor(file->f_dentry->d_inode); + dev = comedi_get_device_by_minor(minor); if(!dev->attached) { - DPRINTK("no driver configured on comedi%i\n", MINOR(dev->devt)); + DPRINTK("no driver configured on comedi%i\n", dev->minor); return -ENODEV; } - if(dev->write_subdev == NULL)return -EIO; - s = dev->write_subdev; + s = comedi_get_subdevice_by_minor(minor); + if(s == NULL) + s = dev->write_subdev; + if(s == NULL || s->async == NULL || (s->subdev_flags & SDF_CMD_WRITE) == 0) return -EIO; async = s->async; if(!nbytes)return 0; @@ -1458,22 +1462,23 @@ static ssize_t comedi_write(struct file *file,const char *buf,size_t nbytes,loff static ssize_t comedi_read(struct file * file,char *buf,size_t nbytes,loff_t *offset) { - comedi_device *dev; comedi_subdevice *s; comedi_async *async; int n,m,count=0,retval=0; DECLARE_WAITQUEUE(wait,current); - - dev=comedi_get_device_by_minor(MINOR(RDEV_OF_FILE(file))); + const unsigned minor = iminor(file->f_dentry->d_inode); + comedi_device *dev = comedi_get_device_by_minor(minor); if(!dev->attached) { - DPRINTK("no driver configured on comedi%i\n", MINOR(dev->devt)); + DPRINTK("no driver configured on comedi%i\n", dev->minor); return -ENODEV; } - s = dev->read_subdev; - if(s == NULL)return -EIO; + 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; async = s->async; if(!nbytes)return 0; @@ -1579,10 +1584,9 @@ void do_become_nonbusy(comedi_device *dev,comedi_subdevice *s) static loff_t comedi_lseek(struct file *file,loff_t offset,int origin) { - comedi_device *dev; loff_t new_offset; - - dev=comedi_get_device_by_minor(MINOR(RDEV_OF_FILE(file))); + const unsigned minor = iminor(file->f_dentry->d_inode); + comedi_device *dev = comedi_get_device_by_minor(minor); switch(origin){ case SEEK_SET: @@ -1603,17 +1607,16 @@ static loff_t comedi_lseek(struct file *file,loff_t offset,int origin) return file->f_pos=new_offset; } -static int comedi_open(struct inode *inode,struct file *file) +static int comedi_open(struct inode *inode, struct file *file) { - unsigned int minor=MINOR(inode->i_rdev); - comedi_device *dev; char mod[32]; - - if(minor>=COMEDI_NDEVICES){ + const unsigned minor = iminor(inode); + comedi_device *dev = comedi_get_device_by_minor(minor); + if(dev == NULL) + { DPRINTK("invalid minor number\n"); return -ENODEV; } - dev=comedi_get_device_by_minor(minor); /* This is slightly hacky, but we want module autoloading * to work for root. @@ -1639,7 +1642,7 @@ static int comedi_open(struct inode *inode,struct file *file) dev->in_request_module=1; - sprintf(mod,"char-major-%i-%i",COMEDI_MAJOR,minor); + sprintf(mod,"char-major-%i-%i", COMEDI_MAJOR, dev->minor); #ifdef CONFIG_KMOD request_module(mod); #endif @@ -1669,7 +1672,8 @@ ok: static int comedi_close(struct inode *inode,struct file *file) { - comedi_device *dev=comedi_get_device_by_minor(MINOR(inode->i_rdev)); + const unsigned minor = iminor(inode); + comedi_device *dev = comedi_get_device_by_minor(minor); comedi_subdevice *s = NULL; int i; @@ -1706,13 +1710,14 @@ static int comedi_close(struct inode *inode,struct file *file) static int comedi_fasync (int fd, struct file *file, int on) { - comedi_device *dev=comedi_get_device_by_minor(MINOR(RDEV_OF_FILE(file))); + const unsigned minor = iminor(file->f_dentry->d_inode); + comedi_device *dev = comedi_get_device_by_minor(minor); return fasync_helper(fd,file,on,&dev->async_queue); } -static struct file_operations comedi_fops={ +struct file_operations comedi_fops={ owner : THIS_MODULE, llseek : comedi_lseek, ioctl : comedi_ioctl, @@ -1725,30 +1730,40 @@ static struct file_operations comedi_fops={ fasync : comedi_fasync, }; -static struct class *comedi_class; +struct class *comedi_class = NULL; +static struct cdev comedi_cdev; static int __init comedi_init(void) { int i; + int retval; printk("comedi: version " COMEDI_RELEASE " - David Schleef \n"); spin_lock_init(&big_comedi_lock); - if(devfs_register_chrdev(COMEDI_MAJOR,"comedi",&comedi_fops)){ - printk("comedi: unable to get major %d\n",COMEDI_MAJOR); + retval = register_chrdev_region(MKDEV(COMEDI_MAJOR, 0), COMEDI_NUM_MINORS, "comedi"); + if(retval) return -EIO; + cdev_init(&comedi_cdev, &comedi_fops); + comedi_cdev.owner = THIS_MODULE; + kobject_set_name(&comedi_cdev.kobj, "comedi"); + if(cdev_add(&comedi_cdev, MKDEV(COMEDI_MAJOR, 0), COMEDI_NUM_MINORS)) + { + unregister_chrdev_region(MKDEV(COMEDI_MAJOR, 0), COMEDI_NUM_MINORS); return -EIO; } comedi_class = class_create(THIS_MODULE, "comedi"); if(IS_ERR(comedi_class)) { printk("comedi: failed to create class"); - devfs_unregister_chrdev(COMEDI_MAJOR,"comedi"); + unregister_chrdev_region(MKDEV(COMEDI_MAJOR, 0), COMEDI_NUM_MINORS); + cdev_del(&comedi_cdev); return PTR_ERR(comedi_class); } comedi_devices=(comedi_device *)kmalloc(sizeof(comedi_device)*COMEDI_NDEVICES,GFP_KERNEL); if(!comedi_devices) { + unregister_chrdev_region(MKDEV(COMEDI_MAJOR, 0), COMEDI_NUM_MINORS); + cdev_del(&comedi_cdev); class_destroy(comedi_class); - devfs_unregister_chrdev(COMEDI_MAJOR,"comedi"); return -ENOMEM; } memset(comedi_devices,0,sizeof(comedi_device)*COMEDI_NDEVICES); @@ -1758,14 +1773,10 @@ static int __init comedi_init(void) for(i=0;idevt; - comedi_devices[i].minor = MINOR(class_dev->devt); spin_lock_init(&comedi_devices[i].spinlock); } @@ -1784,20 +1795,19 @@ static void __exit comedi_cleanup(void) for(i = 0; i < COMEDI_NDEVICES; i++){ comedi_device *dev; - dev=comedi_get_device_by_minor(i); + dev = comedi_devices + i; if(dev->attached) comedi_device_detach(dev); } for(i = 0; i < COMEDI_NDEVICES; i++){ char name[20]; - class_device_destroy(comedi_class, comedi_devices[i].devt); + class_device_destroy(comedi_class, comedi_devices[i].class_dev->devt); sprintf(name, "comedi%d", i); - devfs_unregister(devfs_find_handle(NULL, name, - COMEDI_MAJOR, i, DEVFS_SPECIAL_CHR, 0)); } class_destroy(comedi_class); - devfs_unregister_chrdev(COMEDI_MAJOR,"comedi"); + cdev_del(&comedi_cdev); + unregister_chrdev_region(MKDEV(COMEDI_MAJOR, 0), COMEDI_NUM_MINORS); comedi_proc_cleanup(); @@ -1811,7 +1821,7 @@ module_exit(comedi_cleanup); void comedi_error(const comedi_device *dev,const char *s) { - rt_printk("comedi%d: %s: %s\n", MINOR(dev->devt), dev->driver->driver_name, s); + rt_printk("comedi%d: %s: %s\n", dev->minor, dev->driver->driver_name, s); } void comedi_event(comedi_device *dev,comedi_subdevice *s, unsigned int mask) @@ -1841,19 +1851,19 @@ void comedi_event(comedi_device *dev,comedi_subdevice *s, unsigned int mask) if(dev->rt){ #ifdef CONFIG_COMEDI_RT // pend wake up - if(s==dev->read_subdev) + if(s->subdev_flags & SDF_CMD_READ) comedi_rt_pend_wakeup(&dev->read_wait); - if(s==dev->write_subdev) + if(s->subdev_flags & SDF_CMD_WRITE) comedi_rt_pend_wakeup(&dev->write_wait); #else printk("BUG: comedi_event() code unreachable\n"); #endif }else{ - if(s==dev->read_subdev){ + if(s->subdev_flags & SDF_CMD_READ){ wake_up_interruptible(&dev->read_wait); kill_fasync(&dev->async_queue, SIGIO, POLL_IN); } - if(s==dev->write_subdev){ + if(s->subdev_flags & SDF_CMD_WRITE){ wake_up_interruptible(&dev->write_wait); kill_fasync(&dev->async_queue, SIGIO, POLL_OUT); } diff --git a/comedi/comedi_fops.h b/comedi/comedi_fops.h new file mode 100644 index 00000000..987cc3c6 --- /dev/null +++ b/comedi/comedi_fops.h @@ -0,0 +1,8 @@ + +#ifndef _COMEDI_FOPS_H +#define _COMEDI_FOPS_H + +extern struct class *comedi_class; +extern struct file_operations comedi_fops; + +#endif //_COMEDI_FOPS_H diff --git a/comedi/drivers.c b/comedi/drivers.c index 7ebc8196..f42a4036 100644 --- a/comedi/drivers.c +++ b/comedi/drivers.c @@ -24,6 +24,8 @@ #define _GNU_SOURCE #define __NO_VERSION__ +#include "comedi_fops.h" +#include #include #include #include @@ -37,6 +39,7 @@ #include #include /* for SuSE brokenness */ #include +#include #include #include @@ -68,6 +71,10 @@ static void cleanup_device_allocations(comedi_device *dev) for(i = 0; i < dev->n_subdevices; i++) { s = dev->subdevices + i; + if(s->class_dev) + { + class_device_destroy(comedi_class, s->class_dev->devt); + } if(s->async) { comedi_buf_alloc(dev, s, 0); @@ -205,7 +212,7 @@ int comedi_driver_unregister(comedi_driver *driver) for(i=0;iattached && dev->driver==driver){ if(dev->use_count) printk("BUG! detaching device with use_count=%d\n",dev->use_count); @@ -229,15 +236,7 @@ int comedi_driver_unregister(comedi_driver *driver) comedi_device *comedi_allocate_dev(comedi_driver *driver) { - comedi_device *dev; - - // XXX we need to do actual allocation here. - - dev=comedi_get_device_by_minor(0); - - dev->driver=driver; - - return dev; + return NULL; } void comedi_deallocate_dev(comedi_device *dev) @@ -262,6 +261,9 @@ static int postconfig(comedi_device *dev) s->len_chanlist=1; if(s->do_cmd){ + unsigned minor; + dev_t devt; + async = kmalloc(sizeof(comedi_async), GFP_KERNEL); if(async == NULL) { @@ -286,6 +288,10 @@ static int postconfig(comedi_device *dev) ret = s->buf_change(dev,s,DEFAULT_BUF_SIZE); if(ret < 0)return ret; } + minor = comedi_construct_minor_for_subdevice(dev, i); + devt = MKDEV(COMEDI_MAJOR, minor); + s->class_dev = COMEDI_CLASS_DEVICE_CREATE(comedi_class, dev->class_dev, + devt, NULL, "comedi%i_sub%i", dev->minor, i); } if(!s->range_table && !s->range_table_list) diff --git a/comedi/drivers/adl_pci9111.c b/comedi/drivers/adl_pci9111.c index fc07b071..7028475c 100644 --- a/comedi/drivers/adl_pci9111.c +++ b/comedi/drivers/adl_pci9111.c @@ -1391,7 +1391,7 @@ found: dev->read_subdev = subdevice; subdevice->type = COMEDI_SUBD_AI; - subdevice->subdev_flags = SDF_READABLE|SDF_COMMON; + subdevice->subdev_flags = SDF_READABLE | SDF_COMMON | SDF_CMD_READ; // // TODO: Add external multiplexer data diff --git a/comedi/drivers/adl_pci9118.c b/comedi/drivers/adl_pci9118.c index be18c9ba..be3c8727 100644 --- a/comedi/drivers/adl_pci9118.c +++ b/comedi/drivers/adl_pci9118.c @@ -1833,6 +1833,7 @@ static int pci9118_attach(comedi_device *dev,comedi_devconfig *it) s->cancel=pci9118_ai_cancel; s->insn_read=pci9118_insn_read_ai; if (dev->irq) { + s->subdev_flags |= SDF_CMD_READ; s->do_cmdtest=pci9118_ai_cmdtest; s->do_cmd=pci9118_ai_cmd; s->munge=pci9118_ai_munge; diff --git a/comedi/drivers/adv_pci1710.c b/comedi/drivers/adv_pci1710.c index 0fc1c5cc..787b6549 100644 --- a/comedi/drivers/adv_pci1710.c +++ b/comedi/drivers/adv_pci1710.c @@ -1333,6 +1333,7 @@ static int pci1710_attach(comedi_device *dev,comedi_devconfig *it) s->cancel=pci171x_ai_cancel; s->insn_read=pci171x_insn_read_ai; if (irq) { + s->subdev_flags |= SDF_CMD_READ; s->do_cmdtest=pci171x_ai_cmdtest; s->do_cmd=pci171x_ai_cmd; } diff --git a/comedi/drivers/amplc_dio200.c b/comedi/drivers/amplc_dio200.c index 85022b12..a051d505 100644 --- a/comedi/drivers/amplc_dio200.c +++ b/comedi/drivers/amplc_dio200.c @@ -916,7 +916,7 @@ dio200_subdev_intr_init(comedi_device *dev, comedi_subdevice *s, s->private = subpriv; s->type = COMEDI_SUBD_DI; - s->subdev_flags = SDF_READABLE; + s->subdev_flags = SDF_READABLE | SDF_CMD_READ; if (has_int_sce) { s->n_chan = DIO200_MAX_ISNS; s->len_chanlist = DIO200_MAX_ISNS; diff --git a/comedi/drivers/amplc_pc236.c b/comedi/drivers/amplc_pc236.c index 0485f98e..8136fab4 100644 --- a/comedi/drivers/amplc_pc236.c +++ b/comedi/drivers/amplc_pc236.c @@ -293,7 +293,7 @@ static int pc236_attach(comedi_device *dev,comedi_devconfig *it) PC236_DRIVER_NAME, dev) >= 0) { dev->irq = irq; s->type = COMEDI_SUBD_DI; - s->subdev_flags = SDF_READABLE; + s->subdev_flags = SDF_READABLE | SDF_CMD_READ; s->n_chan = 1; s->maxdata = 1; s->range_table = &range_digital; diff --git a/comedi/drivers/amplc_pci224.c b/comedi/drivers/amplc_pci224.c index cc54cc64..7be2eaa1 100644 --- a/comedi/drivers/amplc_pci224.c +++ b/comedi/drivers/amplc_pci224.c @@ -1403,7 +1403,7 @@ pci224_attach(comedi_device *dev,comedi_devconfig *it) s = dev->subdevices + 0; /* Analog output subdevice. */ s->type = COMEDI_SUBD_AO; - s->subdev_flags = SDF_WRITABLE | SDF_GROUND; + s->subdev_flags = SDF_WRITABLE | SDF_GROUND | SDF_CMD_WRITE; s->n_chan = thisboard->ao_chans; s->maxdata = (1 << thisboard->ao_bits) - 1; s->insn_write = &pci224_ao_insn_write; diff --git a/comedi/drivers/amplc_pci230.c b/comedi/drivers/amplc_pci230.c index c4f75fe8..37d48d34 100644 --- a/comedi/drivers/amplc_pci230.c +++ b/comedi/drivers/amplc_pci230.c @@ -31,7 +31,7 @@ Status: works */ /* -extra triggered scan functionality, interrupt bug-fix added by Steve Sharples +extra triggered scan functionality, interrupt bug-fix added by Steve Sharples */ #include @@ -62,7 +62,7 @@ extra triggered scan functionality, interrupt bug-fix added by Steve Sharples #define PCI230_ZCLK_SCE 0x1A /* Group Z Clock Configuration Register */ #define PCI230_ZGAT_SCE 0x1D /* Group Z Gate Configuration Register */ #define PCI230_INT_SCE 0x1E /* ISR Interrupt source mask register/Interrupt status */ - + /* PCI230 i/o space 2 registers. */ #define PCI230_DACCON 0x00 #define PCI230_DACOUT1 0x02 @@ -74,8 +74,8 @@ extra triggered scan functionality, interrupt bug-fix added by Steve Sharples #define PCI230_ADCG 0x0E /* Convertor related constants. */ -#define PCI230_DAC_SETTLE 5 /* Analogue output settling time in µs (DAC itself is 1µs nominally). */ -#define PCI230_ADC_SETTLE 1 /* Analogue input settling time in µs (ADC itself is 1.6µs nominally but we poll anyway). */ +#define PCI230_DAC_SETTLE 5 /* Analogue output settling time in µs (DAC itself is 1µs nominally). */ +#define PCI230_ADC_SETTLE 1 /* Analogue input settling time in µs (ADC itself is 1.6µs nominally but we poll anyway). */ #define PCI230_MUX_SETTLE 10 /* ADC MUX settling time in µS - 10µs for se, 20µs de. */ /* DACCON values. */ @@ -117,13 +117,13 @@ extra triggered scan functionality, interrupt bug-fix added by Steve Sharples #define PCI230_ZCLK_CT2 16 #define PCI230_ZCLK_RES 24 #define PCI230_ZCLK_SRC_PPCN 0 /* The counter/timer's CLK input from the SK1 connector. */ -#define PCI230_ZCLK_SRC_10MHZ 1 /* The internal 10MHz clock. */ -#define PCI230_ZCLK_SRC_1MHZ 2 /* The internal 1MHz clock. */ -#define PCI230_ZCLK_SRC_100KHZ 3 /* The internal 100kHz clock. */ -#define PCI230_ZCLK_SRC_10KHZ 4 /* The internal 10kHz clock. */ -#define PCI230_ZCLK_SRC_1KHZ 5 /* The internal 1kHz clock. */ -#define PCI230_ZCLK_SRC_OUTNM1 6 /* The output of the preceding counter/timer channel (OUT n-1). */ -#define PCI230_ZCLK_SRC_EXTCLK 7 /* The dedicated external clock input for the group (X1/X2, Y1/Y2, Z1/Z2). */ +#define PCI230_ZCLK_SRC_10MHZ 1 /* The internal 10MHz clock. */ +#define PCI230_ZCLK_SRC_1MHZ 2 /* The internal 1MHz clock. */ +#define PCI230_ZCLK_SRC_100KHZ 3 /* The internal 100kHz clock. */ +#define PCI230_ZCLK_SRC_10KHZ 4 /* The internal 10kHz clock. */ +#define PCI230_ZCLK_SRC_1KHZ 5 /* The internal 1kHz clock. */ +#define PCI230_ZCLK_SRC_OUTNM1 6 /* The output of the preceding counter/timer channel (OUT n-1). */ +#define PCI230_ZCLK_SRC_EXTCLK 7 /* The dedicated external clock input for the group (X1/X2, Y1/Y2, Z1/Z2). */ /* Group Z gate configuration register values. */ #define PCI230_ZGAT_CT0 0 @@ -163,7 +163,7 @@ typedef struct pci230_board_struct{ int ai_bits; int have_ao; int ao_chans; - int ao_bits; + int ao_bits; int have_dio; }pci230_board; static pci230_board pci230_boards[] = { @@ -207,15 +207,15 @@ MODULE_DEVICE_TABLE(pci, pci230_pci_table); struct pci230_private{ struct pci_dev *pci_dev; lsampl_t ao_readback[2]; /* Used for AO readback */ - unsigned long pci_iobase; /* PCI230's I/O space 1 */ - /* Divisors for 8254 counter/timer. */ + unsigned long pci_iobase; /* PCI230's I/O space 1 */ + /* Divisors for 8254 counter/timer. */ unsigned int clk_src0; /* which clock to use for the counter/timers: 10MHz, 1MHz, 100kHz etc */ unsigned int clk_src1; unsigned int clk_src2; unsigned int divisor0; unsigned int divisor1; unsigned int divisor2; - unsigned int int_en; /* Interrupt enables bits. */ + unsigned int int_en; /* Interrupt enables bits. */ unsigned int ai_count; /* Number of analogue input samples remaining. */ unsigned int ao_count; /* Number of analogue output samples remaining. */ unsigned int ai_stop; /* Flag set when cmd->stop_src == TRIG_NONE - user chooses to stop continuous conversion by cancelation. */ @@ -227,7 +227,7 @@ struct pci230_private{ #define devpriv ((struct pci230_private *)dev->private) -/* PCI230 analogue input range table */ +/* PCI230 analogue input range table */ static comedi_lrange pci230_ai_range = { 7, { BIP_RANGE(10), BIP_RANGE(5), @@ -238,7 +238,7 @@ static comedi_lrange pci230_ai_range = { 7, { UNI_RANGE(2.5) }}; -/* PCI230 analogue output range table */ +/* PCI230 analogue output range table */ static comedi_lrange pci230_ao_range = { 2, { UNI_RANGE(10), BIP_RANGE(10) @@ -292,7 +292,7 @@ static int pci230_ai_cancel(comedi_device *dev, comedi_subdevice *s); static void pci230_handle_ai(comedi_device *dev, comedi_subdevice *s); static void pci230_handle_fifo_half_full(comedi_device *dev, comedi_subdevice *s); static void pci230_handle_fifo_not_empty(comedi_device *dev, comedi_subdevice *s); - + static sampl_t pci230_ai_read(comedi_device *dev) { /* Read sample. */ @@ -301,7 +301,7 @@ static sampl_t pci230_ai_read(comedi_device *dev) /* PCI230 is 12 bit - stored in upper bits of 16 bit register (lower four bits reserved for expansion). */ data = data>>4; - /* If a bipolar range was specified, mangle it (twos complement->straight binary). */ + /* If a bipolar range was specified, mangle it (twos complement->straight binary). */ if (devpriv->ai_bipolar) { data ^= 1<<(thisboard->ai_bits-1); } @@ -310,14 +310,14 @@ static sampl_t pci230_ai_read(comedi_device *dev) static void pci230_ao_write(comedi_device *dev, sampl_t data, int chan) { - /* If a bipolar range was specified, mangle it (straight binary->twos complement). */ + /* If a bipolar range was specified, mangle it (straight binary->twos complement). */ if (devpriv->ao_bipolar) { data ^= 1<<(thisboard->ao_bits-1); } - + /* PCI230 is 12 bit - stored in upper bits of 16 bit register (lower four bits reserved for expansion). */ data = data<<4; - + /* Write data. */ outw((unsigned int) data, dev->iobase + (((chan) == 0) ? PCI230_DACOUT1 : PCI230_DACOUT2)); } @@ -336,14 +336,14 @@ static int pci230_attach(comedi_device *dev,comedi_devconfig *it) int i=0,irq_hdl; printk("comedi%d: amplc_pci230\n",dev->minor); - + /* Allocate the private structure area using alloc_private(). * Macro defined in comedidev.h - memsets struct fields to 0. */ if((alloc_private(dev,sizeof(struct pci230_private)))<0){ return -ENOMEM; } /* Find card */ - for(pci_dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, NULL); pci_dev != NULL ; + for(pci_dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, NULL); pci_dev != NULL ; pci_dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, pci_dev)) { if(pci_dev->vendor != PCI_VENDOR_ID_AMPLICON) continue; @@ -360,7 +360,7 @@ static int pci230_attach(comedi_device *dev,comedi_devconfig *it) } devpriv->pci_dev = pci_dev; dev->board_ptr = pci230_boards+i; - + /* Read base addressses of the PCI230's two I/O regions from PCI configuration register. */ if(pci_enable_device(pci_dev)<0){ return -EIO; @@ -398,7 +398,7 @@ static int pci230_attach(comedi_device *dev,comedi_devconfig *it) dev->irq = devpriv->pci_dev->irq; printk("comedi%d: amplc_pci230: registered irq %u\n", dev->minor, devpriv->pci_dev->irq); } - + /* * Allocate the subdevice structures. alloc_subdevice() is a * convenient macro defined in comedidev.h. @@ -418,6 +418,7 @@ static int pci230_attach(comedi_device *dev,comedi_devconfig *it) /* Only register commands if the interrupt handler is installed. */ if(irq_hdl==0) { dev->read_subdev=s; + s->subdev_flags |= SDF_CMD_READ; s->do_cmd = &pci230_ai_cmd; s->do_cmdtest = &pci230_ai_cmdtest; s->cancel = pci230_ai_cancel; @@ -436,6 +437,7 @@ static int pci230_attach(comedi_device *dev,comedi_devconfig *it) /* Only register commands if the interrupt handler is installed. */ if(irq_hdl==0) { dev->write_subdev=s; + s->subdev_flags |= SDF_CMD_WRITE; s->do_cmd = &pci230_ao_cmd; s->do_cmdtest = &pci230_ao_cmdtest; s->cancel = pci230_ao_cancel; @@ -467,7 +469,7 @@ static int pci230_attach(comedi_device *dev,comedi_devconfig *it) /* * _detach is called to deconfigure a device. It should deallocate - * resources. + * resources. * This function is also called when _attach() fails, so it should be * careful not to release resources that were not necessarily * allocated by _attach(). dev->private and dev->subdevices are @@ -493,13 +495,13 @@ static int pci230_detach(comedi_device *dev) pci_dev_put(devpriv->pci_dev); } } - + return 0; } /* - * COMEDI_SUBD_AI instruction; - */ + * COMEDI_SUBD_AI instruction; + */ static int pci230_ai_rinsn(comedi_device *dev,comedi_subdevice *s,comedi_insn *insn,lsampl_t *data) { int n,i; @@ -518,7 +520,7 @@ static int pci230_ai_rinsn(comedi_device *dev,comedi_subdevice *s,comedi_insn *i if (aref==AREF_DIFF) { /* Differential. */ adcen = 3<<2*chan; - adccon |= PCI230_ADC_IM_DIF; + adccon |= PCI230_ADC_IM_DIF; if (devpriv->ai_bipolar) { adccon |= PCI230_ADC_IR_BIP; adcg = range<<(2*chan-2*chan%2); @@ -531,7 +533,7 @@ static int pci230_ai_rinsn(comedi_device *dev,comedi_subdevice *s,comedi_insn *i else { /* Single ended. */ adcen = 1<ai_bipolar) { adccon |= PCI230_ADC_IR_BIP; adcg = range<<(chan-chan%2); @@ -578,13 +580,13 @@ static int pci230_ai_rinsn(comedi_device *dev,comedi_subdevice *s,comedi_insn *i } /* - * COMEDI_SUBD_AO instructions; - */ + * COMEDI_SUBD_AO instructions; + */ static int pci230_ao_winsn(comedi_device *dev,comedi_subdevice *s,comedi_insn *insn,lsampl_t *data) { int i; int chan, range; - + /* Unpack channel and range. */ chan = CR_CHAN(insn->chanspec); range = CR_RANGE(insn->chanspec); @@ -621,18 +623,18 @@ static int pci230_ao_rinsn(comedi_device *dev,comedi_subdevice *s,comedi_insn *i } /* - * COMEDI_SUBD_TIMER instructions; - * + * COMEDI_SUBD_TIMER instructions; + * * insn_config allows user to start and stop counter/timer 2 (SK1 pin 21). * Period specified in ns. * - * rinsn returns counter/timer's actual period in ns. + * rinsn returns counter/timer's actual period in ns. */ static int pci230_ct_insn_config(comedi_device *dev,comedi_subdevice *s, comedi_insn *insn,lsampl_t *data) { unsigned int ns; - + if(insn->n!=1)return -EINVAL; ns = data[0]; @@ -651,7 +653,7 @@ static int pci230_ct_insn_config(comedi_device *dev,comedi_subdevice *s, static int pci230_ct_rinsn(comedi_device *dev,comedi_subdevice *s,comedi_insn *insn,lsampl_t *data) { if(insn->n!=1)return -EINVAL; - + /* Return the actual period set in ns. */ data[0] = PCI230_TIMEBASE_10MHZ*devpriv->divisor1*devpriv->divisor2; return 1; @@ -671,7 +673,7 @@ static int pci230_ao_cmdtest(comedi_device *dev,comedi_subdevice *s, * the command passes. */ /* Step 1: make sure trigger sources are trivially valid. - * "invalid source" returned by comedilib to user mode process + * "invalid source" returned by comedilib to user mode process * if this fails. */ tmp=cmd->start_src; @@ -697,7 +699,7 @@ static int pci230_ao_cmdtest(comedi_device *dev,comedi_subdevice *s, if(err)return 1; /* Step 2: make sure trigger sources are unique and mutually compatible - * "source conflict" returned by comedilib to user mode process + * "source conflict" returned by comedilib to user mode process * if this fails. */ if(cmd->stop_src!=TRIG_COUNT && @@ -706,7 +708,7 @@ static int pci230_ao_cmdtest(comedi_device *dev,comedi_subdevice *s, if(err)return 2; /* Step 3: make sure arguments are trivially compatible. - * "invalid argument" returned by comedilib to user mode process + * "invalid argument" returned by comedilib to user mode process * if this fails. */ if(cmd->start_arg!=0){ @@ -743,7 +745,7 @@ static int pci230_ao_cmdtest(comedi_device *dev,comedi_subdevice *s, if(err)return 3; /* Step 4: fix up any arguments. - * "argument conflict" returned by comedilib to user mode process + * "argument conflict" returned by comedilib to user mode process * if this fails. */ if(cmd->scan_begin_src==TRIG_TIMER){ @@ -789,7 +791,7 @@ static int pci230_ao_cmd(comedi_device *dev,comedi_subdevice *s) devpriv->ao_count = 0; devpriv->ao_stop = 1; } - + /* Disable DAC interrupt. */ devpriv->ier &= ~PCI230_INT_ZCLK_CT1; outb(devpriv->ier, devpriv->pci_iobase + PCI230_INT_SCE); @@ -828,7 +830,7 @@ static int pci230_ai_cmdtest(comedi_device *dev,comedi_subdevice *s, * the command passes. */ /* Step 1: make sure trigger sources are trivially valid. - * "invalid source" returned by comedilib to user mode process + * "invalid source" returned by comedilib to user mode process * if this fails. */ tmp=cmd->start_src; @@ -862,7 +864,7 @@ static int pci230_ai_cmdtest(comedi_device *dev,comedi_subdevice *s, if(err)return 1; /* Step 2: make sure trigger sources are unique and mutually compatible - * "source conflict" returned by comedilib to user mode process + * "source conflict" returned by comedilib to user mode process * if this fails. */ if(cmd->start_src!=TRIG_NOW)err++; @@ -872,10 +874,10 @@ static int pci230_ai_cmdtest(comedi_device *dev,comedi_subdevice *s, cmd->convert_src!=TRIG_EXT)err++; if(cmd->stop_src!=TRIG_COUNT && cmd->stop_src!=TRIG_NONE)err++; - + /* Although the scan and convert triggers come from different sources, the * driver relies on the knowledge of convert rate to trigger the correct number - * of channels. If the is not known (ie if convert_src==TRIG_EXT) then the + * of channels. If the is not known (ie if convert_src==TRIG_EXT) then the * scan trigger will not work correctly. * The convert trigger is the input into the "EXT TRIG" line (pin 25), whilst * the scan trigger is "PPC0" (pin 49). */ @@ -885,7 +887,7 @@ static int pci230_ai_cmdtest(comedi_device *dev,comedi_subdevice *s, if(err)return 2; /* Step 3: make sure arguments are trivially compatible. - * "invalid argument" returned by comedilib to user mode process + * "invalid argument" returned by comedilib to user mode process * if this fails. */ if(cmd->start_arg!=0){ @@ -941,7 +943,7 @@ static int pci230_ai_cmdtest(comedi_device *dev,comedi_subdevice *s, if(err)return 3; /* Step 4: fix up any arguments. - * "argument conflict" returned by comedilib to user mode process + * "argument conflict" returned by comedilib to user mode process * if this fails. */ if(cmd->convert_src==TRIG_TIMER){ @@ -984,7 +986,7 @@ static int pci230_ai_cmd(comedi_device *dev,comedi_subdevice *s) * - PAUSE (25us) - failure to do this leads to "dodgy data" for the first few channels at high convert rates. * - Enable conversion complete interrupt. * - Set the counter timers to the specified sampling frequency. - * - Enable AND RESET FIFO (yes you do need to do this twice), set FIFO interrupt trigger level, set start conversion source to counter 2. + * - Enable AND RESET FIFO (yes you do need to do this twice), set FIFO interrupt trigger level, set start conversion source to counter 2. */ /* Disable ADC interrupt. */ @@ -994,12 +996,12 @@ static int pci230_ai_cmd(comedi_device *dev,comedi_subdevice *s) if (CR_AREF(cmd->chanlist[0])==AREF_DIFF) { /* Differential - all channels must be differential. */ diff = 1; - adccon = PCI230_ADC_IM_DIF; + adccon = PCI230_ADC_IM_DIF; } else { /* Single ended - all channels must be single-ended. */ diff = 0; - adccon = PCI230_ADC_IM_SE; + adccon = PCI230_ADC_IM_SE; } adccon |= PCI230_ADC_FIFO_RESET | PCI230_ADC_FIFO_EN; @@ -1009,7 +1011,7 @@ static int pci230_ai_cmd(comedi_device *dev,comedi_subdevice *s) /* If bit 2 of range unset, range is referring to bipolar element in range table */ range = CR_RANGE(cmd->chanlist[0]); - devpriv->ai_bipolar = !PCI230_TEST_BIT(range, 2); + devpriv->ai_bipolar = !PCI230_TEST_BIT(range, 2); if (devpriv->ai_bipolar) { adccon |= PCI230_ADC_IR_BIP; for (i = 0; i < cmd->chanlist_len; i++) { @@ -1076,7 +1078,7 @@ static int pci230_ai_cmd(comedi_device *dev,comedi_subdevice *s) * This pulse is then used as to gate the counter responsible for your * convert source. * - * So, if your conversion rate is set to 100kHz (10us/conversion) and you + * So, if your conversion rate is set to 100kHz (10us/conversion) and you * have 8 channels in your channel list, a positive edge on PPC0 will * trigger a pulse of length 80us (8 x 10us). Because the two counters * involved have the same clock source, the monostable pulse will always @@ -1130,7 +1132,7 @@ static int pci230_ai_cmd(comedi_device *dev,comedi_subdevice *s) else { /* Trigger on -ve edge. */ adccon = adccon | PCI230_ADC_TRIG_EXTN; - } + } } @@ -1225,7 +1227,7 @@ static void i8253_single_ns_to_timer(unsigned int i8253_osc_base, unsigned int * break; case TRIG_ROUND_DOWN: div=(*nanosec + i8253_osc_base + 1 ) / i8253_osc_base; - break; + break; } *nanosec = div * i8253_osc_base; @@ -1274,7 +1276,7 @@ static void pci230_setup_monostable_ct0(comedi_device *dev, unsigned int ns, uns #if 0 -/* +/* * Set ZCLK_CT0 to square wave mode with period of ns. */ static void pci230_z2_ct0(comedi_device *dev, unsigned int *ns,int round) @@ -1316,7 +1318,7 @@ static void pci230_cancel_ct0(comedi_device *dev) } #endif -/* +/* * Set ZCLK_CT1 to square wave mode with period of ns. * Default clk source for DAC. */ @@ -1356,7 +1358,7 @@ static void pci230_cancel_ct1(comedi_device *dev) i8254_load(devpriv->pci_iobase + PCI230_Z2_CT0, 1, devpriv->divisor1, 0); /* Counter 1, divisor1, 8254 mode 0. */ } -/* +/* * Set ZCLK_CT2 to square wave mode with period of ns. * Default clk source for ADC. */ @@ -1412,16 +1414,16 @@ static irqreturn_t pci230_interrupt(int irq, void *d, struct pt_regs *regs) /* Disable all of board's interrupts. * (Only those interrrupts that need re-enabling, are, later in the handler). */ - devpriv->ier = PCI230_INT_DISABLE; + devpriv->ier = PCI230_INT_DISABLE; outb(devpriv->ier, devpriv->pci_iobase + PCI230_INT_SCE); - /* + /* * Check the source of interrupt and handle it. * The PCI230 can cope with concurrent ADC, DAC, PPI C0 and C3 interrupts. * However, at present (Comedi-0.7.60) does not allow concurrent * execution of commands, instructions or a mixture of the two. */ - + if (status_int & PCI230_INT_ZCLK_CT1) { s = dev->write_subdev; s->async->events = 0; @@ -1481,7 +1483,7 @@ static void pci230_handle_ao(comedi_device *dev, comedi_subdevice *s) { static void pci230_handle_ai(comedi_device *dev, comedi_subdevice *s) { int error = 0; int status_fifo; - + /* Read FIFO state. */ status_fifo = inw(dev->iobase + PCI230_ADCCON); @@ -1506,7 +1508,7 @@ static void pci230_handle_ai(comedi_device *dev, comedi_subdevice *s) { if (error) { /* Cancel sampled conversion. */ s->async->events |= COMEDI_CB_ERROR | COMEDI_CB_EOA; - pci230_ai_cancel(dev, s); + pci230_ai_cancel(dev, s); }else if(devpriv->ai_count == 0 && devpriv->ai_stop == 0) { /* Acquisition complete. */ s->async->events |= COMEDI_CB_EOA; diff --git a/comedi/drivers/cb_das16_cs.c b/comedi/drivers/cb_das16_cs.c index aa38a195..19bf2b78 100644 --- a/comedi/drivers/cb_das16_cs.c +++ b/comedi/drivers/cb_das16_cs.c @@ -168,7 +168,7 @@ static int das16cs_attach(comedi_device *dev,comedi_devconfig *it) int i; printk("comedi%d: cb_das16_cs: ",dev->minor); - + link = dev_list; /* XXX hack */ if(!link)return -EIO; @@ -204,7 +204,7 @@ static int das16cs_attach(comedi_device *dev,comedi_devconfig *it) dev->read_subdev=s; /* analog input subdevice */ s->type=COMEDI_SUBD_AI; - s->subdev_flags=SDF_READABLE|SDF_GROUND|SDF_DIFF; + s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_DIFF | SDF_CMD_READ; s->n_chan=16; s->maxdata=0xffff; s->range_table=&das16cs_ai_range; @@ -238,7 +238,7 @@ static int das16cs_attach(comedi_device *dev,comedi_devconfig *it) }else{ s->type = COMEDI_SUBD_UNUSED; } - + s=dev->subdevices+3; /* timer subdevice */ if(0){ @@ -265,7 +265,7 @@ static int das16cs_detach(comedi_device *dev) if(dev->irq){ comedi_free_irq(dev->irq, dev); } - + return 0; } @@ -445,7 +445,7 @@ static int das16cs_ai_cmdtest(comedi_device *dev,comedi_subdevice *s, unsigned int div1, div2; tmp=cmd->scan_begin_arg; - i8253_cascade_ns_to_timer(100, &div1, &div2, + i8253_cascade_ns_to_timer(100, &div1, &div2, &cmd->scan_begin_arg, cmd->flags&TRIG_ROUND_MASK); if(tmp!=cmd->scan_begin_arg)err++; } @@ -453,7 +453,7 @@ static int das16cs_ai_cmdtest(comedi_device *dev,comedi_subdevice *s, unsigned int div1, div2; tmp=cmd->convert_arg; - i8253_cascade_ns_to_timer(100, &div1, &div2, + i8253_cascade_ns_to_timer(100, &div1, &div2, &cmd->scan_begin_arg, cmd->flags&TRIG_ROUND_MASK); if(tmp!=cmd->convert_arg)err++; if(cmd->scan_begin_src==TRIG_TIMER && @@ -1043,7 +1043,7 @@ struct pcmcia_driver das16cs_driver = .owner = THIS_MODULE, .drv = { .name = dev_info, - }, + }, }; static int __init init_das16cs_pcmcia_cs(void) diff --git a/comedi/drivers/cb_pcidas.c b/comedi/drivers/cb_pcidas.c index 3975d0c3..98d7b47f 100644 --- a/comedi/drivers/cb_pcidas.c +++ b/comedi/drivers/cb_pcidas.c @@ -43,7 +43,7 @@ Status: The boards may be autocalibrated using the comedi_calibrate utility. - + Configuration options: [0] - PCI bus of device (optional) [1] - PCI slot of device (optional) @@ -522,8 +522,8 @@ static int cb_pcidas_attach(comedi_device *dev, comedi_devconfig *it) */ printk("\n"); - for(pcidev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, NULL); pcidev != NULL ; - pcidev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, pcidev)) + for(pcidev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, NULL); pcidev != NULL ; + pcidev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, pcidev)) { // is it not a computer boards card? if(pcidev->vendor != PCI_VENDOR_ID_CB) @@ -575,13 +575,13 @@ found: * Initialize devpriv->control_status and devpriv->adc_fifo to point to * their base address. */ - devpriv->s5933_config = pci_resource_start(devpriv->pci_dev, S5933_BADRINDEX); - devpriv->control_status = pci_resource_start(devpriv->pci_dev, CONT_STAT_BADRINDEX); - devpriv->adc_fifo = pci_resource_start(devpriv->pci_dev, ADC_FIFO_BADRINDEX); - devpriv->pacer_counter_dio = pci_resource_start(devpriv->pci_dev, PACER_BADRINDEX); + devpriv->s5933_config = pci_resource_start(devpriv->pci_dev, S5933_BADRINDEX); + devpriv->control_status = pci_resource_start(devpriv->pci_dev, CONT_STAT_BADRINDEX); + devpriv->adc_fifo = pci_resource_start(devpriv->pci_dev, ADC_FIFO_BADRINDEX); + devpriv->pacer_counter_dio = pci_resource_start(devpriv->pci_dev, PACER_BADRINDEX); if(thisboard->ao_nchan) { - devpriv->ao_registers = pci_resource_start(devpriv->pci_dev, AO_BADRINDEX); + devpriv->ao_registers = pci_resource_start(devpriv->pci_dev, AO_BADRINDEX); } // get irq @@ -605,7 +605,7 @@ found: /* analog input subdevice */ dev->read_subdev = s; s->type = COMEDI_SUBD_AI; - s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_DIFF; + s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_DIFF | SDF_CMD_READ; /* WARNING: Number of inputs in differential mode is ignored */ s->n_chan = thisboard->ai_se_chans; s->len_chanlist = thisboard->ai_se_chans; @@ -631,6 +631,7 @@ found: if(thisboard->has_ao_fifo) { dev->write_subdev = s; + s->subdev_flags |= SDF_CMD_WRITE; s->insn_write = cb_pcidas_ao_fifo_winsn; s->do_cmdtest = cb_pcidas_ao_cmdtest; s->do_cmd = cb_pcidas_ao_cmd; diff --git a/comedi/drivers/cb_pcidas64.c b/comedi/drivers/cb_pcidas64.c index 7aa3f4cc..8b506564 100644 --- a/comedi/drivers/cb_pcidas64.c +++ b/comedi/drivers/cb_pcidas64.c @@ -46,7 +46,7 @@ Devices: [Measurement Computing] PCI-DAS6402/16 (cb_pcidas64), PCI-DAS6402/12, PCI-DAS64/M1/16, PCI-DAS64/M2/16, PCI-DAS64/M3/16, PCI-DAS6402/16/JR, PCI-DAS64/M1/16/JR, PCI-DAS64/M2/16/JR, PCI-DAS64/M3/16/JR, PCI-DAS64/M1/14, - PCI-DAS64/M2/14, PCI-DAS64/M3/14, PCI-DAS6014, + PCI-DAS64/M2/14, PCI-DAS64/M3/14, PCI-DAS6014, PCI-DAS6023, PCI-DAS6025, PCI-DAS6030, PCI-DAS6031, PCI-DAS6032, PCI-DAS6033, PCI-DAS6034, PCI-DAS6035, PCI-DAS6036, PCI-DAS6040, PCI-DAS6052, @@ -1355,7 +1355,7 @@ static int setup_subdevices(comedi_device *dev) /* analog input subdevice */ dev->read_subdev = s; s->type = COMEDI_SUBD_AI; - s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_DITHER; + s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_DITHER | SDF_CMD_READ; if(board(dev)->layout == LAYOUT_60XX) s->subdev_flags |= SDF_COMMON | SDF_DIFF; else if(board(dev)->layout == LAYOUT_64XX) @@ -1388,7 +1388,7 @@ static int setup_subdevices(comedi_device *dev) if(board(dev)->ao_nchan) { s->type = COMEDI_SUBD_AO; - s->subdev_flags = SDF_READABLE | SDF_WRITABLE | SDF_GROUND; + s->subdev_flags = SDF_READABLE | SDF_WRITABLE | SDF_GROUND | SDF_CMD_WRITE; s->n_chan = board(dev)->ao_nchan; s->maxdata = (1 << board(dev)->ao_bits) - 1; s->range_table = board(dev)->ao_range_table; @@ -1658,8 +1658,8 @@ static int attach(comedi_device *dev, comedi_devconfig *it) * Probe the device to determine what device in the series it is. */ - for(pcidev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, NULL); pcidev != NULL ; - pcidev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, pcidev)) + for(pcidev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, NULL); pcidev != NULL ; + pcidev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, pcidev)) { // is it not a computer boards card? if( pcidev->vendor != PCI_VENDOR_ID_COMPUTERBOARDS ) @@ -1970,7 +1970,7 @@ static int ai_config_calibration_source( comedi_device *dev, lsampl_t *data ) { lsampl_t source = data[1]; int num_calibration_sources; - + if( board(dev)->layout == LAYOUT_60XX) num_calibration_sources = 16; else @@ -2440,7 +2440,7 @@ static void select_master_clock( comedi_device *dev, const comedi_cmd *cmd ) static inline void dma_start_sync(comedi_device *dev, unsigned int channel) { unsigned long flags; - + // spinlock for plx dma control/status reg comedi_spin_lock_irqsave( &dev->spinlock, flags ); if(channel) @@ -3921,7 +3921,7 @@ static int caldac_8800_write(comedi_device *dev, unsigned int address, uint8_t v writew(SELECT_8800_BIT, priv(dev)->main_iobase + CALIBRATION_REG); comedi_udelay(caldac_8800_udelay); writew(0, priv(dev)->main_iobase + CALIBRATION_REG); - comedi_udelay(caldac_8800_udelay); + comedi_udelay(caldac_8800_udelay); return 0; } diff --git a/comedi/drivers/cb_pcidda.c b/comedi/drivers/cb_pcidda.c index 080eb9ad..ec3d8118 100644 --- a/comedi/drivers/cb_pcidda.c +++ b/comedi/drivers/cb_pcidda.c @@ -284,7 +284,7 @@ static int cb_pcidda_attach(comedi_device *dev, comedi_devconfig *it) */ printk("\n"); - for(pcidev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, NULL); pcidev != NULL ; + for(pcidev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, NULL); pcidev != NULL ; pcidev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, pcidev)) { if(pcidev->vendor==PCI_VENDOR_ID_CB){ if(it->options[0] || it->options[1]){ @@ -358,8 +358,9 @@ found: s->maxdata = (1 << thisboard->ao_bits) - 1; s->range_table = thisboard->ranges; s->insn_write = cb_pcidda_ao_winsn; -// s->do_cmd = cb_pcidda_ai_cmd; - s->do_cmdtest = cb_pcidda_ai_cmdtest; +// s->subdev_flags |= SDF_CMD_READ; +// s->do_cmd = cb_pcidda_ai_cmd; +// s->do_cmdtest = cb_pcidda_ai_cmdtest; // two 8255 digital io subdevices s = dev->subdevices + 1; diff --git a/comedi/drivers/comedi_parport.c b/comedi/drivers/comedi_parport.c index 7c8c9814..c4f2da9e 100644 --- a/comedi/drivers/comedi_parport.c +++ b/comedi/drivers/comedi_parport.c @@ -123,7 +123,7 @@ static int parport_insn_a(comedi_device *dev,comedi_subdevice *s, return 2; } - + static int parport_insn_config_a(comedi_device *dev,comedi_subdevice *s, comedi_insn *insn,lsampl_t *data) { @@ -138,7 +138,7 @@ static int parport_insn_config_a(comedi_device *dev,comedi_subdevice *s, return 1; } - + static int parport_insn_b(comedi_device *dev,comedi_subdevice *s, comedi_insn *insn,lsampl_t *data) { @@ -340,10 +340,10 @@ static int parport_attach(comedi_device *dev,comedi_devconfig *it) s->insn_bits = parport_insn_c; s=dev->subdevices+3; - dev->read_subdev=s; if(irq){ + dev->read_subdev=s; s->type=COMEDI_SUBD_DI; - s->subdev_flags=SDF_READABLE; + s->subdev_flags=SDF_READABLE | SDF_CMD_READ; s->n_chan=1; s->maxdata=1; s->range_table=&range_digital; @@ -368,7 +368,7 @@ static int parport_attach(comedi_device *dev,comedi_devconfig *it) static int parport_detach(comedi_device *dev) { printk("comedi%d: parport: remove\n",dev->minor); - + if(dev->iobase)release_region(dev->iobase,PARPORT_SIZE); if(dev->irq)comedi_free_irq(dev->irq,dev); diff --git a/comedi/drivers/comedi_rt_timer.c b/comedi/drivers/comedi_rt_timer.c index cdd75b1c..fa131ee9 100644 --- a/comedi/drivers/comedi_rt_timer.c +++ b/comedi/drivers/comedi_rt_timer.c @@ -634,12 +634,14 @@ static int timer_attach(comedi_device *dev,comedi_devconfig *it) case COMEDI_SUBD_AI: s->insn_read=timer_insn; dev->read_subdev = s; + s->subdev_flags |= SDF_CMD_READ; devpriv->io_function = timer_data_read; break; case COMEDI_SUBD_AO: s->insn_write=timer_insn; s->insn_read=timer_insn; dev->write_subdev = s; + s->subdev_flags |= SDF_CMD_WRITE; devpriv->io_function = timer_data_write; break; case COMEDI_SUBD_DIO: @@ -647,6 +649,7 @@ static int timer_attach(comedi_device *dev,comedi_devconfig *it) s->insn_read=timer_insn; s->insn_bits=timer_insn; dev->read_subdev = s; + s->subdev_flags |= SDF_CMD_READ; devpriv->io_function = timer_dio_read; break; default: @@ -703,7 +706,7 @@ static int timer_detach(comedi_device *dev) if(devpriv->timer_running) stop_rt_timer(); if(devpriv->device) - comedi_close(devpriv->device); + comedi_close(devpriv->device); } return 0; } diff --git a/comedi/drivers/comedi_test.c b/comedi/drivers/comedi_test.c index 5e753ba9..8fbd0017 100644 --- a/comedi/drivers/comedi_test.c +++ b/comedi/drivers/comedi_test.c @@ -211,7 +211,7 @@ static int waveform_attach(comedi_device *dev,comedi_devconfig *it) dev->read_subdev = s; /* analog input subdevice */ s->type = COMEDI_SUBD_AI; - s->subdev_flags = SDF_READABLE | SDF_GROUND; + s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_CMD_READ; s->n_chan = thisboard->ai_chans; s->maxdata = (1 << thisboard->ai_bits) - 1; s->range_table = &waveform_ai_ranges; diff --git a/comedi/drivers/das16.c b/comedi/drivers/das16.c index 438bb2da..6fc2fe83 100644 --- a/comedi/drivers/das16.c +++ b/comedi/drivers/das16.c @@ -1557,7 +1557,7 @@ static int das16_attach(comedi_device *dev, comedi_devconfig *it) /* ai */ if(thisboard->ai){ s->type = COMEDI_SUBD_AI; - s->subdev_flags = SDF_READABLE; + s->subdev_flags = SDF_READABLE | SDF_CMD_READ; if(devpriv->ai_singleended){ s->n_chan = 16; s->len_chanlist = 16; diff --git a/comedi/drivers/das16m1.c b/comedi/drivers/das16m1.c index 26b918dc..436621f9 100644 --- a/comedi/drivers/das16m1.c +++ b/comedi/drivers/das16m1.c @@ -689,7 +689,7 @@ static int das16m1_attach(comedi_device *dev, comedi_devconfig *it) dev->read_subdev = s; /* ai */ s->type = COMEDI_SUBD_AI; - s->subdev_flags = SDF_READABLE; + s->subdev_flags = SDF_READABLE | SDF_CMD_READ; s->n_chan = 8; s->subdev_flags = SDF_DIFF; s->len_chanlist = 256; diff --git a/comedi/drivers/das1800.c b/comedi/drivers/das1800.c index cdcec9b3..e92ebcdb 100644 --- a/comedi/drivers/das1800.c +++ b/comedi/drivers/das1800.c @@ -705,7 +705,7 @@ static int das1800_attach(comedi_device *dev, comedi_devconfig *it) s = dev->subdevices + 0; dev->read_subdev = s; s->type = COMEDI_SUBD_AI; - s->subdev_flags = SDF_READABLE | SDF_DIFF | SDF_GROUND; + s->subdev_flags = SDF_READABLE | SDF_DIFF | SDF_GROUND | SDF_CMD_READ; if(thisboard->common) s->subdev_flags |= SDF_COMMON; s->n_chan = thisboard->qram_len; diff --git a/comedi/drivers/das800.c b/comedi/drivers/das800.c index 8683bd9b..d96768c4 100644 --- a/comedi/drivers/das800.c +++ b/comedi/drivers/das800.c @@ -517,7 +517,7 @@ static int das800_attach(comedi_device *dev, comedi_devconfig *it) s = dev->subdevices + 0; dev->read_subdev = s; s->type = COMEDI_SUBD_AI; - s->subdev_flags = SDF_READABLE | SDF_GROUND; + s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_CMD_READ; s->n_chan = 8; s->len_chanlist = 8; s->maxdata = (1 << thisboard->resolution) - 1; diff --git a/comedi/drivers/dmm32at.c b/comedi/drivers/dmm32at.c index da6d4ac0..63f29e5d 100644 --- a/comedi/drivers/dmm32at.c +++ b/comedi/drivers/dmm32at.c @@ -433,7 +433,7 @@ static int dmm32at_attach(comedi_device *dev,comedi_devconfig *it) /* analog input subdevice */ s->type=COMEDI_SUBD_AI; /* we support single-ended (ground) and differential */ - s->subdev_flags=SDF_READABLE|SDF_GROUND|SDF_DIFF; + s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_DIFF | SDF_CMD_READ; s->n_chan=thisboard->ai_chans; s->maxdata=(1<ai_bits)-1; s->range_table=thisboard->ai_ranges; diff --git a/comedi/drivers/dt2814.c b/comedi/drivers/dt2814.c index 30f8a671..bdcee406 100644 --- a/comedi/drivers/dt2814.c +++ b/comedi/drivers/dt2814.c @@ -110,7 +110,7 @@ comedi_udelay(10); data[n]=(hi<<4)|(lo>>4); } - + return n; } @@ -227,7 +227,7 @@ static int dt2814_ai_cmd(comedi_device *dev,comedi_subdevice *s) devpriv->ntrig=cmd->stop_arg; outb(chan|DT2814_ENB|(trigvar<<5), dev->iobase+DT2814_CSR); - + return 0; } @@ -263,7 +263,7 @@ static int dt2814_attach(comedi_device *dev,comedi_devconfig *it) save_flags(flags); sti(); irqs=probe_irq_on(); - + outb(0,dev->iobase+DT2814_CSR); comedi_udelay(100); @@ -301,7 +301,7 @@ static int dt2814_attach(comedi_device *dev,comedi_devconfig *it) s=dev->subdevices+0; dev->read_subdev = s; s->type=COMEDI_SUBD_AI; - s->subdev_flags=SDF_READABLE|SDF_GROUND; + s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_CMD_READ; s->n_chan=16; /* XXX */ s->len_chanlist=1; s->insn_read = dt2814_ai_insn_read; @@ -317,7 +317,7 @@ static int dt2814_attach(comedi_device *dev,comedi_devconfig *it) static int dt2814_detach(comedi_device *dev) { printk("comedi%d: dt2814: remove\n",dev->minor); - + if(dev->irq){ comedi_free_irq(dev->irq,dev); } diff --git a/comedi/drivers/dt282x.c b/comedi/drivers/dt282x.c index cf09ef0c..c688709f 100644 --- a/comedi/drivers/dt282x.c +++ b/comedi/drivers/dt282x.c @@ -1305,7 +1305,8 @@ static int dt282x_attach(comedi_device * dev, comedi_devconfig * it) dev->read_subdev=s; /* ai subdevice */ s->type=COMEDI_SUBD_AI; - s->subdev_flags=SDF_READABLE|((it->options[opt_diff])?SDF_DIFF:SDF_COMMON); + s->subdev_flags=SDF_READABLE | SDF_CMD_READ | + ((it->options[opt_diff])?SDF_DIFF:SDF_COMMON); s->n_chan=(it->options[opt_diff])?boardtype.adchan_di:boardtype.adchan_se; s->insn_read=dt282x_ai_insn_read; s->do_cmdtest=dt282x_ai_cmdtest; @@ -1321,7 +1322,7 @@ static int dt282x_attach(comedi_device * dev, comedi_devconfig * it) /* ao subsystem */ s->type=COMEDI_SUBD_AO; dev->write_subdev=s; - s->subdev_flags=SDF_WRITABLE; + s->subdev_flags = SDF_WRITABLE | SDF_CMD_WRITE; s->insn_read=dt282x_ao_insn_read; s->insn_write=dt282x_ao_insn_write; s->do_cmdtest=dt282x_ao_cmdtest; diff --git a/comedi/drivers/dt3000.c b/comedi/drivers/dt3000.c index d45752a2..c83cf99c 100644 --- a/comedi/drivers/dt3000.c +++ b/comedi/drivers/dt3000.c @@ -290,7 +290,7 @@ static int dt3k_send_cmd(comedi_device *dev,unsigned int cmd) unsigned int status = 0; writew(cmd,devpriv->io_addr+DPR_Command_Mbx); - + for(i=0;iio_addr+DPR_Command_Mbx); if((status&DT3000_COMPLETION_MASK)!=DT3000_NOTPROCESSED) @@ -302,7 +302,7 @@ static int dt3k_send_cmd(comedi_device *dev,unsigned int cmd) } printk("dt3k_send_cmd() timeout/error status=0x%04x\n",status); - + return -ETIME; } @@ -310,10 +310,10 @@ static unsigned int dt3k_readsingle(comedi_device *dev,unsigned int subsys, unsigned int chan,unsigned int gain) { writew(subsys,devpriv->io_addr+DPR_SubSys); - + writew(chan,devpriv->io_addr+DPR_Params(0)); writew(gain,devpriv->io_addr+DPR_Params(1)); - + dt3k_send_cmd(dev,CMD_READSINGLE); return readw(devpriv->io_addr+DPR_Params(2)); @@ -323,11 +323,11 @@ static void dt3k_writesingle(comedi_device *dev,unsigned int subsys, unsigned int chan,unsigned int data) { writew(subsys,devpriv->io_addr+DPR_SubSys); - + writew(chan,devpriv->io_addr+DPR_Params(0)); writew(0,devpriv->io_addr+DPR_Params(1)); writew(data,devpriv->io_addr+DPR_Params(2)); - + dt3k_send_cmd(dev,CMD_WRITESINGLE); } @@ -401,7 +401,7 @@ printk("reading %d samples\n",count); rear++; if(rear>=AI_FIFO_DEPTH)rear = 0; } - + devpriv->ai_rear = rear; writew(rear,devpriv->io_addr + DPR_AD_Buf_Rear); } @@ -549,7 +549,7 @@ static int dt3k_ns_to_timer(unsigned int timer_base, unsigned int *nanosec, return (prescale<<16)|(divider); } } - + prescale = 15; base = timer_base * (1<chanlist_len;i++){ chan=CR_CHAN(cmd->chanlist[i]); range=CR_RANGE(cmd->chanlist[i]); - + writew((range<<6)|chan,devpriv->io_addr+DPR_ADC_buffer+i); } aref=CR_AREF(cmd->chanlist[0]); - + writew(cmd->scan_end_arg,devpriv->io_addr+DPR_Params(0)); printk("param[0]=0x%04x\n",cmd->scan_end_arg); @@ -601,7 +601,7 @@ printk("param[4]=0x%04x\n",tscandiv&0xffff); }else{ /* not supported */ } - + mode = DT3000_AD_RETRIG_INTERNAL | 0 | 0; writew(mode,devpriv->io_addr+DPR_Params(5)); printk("param[5]=0x%04x\n",mode); @@ -610,7 +610,7 @@ printk("param[6]=0x%04x\n",aref==AREF_DIFF); writew(AI_FIFO_DEPTH/2,devpriv->io_addr+DPR_Params(7)); printk("param[7]=0x%04x\n",AI_FIFO_DEPTH/2); - + writew(SUBS_AI,devpriv->io_addr+DPR_SubSys); ret = dt3k_send_cmd(dev,CMD_CONFIG); @@ -688,14 +688,14 @@ static void dt3k_dio_config(comedi_device *dev,int bits) { /* XXX */ writew(SUBS_DOUT,devpriv->io_addr+DPR_SubSys); - + writew(bits,devpriv->io_addr+DPR_Params(0)); #if 0 /* don't know */ writew(0,devpriv->io_addr+DPR_Params(1)); writew(0,devpriv->io_addr+DPR_Params(2)); #endif - + dt3k_send_cmd(dev,CMD_CONFIG); } @@ -705,7 +705,7 @@ static int dt3k_dio_insn_config(comedi_device *dev,comedi_subdevice *s, int mask; mask=(CR_CHAN(insn->chanspec)<4)?0x0f:0xf0; - + switch(data[0]) { case INSN_CONFIG_DIO_OUTPUT: @@ -721,7 +721,7 @@ static int dt3k_dio_insn_config(comedi_device *dev,comedi_subdevice *s, default: return -EINVAL; break; - } + } mask=(s->io_bits&0x01)|((s->io_bits&0x10)>>3); dt3k_dio_config(dev,mask); @@ -758,7 +758,7 @@ static int dt3k_mem_insn_read(comedi_device *dev,comedi_subdevice *s, data[i]=readw(devpriv->io_addr+DPR_Params(2)); } - + return i; } @@ -768,9 +768,9 @@ static int dt3000_attach(comedi_device *dev,comedi_devconfig *it) { comedi_subdevice *s; int ret=0; - + printk("dt3000:"); - + if((ret=alloc_private(dev,sizeof(dt3k_private)))<0) return ret; @@ -798,7 +798,7 @@ static int dt3000_attach(comedi_device *dev,comedi_devconfig *it) /* ai subdevice */ s->type=COMEDI_SUBD_AI; - s->subdev_flags=SDF_READABLE|SDF_GROUND|SDF_DIFF; + s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_DIFF | SDF_CMD_READ; s->n_chan=this_board->adchan; s->insn_read=dt3k_ai_insn; s->maxdata=(1<adbits)-1; @@ -865,7 +865,7 @@ static int dt3000_detach(comedi_device *dev) pci_dev_put(devpriv->pci_dev); } if(devpriv->io_addr) iounmap(devpriv->io_addr); - } + } /* XXX */ return 0; @@ -918,7 +918,7 @@ static int setup_pci(comedi_device *dev) static struct pci_dev *dt_pci_find_device(struct pci_dev *from,int *board) { int i; - + for(from=pci_get_device(PCI_VENDOR_ID_DT,PCI_ANY_ID,from); from!=NULL; from=pci_get_device(PCI_VENDOR_ID_DT,PCI_ANY_ID,from)){ for(i=0;iread_subdev = s; /* dev->write_subdev = s; */ s->type = COMEDI_SUBD_DIO; - s->subdev_flags = SDF_READABLE | SDF_WRITEABLE | SDF_LSAMPL; + s->subdev_flags = SDF_READABLE | SDF_WRITEABLE | SDF_LSAMPL | SDF_CMD_READ; s->n_chan = 32; s->len_chanlist = 32; s->maxdata = 1; diff --git a/comedi/drivers/me4000.c b/comedi/drivers/me4000.c index 17c87886..2dc0d91c 100644 --- a/comedi/drivers/me4000.c +++ b/comedi/drivers/me4000.c @@ -308,6 +308,7 @@ static int me4000_attach(comedi_device *dev, comedi_devconfig *it){ } else{ dev->read_subdev = s; + s->subdev_flags |= SDF_CMD_READ; s->cancel = me4000_ai_cancel; s->do_cmdtest = me4000_ai_do_cmd_test; s->do_cmd = me4000_ai_do_cmd; diff --git a/comedi/drivers/me_daq.c b/comedi/drivers/me_daq.c index d92a32ef..799b1b5a 100644 --- a/comedi/drivers/me_daq.c +++ b/comedi/drivers/me_daq.c @@ -844,7 +844,7 @@ found: subdevice = dev->subdevices + 0; subdevice->type = COMEDI_SUBD_AI; - subdevice->subdev_flags = SDF_READABLE | SDF_COMMON; + subdevice->subdev_flags = SDF_READABLE | SDF_COMMON | SDF_CMD_READ; subdevice->n_chan = board->ai_channel_nbr; subdevice->maxdata = board->ai_resolution_mask; subdevice->len_chanlist = board->ai_channel_nbr; diff --git a/comedi/drivers/mite.c b/comedi/drivers/mite.c index 03b20c3c..558428ed 100644 --- a/comedi/drivers/mite.c +++ b/comedi/drivers/mite.c @@ -303,7 +303,7 @@ void mite_prep_dma( struct mite_struct *mite, unsigned int channel, writel(chor, mite->mite_io_addr + MITE_CHOR(channel)); /* short link chaining mode */ - chcr = CHCR_SET_DMA_IE| CHCR_LINKSHORT | CHCR_SET_DONE_IE | CHCR_BURSTEN; + chcr = CHCR_SET_DMA_IE | CHCR_LINKSHORT | CHCR_SET_DONE_IE | CHCR_BURSTEN; /* * Link Complete Interrupt: interrupt every time a link * in MITE_RING is completed. This can generate a lot of diff --git a/comedi/drivers/mite.h b/comedi/drivers/mite.h index ed996a9c..d0c5e758 100644 --- a/comedi/drivers/mite.h +++ b/comedi/drivers/mite.h @@ -161,7 +161,7 @@ static inline int MITE_LKAR(int channel) // link address { return CHAN_OFFSET(channel) + 0x20; }; -static inline int MITE_LLKAR(int channel) // ? +static inline int MITE_LLKAR(int channel) // see mite section of tnt5002 manual { return CHAN_OFFSET(channel) + 0x24; }; @@ -257,8 +257,8 @@ enum MITE_CHOR_bits CHOR_CLRRB = (1<<6), CHOR_CLRLC = (1<<5), CHOR_FRESET = (1<<4), - CHOR_ABORT = (1<<3), - CHOR_STOP = (1<<2), + CHOR_ABORT = (1<<3), /* stop without emptying fifo */ + CHOR_STOP = (1<<2), /* stop after emptying fifo */ CHOR_CONT = (1<<1), CHOR_START = (1<<0), CHOR_PON = (CHOR_CLR_SEND_TC|CHOR_CLR_LPAUSE), diff --git a/comedi/drivers/ni_6527.c b/comedi/drivers/ni_6527.c index 97b059fa..16169250 100644 --- a/comedi/drivers/ni_6527.c +++ b/comedi/drivers/ni_6527.c @@ -376,7 +376,7 @@ static int ni6527_attach(comedi_device *dev,comedi_devconfig *it) s=dev->subdevices + 2; dev->read_subdev = s; s->type=COMEDI_SUBD_DI; - s->subdev_flags=SDF_READABLE; + s->subdev_flags = SDF_READABLE | SDF_CMD_READ; s->n_chan=1; s->range_table=&range_unknown; s->maxdata=1; diff --git a/comedi/drivers/ni_65xx.c b/comedi/drivers/ni_65xx.c index e45c40c9..90ed50a5 100644 --- a/comedi/drivers/ni_65xx.c +++ b/comedi/drivers/ni_65xx.c @@ -673,7 +673,7 @@ static int ni_65xx_attach(comedi_device *dev,comedi_devconfig *it) s=dev->subdevices + 3; dev->read_subdev = s; s->type=COMEDI_SUBD_DI; - s->subdev_flags=SDF_READABLE; + s->subdev_flags = SDF_READABLE | SDF_CMD_READ; s->n_chan=1; s->range_table=&range_unknown; s->maxdata=1; diff --git a/comedi/drivers/ni_660x.c b/comedi/drivers/ni_660x.c index fe79abfc..e2b3fc32 100644 --- a/comedi/drivers/ni_660x.c +++ b/comedi/drivers/ni_660x.c @@ -744,7 +744,7 @@ static int ni_660x_attach(comedi_device *dev,comedi_devconfig *it) s=dev->subdevices+0; /* GENERAL-PURPOSE COUNTER/TIME (GPCT) */ s->type = COMEDI_SUBD_COUNTER; - s->subdev_flags = SDF_READABLE | SDF_WRITABLE | SDF_LSAMPL; + s->subdev_flags = SDF_READABLE | SDF_WRITABLE | SDF_LSAMPL | SDF_CMD_READ | SDF_CMD_WRITE; /* KG: What does SDF_LSAMPL (see multiq3.c) mean? */ s->n_chan = thisboard->n_ctrs; s->maxdata = 0xffffffff; /* 32 bit counter */ @@ -788,11 +788,7 @@ static int ni_660x_attach(comedi_device *dev,comedi_devconfig *it) } printk("attached\n"); - - /* What does this "return value" mean? Is this fixed by API?? - - skel_attach in skel.c returns 1; - - ni_E_init in ni_mio_common.c returns "0" ... */ - return 1; + return 0; } @@ -856,7 +852,7 @@ ni_660x_GPCT_rinsn(comedi_device *dev, comedi_subdevice *s, // Check what Application of Counter this channel is configured for switch(ni_660x_gpct_config[subdev_channel].App) { - case PositionMeasurement: case CountingAndTimeMeasurement: + case PositionMeasurement: case CountingAndTimeMeasurement: // Check if (n > 0) if ( insn->n <= 0 ) { @@ -897,7 +893,7 @@ ni_660x_GPCT_rinsn(comedi_device *dev, comedi_subdevice *s, static void init_tio_chip(comedi_device *dev, int chipset) { /* See P. 3.5 of the Register-Level Programming manual. The - CounterSwap bit has to be set on the second chip, otherwise + CounterSwap bit has to be set on the second chip, otherwise it will try to use the same pins as the first chip. */ if(chipset) @@ -905,7 +901,7 @@ static void init_tio_chip(comedi_device *dev, int chipset) + registerData[ClockConfigRegister].offset); else writel(0,devpriv->mite->daq_io_addr + GPCT_OFFSET[0] - + registerData[ClockConfigRegister].offset); + + registerData[ClockConfigRegister].offset); } static int @@ -1124,7 +1120,7 @@ ni_660x_GPCT_insn_config(comedi_device *dev, comedi_subdevice *s, break; case GPCT_SIMPLE_EVENT: DPRINTK("NI_660x: INSN_CONFIG: Config Simple Event Counter\n"); - ni_660x_gpct_config[subdev_channel].App = + ni_660x_gpct_config[subdev_channel].App = CountingAndTimeMeasurement; // Reset the counter writew(GxReset(counter_channel), @@ -1323,12 +1319,12 @@ static int ni_660x_dio_insn_config(comedi_device *dev, lsampl_t *data) { int chan=CR_CHAN(insn->chanspec); - + /* The input or output configuration of each digital line is * configured by a special insn_config instruction. chanspec * contains the channel to be changed, and data[0] contains the * value COMEDI_INPUT or COMEDI_OUTPUT. */ - + switch(data[0]) { case INSN_CONFIG_DIO_OUTPUT: diff --git a/comedi/drivers/ni_at_a2150.c b/comedi/drivers/ni_at_a2150.c index 23776be3..e078f602 100644 --- a/comedi/drivers/ni_at_a2150.c +++ b/comedi/drivers/ni_at_a2150.c @@ -424,7 +424,7 @@ static int a2150_attach(comedi_device *dev, comedi_devconfig *it) s = dev->subdevices + 0; dev->read_subdev = s; s->type = COMEDI_SUBD_AI; - s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_OTHER; + s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_OTHER | SDF_CMD_READ; s->n_chan = 4; s->len_chanlist = 4; s->maxdata = 0xffff; diff --git a/comedi/drivers/ni_atmio16d.c b/comedi/drivers/ni_atmio16d.c index d765c3e5..0de50833 100644 --- a/comedi/drivers/ni_atmio16d.c +++ b/comedi/drivers/ni_atmio16d.c @@ -758,7 +758,7 @@ static int atmio16d_attach(comedi_device * dev, comedi_devconfig * it) dev->read_subdev = s; /* ai subdevice */ s->type=COMEDI_SUBD_AI; - s->subdev_flags=SDF_READABLE|SDF_GROUND; + s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_CMD_READ; s->n_chan=(devpriv->adc_mux? 16 : 8); s->len_chanlist=16; s->insn_read = atmio16d_ai_insn_read; diff --git a/comedi/drivers/ni_labpc.c b/comedi/drivers/ni_labpc.c index 4bf8c827..2a5222cd 100644 --- a/comedi/drivers/ni_labpc.c +++ b/comedi/drivers/ni_labpc.c @@ -571,7 +571,7 @@ int labpc_common_attach( comedi_device *dev, unsigned long iobase, s = dev->subdevices + 0; dev->read_subdev = s; s->type = COMEDI_SUBD_AI; - s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_COMMON | SDF_DIFF; + s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_COMMON | SDF_DIFF | SDF_CMD_READ; s->n_chan = 8; s->len_chanlist = 8; s->maxdata = (1 << 12) - 1; // 12 bit resolution diff --git a/comedi/drivers/ni_mio_common.c b/comedi/drivers/ni_mio_common.c index 2ad7abbe..b04519e7 100644 --- a/comedi/drivers/ni_mio_common.c +++ b/comedi/drivers/ni_mio_common.c @@ -2795,14 +2795,18 @@ static int ni_ao_reset(comedi_device *dev,comedi_subdevice *s) devpriv->ao_cmd1=0; devpriv->stc_writew(dev, devpriv->ao_cmd1,AO_Command_1_Register); devpriv->ao_cmd2=0; + devpriv->stc_writew(dev, devpriv->ao_cmd2, AO_Command_2_Register); devpriv->ao_mode1=0; + devpriv->stc_writew(dev, devpriv->ao_mode1, AO_Mode_1_Register); devpriv->ao_mode2=0; + devpriv->stc_writew(dev, devpriv->ao_mode2, AO_Mode_2_Register); if(boardtype.reg_type == ni_reg_m_series) devpriv->ao_mode3 = AO_Last_Gate_Disable; else devpriv->ao_mode3 = 0; devpriv->stc_writew(dev, devpriv->ao_mode3, AO_Mode_3_Register); - devpriv->ao_trigger_select=0; + devpriv->ao_trigger_select = 0; + devpriv->stc_writew(dev, devpriv->ao_trigger_select,AO_Trigger_Select_Register); if(boardtype.reg_type & ni_reg_6xxx_mask){ ao_win_out(0x3, AO_Immediate_671x); ao_win_out(CLEAR_WG, AO_Misc_611x); @@ -3150,7 +3154,7 @@ static int ni_E_init(comedi_device *dev,comedi_devconfig *it) dev->read_subdev=s; if(boardtype.n_adchan){ s->type=COMEDI_SUBD_AI; - s->subdev_flags=SDF_READABLE | SDF_DIFF | SDF_DITHER; + s->subdev_flags=SDF_READABLE | SDF_DIFF | SDF_DITHER | SDF_CMD_READ; if(boardtype.reg_type != ni_reg_611x) s->subdev_flags |= SDF_GROUND | SDF_COMMON | SDF_OTHER; if(boardtype.adbits > 16) @@ -3176,7 +3180,6 @@ static int ni_E_init(comedi_device *dev,comedi_devconfig *it) s=dev->subdevices+1; if(boardtype.n_aochan){ - dev->write_subdev=s; s->type=COMEDI_SUBD_AO; s->subdev_flags=SDF_WRITABLE|SDF_DEGLITCH|SDF_GROUND; if(boardtype.reg_type == ni_reg_m_series) @@ -3195,6 +3198,8 @@ static int ni_E_init(comedi_device *dev,comedi_devconfig *it) #else if(boardtype.ao_fifo_depth){ #endif + dev->write_subdev=s; + s->subdev_flags |= SDF_CMD_WRITE; s->do_cmd=ni_ao_cmd; s->do_cmdtest=ni_ao_cmdtest; s->len_chanlist = boardtype.n_aochan; @@ -3242,7 +3247,7 @@ static int ni_E_init(comedi_device *dev,comedi_devconfig *it) /* general purpose counter/timer device */ s=dev->subdevices+4; s->type = COMEDI_SUBD_COUNTER; - s->subdev_flags = SDF_READABLE | SDF_WRITABLE; + s->subdev_flags = SDF_READABLE | SDF_WRITABLE | SDF_CMD_READ; s->insn_read = ni_gpct_insn_read; s->insn_write = ni_gpct_insn_write; s->insn_config = ni_gpct_insn_config; diff --git a/comedi/drivers/ni_pcidio.c b/comedi/drivers/ni_pcidio.c index 33a65632..7d7e74a6 100644 --- a/comedi/drivers/ni_pcidio.c +++ b/comedi/drivers/ni_pcidio.c @@ -1111,7 +1111,7 @@ static int nidio_attach(comedi_device *dev,comedi_devconfig *it) dev->read_subdev = s; s->type=COMEDI_SUBD_DIO; - s->subdev_flags=SDF_READABLE | SDF_WRITABLE | SDF_LSAMPL | SDF_PACKED; + s->subdev_flags = SDF_READABLE | SDF_WRITABLE | SDF_LSAMPL | SDF_PACKED | SDF_CMD_READ; s->n_chan=32; s->range_table=&range_digital; s->maxdata=1; diff --git a/comedi/drivers/pcl711.c b/comedi/drivers/pcl711.c index 5fa14161..cd8ad883 100644 --- a/comedi/drivers/pcl711.c +++ b/comedi/drivers/pcl711.c @@ -534,13 +534,15 @@ static int pcl711_attach(comedi_device * dev, comedi_devconfig * it) s = dev->subdevices + 0; /* AI subdevice */ s->type = COMEDI_SUBD_AI; - s->subdev_flags = SDF_READABLE|SDF_GROUND; + s->subdev_flags = SDF_READABLE | SDF_GROUND; s->n_chan = this_board->n_aichan; s->maxdata = 0xfff; s->len_chanlist = 1; s->range_table = this_board->ai_range_type; s->insn_read = pcl711_ai_insn; if(irq){ + dev->read_subdev = s; + s->subdev_flags |= SDF_CMD_READ; s->do_cmdtest = pcl711_ai_cmdtest; s->do_cmd = pcl711_ai_cmd; } diff --git a/comedi/drivers/pcl812.c b/comedi/drivers/pcl812.c index d123cf07..8c3f4d63 100644 --- a/comedi/drivers/pcl812.c +++ b/comedi/drivers/pcl812.c @@ -1272,7 +1272,6 @@ static int pcl812_attach(comedi_device * dev, comedi_devconfig * it) /* analog input */ if (this_board->n_aichan>0) { s = dev->subdevices + subdev; - dev->read_subdev = s; s->type = COMEDI_SUBD_AI; s->subdev_flags = SDF_READABLE; switch (this_board->board_type) { @@ -1313,6 +1312,8 @@ static int pcl812_attach(comedi_device * dev, comedi_devconfig * it) devpriv->use_MPC = this_board->haveMPC508; s->cancel = pcl812_ai_cancel; if (dev->irq) { + dev->read_subdev = s; + s->subdev_flags |= SDF_CMD_READ; s->do_cmdtest = pcl812_ai_cmdtest; s->do_cmd = pcl812_ai_cmd; s->poll = pcl812_ai_poll; diff --git a/comedi/drivers/pcl816.c b/comedi/drivers/pcl816.c index fdb65ba2..d617561d 100644 --- a/comedi/drivers/pcl816.c +++ b/comedi/drivers/pcl816.c @@ -1178,7 +1178,7 @@ no_dma: s->type = COMEDI_SUBD_AI; devpriv->sub_ai = s; dev->read_subdev = s; - s->subdev_flags = SDF_READABLE; + s->subdev_flags = SDF_READABLE | SDF_CMD_READ; s->n_chan = this_board->n_aichan; s->subdev_flags |= SDF_DIFF; //printk (", %dchans DIFF DAC - %d", s->n_chan, i); diff --git a/comedi/drivers/pcmuio.c b/comedi/drivers/pcmuio.c index 45f9cfa0..e592424f 100644 --- a/comedi/drivers/pcmuio.c +++ b/comedi/drivers/pcmuio.c @@ -392,6 +392,8 @@ static int pcmuio_attach(comedi_device *dev, comedi_devconfig *it) subpriv->intr.first_chan = byte_no * 8; subpriv->intr.asic_chan = thisasic_chanct; subpriv->intr.num_asic_chans = s->n_chan - subpriv->intr.first_chan; + dev->read_subdev = s; + s->subdev_flags |= SDF_CMD_READ; s->cancel = pcmuio_cancel; s->do_cmd = pcmuio_cmd; s->do_cmdtest = pcmuio_cmdtest; diff --git a/comedi/drivers/quatech_daqp_cs.c b/comedi/drivers/quatech_daqp_cs.c index 59aafed3..aa7f4581 100644 --- a/comedi/drivers/quatech_daqp_cs.c +++ b/comedi/drivers/quatech_daqp_cs.c @@ -124,7 +124,7 @@ static char *version = * (only the A/D converter is supported), and 'count' is how many * samples remain to be taken (or -1 if it's unlimited). */ - + typedef struct local_info_t { dev_link_t link; dev_node_t node; @@ -920,9 +920,9 @@ static int daqp_attach(comedi_device *dev, comedi_devconfig *it) tuple.TupleOffset = 2; if (pcmcia_get_tuple_data(local->link.handle, &tuple) == 0) { - for (i=0; iread_subdev = s; s->private = local; s->type=COMEDI_SUBD_AI; - s->subdev_flags=SDF_READABLE | SDF_GROUND | SDF_DIFF; + s->subdev_flags=SDF_READABLE | SDF_GROUND | SDF_DIFF | SDF_CMD_READ; s->n_chan=8; s->len_chanlist=2048; s->maxdata=0xffff; @@ -993,7 +993,7 @@ static int daqp_attach(comedi_device *dev, comedi_devconfig *it) static int daqp_detach(comedi_device *dev) { printk("comedi%d: detaching daqp\n",dev->minor); - + return 0; } @@ -1029,7 +1029,7 @@ static int daqp_detach(comedi_device *dev) and other provisions required by the GPL. If you do not delete the provisions above, a recipient may use your version of this file under either the MPL or the GPL. - + ======================================================================*/ /* @@ -1075,7 +1075,7 @@ static dev_info_t dev_info = "quatech_daqp_cs"; The dev_link structure is initialized, but we don't actually configure the card at this point -- we wait until we receive a card insertion event. - + ======================================================================*/ static int daqp_cs_attach(struct pcmcia_device *p_dev) @@ -1083,7 +1083,7 @@ static int daqp_cs_attach(struct pcmcia_device *p_dev) local_info_t *local; dev_link_t *link; int i; - + DEBUG(0, "daqp_cs_attach()\n"); for (i = 0; i < MAX_DEV; i++) @@ -1092,7 +1092,7 @@ static int daqp_cs_attach(struct pcmcia_device *p_dev) printk(KERN_NOTICE "daqp_cs: no devices available\n"); return -ENODEV; } - + /* Allocate space for private device-specific data */ local = kmalloc(sizeof(local_info_t), GFP_KERNEL); if (!local) return -ENOMEM; @@ -1102,13 +1102,13 @@ static int daqp_cs_attach(struct pcmcia_device *p_dev) dev_table[i] = local; link = &local->link; link->priv = local; - + /* Interrupt setup */ link->irq.Attributes = IRQ_TYPE_EXCLUSIVE | IRQ_HANDLE_PRESENT; link->irq.IRQInfo1 = IRQ_LEVEL_ID; link->irq.Handler = daqp_interrupt; link->irq.Instance = local; - + /* General socket configuration defaults can go here. In this client, we assume very little, and rely on the CIS for almost @@ -1143,7 +1143,7 @@ static void daqp_cs_detach(struct pcmcia_device *p_dev) local_info_t *dev = link->priv; DEBUG(0, "daqp_cs_detach(0x%p)\n", link); - + /* If the device is currently configured and active, we won't actually delete it yet. Instead, it is marked so that when @@ -1158,7 +1158,7 @@ static void daqp_cs_detach(struct pcmcia_device *p_dev) /* Unlink device structure, and free it */ dev_table[dev->table_index] = NULL; kfree(dev); - + } /* daqp_cs_detach */ /*====================================================================== @@ -1166,7 +1166,7 @@ static void daqp_cs_detach(struct pcmcia_device *p_dev) daqp_cs_config() is scheduled to run after a CARD_INSERTION event is received, to configure the PCMCIA socket, and to make the device available to the system. - + ======================================================================*/ static void daqp_cs_config(dev_link_t *link) @@ -1178,7 +1178,7 @@ static void daqp_cs_config(dev_link_t *link) int last_ret; u_char buf[64]; config_info_t conf; - + DEBUG(0, "daqp_cs_config(0x%p)\n", link); /* @@ -1207,7 +1207,7 @@ static void daqp_cs_config(dev_link_t *link) } link->conf.ConfigBase = parse.config.base; link->conf.Present = parse.config.rmask[0]; - + /* Configure card */ link->state |= DEV_CONFIG; @@ -1246,7 +1246,7 @@ static void daqp_cs_config(dev_link_t *link) if (cfg->flags & CISTPL_CFTABLE_DEFAULT) dflt = *cfg; if (cfg->index == 0) goto next_entry; link->conf.ConfigIndex = cfg->index; - + /* Use power settings for Vcc and Vpp if present */ /* Note that the CIS values need to be rescaled */ if (cfg->vcc.present & (1<vpp1.present & (1<conf.Vpp1 = link->conf.Vpp2 = cfg->vpp1.param[CISTPL_POWER_VNOM]/10000; else if (dflt.vpp1.present & (1<conf.Vpp1 = link->conf.Vpp2 = dflt.vpp1.param[CISTPL_POWER_VNOM]/10000; - + /* Do we need to allocate an interrupt? */ if (cfg->irq.IRQInfo1 || dflt.irq.IRQInfo1) link->conf.Attributes |= CONF_ENABLE_IRQ; - + /* IO window settings */ link->io.NumPorts1 = link->io.NumPorts2 = 0; if ((cfg->io.nwin > 0) || (dflt.io.nwin > 0)) { @@ -1292,7 +1292,7 @@ static void daqp_cs_config(dev_link_t *link) /* If we got this far, we're cool! */ break; - + next_entry: if((last_ret = pcmcia_get_next_tuple(handle, &tuple))) { @@ -1300,7 +1300,7 @@ next_entry: goto cs_failed; } } - + /* Allocate an interrupt line. Note that this does not assign a handler to the interrupt, unless the 'Handler' member of the @@ -1312,7 +1312,7 @@ next_entry: cs_error(handle, RequestIRQ, last_ret); goto cs_failed; } - + /* This actually configures the PCMCIA socket -- setting up the I/O windows and the interrupt mapping, and putting the @@ -1351,7 +1351,7 @@ next_entry: printk(" & 0x%04x-0x%04x", link->io.BasePort2, link->io.BasePort2+link->io.NumPorts2-1); printk("\n"); - + link->state &= ~DEV_CONFIG_PENDING; return; @@ -1365,7 +1365,7 @@ cs_failed: After a card is removed, daqp_cs_release() will unregister the device, and release the PCMCIA configuration. If the device is still open, this will be postponed until it is closed. - + ======================================================================*/ static void daqp_cs_release(u_long arg) @@ -1379,9 +1379,9 @@ static void daqp_cs_release(u_long arg) /* In a normal driver, additional code may be needed to release - other kernel data structures associated with this device. + other kernel data structures associated with this device. */ - + /* Don't bother checking to see if these succeed or not */ pcmcia_release_configuration(link->handle); @@ -1390,7 +1390,7 @@ static void daqp_cs_release(u_long arg) if (link->irq.AssignedIRQ) pcmcia_release_irq(link->handle, &link->irq); link->state &= ~DEV_CONFIG; - + } /* daqp_cs_release */ /*====================================================================== @@ -1402,7 +1402,7 @@ static void daqp_cs_release(u_long arg) private flag to block future accesses to this device. All the functions that actually access the device should check this flag to make sure the card is still present. - + ======================================================================*/ static int daqp_cs_suspend(struct pcmcia_device *p_dev) @@ -1453,7 +1453,7 @@ struct pcmcia_driver daqp_cs_driver = .owner = THIS_MODULE, .drv = { .name = dev_info, - }, + }, }; int __init init_module(void) diff --git a/comedi/drivers/rtd520.c b/comedi/drivers/rtd520.c index 96a3f26e..3e92a50f 100644 --- a/comedi/drivers/rtd520.c +++ b/comedi/drivers/rtd520.c @@ -879,7 +879,7 @@ static int rtd_attach ( dev->read_subdev=s; /* analog input subdevice */ s->type=COMEDI_SUBD_AI; - s->subdev_flags=SDF_READABLE|SDF_GROUND|SDF_COMMON|SDF_DIFF; + s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_COMMON | SDF_DIFF | SDF_CMD_READ; s->n_chan=thisboard->aiChans; s->maxdata=(1<aiBits)-1; if (thisboard->aiMaxGain <= 32) { diff --git a/comedi/drivers/s626.c b/comedi/drivers/s626.c index b0d3d041..b631cfd1 100644 --- a/comedi/drivers/s626.c +++ b/comedi/drivers/s626.c @@ -4,9 +4,9 @@ COMEDI - Linux Control and Measurement Device Interface Copyright (C) 2000 David A. Schleef - + Based on Sensoray Model 626 Linux driver Version 0.2 - Copyright (C) 2002-2004 Sensoray Co., Inc. + Copyright (C) 2002-2004 Sensoray Co., Inc. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -35,30 +35,30 @@ Configuration Options: analog input: none - + analog output: none - + digital channel: - s626 has 3 dio subdevices (2,3 and 4) each with 16 i/o channels + s626 has 3 dio subdevices (2,3 and 4) each with 16 i/o channels supported configuration options: - INSN_CONFIG_DIO_QUERY + INSN_CONFIG_DIO_QUERY COMEDI_INPUT COMEDI_OUTPUT encoder: Every channel must be configured before reading. - + Example code insn.insn=INSN_CONFIG; //configuration instruction insn.n=1; //number of operation (must be 1) - insn.data=&initialvalue; //initial value loaded into encoder + insn.data=&initialvalue; //initial value loaded into encoder //during configuration insn.subdev=5; //encoder subdevice - insn.chanspec=CR_PACK(encoder_channel,0,AREF_OTHER); //encoder_channel + insn.chanspec=CR_PACK(encoder_channel,0,AREF_OTHER); //encoder_channel //to configure - + comedi_do_insn(cf,&insn); //executing configuration */ @@ -96,7 +96,7 @@ static s626_board s626_boards[] = { ao_bits: 13, dio_chans: S626_DIO_CHANNELS, dio_banks: S626_DIO_BANKS, - enc_chans: S626_ENCODER_CHANNELS, + enc_chans: S626_ENCODER_CHANNELS, } }; @@ -109,7 +109,7 @@ static struct pci_device_id s626_pci_table[] __devinitdata = { { 0 } }; -MODULE_DEVICE_TABLE(pci, s626_pci_table); +MODULE_DEVICE_TABLE(pci, s626_pci_table); static int s626_attach(comedi_device *dev,comedi_devconfig *it); static int s626_detach(comedi_device *dev); @@ -180,7 +180,7 @@ static dio_private dio_private_A={ WREdgSel: LP_WREDGSELA, RDCapSel: LP_RDCAPSELA, WRCapSel: LP_WRCAPSELA, - RDCapFlg: LP_RDCAPFLGA, + RDCapFlg: LP_RDCAPFLGA, RDIntSel: LP_RDINTSELA, WRIntSel: LP_WRINTSELA, }; @@ -192,7 +192,7 @@ static dio_private dio_private_B={ WREdgSel: LP_WREDGSELB, RDCapSel: LP_RDCAPSELB, WRCapSel: LP_WRCAPSELB, - RDCapFlg: LP_RDCAPFLGB, + RDCapFlg: LP_RDCAPFLGB, RDIntSel: LP_RDINTSELB, WRIntSel: LP_WRINTSELB, }; @@ -204,15 +204,15 @@ static dio_private dio_private_C={ WREdgSel: LP_WREDGSELC, RDCapSel: LP_RDCAPSELC, WRCapSel: LP_WRCAPSELC, - RDCapFlg: LP_RDCAPFLGC, + RDCapFlg: LP_RDCAPFLGC, RDIntSel: LP_RDINTSELC, WRIntSel: LP_WRINTSELC, }; /* to group dio devices (48 bits mask and data are not allowed ???) static dio_private *dio_private_word[]={ - &dio_private_A, - &dio_private_B, + &dio_private_A, + &dio_private_B, &dio_private_C, }; */ @@ -247,8 +247,8 @@ static irqreturn_t s626_irq_handler(int irq,void *d,struct pt_regs * regs); static lsampl_t s626_ai_reg_to_uint(int data); /* static lsampl_t s626_uint_to_reg(comedi_subdevice *s, int data); */ -//end ioctl routines - +//end ioctl routines + //internal routines static void s626_dio_init(comedi_device *dev); static void ResetADC(comedi_device *dev,uint8_t *ppl ); @@ -278,7 +278,7 @@ typedef struct enc_private_struct { void (*SetLoadTrig)(comedi_device *dev,struct enc_private_struct *,uint16_t Trig); //Program preload trigger source. void (*SetMode)(comedi_device *dev,struct enc_private_struct *,uint16_t Setup,uint16_t DisableIntSrc); //Program standardized operating mode. void (*ResetCapFlags)(comedi_device *dev,struct enc_private_struct *); //Reset event capture flags. - + uint16_t MyCRA; // Address of CRA register. uint16_t MyCRB; // Address of CRB register. uint16_t MyLatchLsw; // Address of Latch least-significant-word @@ -337,9 +337,9 @@ static void CountersInit(comedi_device *dev); // bits. //static const uint16_t EventBits[][4] = { EVBITS(0), EVBITS(1), EVBITS(2), EVBITS(3), EVBITS(4), EVBITS(5) }; -/* enc_private; */ +/* enc_private; */ static enc_private enc_private_data[]={ - { + { GetEnable: GetEnable_A, GetIntSrc: GetIntSrc_A, GetLoadTrig: GetLoadTrig_A, @@ -355,7 +355,7 @@ static enc_private enc_private_data[]={ MyLatchLsw: LP_CNTR0ALSW, MyEventBits: EVBITS(0), }, - { + { GetEnable: GetEnable_A, GetIntSrc: GetIntSrc_A, GetLoadTrig: GetLoadTrig_A, @@ -371,7 +371,7 @@ static enc_private enc_private_data[]={ MyLatchLsw: LP_CNTR1ALSW, MyEventBits: EVBITS(1), }, - { + { GetEnable: GetEnable_A, GetIntSrc: GetIntSrc_A, GetLoadTrig: GetLoadTrig_A, @@ -387,7 +387,7 @@ static enc_private enc_private_data[]={ MyLatchLsw: LP_CNTR2ALSW, MyEventBits: EVBITS(2), }, - { + { GetEnable: GetEnable_B, GetIntSrc: GetIntSrc_B, GetLoadTrig: GetLoadTrig_B, @@ -403,7 +403,7 @@ static enc_private enc_private_data[]={ MyLatchLsw: LP_CNTR0BLSW, MyEventBits: EVBITS(3), }, - { + { GetEnable: GetEnable_B, GetIntSrc: GetIntSrc_B, GetLoadTrig: GetLoadTrig_B, @@ -470,7 +470,7 @@ static comedi_lrange s626_range_table={ 2,{ }}; static int s626_attach(comedi_device *dev,comedi_devconfig *it) -{ +{ /* uint8_t PollList; */ /* uint16_t AdcData; */ /* uint16_t StartVal; */ @@ -483,18 +483,18 @@ static int s626_attach(comedi_device *dev,comedi_devconfig *it) dma_addr_t appdma; comedi_subdevice *s; struct pci_dev *pdev; - + if(alloc_private(dev,sizeof(s626_private))<0) return -ENOMEM; - + pdev=pci_get_device(PCI_VENDOR_ID_S626, PCI_DEVICE_ID_S626, NULL); devpriv->pdev = pdev; - + if(pdev==NULL) { - printk("s626_attach: Board not present!!!"); + printk("s626_attach: Board not present!!!"); return -ENODEV; } - + if((result = pci_enable_device(pdev))<0){ printk("s626_attach: pci_enable_device fails\n"); return -ENODEV; @@ -507,52 +507,52 @@ static int s626_attach(comedi_device *dev,comedi_devconfig *it) devpriv->got_regions = 1; resourceStart=pci_resource_start(devpriv->pdev,0); - + devpriv->base_addr=ioremap(resourceStart, SIZEOF_ADDRESS_SPACE); if (devpriv->base_addr==NULL) { printk("s626_attach: IOREMAP failed\n"); return -ENODEV; } - + if (devpriv->base_addr){ - //disable master interrupt + //disable master interrupt writel(0,devpriv->base_addr+P_IER); - - //soft reset + + //soft reset writel(MC1_SOFT_RESET,devpriv->base_addr+P_MC1); - + //DMA FIXME DMA// DEBUG("s626_attach: DMA ALLOCATION\n"); //adc buffer allocation devpriv->allocatedBuf=0; - + if((devpriv->ANABuf.LogicalBase = pci_alloc_consistent (devpriv->pdev, DMABUF_SIZE, &appdma))==NULL){ printk("s626_attach: DMA Memory mapping error\n"); return -ENOMEM; } - + devpriv->ANABuf.PhysicalBase=(void*)appdma; - + DEBUG("s626_attach: AllocDMAB ADC Logical=0x%x, bsize=%d, Physical=0x%x\n", (uint32_t) devpriv->ANABuf.LogicalBase, DMABUF_SIZE, (uint32_t)devpriv->ANABuf.PhysicalBase); - + devpriv->allocatedBuf++; - + if((devpriv->RPSBuf.LogicalBase = pci_alloc_consistent (devpriv->pdev, DMABUF_SIZE, &appdma)) ==NULL){ printk("s626_attach: DMA Memory mapping error\n"); return -ENOMEM; } - + devpriv->RPSBuf.PhysicalBase=(void*)appdma; - + DEBUG("s626_attach: AllocDMAB RPS Logical=0x%x, bsize=%d, Physical=0x%x\n", (uint32_t) devpriv->RPSBuf.LogicalBase, DMABUF_SIZE, (uint32_t)devpriv->RPSBuf.PhysicalBase); - + devpriv->allocatedBuf++; - - } - + + } + dev->board_ptr = s626_boards; dev->board_name = thisboard->name; @@ -577,21 +577,21 @@ static int s626_attach(comedi_device *dev,comedi_devconfig *it) s=dev->subdevices+0; /* analog input subdevice */ dev->read_subdev = s; - /* we support single-ended (ground) and differential */ + /* we support single-ended (ground) and differential */ s->type=COMEDI_SUBD_AI; - s->subdev_flags=SDF_READABLE|SDF_DIFF; + s->subdev_flags = SDF_READABLE | SDF_DIFF |SDF_CMD_READ; s->n_chan=thisboard->ai_chans; s->maxdata=(0xffff >> 2); s->range_table=&s626_range_table; s->len_chanlist=thisboard->ai_chans; /* This is the maximum chanlist length that the board can handle */ - s->insn_config = s626_ai_insn_config; + s->insn_config = s626_ai_insn_config; s->insn_read = s626_ai_insn_read; s->do_cmd = s626_ai_cmd; s->do_cmdtest = s626_ai_cmdtest; s->cancel = s626_ai_cancel; - + s=dev->subdevices+1; /* analog output subdevice */ s->type=COMEDI_SUBD_AO; @@ -601,7 +601,7 @@ static int s626_attach(comedi_device *dev,comedi_devconfig *it) s->range_table=&range_bipolar10; s->insn_write = s626_ao_winsn; s->insn_read = s626_ao_rinsn; - + s=dev->subdevices+2; /* digital I/O subdevice */ s->type=COMEDI_SUBD_DIO; @@ -613,7 +613,7 @@ static int s626_attach(comedi_device *dev,comedi_devconfig *it) s->range_table=&range_digital; s->insn_config=s626_dio_insn_config; s->insn_bits = s626_dio_insn_bits; - + s=dev->subdevices+3; /* digital I/O subdevice */ s->type=COMEDI_SUBD_DIO; @@ -637,7 +637,7 @@ static int s626_attach(comedi_device *dev,comedi_devconfig *it) s->range_table=&range_digital; s->insn_config=s626_dio_insn_config; s->insn_bits = s626_dio_insn_bits; - + s=dev->subdevices+5; /* encoder (counter) subdevice */ s->type = COMEDI_SUBD_COUNTER; @@ -650,9 +650,9 @@ static int s626_attach(comedi_device *dev,comedi_devconfig *it) s->maxdata = 0xffffff; s->range_table = &range_unknown; - //stop ai_command - devpriv->ai_cmd_running=0; - + //stop ai_command + devpriv->ai_cmd_running=0; + if (devpriv->base_addr && (devpriv->allocatedBuf==2)){ uint32_t *pPhysBuf; uint16_t chan; @@ -671,19 +671,19 @@ static int s626_attach(comedi_device *dev,comedi_devconfig *it) // local bus (DEBI // never times out). DEBUG("s626_attach: %d debi init -- %d\n", DEBI_CFG_SLAVE16| ( DEBI_TOUT << DEBI_CFG_TOUT_BIT )| DEBI_SWAP| DEBI_CFG_INTEL, DEBI_CFG_INTEL | DEBI_CFG_TOQ | DEBI_CFG_INCQ| DEBI_CFG_16Q); - + //DEBI INIT S626 WR7146( P_DEBICFG, DEBI_CFG_INTEL | DEBI_CFG_TOQ //| DEBI_CFG_INCQ| DEBI_CFG_16Q); //end - + // Paging is disabled. WR7146( P_DEBIPAGE, DEBI_PAGE_DISABLE ); // Disable MMU paging. // Init GPIO so that ADC Start* is negated. WR7146( P_GPIO, GPIO_BASE | GPIO1_HI ); - + //IsBoardRevA is a boolean that indicates whether the board is //RevA. - + // VERSION 2.01 CHANGE: REV A & B BOARDS NOW SUPPORTED BY DYNAMIC // EEPROM ADDRESS SELECTION. Initialize the I2C interface, which // is used to access the onboard serial EEPROM. The EEPROM's I2C @@ -696,15 +696,15 @@ static int s626_attach(comedi_device *dev,comedi_devconfig *it) // configuration EEPROM to reside. On RevA boards, the EEPROM // device address, which is hardwired to 4, prevents the SAA7146 // from retrieving PCI sub-IDs, so the SAA7146 uses its built-in - // default values, instead. - + // default values, instead. + // devpriv->I2Cards= IsBoardRevA ? 0xA8 : 0xA0; // Set I2C EEPROM // DeviceType (0xA0) // and DeviceAddress<<1. - + devpriv->I2CAdrs=0xA0; // I2C device address for onboard - // eeprom(revb) - + // eeprom(revb) + // Issue an I2C ABORT command to halt any I2C operation in //progress and reset BUSY flag. WR7146( P_I2CSTAT, I2C_CLKSEL | I2C_ABORT );// Write I2C control: @@ -715,7 +715,7 @@ static int s626_attach(comedi_device *dev,comedi_devconfig *it) while ( ( RR7146(P_MC2) & MC2_UPLD_IIC ) == 0 );// and wait for // upload to // complete. - + // Per SAA7146 data sheet, write to STATUS reg twice to reset all // I2C error flags. for ( i = 0; i < 2; i++ ) @@ -726,13 +726,13 @@ static int s626_attach(comedi_device *dev,comedi_devconfig *it) while ( !MC_TEST( P_MC2, MC2_UPLD_IIC ) ); // and wait for // upload to // complete. - } - + } + // Init audio interface functional attributes: set DAC/ADC serial // clock rates, invert DAC serial clock so that DAC data setup // times are satisfied, enable DAC serial clock out. WR7146( P_ACON2, ACON2_INIT ); - + // Set up TSL1 slot list, which is used to control the // accumulation of ADC data: RSD1 = shift data in on SD1. SIB_A1 // = store data uint8_t at next available location in FB BUFFER1 @@ -742,14 +742,14 @@ static int s626_attach(comedi_device *dev,comedi_devconfig *it) WR7146( P_TSL1 + 4, RSD1 | SIB_A1 | EOS ); // Fetch ADC low data // uint8_t; end of // TSL1. - + // enab TSL1 slot list so that it executes all the time. WR7146( P_ACON1, ACON1_ADCSTART ); - + // Initialize RPS registers used for ADC. //Physical start of RPS program. - WR7146( P_RPSADDR1, (uint32_t)devpriv->RPSBuf.PhysicalBase ); + WR7146( P_RPSADDR1, (uint32_t)devpriv->RPSBuf.PhysicalBase ); WR7146( P_RPSPAGE1, 0 ); // RPS program performs no // explicit mem writes. @@ -760,16 +760,16 @@ static int s626_attach(comedi_device *dev,comedi_devconfig *it) // that it is correctly receiving ADC data. This is necessary // because the SAA7146 ADC interface does not start up in a // defined state after a PCI reset. - + /* PollList = EOPL; // Create a simple polling */ /* // list for analog input */ /* // channel 0. */ /* ResetADC( dev, &PollList ); */ - + /* s626_ai_rinsn(dev,dev->subdevices,NULL,data); //( &AdcData ); // */ /* //Get initial ADC */ /* //value. */ - + /* StartVal = data[0]; */ /* // VERSION 2.01 CHANGE: TIMEOUT ADDED TO PREVENT HANGED EXECUTION. */ @@ -778,7 +778,7 @@ static int s626_attach(comedi_device *dev,comedi_devconfig *it) /* // possibility that the driver is restarting and the ADC data is a */ /* // fixed value resulting from the applied ADC analog input being */ /* // unusually quiet or at the rail. */ - + /* for ( index = 0; index < 500; index++ ) */ /* { */ /* s626_ai_rinsn(dev,dev->subdevices,NULL,data); */ @@ -786,35 +786,35 @@ static int s626_attach(comedi_device *dev,comedi_devconfig *it) /* if ( AdcData != StartVal ) */ /* break; */ /* } */ - - // end initADC - - // init the DAC interface - + + // end initADC + + // init the DAC interface + // Init Audio2's output DMAC attributes: burst length = 1 DWORD, // threshold = 1 DWORD. WR7146( P_PCI_BT_A, 0 ); - + // Init Audio2's output DMA physical addresses. The protection // address is set to 1 DWORD past the base address so that a // single DWORD will be transferred each time a DMA transfer is // enabled. - + pPhysBuf = (uint32_t *)devpriv->ANABuf.PhysicalBase + DAC_WDMABUF_OS; - + WR7146( P_BASEA2_OUT, (uint32_t) pPhysBuf ); // Buffer base adrs. WR7146( P_PROTA2_OUT, (uint32_t) (pPhysBuf + 1) ); // Protection address. - + // Cache Audio2's output DMA buffer logical address. This is // where DAC data is buffered for A2 output DMA transfers. devpriv->pDacWBuf = (uint32_t *)devpriv->ANABuf.LogicalBase + DAC_WDMABUF_OS; - + // Audio2's output channels does not use paging. The protection // violation handling bit is set so that the DMAC will // automatically halt and its PCI address pointer will be reset // when the protection address is reached. WR7146( P_PAGEA2_OUT, 8 ); - + // Initialize time slot list 2 (TSL2), which is used to control // the clock generation for and serialization of data to be sent // to the DAC devices. Slot 0 is a NOP that is used to trap TSL @@ -827,7 +827,7 @@ static int s626_attach(comedi_device *dev,comedi_devconfig *it) SETVECT( 0, XSD2 | RSD3 | SIB_A2 | EOS ); // Slot 0: Trap TSL // execution, shift 0xFF // into FB_BUFFER2. - + // Initialize slot 1, which is constant. Slot 1 causes a DWORD to // be transferred from audio channel 2's output FIFO to the FIFO's // output buffer so that it can be serialized and sent to the DAC @@ -835,77 +835,77 @@ static int s626_attach(comedi_device *dev,comedi_devconfig *it) // populated as required by the target DAC device. SETVECT( 1, LF_A2 ); // Slot 1: Fetch DWORD from Audio2's // output FIFO. - + // Start DAC's audio interface (TSL2) running. WR7146( P_ACON1, ACON1_DACSTART ); - + //////////////////////////////////////////////////////// - + // end init DAC interface - + // Init Trim DACs to calibrated values. Do it twice because the // SAA7146 audio channel does not always reset properly and // sometimes causes the first few TrimDAC writes to malfunction. - + LoadTrimDACs( dev); LoadTrimDACs( dev); // Insurance. - + ////////////////////////////////////////////////////////////////// // Manually init all gate array hardware in case this is a soft // reset (we have no way of determining whether this is a warm or // cold start). This is necessary because the gate array will // reset only in response to a PCI hard reset; there is no soft // reset function. - + // Init all DAC outputs to 0V and init all DAC setpoint and // polarity images. for ( chan = 0; chan < S626_DAC_CHANNELS; chan++) SetDAC(dev,chan, 0 ); - + // Init image of WRMISC2 Battery Charger Enabled control bit. // This image is used when the state of the charger control bit, // which has no direct hardware readback mechanism, is queried. devpriv->ChargeEnabled = 0; - + // Init image of watchdog timer interval in WRMISC2. This image // maintains the value of the control bits of MISC2 are // continuously reset to zero as long as the WD timer is disabled. devpriv->WDInterval = 0; - + // Init Counter Interrupt enab mask for RDMISC2. This mask is // applied against MISC2 when testing to determine which timer // events are requesting interrupt service. devpriv->CounterIntEnabs = 0; - + // Init counters. - CountersInit(dev); - + CountersInit(dev); + // Without modifying the state of the Battery Backup enab, disable // the watchdog timer, set DIO channels 0-5 to operate in the // standard DIO (vs. counter overflow) mode, disable the battery // charger, and reset the watchdog interval selector to zero. WriteMISC2(dev, (uint16_t)( DEBIread( dev,LP_RDMISC2 ) & MISC2_BATT_ENABLE ) ); - + // Initialize the digital I/O subsystem. s626_dio_init(dev); - //enable interrupt test + //enable interrupt test // writel(IRQ_GPIO3 | IRQ_RPS1,devpriv->base_addr+P_IER); } - + DEBUG("s626_attach: comedi%d s626 attached %04x\n",dev->minor,(uint32_t)devpriv->base_addr); - + return 1; } static lsampl_t s626_ai_reg_to_uint(int data){ lsampl_t tempdata; - tempdata=(data >> 18); + tempdata=(data >> 18); if(tempdata&0x2000) tempdata&=0x1fff; else - tempdata+=(1<<13); + tempdata+=(1<<13); return tempdata; } @@ -938,11 +938,11 @@ static irqreturn_t s626_irq_handler(int irq,void *d,struct pt_regs * regs) //save interrupt enable register state irqstatus=readl(devpriv->base_addr+P_IER); - + //read interrupt type irqtype=readl(devpriv->base_addr+P_ISR); - //disable master interrupt + //disable master interrupt writel(0,devpriv->base_addr+P_IER); //clear interrupt @@ -951,7 +951,7 @@ static irqreturn_t s626_irq_handler(int irq,void *d,struct pt_regs * regs) //do somethings DEBUG("s626_irq_handler: interrupt type %d\n",irqtype); - switch(irqtype){ + switch(irqtype){ case IRQ_RPS1: // end_of_scan occurs DEBUG("s626_irq_handler: RPS1 irq detected\n"); @@ -1017,10 +1017,10 @@ static irqreturn_t s626_irq_handler(int irq,void *d,struct pt_regs * regs) } if(devpriv->ai_cmd_running && cmd->scan_begin_src==TRIG_EXT){ - DEBUG("s626_irq_handler: enable interrupt on dio channel %d\n",cmd->scan_begin_arg); - - s626_dio_set_irq(dev,cmd->scan_begin_arg); - + DEBUG("s626_irq_handler: enable interrupt on dio channel %d\n",cmd->scan_begin_arg); + + s626_dio_set_irq(dev,cmd->scan_begin_arg); + DEBUG("s626_irq_handler: External trigger is set!!!\n"); } @@ -1036,13 +1036,13 @@ static irqreturn_t s626_irq_handler(int irq,void *d,struct pt_regs * regs) s=dev->subdevices; cmd=&(s->async->cmd); - //s626_dio_clear_irq(dev); + //s626_dio_clear_irq(dev); for(group=0;groupsubdevices+2+group)->private)->RDCapFlg); - + //check if interrupt is generated from dio channels if(irqbit){ s626_dio_reset_irq(dev,group,irqbit); @@ -1050,36 +1050,36 @@ static irqreturn_t s626_irq_handler(int irq,void *d,struct pt_regs * regs) if(devpriv->ai_cmd_running){ //check if interrupt is an ai acquisition start trigger if((irqbit>>(cmd->start_arg-(16*group)))==1 && cmd->start_src==TRIG_EXT){ - DEBUG("s626_irq_handler: Edge capture interrupt recieved from channel %d\n",cmd->start_arg); - + DEBUG("s626_irq_handler: Edge capture interrupt recieved from channel %d\n",cmd->start_arg); + // Start executing the RPS program. - MC_ENABLE( P_MC1, MC1_ERPS1 ); - + MC_ENABLE( P_MC1, MC1_ERPS1 ); + DEBUG("s626_irq_handler: aquisition start triggered!!!\n"); - - if(cmd->scan_begin_src==TRIG_EXT){ + + if(cmd->scan_begin_src==TRIG_EXT){ DEBUG("s626_ai_cmd: enable interrupt on dio channel %d\n",cmd->scan_begin_arg); - + s626_dio_set_irq(dev,cmd->scan_begin_arg); - + DEBUG("s626_irq_handler: External scan trigger is set!!!\n"); } } if((irqbit>>(cmd->scan_begin_arg-(16*group)))==1 && cmd->scan_begin_src==TRIG_EXT){ - DEBUG("s626_irq_handler: Edge capture interrupt recieved from channel %d\n",cmd->scan_begin_arg); - + DEBUG("s626_irq_handler: Edge capture interrupt recieved from channel %d\n",cmd->scan_begin_arg); + // Trigger ADC scan loop start by setting RPS Signal 0. - MC_ENABLE( P_MC2, MC2_ADC_RPS ); + MC_ENABLE( P_MC2, MC2_ADC_RPS ); DEBUG("s626_irq_handler: scan triggered!!! %d\n",devpriv->ai_sample_count); if(cmd->convert_src==TRIG_EXT){ - - DEBUG("s626_ai_cmd: enable interrupt on dio channel %d group %d\n",cmd->convert_arg-(16*group),group); + + DEBUG("s626_ai_cmd: enable interrupt on dio channel %d group %d\n",cmd->convert_arg-(16*group),group); devpriv->ai_convert_count=cmd->chanlist_len; - - s626_dio_set_irq(dev,cmd->convert_arg); - + + s626_dio_set_irq(dev,cmd->convert_arg); + DEBUG("s626_irq_handler: External convert trigger is set!!!\n"); } @@ -1090,20 +1090,20 @@ static irqreturn_t s626_irq_handler(int irq,void *d,struct pt_regs * regs) } } if((irqbit>>(cmd->convert_arg-(16*group)))==1 && cmd->convert_src==TRIG_EXT){ - DEBUG("s626_irq_handler: Edge capture interrupt recieved from channel %d\n",cmd->convert_arg); - + DEBUG("s626_irq_handler: Edge capture interrupt recieved from channel %d\n",cmd->convert_arg); + // Trigger ADC scan loop start by setting RPS Signal 0. - MC_ENABLE( P_MC2, MC2_ADC_RPS ); + MC_ENABLE( P_MC2, MC2_ADC_RPS ); DEBUG("s626_irq_handler: adc convert triggered!!!\n"); - devpriv->ai_convert_count--; + devpriv->ai_convert_count--; if(devpriv->ai_convert_count>0){ - - DEBUG("s626_ai_cmd: enable interrupt on dio channel %d group %d\n",cmd->convert_arg-(16*group),group); - - s626_dio_set_irq(dev,cmd->convert_arg); + + DEBUG("s626_ai_cmd: enable interrupt on dio channel %d group %d\n",cmd->convert_arg-(16*group),group); + + s626_dio_set_irq(dev,cmd->convert_arg); DEBUG("s626_irq_handler: External trigger is set!!!\n"); } @@ -1115,7 +1115,7 @@ static irqreturn_t s626_irq_handler(int irq,void *d,struct pt_regs * regs) //read interrupt type irqbit=DEBIread(dev,LP_RDMISC2); - + //check interrupt on counters DEBUG("s626_irq_handler: check counters interrupt %d\n",irqbit); @@ -1133,7 +1133,7 @@ static irqreturn_t s626_irq_handler(int irq,void *d,struct pt_regs * regs) //clear interrupt capture flag k->ResetCapFlags(dev,k); } - if(irqbit&IRQ_COINT3A){ + if(irqbit&IRQ_COINT3A){ DEBUG("s626_irq_handler: interrupt on counter 3A overflow\n"); k=&encpriv[2]; @@ -1155,7 +1155,7 @@ static irqreturn_t s626_irq_handler(int irq,void *d,struct pt_regs * regs) k->ResetCapFlags(dev,k); if(devpriv->ai_convert_count>0){ - devpriv->ai_convert_count--; + devpriv->ai_convert_count--; if(devpriv->ai_convert_count==0) k->SetEnable(dev,k,CLKENAB_INDEX); if(cmd->convert_src==TRIG_TIMER){ @@ -1187,11 +1187,11 @@ static irqreturn_t s626_irq_handler(int irq,void *d,struct pt_regs * regs) k->SetEnable(dev,k,CLKENAB_ALWAYS); } } - } + } //enable interrupt - writel(irqstatus,devpriv->base_addr+P_IER); - + writel(irqstatus,devpriv->base_addr+P_IER); + DEBUG("s626_irq_handler: exit interrupt service routine.\n"); comedi_spin_unlock_irqrestore(&dev->spinlock, flags); @@ -1203,31 +1203,31 @@ static int s626_detach(comedi_device *dev) if(devpriv){ //stop ai_command devpriv->ai_cmd_running=0; - + if(devpriv->base_addr){ //interrupt mask WR7146( P_IER, 0 ); // Disable master interrupt. WR7146( P_ISR, IRQ_GPIO3 | IRQ_RPS1 ); // Clear board's IRQ status flag. - + // Disable the watchdog timer and battery charger. WriteMISC2(dev,0); - + // Close all interfaces on 7146 device. WR7146( P_MC1, MC1_SHUTDOWN ); WR7146( P_ACON1, ACON1_BASE ); - + CloseDMAB(dev,&devpriv->RPSBuf,DMABUF_SIZE); CloseDMAB(dev,&devpriv->ANABuf,DMABUF_SIZE); } - + if(dev->irq){ comedi_free_irq(dev->irq,dev); } - + if(devpriv->base_addr){ iounmap(devpriv->base_addr); } - + if(devpriv->pdev){ if(devpriv->got_regions) { @@ -1237,9 +1237,9 @@ static int s626_detach(comedi_device *dev) pci_dev_put(devpriv->pdev); } } - + DEBUG("s626_detach: S626 detached!\n"); - + return 0; } @@ -1262,15 +1262,15 @@ void ResetADC(comedi_device *dev,uint8_t *ppl ) pRPS = (uint32_t *)devpriv->RPSBuf.LogicalBase; // Initialize RPS instruction pointer. - WR7146( P_RPSADDR1, (uint32_t)devpriv->RPSBuf.PhysicalBase ); + WR7146( P_RPSADDR1, (uint32_t)devpriv->RPSBuf.PhysicalBase ); + + // Construct RPS program in RPSBuf DMA buffer - // Construct RPS program in RPSBuf DMA buffer - if(cmd!=NULL && cmd->scan_begin_src!=TRIG_FOLLOW){ DEBUG("ResetADC: scan_begin pause inserted\n"); // Wait for Start trigger. *pRPS++= RPS_PAUSE | RPS_SIGADC ; - *pRPS++= RPS_CLRSIGNAL | RPS_SIGADC ; + *pRPS++= RPS_CLRSIGNAL | RPS_SIGADC ; } // SAA7146 BUG WORKAROUND Do a dummy DEBI Write. This is necessary @@ -1300,7 +1300,7 @@ void ResetADC(comedi_device *dev,uint8_t *ppl ) // (EOPL,x,x,RANGE,CHAN<3:0>), where RANGE code indicates 0 = // +-10V, 1 = +-5V, and EOPL = End of Poll List marker. LocalPPL = ( *ppl << 8 ) | ( *ppl & 0x10 ? GSEL_BIPOLAR5V : GSEL_BIPOLAR10V ); - + // Switch ADC analog gain. *pRPS++= RPS_LDREG | (P_DEBICMD >> 2) ; // Write DEBI command // and address to @@ -1315,7 +1315,7 @@ void ResetADC(comedi_device *dev,uint8_t *ppl ) *pRPS++= RPS_UPLOAD | RPS_DEBI ; // Invoke shadow RAM upload. *pRPS++= RPS_PAUSE | RPS_DEBI ; // Wait for shadow upload to // finish. - + // Select ADC analog input channel. *pRPS++= RPS_LDREG | (P_DEBICMD >> 2) ; // Write DEBI command // and address to @@ -1330,7 +1330,7 @@ void ResetADC(comedi_device *dev,uint8_t *ppl ) *pRPS++= RPS_UPLOAD | RPS_DEBI ; // Invoke shadow RAM upload. *pRPS++= RPS_PAUSE | RPS_DEBI ; // Wait for shadow upload to // finish. - + // Delay at least 10 microseconds for analog input settling. // Instead of padding with NOPs, we use RPS_JUMP instructions // here; this allows us to produce a longer delay than is @@ -1347,35 +1347,35 @@ void ResetADC(comedi_device *dev,uint8_t *ppl ) DEBUG("ResetADC: convert pause inserted\n"); // Wait for Start trigger. *pRPS++= RPS_PAUSE | RPS_SIGADC ; - *pRPS++= RPS_CLRSIGNAL | RPS_SIGADC ; + *pRPS++= RPS_CLRSIGNAL | RPS_SIGADC ; } // Start ADC by pulsing GPIO1. *pRPS++= RPS_LDREG | (P_GPIO >> 2) ; // Begin ADC Start pulse. *pRPS++= GPIO_BASE | GPIO1_LO ; - *pRPS++= RPS_NOP ; + *pRPS++= RPS_NOP ; // VERSION 2.03 CHANGE: STRETCH OUT ADC START PULSE. *pRPS++= RPS_LDREG | (P_GPIO >> 2) ; // End ADC Start pulse. *pRPS++= GPIO_BASE | GPIO1_HI ; - + // Wait for ADC to complete (GPIO2 is asserted high when ADC not // busy) and for data from previous conversion to shift into FB // BUFFER 1 register. *pRPS++= RPS_PAUSE | RPS_GPIO2 ; // Wait for ADC done. - + // Transfer ADC data from FB BUFFER 1 register to DMA buffer. *pRPS++=RPS_STREG | ( BUGFIX_STREG( P_FB_BUFFER1 ) >> 2 ) ; *pRPS++= (uint32_t)devpriv->ANABuf.PhysicalBase + ( devpriv->AdcItems << 2 ) ; - + // If this slot's EndOfPollList flag is set, all channels have // now been processed. if ( *ppl++ & EOPL ) { devpriv->AdcItems++; // Adjust poll list item count. break; // Exit poll list processing loop. - } + } } DEBUG("ResetADC: ADC items %d \n",devpriv->AdcItems); - + // VERSION 2.01 CHANGE: DELAY CHANGED FROM 250NS to 2US. Allow the // ADC to stabilize for 2 microseconds before starting the final // (dummy) conversion. This delay is necessary to allow sufficient @@ -1396,7 +1396,7 @@ void ResetADC(comedi_device *dev,uint8_t *ppl ) // Wait for the data from the last conversion of interest to arrive // in FB BUFFER 1 register. *pRPS++= RPS_PAUSE | RPS_GPIO2 ; // Wait for ADC done. - + // Transfer final ADC data from FB BUFFER 1 register to DMA buffer. *pRPS++=RPS_STREG | ( BUGFIX_STREG( P_FB_BUFFER1 ) >> 2 ) ;// *pRPS++=(uint32_t)devpriv->ANABuf.PhysicalBase + ( devpriv->AdcItems << 2 ) ; @@ -1418,30 +1418,30 @@ void ResetADC(comedi_device *dev,uint8_t *ppl ) // ------------------------------------------------------------ } -/* TO COMPLETE, IF NECESSARY */ -static int s626_ai_insn_config(comedi_device*dev,comedi_subdevice *s,comedi_insn *insn,lsampl_t *data){ +/* TO COMPLETE, IF NECESSARY */ +static int s626_ai_insn_config(comedi_device*dev,comedi_subdevice *s,comedi_insn *insn,lsampl_t *data){ return -EINVAL; } - + /* static int s626_ai_rinsn(comedi_device *dev,comedi_subdevice *s,comedi_insn *insn,lsampl_t *data) */ /* { */ /* register uint8_t i; */ /* register int32_t *readaddr; */ /* DEBUG("as626_ai_rinsn: ai_rinsn enter \n"); */ - + /* // Trigger ADC scan loop start by setting RPS Signal 0. */ /* MC_ENABLE( P_MC2, MC2_ADC_RPS ); */ - + /* // Wait until ADC scan loop is finished (RPS Signal 0 reset). */ /* while ( MC_TEST( P_MC2, MC2_ADC_RPS ) ); */ - + /* // Init ptr to DMA buffer that holds new ADC data. We skip the */ /* // first uint16_t in the buffer because it contains junk data from */ /* // the final ADC of the previous poll list scan. */ /* readaddr = (uint32_t *)devpriv->ANABuf.LogicalBase + 1; */ - + /* // Convert ADC data to 16-bit integer values and copy to application */ /* // buffer. */ /* for ( i = 0; i < devpriv->AdcItems; i++ ) { */ @@ -1449,7 +1449,7 @@ static int s626_ai_insn_config(comedi_device*dev,comedi_subdevice *s,comedi_insn /* DEBUG("s626_ai_rinsn: data %d \n",*data); */ /* data++; */ /* } */ - + /* DEBUG("s626_ai_rinsn: ai_rinsn escape \n"); */ /* return i; */ /* } */ @@ -1471,40 +1471,40 @@ static int s626_ai_insn_read(comedi_device *dev,comedi_subdevice *s,comedi_insn /* //enabled */ DEBUG("s626_ai_insn_read: entering\n"); - + // Convert application's ADC specification into form // appropriate for register programming. if(range==0) AdcSpec = ( chan << 8 ) | ( GSEL_BIPOLAR5V ); else AdcSpec = ( chan << 8 ) | ( GSEL_BIPOLAR10V ); - + // Switch ADC analog gain. DEBIwrite( dev, LP_GSEL, AdcSpec ); // Set gain. - + // Select ADC analog input channel. DEBIwrite( dev, LP_ISEL, AdcSpec ); // Select channel. - - for(n=0; nn; n++){ - - // Delay 10 microseconds for analog input settling. + + for(n=0; nn; n++){ + + // Delay 10 microseconds for analog input settling. comedi_udelay(10); - + // Start ADC by pulsing GPIO1 low. GpioImage = RR7146( P_GPIO ); // Assert ADC Start command - WR7146( P_GPIO, GpioImage & ~GPIO1_HI ); + WR7146( P_GPIO, GpioImage & ~GPIO1_HI ); // and stretch it out. - WR7146( P_GPIO, GpioImage & ~GPIO1_HI ); + WR7146( P_GPIO, GpioImage & ~GPIO1_HI ); WR7146( P_GPIO, GpioImage & ~GPIO1_HI ); // Negate ADC Start command. - WR7146( P_GPIO, GpioImage | GPIO1_HI ); - + WR7146( P_GPIO, GpioImage | GPIO1_HI ); + // Wait for ADC to complete (GPIO2 is asserted high when // ADC not busy) and for data from previous conversion to // shift into FB BUFFER 1 register. - + // Wait for ADC done. - while ( !( RR7146( P_PSR ) & PSR_GPIO2 ) ); - + while ( !( RR7146( P_PSR ) & PSR_GPIO2 ) ); + // Fetch ADC data. if(n!=0) data[n-1]=s626_ai_reg_to_uint(RR7146( P_FB_BUFFER1 )); @@ -1515,13 +1515,13 @@ static int s626_ai_insn_read(comedi_device *dev,comedi_subdevice *s,comedi_insn // conversion. Without this delay, the last conversion's // data value is sometimes set to the previous // conversion's data value. - comedi_udelay(4); + comedi_udelay(4); } - + // Start a dummy conversion to cause the data from the // previous conversion to be shifted in. GpioImage = RR7146( P_GPIO ); - + //Assert ADC Start command WR7146( P_GPIO, GpioImage & ~GPIO1_HI ); // and stretch it out. @@ -1529,25 +1529,25 @@ static int s626_ai_insn_read(comedi_device *dev,comedi_subdevice *s,comedi_insn WR7146( P_GPIO, GpioImage & ~GPIO1_HI ); // Negate ADC Start command. WR7146( P_GPIO, GpioImage | GPIO1_HI ); - + // Wait for the data to arrive in FB BUFFER 1 register. - + // Wait for ADC done. while ( !( RR7146( P_PSR ) & PSR_GPIO2 ) ); - + // Fetch ADC data from audio interface's input shift // register. - + // Fetch ADC data. if(n!=0) data[n-1]=s626_ai_reg_to_uint(RR7146( P_FB_BUFFER1 )); - + DEBUG("s626_ai_insn_read: samples %d, data %d\n",n,data[n-1]); - + return n; } static int s626_ai_load_polllist(uint8_t *ppl, comedi_cmd *cmd){ - + int n; for(n=0;nchanlist_len;n++){ @@ -1565,9 +1565,9 @@ static int s626_ai_inttrig(comedi_device *dev,comedi_subdevice *s, if(trignum!=0) return -EINVAL; DEBUG("s626_ai_inttrig: trigger adc start..."); - + // Start executing the RPS program. - MC_ENABLE( P_MC1, MC1_ERPS1 ); + MC_ENABLE( P_MC1, MC1_ERPS1 ); s->async->inttrig=NULL; @@ -1582,7 +1582,7 @@ static int s626_ai_cmd(comedi_device *dev,comedi_subdevice *s){ uint8_t ppl[16]; comedi_cmd *cmd=&s->async->cmd; enc_private *k; - int tick; + int tick; DEBUG("s626_ai_cmd: entering command function\n"); @@ -1603,7 +1603,7 @@ static int s626_ai_cmd(comedi_device *dev,comedi_subdevice *s){ // s626_enc_clear_irq(dev); //reset ai_cmd_running flag - devpriv->ai_cmd_running=0; + devpriv->ai_cmd_running=0; // test if cmd is valid if(cmd==NULL){ @@ -1619,7 +1619,7 @@ static int s626_ai_cmd(comedi_device *dev,comedi_subdevice *s){ } s626_ai_load_polllist(ppl,cmd); - devpriv->ai_cmd_running=1; + devpriv->ai_cmd_running=1; devpriv->ai_convert_count=0; switch(cmd->scan_begin_src){ @@ -1638,11 +1638,11 @@ static int s626_ai_cmd(comedi_device *dev,comedi_subdevice *s){ break; case TRIG_EXT: - // set the digital line and interrupt for scan trigger - if(cmd->start_src!=TRIG_EXT) s626_dio_set_irq(dev,cmd->scan_begin_arg); + // set the digital line and interrupt for scan trigger + if(cmd->start_src!=TRIG_EXT) s626_dio_set_irq(dev,cmd->scan_begin_arg); DEBUG("s626_ai_cmd: External scan trigger is set!!!\n"); - + break; } @@ -1662,7 +1662,7 @@ static int s626_ai_cmd(comedi_device *dev,comedi_subdevice *s){ break; case TRIG_EXT: // set the digital line and interrupt for convert trigger - if(cmd->scan_begin_src!=TRIG_EXT && cmd->start_src==TRIG_EXT) + if(cmd->scan_begin_src!=TRIG_EXT && cmd->start_src==TRIG_EXT) s626_dio_set_irq(dev, cmd->convert_arg); DEBUG("s626_ai_cmd: External convert trigger is set!!!\n"); @@ -1683,7 +1683,7 @@ static int s626_ai_cmd(comedi_device *dev,comedi_subdevice *s){ break; } - ResetADC(dev,ppl); + ResetADC(dev,ppl); switch(cmd->start_src){ case TRIG_NOW: @@ -1691,7 +1691,7 @@ static int s626_ai_cmd(comedi_device *dev,comedi_subdevice *s){ // MC_ENABLE( P_MC2, MC2_ADC_RPS ); // Start executing the RPS program. - MC_ENABLE( P_MC1, MC1_ERPS1 ); + MC_ENABLE( P_MC1, MC1_ERPS1 ); DEBUG("s626_ai_cmd: ADC triggered\n"); s->async->inttrig=NULL; @@ -1708,7 +1708,7 @@ static int s626_ai_cmd(comedi_device *dev,comedi_subdevice *s){ s->async->inttrig=s626_ai_inttrig; break; } - + //enable interrupt writel(IRQ_GPIO3 | IRQ_RPS1,devpriv->base_addr+P_IER); @@ -1890,7 +1890,7 @@ static int s626_ai_cancel(comedi_device *dev,comedi_subdevice *s) MC_DISABLE( P_MC1, MC1_ERPS1 ); //disable master interrupt - writel(0,devpriv->base_addr+P_IER); + writel(0,devpriv->base_addr+P_IER); devpriv->ai_cmd_running=0; @@ -1905,7 +1905,7 @@ static int s626_ai_cancel(comedi_device *dev,comedi_subdevice *s) static int s626_ns_to_timer(int *nanosec,int round_mode) { int divider,base; - + base=500; //2MHz internal clock switch(round_mode){ @@ -1926,7 +1926,7 @@ static int s626_ns_to_timer(int *nanosec,int round_mode) } static int s626_ao_winsn(comedi_device *dev,comedi_subdevice *s,comedi_insn *insn,lsampl_t *data){ - + int i; uint16_t chan = CR_CHAN(insn->chanspec); int16_t dacdata; @@ -1934,22 +1934,22 @@ static int s626_ao_winsn(comedi_device *dev,comedi_subdevice *s,comedi_insn *ins for(i=0;in;i++){ dacdata=(int16_t)data[i]; devpriv->ao_readback[CR_CHAN(insn->chanspec)]=data[i]; - dacdata-= ( 0x1fff ); - + dacdata-= ( 0x1fff ); + SetDAC(dev,chan,dacdata); } - + return i; } static int s626_ao_rinsn(comedi_device *dev,comedi_subdevice *s,comedi_insn *insn,lsampl_t *data) { - int i; + int i; for(i=0;in;i++){ - data[i] = devpriv->ao_readback[CR_CHAN(insn->chanspec)]; + data[i] = devpriv->ao_readback[CR_CHAN(insn->chanspec)]; } - + return i; } @@ -1965,10 +1965,10 @@ static void s626_dio_init(comedi_device *dev) { uint16_t group; comedi_subdevice *s; - + // Prepare to treat writes to WRCapSel as capture disables. DEBIwrite(dev, LP_MISC1, MISC1_NOEDCAP ); - + // For each group of sixteen channels ... for ( group = 0; group < S626_DIO_BANKS ; group++ ) { @@ -1991,8 +1991,8 @@ static void s626_dio_init(comedi_device *dev) * This allows packed reading/writing of the DIO channels. The comedi * core can convert between insn_bits and insn_read/write */ -static int s626_dio_insn_bits(comedi_device *dev,comedi_subdevice *s,comedi_insn *insn,lsampl_t *data){ - +static int s626_dio_insn_bits(comedi_device *dev,comedi_subdevice *s,comedi_insn *insn,lsampl_t *data){ + /* Length of data must be 2 (mask and new data, see below) */ if(insn->n == 0){ return 0; @@ -2001,8 +2001,8 @@ static int s626_dio_insn_bits(comedi_device *dev,comedi_subdevice *s,comedi_insn printk("comedi%d: s626: s626_dio_insn_bits(): Invalid instruction length\n", dev->minor); return -EINVAL; } - - /* + + /* * The insn data consists of a mask in data[0] and the new data in * data[1]. The mask defines which bits we are concerning about. * The new data must be anded with the mask. Each channel @@ -2012,21 +2012,21 @@ static int s626_dio_insn_bits(comedi_device *dev,comedi_subdevice *s,comedi_insn /* Check if requested ports are configured for output */ if((s->io_bits & data[0]) != data[0]) return -EIO; - + s->state &= ~data[0]; s->state |= data[0] & data[1]; - + /* Write out the new digital output lines */ - + DEBIwrite(dev,diopriv->WRDOut,s->state); } data[1]=DEBIread(dev,diopriv->RDDIn); - + return 2; } static int s626_dio_insn_config(comedi_device *dev,comedi_subdevice *s,comedi_insn *insn,lsampl_t *data) -{ +{ switch(data[0]){ case INSN_CONFIG_DIO_QUERY: @@ -2034,7 +2034,7 @@ static int s626_dio_insn_config(comedi_device *dev,comedi_subdevice *s,comedi_in return insn->n; break; case COMEDI_INPUT: - s->io_bits&= ~(1 << CR_CHAN(insn->chanspec)); + s->io_bits&= ~(1 << CR_CHAN(insn->chanspec)); break; case COMEDI_OUTPUT: s->io_bits|= 1 << CR_CHAN(insn->chanspec); @@ -2044,49 +2044,49 @@ static int s626_dio_insn_config(comedi_device *dev,comedi_subdevice *s,comedi_in break; } DEBIwrite(dev,diopriv->WRDOut,s->io_bits); - + return 1; } static int s626_dio_set_irq(comedi_device *dev, unsigned int chan) { unsigned int group; - unsigned int bitmask; - unsigned int status; + unsigned int bitmask; + unsigned int status; //select dio bank group=chan/16; bitmask=1<<(chan-(16*group)); - DEBUG("s626_dio_set_irq: enable interrupt on dio channel %d group %d\n",chan-(16*group),group); - + DEBUG("s626_dio_set_irq: enable interrupt on dio channel %d group %d\n",chan-(16*group),group); + //set channel to capture positive edge status=DEBIread(dev,((dio_private *)(dev->subdevices+2+group)->private)->RDEdgSel); DEBIwrite(dev,((dio_private *)(dev->subdevices+2+group)->private)->WREdgSel,bitmask|status); - + //enable interrupt on selected channel status=DEBIread(dev,((dio_private *)(dev->subdevices+2+group)->private)->RDIntSel); DEBIwrite(dev,((dio_private *)(dev->subdevices+2+group)->private)->WRIntSel,bitmask|status); - + //enable edge capture write command DEBIwrite(dev,LP_MISC1,MISC1_EDCAP); - + //enable edge capture on selected channel status=DEBIread(dev,((dio_private *)(dev->subdevices+2+group)->private)->RDCapSel); DEBIwrite(dev,((dio_private *)(dev->subdevices+2+group)->private)->WRCapSel,bitmask|status); - + return 0; } static int s626_dio_reset_irq(comedi_device *dev, unsigned int group, unsigned int mask) { - DEBUG("s626_dio_reset_irq: disable interrupt on dio channel %d group %d\n",mask,group); + DEBUG("s626_dio_reset_irq: disable interrupt on dio channel %d group %d\n",mask,group); //disable edge capture write command DEBIwrite(dev,LP_MISC1,MISC1_NOEDCAP); - + //enable edge capture on selected channel DEBIwrite(dev,((dio_private *)(dev->subdevices+2+group)->private)->WRCapSel,mask); - + return 0; } @@ -2096,7 +2096,7 @@ static int s626_dio_clear_irq(comedi_device *dev) //disable edge capture write command DEBIwrite(dev,LP_MISC1,MISC1_NOEDCAP); - + for(group=0;groupsubdevices+2+group)->private)->WRCapSel,0xffff); @@ -2109,7 +2109,7 @@ static int s626_dio_clear_irq(comedi_device *dev) and set the subdevice. To complete with trigger and interrupt configuration */ static int s626_enc_insn_config(comedi_device *dev,comedi_subdevice *s,comedi_insn *insn,lsampl_t *data) -{ +{ uint16_t Setup = ( LOADSRC_INDX << BF_LOADSRC ) | // Preload upon // index. ( INDXSRC_SOFT << BF_INDXSRC ) | // Disable hardware index. @@ -2121,8 +2121,8 @@ static int s626_enc_insn_config(comedi_device *dev,comedi_subdevice *s,comedi_i /* uint16_t DisableIntSrc=TRUE; */ // uint32_t Preloadvalue; //Counter initial value uint16_t valueSrclatch=LATCHSRC_AB_READ ; - uint16_t enab=CLKENAB_ALWAYS; - enc_private *k=&encpriv[CR_CHAN(insn->chanspec)]; + uint16_t enab=CLKENAB_ALWAYS; + enc_private *k=&encpriv[CR_CHAN(insn->chanspec)]; DEBUG("s626_enc_insn_config: encoder config\n"); @@ -2141,11 +2141,11 @@ static int s626_enc_insn_read(comedi_device *dev,comedi_subdevice *s,comedi_insn int n; enc_private *k=&encpriv[CR_CHAN(insn->chanspec)]; - - DEBUG("s626_enc_insn_read: encoder read channel %d \n",CR_CHAN(insn->chanspec)); - for (n=0;nn;n++) data[n]=ReadLatch(dev,k); - + DEBUG("s626_enc_insn_read: encoder read channel %d \n",CR_CHAN(insn->chanspec)); + + for (n=0;nn;n++) data[n]=ReadLatch(dev,k); + DEBUG("s626_enc_insn_read: encoder sample %d\n",data[n]); return n; @@ -2155,11 +2155,11 @@ static int s626_enc_insn_write(comedi_device *dev,comedi_subdevice *s,comedi_ins enc_private *k=&encpriv[CR_CHAN(insn->chanspec)]; - DEBUG("s626_enc_insn_write: encoder write channel %d \n",CR_CHAN(insn->chanspec)); + DEBUG("s626_enc_insn_write: encoder write channel %d \n",CR_CHAN(insn->chanspec)); // Set the preload register Preload(dev,k,data[0]); - + // Software index pulse forces the preload register to load // into the counter k->SetLoadTrig(dev, k, 0); @@ -2182,13 +2182,13 @@ static void s626_timer_load(comedi_device *dev, enc_private *k, int tick) ( CLKMULT_1X << BF_CLKMULT ) | // Clock multiplier is 1x. ( CLKENAB_INDEX << BF_CLKENAB ); uint16_t valueSrclatch=LATCHSRC_A_INDXA ; - // uint16_t enab=CLKENAB_ALWAYS; + // uint16_t enab=CLKENAB_ALWAYS; k->SetMode(dev,k,Setup,FALSE); // Set the preload register Preload(dev,k,tick); - + // Software index pulse forces the preload register to load // into the counter k->SetLoadTrig(dev, k, 0); @@ -2255,7 +2255,7 @@ static void WriteTrimDAC(comedi_device *dev, uint8_t LogicalChan, uint8_t DacDat // value (that writes a channel 0 NOP command to a non-existent main // DAC channel) that serves to keep the clock running after the // packet has been sent to the target DAC. - + SendDAC(dev, ( (uint32_t)chan << 8 ) // Address the DAC channel // within the trimdac device. | (uint32_t)DacData ); // Include DAC setpoint data. @@ -2271,7 +2271,7 @@ static void WriteTrimDAC(comedi_device *dev, uint8_t LogicalChan, uint8_t DacDat static uint8_t I2Cread(comedi_device *dev, uint8_t addr ) { uint8_t rtnval; - + // Send EEPROM target address. if ( I2Chandshake(dev, I2C_B2( I2C_ATTRSTART, I2CW ) // Byte2 = I2C // command: @@ -2285,7 +2285,7 @@ static uint8_t I2Cread(comedi_device *dev, uint8_t addr ) // sent. { // Abort function and declare error if handshake failed. - DEBUG("I2Cread: error handshake I2Cread a\n"); + DEBUG("I2Cread: error handshake I2Cread a\n"); return 0; } @@ -2302,7 +2302,7 @@ static uint8_t I2Cread(comedi_device *dev, uint8_t addr ) // sent. { // Abort function and declare error if handshake failed. - DEBUG("I2Cread: error handshake I2Cread b\n"); + DEBUG("I2Cread: error handshake I2Cread b\n"); return 0; } @@ -2318,13 +2318,13 @@ static uint32_t I2Chandshake(comedi_device *dev, uint32_t val ) // Upload I2C shadow registers into working registers and wait for // upload confirmation. - + MC_ENABLE( P_MC2, MC2_UPLD_IIC ); while ( !MC_TEST( P_MC2, MC2_UPLD_IIC ) ); // Wait until I2C bus transfer is finished or an error occurs. while ( ( RR7146(P_I2CCTRL) & ( I2C_BUSY | I2C_ERR ) ) == I2C_BUSY ); - + // Return non-zero if I2C error occured. return RR7146(P_I2CCTRL) & I2C_ERR; @@ -2399,7 +2399,7 @@ static void SetDAC(comedi_device *dev,uint16_t chan, short dacdata ) static void SendDAC( comedi_device *dev, uint32_t val ) { - + // START THE SERIAL CLOCK RUNNING ------------- // Assert DAC polarity control and enable gating of DAC serial clock @@ -2413,10 +2413,10 @@ static void SendDAC( comedi_device *dev, uint32_t val ) DEBIwrite(dev, LP_DACPOL, devpriv->Dacpol ); // TRANSFER OUTPUT DWORD VALUE INTO A2'S OUTPUT FIFO ---------------- - + // Copy DAC setpoint value to DAC's output DMA buffer. - - //WR7146( (uint32_t)devpriv->pDacWBuf, val ); + + //WR7146( (uint32_t)devpriv->pDacWBuf, val ); *devpriv->pDacWBuf=val; // enab the output DMA transfer. This will cause the DMAC to copy @@ -2548,7 +2548,7 @@ static void DEBItransfer(comedi_device *dev ) // Write a value to a gate array register. static void DEBIwrite(comedi_device *dev, uint16_t addr, uint16_t wdata ) { - + // Set up DEBI control register value in shadow RAM. WR7146( P_DEBICMD, DEBI_CMD_WRWORD | addr ); WR7146( P_DEBIAD, wdata ); @@ -2588,7 +2588,7 @@ static void CloseDMAB (comedi_device *dev,DMABUF * pdma,size_t bsize ) if (pdma == NULL) return; //find the matching allocation from the board struct - + vbptr=pdma->LogicalBase; vpptr=pdma->PhysicalBase; if (vbptr) @@ -2597,7 +2597,7 @@ static void CloseDMAB (comedi_device *dev,DMABUF * pdma,size_t bsize ) (int) vpptr); pdma->LogicalBase = 0; pdma->PhysicalBase = 0; - + DEBUG ("CloseDMAB(): Logical=0x%x, bsize=%d, Physical=0x%x\n", (uint32_t) vbptr, bsize, (uint32_t) vpptr); } } @@ -2633,7 +2633,7 @@ static uint32_t ReadLatch(comedi_device *dev, enc_private *k ) value |= ( (uint32_t) DEBIread(dev,k->MyLatchLsw + 2 ) << 16 ); // DEBUG FIXME DEBUG("ReadLatch: Read Latch exit\n"); - + // Return latched counts. return value; } @@ -2647,7 +2647,7 @@ static void ResetCapFlags_A(comedi_device *dev, enc_private *k ) } static void ResetCapFlags_B(comedi_device *dev, enc_private *k ) -{ +{ DEBIreplace(dev, k->MyCRB, (uint16_t)( ~CRBMSK_INTCTRL ), CRBMSK_INTRESETCMD | CRBMSK_INTRESET_B ); } @@ -2661,7 +2661,7 @@ static uint16_t GetMode_A(comedi_device *dev, enc_private *k ) register uint16_t crb; register uint16_t setup; - // Fetch CRA and CRB register images. + // Fetch CRA and CRB register images. cra = DEBIread(dev,k->MyCRA ); crb = DEBIread(dev,k->MyCRB ); @@ -2703,7 +2703,7 @@ static uint16_t GetMode_B(comedi_device *dev, enc_private *k ) // Populate the standardized counter setup bit fields. Note: // IndexSrc is restricted to ENC_X or IndxPol. - setup = + setup = ( ( ( crb << ( STDBIT_INTSRC - CRBBIT_INTSRC_B ) ) & STDMSK_INTSRC ) // IntSrc = IntSrcB. | ( ( crb << ( STDBIT_LATCHSRC - CRBBIT_LATCHSRC ) ) & STDMSK_LATCHSRC ) // LatchSrc = LatchSrcB. | ( ( crb << ( STDBIT_LOADSRC - CRBBIT_LOADSRC_B ) ) & STDMSK_LOADSRC ) // LoadSrc = LoadSrcB. @@ -2724,8 +2724,8 @@ static uint16_t GetMode_B(comedi_device *dev, enc_private *k ) else // If Counter mode (ClkSrcB<1> == 0): setup |= ( ( CLKSRC_COUNTER << STDBIT_CLKSRC ) // Indicate Timer mode. - | ( ( crb >> ( CRBBIT_CLKMULT_B - STDBIT_CLKMULT ) ) & STDMSK_CLKMULT ) // Clock multiplier is passed through. - | ( ( crb << ( STDBIT_CLKPOL - CRBBIT_CLKPOL_B ) ) & STDMSK_CLKPOL ) ); // Clock polarity is passed through. + | ( ( crb >> ( CRBBIT_CLKMULT_B - STDBIT_CLKMULT ) ) & STDMSK_CLKMULT ) // Clock multiplier is passed through. + | ( ( crb << ( STDBIT_CLKPOL - CRBBIT_CLKPOL_B ) ) & STDMSK_CLKPOL ) ); // Clock polarity is passed through. // Return adjusted counter setup. return setup; @@ -2739,17 +2739,17 @@ static uint16_t GetMode_B(comedi_device *dev, enc_private *k ) static void SetMode_A(comedi_device *dev, enc_private *k, uint16_t Setup, uint16_t DisableIntSrc ) { - register uint16_t cra; + register uint16_t cra; register uint16_t crb; register uint16_t setup = Setup; // Cache the Standard Setup. // Initialize CRA and CRB images. cra = ( ( setup & CRAMSK_LOADSRC_A ) // Preload trigger is passed through. | ( ( setup & STDMSK_INDXSRC ) >> ( STDBIT_INDXSRC - (CRABIT_INDXSRC_A + 1) ) ) ); // IndexSrc is restricted to ENC_X or IndxPol. - + crb = ( CRBMSK_INTRESETCMD | CRBMSK_INTRESET_A // Reset any pending CounterA event captures. | ( ( setup & STDMSK_CLKENAB ) << ( CRBBIT_CLKENAB_A - STDBIT_CLKENAB ) ) ); // Clock enable is passed through. - + // Force IntSrc to Disabled if DisableIntSrc is asserted. if ( !DisableIntSrc ) cra |= ( ( setup & STDMSK_INTSRC ) >> ( STDBIT_INTSRC - CRABIT_INTSRC_A ) ); @@ -2788,12 +2788,12 @@ static void SetMode_A(comedi_device *dev, enc_private *k, uint16_t Setup, uint16 // While retaining CounterB and LatchSrc configurations, program the // new counter operating mode. DEBIreplace(dev, k->MyCRA, CRAMSK_INDXSRC_B | CRAMSK_CLKSRC_B, cra ); - DEBIreplace(dev, k->MyCRB, (uint16_t)( ~( CRBMSK_INTCTRL | CRBMSK_CLKENAB_A ) ), crb ); + DEBIreplace(dev, k->MyCRB, (uint16_t)( ~( CRBMSK_INTCTRL | CRBMSK_CLKENAB_A ) ), crb ); } static void SetMode_B(comedi_device *dev, enc_private *k, uint16_t Setup, uint16_t DisableIntSrc ) { - register uint16_t cra; + register uint16_t cra; register uint16_t crb; register uint16_t setup = Setup; // Cache the Standard Setup. @@ -2935,10 +2935,10 @@ static void SetIntSrc_A(comedi_device *dev, enc_private *k, uint16_t IntSource ) static void SetIntSrc_B( comedi_device *dev,enc_private *k, uint16_t IntSource ) { uint16_t crb; - + // Cache writeable CRB register image. crb = DEBIread(dev, k->MyCRB ) & ~CRBMSK_INTCTRL; - + // Reset any pending counter overflow or index captures. DEBIwrite(dev, k->MyCRB, (uint16_t)( crb | CRBMSK_INTRESETCMD | CRBMSK_INTRESET_B ) ); @@ -3033,7 +3033,7 @@ static uint16_t GetIntSrc_B( comedi_device *dev,enc_private *k ) static void PulseIndex_A( comedi_device *dev,enc_private *k ) { register uint16_t cra; - + DEBUG("PulseIndex_A: pulse index enter\n"); @@ -3046,10 +3046,10 @@ static void PulseIndex_A( comedi_device *dev,enc_private *k ) static void PulseIndex_B( comedi_device *dev,enc_private *k ) { register uint16_t crb; - + crb = DEBIread(dev, k->MyCRB ) & ~CRBMSK_INTCTRL; // Pulse index. DEBIwrite(dev, k->MyCRB, (uint16_t)( crb ^ CRBMSK_INDXPOL_B ) ); - DEBIwrite(dev, k->MyCRB, crb); + DEBIwrite(dev, k->MyCRB, crb); } ///////////////////////////////////////////////////////// diff --git a/comedi/drivers/skel.c b/comedi/drivers/skel.c index c16222c1..b8f9e402 100644 --- a/comedi/drivers/skel.c +++ b/comedi/drivers/skel.c @@ -243,7 +243,8 @@ static int skel_attach(comedi_device *dev,comedi_devconfig *it) s->len_chanlist=16; /* This is the maximum chanlist length that the board can handle */ s->insn_read = skel_ai_rinsn; - //s->do_cmd = skel_ai_cmd; +// s->subdev_flags |= SDF_CMD_READ; +// s->do_cmd = skel_ai_cmd; s->do_cmdtest = skel_ai_cmdtest; s=dev->subdevices+1; @@ -272,7 +273,7 @@ static int skel_attach(comedi_device *dev,comedi_devconfig *it) printk("attached\n"); - return 1; + return 0; } diff --git a/comedi/drivers/usbdux.c b/comedi/drivers/usbdux.c index 38c39314..2f253e8c 100644 --- a/comedi/drivers/usbdux.c +++ b/comedi/drivers/usbdux.c @@ -345,7 +345,7 @@ static int usbdux_ai_stop(usbduxsub_t* this_usbduxsub, ret=usbduxsub_unlink_InURBs(this_usbduxsub); } - this_usbduxsub->ai_cmd_running=0; + this_usbduxsub->ai_cmd_running=0; return ret; } @@ -355,7 +355,7 @@ static int usbdux_ai_stop(usbduxsub_t* this_usbduxsub, // This will cancel a running acquisition operation. // This is called by comedi but never from inside the // driver. -static int usbdux_ai_cancel(comedi_device *dev, +static int usbdux_ai_cancel(comedi_device *dev, comedi_subdevice *s) { usbduxsub_t* this_usbduxsub; @@ -391,37 +391,37 @@ static int usbdux_ai_cancel(comedi_device *dev, static void usbduxsub_ai_IsocIrq(struct urb *urb) #else static void usbduxsub_ai_IsocIrq(struct urb *urb, struct pt_regs *regs) -#endif +#endif { int i,err,n; usbduxsub_t* this_usbduxsub; comedi_device *this_comedidev; comedi_subdevice *s; - + // sanity checks // is the urb there? if (!urb) { printk("comedi_: usbdux_: ao int-handler called with urb=NULL!\n"); return; } - + // the context variable points to the subdevice this_comedidev=urb->context; if (unlikely(!this_comedidev)) { printk("comedi_: usbdux_: BUG! urb context is a NULL pointer!\n"); return; } - + // the private structure of the subdevice is usbduxsub_t this_usbduxsub=this_comedidev->private; if (unlikely(!this_usbduxsub)) { printk("comedi_: usbdux_: BUG! private of comedi subdev is a NULL pointer!\n"); return; } - + // subdevice which is the AD converter s=this_comedidev->subdevices + SUBDEV_AD; - + // first we test if something unusual has just happened switch (urb->status) { case 0: @@ -438,9 +438,9 @@ static void usbduxsub_ai_IsocIrq(struct urb *urb, struct pt_regs *regs) printk("comedi%d: usbdux: CRC error in ISO IN stream.\n", this_usbduxsub->comedidev->minor); #endif - + break; - + // happens after an unlink command case -ECONNRESET: case -ENOENT: @@ -451,7 +451,7 @@ static void usbduxsub_ai_IsocIrq(struct urb *urb, struct pt_regs *regs) // tell this comedi s->async->events |= COMEDI_CB_EOA; s->async->events |= COMEDI_CB_ERROR; - comedi_event(this_usbduxsub->comedidev, + comedi_event(this_usbduxsub->comedidev, s, s->async->events); // stop the transfer w/o unlink @@ -467,8 +467,8 @@ static void usbduxsub_ai_IsocIrq(struct urb *urb, struct pt_regs *regs) urb->status); s->async->events |= COMEDI_CB_EOA; s->async->events |= COMEDI_CB_ERROR; - comedi_event(this_usbduxsub->comedidev, - s, + comedi_event(this_usbduxsub->comedidev, + s, s->async->events); // don't do an unlink here usbdux_ai_stop(this_usbduxsub,0); @@ -499,14 +499,14 @@ static void usbduxsub_ai_IsocIrq(struct urb *urb, struct pt_regs *regs) } s->async->events |= COMEDI_CB_EOA; s->async->events |= COMEDI_CB_ERROR; - comedi_event(this_usbduxsub->comedidev, - s, + comedi_event(this_usbduxsub->comedidev, + s, s->async->events); // don't do an unlink here usbdux_ai_stop(this_usbduxsub,0); return; } - + this_usbduxsub->ai_counter--; if (likely(this_usbduxsub->ai_counter>0)) { return; @@ -514,7 +514,7 @@ static void usbduxsub_ai_IsocIrq(struct urb *urb, struct pt_regs *regs) // timer zero, transfer measurements to comedi this_usbduxsub->ai_counter=this_usbduxsub->ai_timer; - + // test, if we transmit only a fixed number of samples if (!(this_usbduxsub->ai_continous)) { // not continous, fixed number of samples @@ -526,8 +526,8 @@ static void usbduxsub_ai_IsocIrq(struct urb *urb, struct pt_regs *regs) 0); // say comedi that the acquistion is over s->async->events |= COMEDI_CB_EOA; - comedi_event(this_usbduxsub->comedidev, - s, + comedi_event(this_usbduxsub->comedidev, + s, s->async->events); return; } @@ -540,17 +540,17 @@ static void usbduxsub_ai_IsocIrq(struct urb *urb, struct pt_regs *regs) // transfer data if (CR_RANGE(s->async->cmd.chanlist[i])<=1) { comedi_buf_put - (s->async, + (s->async, le16_to_cpu(this_usbduxsub->inBuffer[i])^0x800); } else { comedi_buf_put - (s->async, + (s->async, le16_to_cpu(this_usbduxsub->inBuffer[i])); } } // tell comedi that data is there - comedi_event(this_usbduxsub->comedidev, - s, + comedi_event(this_usbduxsub->comedidev, + s, s->async->events); } @@ -696,8 +696,8 @@ static void usbduxsub_ao_IsocIrq(struct urb *urb, struct pt_regs *regs) { case -ECONNABORTED: if (this_usbduxsub->ao_cmd_running) { s->async->events |= COMEDI_CB_EOA; - comedi_event(this_usbduxsub->comedidev, - s, + comedi_event(this_usbduxsub->comedidev, + s, s->async->events); usbdux_ao_stop(this_usbduxsub,0); } @@ -710,8 +710,8 @@ static void usbduxsub_ao_IsocIrq(struct urb *urb, struct pt_regs *regs) { urb->status); s->async->events |= COMEDI_CB_ERROR; s->async->events |= COMEDI_CB_EOA; - comedi_event(this_usbduxsub->comedidev, - s, + comedi_event(this_usbduxsub->comedidev, + s, s->async->events); // we do an unlink if we are in the high speed mode usbdux_ao_stop(this_usbduxsub,0); @@ -726,7 +726,7 @@ static void usbduxsub_ao_IsocIrq(struct urb *urb, struct pt_regs *regs) { // normal operation: executing a command in this subdevice this_usbduxsub->ao_counter--; - if (this_usbduxsub->ao_counter<=0) { + if (this_usbduxsub->ao_counter<=0) { // timer zero this_usbduxsub->ao_counter=this_usbduxsub->ao_timer; @@ -739,8 +739,8 @@ static void usbduxsub_ao_IsocIrq(struct urb *urb, struct pt_regs *regs) { usbdux_ao_stop(this_usbduxsub, 0); s->async->events |= COMEDI_CB_EOA; - comedi_event(this_usbduxsub->comedidev, - s, + comedi_event(this_usbduxsub->comedidev, + s, s->async->events); // no resubmit of the urb return; @@ -772,15 +772,15 @@ static void usbduxsub_ao_IsocIrq(struct urb *urb, struct pt_regs *regs) { } // transmit data to comedi s->async->events |= COMEDI_CB_BLOCK; - comedi_event(this_usbduxsub->comedidev, - s, + comedi_event(this_usbduxsub->comedidev, + s, s->async->events); } } urb->transfer_buffer_length = SIZEOUTBUF; urb->dev = this_usbduxsub->usbdev; urb->status = 0; - if (this_usbduxsub->ao_cmd_running) { + if (this_usbduxsub->ao_cmd_running) { if (this_usbduxsub->high_speed) { // uframes urb->interval=8; @@ -788,7 +788,7 @@ static void usbduxsub_ao_IsocIrq(struct urb *urb, struct pt_regs *regs) { // frames urb->interval=1; } - urb->number_of_packets = 1; + urb->number_of_packets = 1; urb->iso_frame_desc[0].offset = 0; urb->iso_frame_desc[0].length = SIZEOUTBUF; urb->iso_frame_desc[0].status = 0; @@ -802,8 +802,8 @@ static void usbduxsub_ao_IsocIrq(struct urb *urb, struct pt_regs *regs) { } s->async->events |= COMEDI_CB_EOA; s->async->events |= COMEDI_CB_ERROR; - comedi_event(this_usbduxsub->comedidev, - s, + comedi_event(this_usbduxsub->comedidev, + s, s->async->events); // don't do an unlink here usbdux_ao_stop(this_usbduxsub,0); @@ -828,17 +828,17 @@ static int usbduxsub_start(usbduxsub_t* usbduxsub) { if (usbduxsub->probed) { // 7f92 to zero - local_transfer_buffer[0]=0; + local_transfer_buffer[0]=0; errcode=USB_CONTROL_MSG (usbduxsub->usbdev, // create a pipe for a control transfer usb_sndctrlpipe(usbduxsub->usbdev,0), // bRequest, "Firmware" - USBDUXSUB_FIRMWARE, + USBDUXSUB_FIRMWARE, // bmRequestType - VENDOR_DIR_OUT, + VENDOR_DIR_OUT, // Value - USBDUXSUB_CPUCS, + USBDUXSUB_CPUCS, // Index 0x0000, // address of the transfer buffer @@ -846,7 +846,7 @@ static int usbduxsub_start(usbduxsub_t* usbduxsub) { // Length 1, // Timeout - EZTIMEOUT + EZTIMEOUT ); if (errcode<0) { printk("comedi_: usbdux_: control msg failed (start)\n"); @@ -865,23 +865,23 @@ static int usbduxsub_stop(usbduxsub_t* usbduxsub) { uint8_t local_transfer_buffer[16]; if (usbduxsub->probed) { // 7f92 to one - local_transfer_buffer[0]=1; + local_transfer_buffer[0]=1; errcode=USB_CONTROL_MSG (usbduxsub->usbdev, usb_sndctrlpipe(usbduxsub->usbdev,0), // bRequest, "Firmware" - USBDUXSUB_FIRMWARE, + USBDUXSUB_FIRMWARE, // bmRequestType VENDOR_DIR_OUT, // Value USBDUXSUB_CPUCS, // Index - 0x0000, + 0x0000, local_transfer_buffer, // Length 1, // Timeout - EZTIMEOUT + EZTIMEOUT ); if (errcode<0) { printk("comedi_: usbdux: control msg failed (stop)\n"); @@ -890,7 +890,7 @@ static int usbduxsub_stop(usbduxsub_t* usbduxsub) { } return 0; } - + @@ -945,7 +945,7 @@ return 0; -int firmwareUpload(usbduxsub_t* usbduxsub, +int firmwareUpload(usbduxsub_t* usbduxsub, uint8_t* firmwareBinary, int sizeFirmware) { int ret; @@ -976,7 +976,7 @@ int firmwareUpload(usbduxsub_t* usbduxsub, } return 0; } - + int usbduxsub_submit_InURBs(usbduxsub_t* usbduxsub) { @@ -1047,12 +1047,12 @@ int usbduxsub_submit_OutURBs(usbduxsub_t* usbduxsub) { -static int usbdux_ai_cmdtest(comedi_device *dev, - comedi_subdevice *s, +static int usbdux_ai_cmdtest(comedi_device *dev, + comedi_subdevice *s, comedi_cmd *cmd) { int err=0,tmp,i; - unsigned int tmpTimer; + unsigned int tmpTimer; usbduxsub_t* this_usbduxsub=dev->private; if (!(this_usbduxsub->probed)) { return -ENODEV; @@ -1157,7 +1157,7 @@ static int usbdux_ai_cmdtest(comedi_device *dev, err++; } - + if(cmd->stop_src==TRIG_COUNT){ /* any count is allowed */ }else{ @@ -1177,7 +1177,7 @@ static int usbdux_ai_cmdtest(comedi_device *dev, // creates the ADC command for the MAX1271 // range is the range value from comedi static int8_t create_adc_command(unsigned int chan, int range) { - int8_t p=(range<=1); + int8_t p=(range<=1); int8_t r=((range%2)==0); return (chan<<4)| ((p==1)<<2)| @@ -1214,7 +1214,7 @@ static int send_dux_commands(usbduxsub_t* this_usbduxsub,int cmd_type) { COMMAND_OUT_EP), this_usbduxsub->dux_commands, SIZEOFDUXBUFFER, - &nsent, + &nsent, 10*HZ); if (result<0) { printk("comedi%d: could not transmit dux_command to the usb-device, err=%d\n", @@ -1232,14 +1232,14 @@ static int receive_dux_commands(usbduxsub_t* this_usbduxsub,int command) { int result=-EFAULT; int nrec; int i; - + for(i=0;iusbdev, usb_rcvbulkpipe(this_usbduxsub->usbdev, COMMAND_IN_EP), this_usbduxsub->insnBuffer, SIZEINSNBUF, - &nrec, + &nrec, 1*HZ); if (result<0) { printk("comedi%d: insn: USB error %d while receiving DUX command\n", @@ -1349,7 +1349,7 @@ static int usbdux_ai_cmd(comedi_device *dev, comedi_subdevice *s) // set current channel of the running aquisition to zero s->async->cur_chan=0; - + this_usbduxsub->dux_commands[1]=cmd->chanlist_len; for(i=0; i < cmd->chanlist_len; ++i ) { chan = CR_CHAN(cmd->chanlist[i]); @@ -1389,8 +1389,8 @@ static int usbdux_ai_cmd(comedi_device *dev, comedi_subdevice *s) this_usbduxsub->ai_timer = cmd->scan_begin_arg/1000000; } if (this_usbduxsub->ai_timer<1) { - printk("comedi%d: usbdux: ai_cmd: timer=%d, scan_begin_arg=%d. Not properly tested by cmdtest?\n", - dev->minor, + printk("comedi%d: usbdux: ai_cmd: timer=%d, scan_begin_arg=%d. Not properly tested by cmdtest?\n", + dev->minor, this_usbduxsub->ai_timer, cmd->scan_begin_arg); up(&this_usbduxsub->sem); @@ -1401,7 +1401,7 @@ static int usbdux_ai_cmd(comedi_device *dev, comedi_subdevice *s) if(cmd->stop_src==TRIG_COUNT){ // data arrives as one packet this_usbduxsub->ai_sample_count = cmd->stop_arg; - this_usbduxsub->ai_continous=0; + this_usbduxsub->ai_continous=0; } else { // continous aquisition this_usbduxsub->ai_continous=1; @@ -1434,9 +1434,9 @@ static int usbdux_ai_cmd(comedi_device *dev, comedi_subdevice *s) /* Mode 0 is used to get a single conversion on demand */ -static int usbdux_ai_insn_read(comedi_device * dev, +static int usbdux_ai_insn_read(comedi_device * dev, comedi_subdevice *s, - comedi_insn *insn, + comedi_insn *insn, lsampl_t *data) { int i; @@ -1449,7 +1449,7 @@ static int usbdux_ai_insn_read(comedi_device * dev, printk("comedi%d: ai_insn_read: no usb dev.\n", dev->minor); return 0; - } + } #ifdef NOISY_DUX_DEBUGBUG printk("comedi%d: ai_insn_read, insn->n=%d, insn->subdev=%d\n", dev->minor, @@ -1508,12 +1508,12 @@ static int usbdux_ai_insn_read(comedi_device * dev, static int usbdux_ao_insn_read(comedi_device *dev, comedi_subdevice *s, - comedi_insn *insn, lsampl_t *data) + comedi_insn *insn, lsampl_t *data) { int i; int chan = CR_CHAN(insn->chanspec); usbduxsub_t* this_usbduxsub=dev->private; - + if (!this_usbduxsub) { return -EFAULT; } @@ -1537,7 +1537,7 @@ static int usbdux_ao_insn_write(comedi_device *dev, comedi_subdevice *s, int i,err; int chan = CR_CHAN(insn->chanspec); usbduxsub_t* this_usbduxsub=dev->private; - + #ifdef NOISY_DUX_DEBUGBUG printk("comedi%d: ao_insn_write\n",dev->minor); #endif @@ -1556,7 +1556,7 @@ static int usbdux_ao_insn_write(comedi_device *dev, comedi_subdevice *s, up(&this_usbduxsub->sem); return 0; } - + for(i=0;in;i++){ #ifdef NOISY_DUX_DEBUGBUG printk("comedi%d: ao_insn_write: data[chan=%d,i=%d]=%d\n",dev->minor,chan,i,data[i]); @@ -1574,7 +1574,7 @@ static int usbdux_ao_insn_write(comedi_device *dev, comedi_subdevice *s, } } up(&this_usbduxsub->sem); - + return i; } @@ -1627,8 +1627,8 @@ static int usbdux_ao_inttrig(comedi_device *dev, comedi_subdevice *s, -static int usbdux_ao_cmdtest(comedi_device *dev, - comedi_subdevice *s, +static int usbdux_ao_cmdtest(comedi_device *dev, + comedi_subdevice *s, comedi_cmd *cmd) { int err=0, tmp; @@ -1672,7 +1672,7 @@ static int usbdux_ao_cmdtest(comedi_device *dev, } else { // all conversion events happen simultaneously with a rate of 1kHz/n cmd->convert_src &= TRIG_NOW; - } + } if(!cmd->convert_src || tmp!=cmd->convert_src)err++; // issue a trigger when scan is finished and start a new scan @@ -1737,7 +1737,7 @@ static int usbdux_ao_cmdtest(comedi_device *dev, err++; } - + if(cmd->stop_src==TRIG_COUNT){ /* any count is allowed */ }else{ @@ -1748,14 +1748,14 @@ static int usbdux_ao_cmdtest(comedi_device *dev, } } -#ifdef NOISY_DUX_DEBUGBUG - printk("comedi%d: err=%d, scan_begin_src=%d, scan_begin_arg=%d, convert_src=%d, convert_arg=%d\n", - dev->minor, +#ifdef NOISY_DUX_DEBUGBUG + printk("comedi%d: err=%d, scan_begin_src=%d, scan_begin_arg=%d, convert_src=%d, convert_arg=%d\n", + dev->minor, err, - cmd->scan_begin_src, - cmd->scan_begin_arg, - cmd->convert_src, - cmd->convert_arg); + cmd->scan_begin_src, + cmd->scan_begin_arg, + cmd->convert_src, + cmd->convert_arg); #endif if(err)return 3; @@ -1786,7 +1786,7 @@ static int usbdux_ao_cmd(comedi_device *dev, comedi_subdevice *s) #endif // set current channel of the running aquisition to zero - s->async->cur_chan = 0; + s->async->cur_chan = 0; for(i=0; i < cmd->chanlist_len; ++i ) { chan = CR_CHAN(cmd->chanlist[i]); gain = CR_RANGE(cmd->chanlist[i]); @@ -1820,7 +1820,7 @@ static int usbdux_ao_cmd(comedi_device *dev, comedi_subdevice *s) cmd->scan_begin_src, cmd->scan_begin_arg, cmd->convert_src, - cmd->convert_arg); + cmd->convert_arg); printk("comedi%d: usbdux: ao_timer=%d (ms)\n", dev->minor, this_usbduxsub->ao_timer); @@ -1841,16 +1841,16 @@ static int usbdux_ao_cmd(comedi_device *dev, comedi_subdevice *s) // counter // high speed also scans everything at once if (0) /* (this_usbduxsub->high_speed) */ { - this_usbduxsub->ao_sample_count = + this_usbduxsub->ao_sample_count = (cmd->stop_arg)*(cmd->scan_end_arg); } else { - // there's no scan as the scan has been + // there's no scan as the scan has been // perf inside the FX2 // data arrives as one packet - this_usbduxsub->ao_sample_count = + this_usbduxsub->ao_sample_count = cmd->stop_arg; - } - this_usbduxsub->ao_continous=0; + } + this_usbduxsub->ao_continous=0; } else { // continous aquisition this_usbduxsub->ao_continous=1; @@ -1889,12 +1889,12 @@ static int usbdux_dio_insn_config (comedi_device *dev, comedi_insn *insn, lsampl_t *data) { int chan=CR_CHAN(insn->chanspec); - + /* The input or output configuration of each digital line is * configured by a special insn_config instruction. chanspec - * contains the channel to be changed, and data[0] contains the + * contains the channel to be changed, and data[0] contains the * value COMEDI_INPUT or COMEDI_OUTPUT. */ - + switch(data[0]) { case INSN_CONFIG_DIO_OUTPUT: @@ -1921,7 +1921,7 @@ static int usbdux_dio_insn_bits (comedi_device *dev, comedi_subdevice *s, comedi_insn *insn, lsampl_t *data) { - + usbduxsub_t* this_usbduxsub=dev->private; int err; @@ -1997,7 +1997,7 @@ static int usbdux_counter_read(comedi_device *dev,comedi_subdevice *s, comedi_in } -static int usbdux_counter_write(comedi_device *dev,comedi_subdevice *s, +static int usbdux_counter_write(comedi_device *dev,comedi_subdevice *s, comedi_insn *insn,lsampl_t *data) { usbduxsub_t* this_usbduxsub=dev->private; int err; @@ -2022,7 +2022,7 @@ static int usbdux_counter_write(comedi_device *dev,comedi_subdevice *s, } up(&this_usbduxsub->sem); - + return 1; } @@ -2164,7 +2164,7 @@ static int read_firmware(usbduxsub_t* usbduxsub,void *firmwarePtr,long size) { ); return -ENOMEM; } - + for (;;) { char buf[256],*cp; char type; @@ -2213,7 +2213,7 @@ static int read_firmware(usbduxsub_t* usbduxsub,void *firmwarePtr,long size) { printk("comedi_: usbdux: firmware upload goes beyond FX2 RAM boundaries."); return -EFAULT; } - + //printk("comedi_: usbdux: off=%x, len=%x:",off,len); /* Read the record type */ @@ -2258,11 +2258,11 @@ static int read_firmware(usbduxsub_t* usbduxsub,void *firmwarePtr,long size) { // allocate memory for the urbs and initialise them #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0) -static void* usbduxsub_probe(struct usb_device *udev, +static void* usbduxsub_probe(struct usb_device *udev, unsigned int interfnum, const struct usb_device_id *id) { #else -static int usbduxsub_probe(struct usb_interface *uinterf, +static int usbduxsub_probe(struct usb_interface *uinterf, const struct usb_device_id *id) { struct usb_device *udev = interface_to_usbdev(uinterf); #endif @@ -2384,7 +2384,7 @@ static int usbduxsub_probe(struct usb_interface *uinterf, usbduxsub[index].numOfInBuffers=NUMOFINBUFFERSHIGH; } else { usbduxsub[index].numOfInBuffers=NUMOFINBUFFERSFULL; - } + } usbduxsub[index].urbIn=kmalloc(sizeof(struct urb*)*usbduxsub[index].numOfInBuffers, GFP_KERNEL); if (!(usbduxsub[index].urbIn)) { @@ -2392,7 +2392,7 @@ static int usbduxsub_probe(struct usb_interface *uinterf, tidy_up(&(usbduxsub[index])); up(&start_stop_sem); return PROBE_ERR_RETURN( -ENOMEM); - } + } for (i=0; i < usbduxsub[index].numOfInBuffers; i++) { // one frame: 1ms usbduxsub[index].urbIn[i]=USB_ALLOC_URB(1); @@ -2401,12 +2401,12 @@ static int usbduxsub_probe(struct usb_interface *uinterf, tidy_up(&(usbduxsub[index])); up(&start_stop_sem); return PROBE_ERR_RETURN( -ENOMEM); - } + } usbduxsub[index].urbIn[i]->dev = usbduxsub[index].usbdev; // will be filled later with a pointer to the comedi-device // and ONLY then the urb should be submitted usbduxsub[index].urbIn[i]->context = NULL; - usbduxsub[index].urbIn[i]->pipe = + usbduxsub[index].urbIn[i]->pipe = usb_rcvisocpipe(usbduxsub[index].usbdev, ISOINEP); usbduxsub[index].urbIn[i]->transfer_flags = URB_ISO_ASAP; usbduxsub[index].urbIn[i]->transfer_buffer= @@ -2439,7 +2439,7 @@ static int usbduxsub_probe(struct usb_interface *uinterf, tidy_up(&(usbduxsub[index])); up(&start_stop_sem); return PROBE_ERR_RETURN( -ENOMEM); - } + } for (i=0; i < usbduxsub[index].numOfOutBuffers; i++) { // one frame: 1ms usbduxsub[index].urbOut[i]=USB_ALLOC_URB(1); @@ -2448,12 +2448,12 @@ static int usbduxsub_probe(struct usb_interface *uinterf, tidy_up(&(usbduxsub[index])); up(&start_stop_sem); return PROBE_ERR_RETURN( -ENOMEM); - } + } usbduxsub[index].urbOut[i]->dev = usbduxsub[index].usbdev; // will be filled later with a pointer to the comedi-device // and ONLY then the urb should be submitted usbduxsub[index].urbOut[i]->context = NULL; - usbduxsub[index].urbOut[i]->pipe = + usbduxsub[index].urbOut[i]->pipe = usb_sndisocpipe(usbduxsub[index].usbdev, ISOOUTEP); usbduxsub[index].urbOut[i]->transfer_flags = URB_ISO_ASAP; usbduxsub[index].urbOut[i]->transfer_buffer= @@ -2466,10 +2466,10 @@ static int usbduxsub_probe(struct usb_interface *uinterf, } usbduxsub[index].urbOut[i]->complete = usbduxsub_ao_IsocIrq; usbduxsub[index].urbOut[i]->number_of_packets = 1; - usbduxsub[index].urbOut[i]->transfer_buffer_length = + usbduxsub[index].urbOut[i]->transfer_buffer_length = SIZEOUTBUF; usbduxsub[index].urbOut[i]->iso_frame_desc[0].offset = 0; - usbduxsub[index].urbOut[i]->iso_frame_desc[0].length = + usbduxsub[index].urbOut[i]->iso_frame_desc[0].length = SIZEOUTBUF; if (usbduxsub[index].high_speed) { // uframes @@ -2482,7 +2482,7 @@ static int usbduxsub_probe(struct usb_interface *uinterf, // we've reached the bottom of the function usbduxsub[index].probed=1; - up(&start_stop_sem); + up(&start_stop_sem); printk("comedi_: usbdux%d has been successfully initialised.\n",index); #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0) return (void*)(&usbduxsub[index]); @@ -2508,7 +2508,7 @@ static void usbduxsub_disconnect(struct usb_interface *intf) { if (!usbduxsub_tmp) { printk("comedi_: usbdux: disconnect called with null pointer.\n"); return; - } + } if (usbduxsub_tmp->usbdev!=udev) { printk("comedi_: usbdux: BUG! called with wrong ptr!!!\n"); return; @@ -2559,15 +2559,15 @@ static int usbdux_attach(comedi_device * dev, comedi_devconfig * it) usbduxsub[index].comedidev=dev; // trying to upload the firmware into the chip - if(comedi_aux_data(it->options, 0) && + if(comedi_aux_data(it->options, 0) && it->options[COMEDI_DEVCONF_AUX_DATA_LENGTH]){ read_firmware(usbduxsub+index, comedi_aux_data(it->options, 0), it->options[COMEDI_DEVCONF_AUX_DATA_LENGTH]); - } + } dev->board_name = BOARDNAME; - + /* set number of subdevices */ dev->n_subdevices=N_SUBDEVICES; @@ -2595,7 +2595,7 @@ static int usbdux_attach(comedi_device * dev, comedi_devconfig * it) // analog input s->type=COMEDI_SUBD_AI; // readable and ref is to ground - s->subdev_flags=SDF_READABLE|SDF_GROUND; + s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_CMD_READ; // 8 channels s->n_chan=8; // length of the channellist @@ -2621,7 +2621,7 @@ static int usbdux_attach(comedi_device * dev, comedi_devconfig * it) // usb-structure s->private=NULL; // are writable - s->subdev_flags=SDF_WRITABLE|SDF_GROUND; + s->subdev_flags = SDF_WRITABLE | SDF_GROUND | SDF_CMD_WRITE; // 4 channels s->n_chan=4; // length of the channellist @@ -2752,7 +2752,7 @@ static void init_usb_devices(void) { static struct usb_device_id usbduxsub_table [] = { { USB_DEVICE(0x13d8, 0x0001), }, - { USB_DEVICE(0x13d8, 0x0002) + { USB_DEVICE(0x13d8, 0x0002) }, { } /* Terminating entry */ }; @@ -2799,7 +2799,7 @@ static void exit_usbdux(void) { module_init(init_usbdux); -module_exit(exit_usbdux); +module_exit(exit_usbdux); MODULE_AUTHOR( DRIVER_AUTHOR ); MODULE_DESCRIPTION( DRIVER_DESC ); diff --git a/comedi/drivers/usbduxfast.c b/comedi/drivers/usbduxfast.c index 730f6c4a..80adde83 100644 --- a/comedi/drivers/usbduxfast.c +++ b/comedi/drivers/usbduxfast.c @@ -214,7 +214,7 @@ static int send_dux_commands(usbduxfastsub_t* this_usbduxfastsub,int cmd_type) { CHANNELLISTEP), this_usbduxfastsub->dux_commands, SIZEOFDUXBUFFER, - &nsent, + &nsent, 10000); if (result<0) { printk("comedi%d: could not transmit dux_commands to the usb-device, err=%d\n", @@ -273,7 +273,7 @@ static int usbduxfast_ai_stop(usbduxfastsub_t* this_usbduxfastsub, #endif - this_usbduxfastsub->ai_cmd_running=0; + this_usbduxfastsub->ai_cmd_running=0; if (do_unlink) { // stop aquistion @@ -311,7 +311,7 @@ static int usbduxfast_ai_cancel(comedi_device *dev, // unlink res=usbduxfast_ai_stop(this_usbduxfastsub,1); up(&this_usbduxfastsub->sem); - + return res; } @@ -382,7 +382,7 @@ static void usbduxfastsub_ai_Irq(struct urb *urb, struct pt_regs *regs) // tell this comedi s->async->events |= COMEDI_CB_EOA; s->async->events |= COMEDI_CB_ERROR; - comedi_event(this_usbduxfastsub->comedidev, + comedi_event(this_usbduxfastsub->comedidev, s, s->async->events); // stop the transfer w/o unlink @@ -395,8 +395,8 @@ static void usbduxfastsub_ai_Irq(struct urb *urb, struct pt_regs *regs) urb->status); s->async->events |= COMEDI_CB_EOA; s->async->events |= COMEDI_CB_ERROR; - comedi_event(this_usbduxfastsub->comedidev, - s, + comedi_event(this_usbduxfastsub->comedidev, + s, s->async->events); usbduxfast_ai_stop(this_usbduxfastsub,0); return; @@ -416,21 +416,21 @@ static void usbduxfastsub_ai_Irq(struct urb *urb, struct pt_regs *regs) 0); // say comedi that the acquistion is over s->async->events |= COMEDI_CB_EOA; - comedi_event(this_usbduxfastsub->comedidev, - s, + comedi_event(this_usbduxfastsub->comedidev, + s, s->async->events); return; } this_usbduxfastsub->ai_sample_count-=n; } - + // write the full buffer to comedi cfc_write_array_to_buffer(s, urb->transfer_buffer, urb->actual_length); - + // tell comedi that data is there - comedi_event(this_usbduxfastsub->comedidev, + comedi_event(this_usbduxfastsub->comedidev, s, s->async->events); @@ -449,7 +449,7 @@ static void usbduxfastsub_ai_Irq(struct urb *urb, struct pt_regs *regs) err); s->async->events |= COMEDI_CB_EOA; s->async->events |= COMEDI_CB_ERROR; - comedi_event(this_usbduxfastsub->comedidev, + comedi_event(this_usbduxfastsub->comedidev, s, s->async->events); usbduxfast_ai_stop(this_usbduxfastsub,0); @@ -466,17 +466,17 @@ static int usbduxfastsub_start(usbduxfastsub_t* usbduxfastsub) { if (usbduxfastsub->probed) { // 7f92 to zero - local_transfer_buffer[0]=0; + local_transfer_buffer[0]=0; errcode=USB_CONTROL_MSG (usbduxfastsub->usbdev, // create a pipe for a control transfer usb_sndctrlpipe(usbduxfastsub->usbdev,0), // bRequest, "Firmware" - USBDUXFASTSUB_FIRMWARE, + USBDUXFASTSUB_FIRMWARE, // bmRequestType - VENDOR_DIR_OUT, + VENDOR_DIR_OUT, // Value - USBDUXFASTSUB_CPUCS, + USBDUXFASTSUB_CPUCS, // Index 0x0000, // address of the transfer buffer @@ -484,7 +484,7 @@ static int usbduxfastsub_start(usbduxfastsub_t* usbduxfastsub) { // Length 1, // Timeout - EZTIMEOUT + EZTIMEOUT ); if (errcode<0) { printk("comedi_: usbduxfast_: control msg failed (start)\n"); @@ -503,23 +503,23 @@ static int usbduxfastsub_stop(usbduxfastsub_t* usbduxfastsub) { unsigned char local_transfer_buffer[16]; if (usbduxfastsub->probed) { // 7f92 to one - local_transfer_buffer[0]=1; + local_transfer_buffer[0]=1; errcode=USB_CONTROL_MSG (usbduxfastsub->usbdev, usb_sndctrlpipe(usbduxfastsub->usbdev,0), // bRequest, "Firmware" - USBDUXFASTSUB_FIRMWARE, + USBDUXFASTSUB_FIRMWARE, // bmRequestType VENDOR_DIR_OUT, // Value USBDUXFASTSUB_CPUCS, // Index - 0x0000, + 0x0000, local_transfer_buffer, // Length 1, // Timeout - EZTIMEOUT + EZTIMEOUT ); if (errcode<0) { printk("comedi_: usbduxfast: control msg failed (stop)\n"); @@ -528,7 +528,7 @@ static int usbduxfastsub_stop(usbduxfastsub_t* usbduxfastsub) { } return 0; } - + @@ -583,7 +583,7 @@ return 0; -int firmwareUpload(usbduxfastsub_t* usbduxfastsub, +int firmwareUpload(usbduxfastsub_t* usbduxfastsub, unsigned char* firmwareBinary, int sizeFirmware) { int ret; @@ -614,7 +614,7 @@ int firmwareUpload(usbduxfastsub_t* usbduxfastsub, } return 0; } - + int usbduxfastsub_submit_InURBs(usbduxfastsub_t* usbduxfastsub) { @@ -651,8 +651,8 @@ int usbduxfastsub_submit_InURBs(usbduxfastsub_t* usbduxfastsub) { -static int usbduxfast_ai_cmdtest(comedi_device *dev, - comedi_subdevice *s, +static int usbduxfast_ai_cmdtest(comedi_device *dev, + comedi_subdevice *s, comedi_cmd *cmd) { int err=0, stop_mask=0; @@ -906,7 +906,7 @@ static int usbduxfast_ai_cmd(comedi_device *dev, comedi_subdevice *s) } steps=0; if(cmd->scan_begin_src == TRIG_TIMER) { - printk("comedi%d: usbduxfast: scan_begin_src==TRIG_TIMER not valid.\n", + printk("comedi%d: usbduxfast: scan_begin_src==TRIG_TIMER not valid.\n", dev->minor); up(&this_usbduxfastsub->sem); return -EINVAL; @@ -915,8 +915,8 @@ static int usbduxfast_ai_cmd(comedi_device *dev, comedi_subdevice *s) steps=(cmd->convert_arg*30)/1000; } if ((stepschanlist_len!=1)) { - printk("comedi%d: usbduxfast: ai_cmd: steps=%ld, scan_begin_arg=%d. Not properly tested by cmdtest?\n", - dev->minor, + printk("comedi%d: usbduxfast: ai_cmd: steps=%ld, scan_begin_arg=%d. Not properly tested by cmdtest?\n", + dev->minor, steps, cmd->scan_begin_arg); up(&this_usbduxfastsub->sem); @@ -955,7 +955,7 @@ static int usbduxfast_ai_cmd(comedi_device *dev, comedi_subdevice *s) this_usbduxfastsub->dux_commands[OPBASE+0]=0x02; // data this_usbduxfastsub->dux_commands[OUTBASE+0]=0xFF & rngmask; this_usbduxfastsub->dux_commands[LOGBASE+0]=0; - } + } this_usbduxfastsub->dux_commands[LENBASE+1]=0x00; // branch back to state 0 this_usbduxfastsub->dux_commands[OPBASE+1]=0x01; // deceision state w/o data this_usbduxfastsub->dux_commands[OUTBASE+1]=0xFF & rngmask; @@ -966,37 +966,37 @@ static int usbduxfast_ai_cmd(comedi_device *dev, comedi_subdevice *s) this_usbduxfastsub->dux_commands[OPBASE+0]=0x02; // data this_usbduxfastsub->dux_commands[OUTBASE+0]=0xFF & rngmask; this_usbduxfastsub->dux_commands[LOGBASE+0]=0; - + // we have 6 states with duration 1 steps=steps-6; - + // do the first part of the delay this_usbduxfastsub->dux_commands[LENBASE+1]=steps/2; this_usbduxfastsub->dux_commands[OPBASE+1]=0; this_usbduxfastsub->dux_commands[OUTBASE+1]=0xFF & rngmask; this_usbduxfastsub->dux_commands[LOGBASE+1]=0; - + // and the second part this_usbduxfastsub->dux_commands[LENBASE+2]=steps-steps/2; this_usbduxfastsub->dux_commands[OPBASE+2]=0; this_usbduxfastsub->dux_commands[OUTBASE+2]=0xFF & rngmask; this_usbduxfastsub->dux_commands[LOGBASE+2]=0; - + this_usbduxfastsub->dux_commands[LENBASE+3]=1; this_usbduxfastsub->dux_commands[OPBASE+3]=0; this_usbduxfastsub->dux_commands[OUTBASE+3]=0xFF & rngmask; this_usbduxfastsub->dux_commands[LOGBASE+3]=0; - + this_usbduxfastsub->dux_commands[LENBASE+4]=1; this_usbduxfastsub->dux_commands[OPBASE+4]=0; this_usbduxfastsub->dux_commands[OUTBASE+4]=0xFF & rngmask; this_usbduxfastsub->dux_commands[LOGBASE+4]=0; - + this_usbduxfastsub->dux_commands[LENBASE+5]=1; this_usbduxfastsub->dux_commands[OPBASE+5]=0; this_usbduxfastsub->dux_commands[OUTBASE+5]=0xFF & rngmask; this_usbduxfastsub->dux_commands[LOGBASE+5]=0; - + this_usbduxfastsub->dux_commands[LENBASE+6]=1; this_usbduxfastsub->dux_commands[OPBASE+6]=0; this_usbduxfastsub->dux_commands[OUTBASE+6]=0xFF & rngmask; @@ -1028,7 +1028,7 @@ static int usbduxfast_ai_cmd(comedi_device *dev, comedi_subdevice *s) this_usbduxfastsub->dux_commands[OPBASE+2]=0; this_usbduxfastsub->dux_commands[OUTBASE+2]=0xFF & rngmask; this_usbduxfastsub->dux_commands[LOGBASE+2]=0; - + this_usbduxfastsub->dux_commands[LENBASE+3]=1; this_usbduxfastsub->dux_commands[OPBASE+3]=0x02; // data this_usbduxfastsub->dux_commands[OUTBASE+3]=0xFF & rngmask; @@ -1049,7 +1049,7 @@ static int usbduxfast_ai_cmd(comedi_device *dev, comedi_subdevice *s) this_usbduxfastsub->dux_commands[OPBASE+5]=0; this_usbduxfastsub->dux_commands[OUTBASE+5]=0xFF & rngmask; this_usbduxfastsub->dux_commands[LOGBASE+5]=0; - + this_usbduxfastsub->dux_commands[LENBASE+6]=1; this_usbduxfastsub->dux_commands[OPBASE+6]=0; this_usbduxfastsub->dux_commands[OUTBASE+6]=0xFF & rngmask; @@ -1073,7 +1073,7 @@ static int usbduxfast_ai_cmd(comedi_device *dev, comedi_subdevice *s) this_usbduxfastsub->dux_commands[OUTBASE+j*2+1]=0xFE & rngmask; //count this_usbduxfastsub->dux_commands[LOGBASE+j*2+1]=0; } - + // 2 steps with duration 1: the idele step and step 6: steps_tmp=steps-2; // commit data to the FIFO and do the first part of the delay @@ -1081,7 +1081,7 @@ static int usbduxfast_ai_cmd(comedi_device *dev, comedi_subdevice *s) this_usbduxfastsub->dux_commands[OPBASE+4]=0x02; // data this_usbduxfastsub->dux_commands[OUTBASE+4]=0xFF & rngmask; // no change this_usbduxfastsub->dux_commands[LOGBASE+4]=0; - + if (CR_RANGE(cmd->chanlist[0])>0) rngmask=0xff-0x04; else rngmask=0xff; // do the second part of the delay this_usbduxfastsub->dux_commands[LENBASE+5]=steps_tmp-steps_tmp/2; @@ -1093,7 +1093,7 @@ static int usbduxfast_ai_cmd(comedi_device *dev, comedi_subdevice *s) this_usbduxfastsub->dux_commands[OPBASE+6]=0; this_usbduxfastsub->dux_commands[OUTBASE+6]=0xFF & rngmask; this_usbduxfastsub->dux_commands[LOGBASE+6]=0; - + case 16: if (CR_RANGE(cmd->chanlist[0])>0) rngmask=0xff-0x04; else rngmask=0xff; // commit data to the FIFO @@ -1115,17 +1115,17 @@ static int usbduxfast_ai_cmd(comedi_device *dev, comedi_subdevice *s) this_usbduxfastsub->dux_commands[OPBASE+2]=0; this_usbduxfastsub->dux_commands[OUTBASE+2]=0xFE & rngmask; this_usbduxfastsub->dux_commands[LOGBASE+2]=0; - + this_usbduxfastsub->dux_commands[LENBASE+3]=1; this_usbduxfastsub->dux_commands[OPBASE+3]=0; this_usbduxfastsub->dux_commands[OUTBASE+3]=0xFE & rngmask; this_usbduxfastsub->dux_commands[LOGBASE+3]=0; - + this_usbduxfastsub->dux_commands[LENBASE+4]=1; this_usbduxfastsub->dux_commands[OPBASE+4]=0; this_usbduxfastsub->dux_commands[OUTBASE+4]=0xFE & rngmask; this_usbduxfastsub->dux_commands[LOGBASE+4]=0; - + // and the second part this_usbduxfastsub->dux_commands[LENBASE+5]=steps-steps/2; this_usbduxfastsub->dux_commands[OPBASE+5]=0; @@ -1144,7 +1144,7 @@ static int usbduxfast_ai_cmd(comedi_device *dev, comedi_subdevice *s) up(&this_usbduxfastsub->sem); return -EFAULT; } - + #ifdef CONFIG_COMEDI_DEBUG printk("comedi %d: sending commands to the usb device\n", @@ -1166,7 +1166,7 @@ static int usbduxfast_ai_cmd(comedi_device *dev, comedi_subdevice *s) up(&this_usbduxfastsub->sem); return -EFAULT; } - this_usbduxfastsub->ai_continous=0; + this_usbduxfastsub->ai_continous=0; } else { // continous aquisition this_usbduxfastsub->ai_continous=1; @@ -1243,28 +1243,28 @@ static int usbduxfast_ai_insn_read(comedi_device * dev, usbduxfastsub->dux_commands[OPBASE+0]=0x02; // data usbduxfastsub->dux_commands[OUTBASE+0]=0xFF & rngmask; usbduxfastsub->dux_commands[LOGBASE+0]=0; - + // do the first part of the delay usbduxfastsub->dux_commands[LENBASE+1]=12; usbduxfastsub->dux_commands[OPBASE+1]=0; usbduxfastsub->dux_commands[OUTBASE+1]=0xFE & rngmask; usbduxfastsub->dux_commands[LOGBASE+1]=0; - + usbduxfastsub->dux_commands[LENBASE+2]=1; usbduxfastsub->dux_commands[OPBASE+2]=0; usbduxfastsub->dux_commands[OUTBASE+2]=0xFE & rngmask; usbduxfastsub->dux_commands[LOGBASE+2]=0; - + usbduxfastsub->dux_commands[LENBASE+3]=1; usbduxfastsub->dux_commands[OPBASE+3]=0; usbduxfastsub->dux_commands[OUTBASE+3]=0xFE & rngmask; usbduxfastsub->dux_commands[LOGBASE+3]=0; - + usbduxfastsub->dux_commands[LENBASE+4]=1; usbduxfastsub->dux_commands[OPBASE+4]=0; usbduxfastsub->dux_commands[OUTBASE+4]=0xFE & rngmask; usbduxfastsub->dux_commands[LOGBASE+4]=0; - + // second part usbduxfastsub->dux_commands[LENBASE+5]=12; usbduxfastsub->dux_commands[OPBASE+5]=0; @@ -1296,7 +1296,7 @@ static int usbduxfast_ai_insn_read(comedi_device * dev, (int)(usbduxfastsub->urbIn->dev)); #endif for(i=0;iusbdev, + err=USB_BULK_MSG(usbduxfastsub->usbdev, usb_rcvbulkpipe(usbduxfastsub->usbdev,BULKINEP), usbduxfastsub->transfer_buffer, SIZEINBUF, @@ -1311,7 +1311,7 @@ static int usbduxfast_ai_insn_read(comedi_device * dev, } // data points for(i=0;in;) { - err=USB_BULK_MSG(usbduxfastsub->usbdev, + err=USB_BULK_MSG(usbduxfastsub->usbdev, usb_rcvbulkpipe(usbduxfastsub->usbdev,BULKINEP), usbduxfastsub->transfer_buffer, SIZEINBUF, @@ -1329,7 +1329,7 @@ static int usbduxfast_ai_insn_read(comedi_device * dev, dev->minor); up(&usbduxfastsub->sem); return -EINVAL; - } + } for(j=chan;(jn);j=j+16) { data[i]=((uint16_t*)(usbduxfastsub->transfer_buffer))[j]; i++; @@ -1375,7 +1375,7 @@ static int read_firmware(usbduxfastsub_t* usbduxfastsub, void *firmwarePtr,long ); return -ENOMEM; } - + for (;;) { char buf[256],*cp; char type; @@ -1424,7 +1424,7 @@ static int read_firmware(usbduxfastsub_t* usbduxfastsub, void *firmwarePtr,long printk("comedi_: usbduxfast: firmware upload goes beyond FX2 RAM boundaries."); return -EFAULT; } - + //printk("comedi_: usbduxfast: off=%x, len=%x:",off,len); /* Read the record type */ @@ -1515,11 +1515,11 @@ static void tidy_up(usbduxfastsub_t* usbduxfastsub_tmp) { // allocate memory for the urbs and initialise them #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0) -static void* usbduxfastsub_probe(struct usb_device *udev, +static void* usbduxfastsub_probe(struct usb_device *udev, unsigned int interfnum, const struct usb_device_id *id) { #else -static int usbduxfastsub_probe(struct usb_interface *uinterf, +static int usbduxfastsub_probe(struct usb_interface *uinterf, const struct usb_device_id *id) { struct usb_device *udev = interface_to_usbdev(uinterf); #endif @@ -1611,7 +1611,7 @@ static int usbduxfastsub_probe(struct usb_interface *uinterf, tidy_up(&(usbduxfastsub[index])); up(&start_stop_sem); return PROBE_ERR_RETURN( -ENOMEM); - } + } usbduxfastsub[index].transfer_buffer= kmalloc(SIZEINBUF,GFP_KERNEL); if (!(usbduxfastsub[index].transfer_buffer)) { @@ -1622,7 +1622,7 @@ static int usbduxfastsub_probe(struct usb_interface *uinterf, } // we've reached the bottom of the function usbduxfastsub[index].probed=1; - up(&start_stop_sem); + up(&start_stop_sem); printk("comedi_: usbduxfast%d has been successfully initialized.\n",index); #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0) return (void*)(&usbduxfastsub[index]); @@ -1648,7 +1648,7 @@ static void usbduxfastsub_disconnect(struct usb_interface *intf) { if (!usbduxfastsub_tmp) { printk("comedi_: usbduxfast: disconnect called with null pointer.\n"); return; - } + } if (usbduxfastsub_tmp->usbdev!=udev) { printk("comedi_: usbduxfast: BUG! called with wrong ptr!!!\n"); return; @@ -1699,15 +1699,15 @@ static int usbduxfast_attach(comedi_device * dev, comedi_devconfig * it) usbduxfastsub[index].comedidev=dev; // trying to upload the firmware into the chip - if(comedi_aux_data(it->options, 0) && + if(comedi_aux_data(it->options, 0) && it->options[COMEDI_DEVCONF_AUX_DATA_LENGTH]){ read_firmware(usbduxfastsub, comedi_aux_data(it->options, 0), it->options[COMEDI_DEVCONF_AUX_DATA_LENGTH]); - } + } dev->board_name = BOARDNAME; - + /* set number of subdevices */ dev->n_subdevices=N_SUBDEVICES; @@ -1735,7 +1735,7 @@ static int usbduxfast_attach(comedi_device * dev, comedi_devconfig * it) // analog input s->type=COMEDI_SUBD_AI; // readable and ref is to ground - s->subdev_flags=SDF_READABLE|SDF_GROUND; + s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_CMD_READ; // 8 channels s->n_chan=16; // length of the channellist @@ -1894,7 +1894,7 @@ static void exit_usbduxfast(void) { module_init(init_usbduxfast); -module_exit(exit_usbduxfast); +module_exit(exit_usbduxfast); MODULE_AUTHOR( DRIVER_AUTHOR ); MODULE_DESCRIPTION( DRIVER_DESC ); diff --git a/comedi/proc.c b/comedi/proc.c index 657df6fb..506d31e8 100644 --- a/comedi/proc.c +++ b/comedi/proc.c @@ -23,7 +23,7 @@ /* This is some serious bloatware. - + Taken from Dave A.'s PCL-711 driver, 'cuz I thought it was cool. */ @@ -46,7 +46,7 @@ int comedi_read_procmem(char *buf,char **start,off_t offset,int len,int *eof,voi int devices_q=0; int l=0; comedi_driver *driv; - + l+=sprintf(buf+l, "comedi version " COMEDI_RELEASE "\n" "format string: %s\n", @@ -55,7 +55,7 @@ int comedi_read_procmem(char *buf,char **start,off_t offset,int len,int *eof,voi for(i=0;iattached){ devices_q=1; l+=sprintf(buf+l,"%2d: %-20s %-20s %4d\n", @@ -88,7 +88,7 @@ int comedi_read_procmem(char *buf,char **start,off_t offset,int len,int *eof,voi void comedi_proc_init(void) { struct proc_dir_entry *comedi_proc; - + comedi_proc = create_proc_entry("comedi",S_IFREG | S_IRUGO,0); if(comedi_proc) comedi_proc->read_proc = comedi_read_procmem; diff --git a/comedi/range.c b/comedi/range.c index cede75fc..fd956641 100644 --- a/comedi/range.c +++ b/comedi/range.c @@ -41,11 +41,11 @@ comedi_lrange range_unknown={ 1, {{0,1000000,UNIT_none}}}; reads: range info structure - + writes: n comedi_krange structures to rangeinfo->range_ptr */ -int do_rangeinfo_ioctl(comedi_device *dev,comedi_rangeinfo *arg) +int do_rangeinfo_ioctl(comedi_device *dev, comedi_rangeinfo *arg) { comedi_rangeinfo it; int minor,subd,chan; @@ -54,36 +54,37 @@ int do_rangeinfo_ioctl(comedi_device *dev,comedi_rangeinfo *arg) if(copy_from_user(&it,arg,sizeof(comedi_rangeinfo))) return -EFAULT; + /* FIXME why do we have to support queries to devices that are different + * than the one passed as the dev argument? */ + minor=(it.range_type>>28) & 0xf; + subd=(it.range_type>>24) & 0xf; + chan=(it.range_type>>16) & 0xff; - minor=(it.range_type>>28)&0xf; - subd=(it.range_type>>24)&0xf; - chan=(it.range_type>>16)&0xff; - - if(minor>COMEDI_NDEVICES) + if(minor > COMEDI_NDEVICES) return -EINVAL; - dev=comedi_get_device_by_minor(minor); - if(!dev->attached)return -EINVAL; - if(subd>=dev->n_subdevices)return -EINVAL; - s=dev->subdevices+subd; + comedi_device *query_dev = comedi_devices + minor; + if(!query_dev->attached) return -EINVAL; + if(subd>=query_dev->n_subdevices) return -EINVAL; + s = query_dev->subdevices + subd; if(s->range_table){ - lr=s->range_table; + lr = s->range_table; }else if(s->range_table_list){ - if(chan>=s->n_chan)return -EINVAL; - lr=s->range_table_list[chan]; + if(chan >= s->n_chan) return -EINVAL; + lr = s->range_table_list[chan]; }else{ return -EINVAL; } if( RANGE_LENGTH(it.range_type) != lr->length){ DPRINTK("wrong length %d should be %d (0x%08x)\n", - RANGE_LENGTH(it.range_type),lr->length,it.range_type); + RANGE_LENGTH(it.range_type), lr->length, it.range_type); return -EINVAL; } - if(copy_to_user(it.range_ptr,lr->range, - sizeof(comedi_krange)*lr->length)) + if(copy_to_user(it.range_ptr, lr->range, + sizeof(comedi_krange) * lr->length)) return -EFAULT; - + return 0; } diff --git a/include/linux/comedi.h b/include/linux/comedi.h index fbc72b05..e6371773 100644 --- a/include/linux/comedi.h +++ b/include/linux/comedi.h @@ -179,8 +179,10 @@ 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_CMD 0x1000 /* can do commands (deprecated) */ #define SDF_SOFT_CALIBRATED 0x2000 /* subdevice uses software calibration */ +#define SDF_CMD_WRITE 0x4000 /* can do output commands */ +#define SDF_CMD_READ 0x8000 /* can do input commands */ #define SDF_READABLE 0x00010000 /* subdevice can be read (e.g. analog input) */ #define SDF_WRITABLE 0x00020000 /* subdevice can be written (e.g. analog output) */ diff --git a/include/linux/comedidev.h b/include/linux/comedidev.h index b3e31207..38cfd26c 100644 --- a/include/linux/comedidev.h +++ b/include/linux/comedidev.h @@ -96,6 +96,7 @@ typedef struct comedi_lrange_struct comedi_lrange; struct comedi_subdevice_struct{ + comedi_device *device; int type; int n_chan; volatile int subdev_flags; @@ -144,7 +145,7 @@ struct comedi_subdevice_struct{ unsigned int state; - dev_t devt; + struct class_device *class_dev; }; struct comedi_async_struct{ @@ -202,8 +203,10 @@ struct comedi_device_struct{ int use_count; comedi_driver *driver; void *private; + + struct class_device *class_dev; unsigned minor; - dev_t devt; + const char *board_name; const void * board_ptr; int attached; @@ -230,7 +233,11 @@ struct comedi_device_struct{ void (*close)(comedi_device *dev); }; - +struct comedi_inode_private +{ + comedi_device *device; + comedi_subdevice *subdevice; +}; extern comedi_device *comedi_devices; extern spinlock_t big_comedi_lock; @@ -248,9 +255,47 @@ static const int comedi_debug = 0; void comedi_event(comedi_device *dev,comedi_subdevice *s,unsigned int mask); void comedi_error(const comedi_device *dev,const char *s); -static inline comedi_device * comedi_get_device_by_minor( unsigned int minor ) +/* we can expand the number of bits used to encode devices/subdevices into + the minor number soon, after more distros support > 8 bit minor numbers + (like after Debian Etch gets released) */ +enum comedi_minor_bits +{ + COMEDI_DEVICE_MINOR_MASK = 0xf, + COMEDI_SUBDEVICE_MINOR_MASK = 0xf0 +}; +static const unsigned COMEDI_SUBDEVICE_MINOR_SHIFT = 4; +static const unsigned COMEDI_SUBDEVICE_MINOR_OFFSET = 1; +static const unsigned COMEDI_NUM_MINORS = 0x100; + +static inline comedi_device * comedi_get_device_by_minor(unsigned minor) { - return comedi_devices + minor; + unsigned device_index; + if(minor >= COMEDI_NUM_MINORS) return NULL; + device_index = minor & COMEDI_DEVICE_MINOR_MASK; + if(device_index >= COMEDI_NDEVICES) return NULL; + return comedi_devices + device_index; +} + +static inline comedi_subdevice * comedi_get_subdevice_by_minor(unsigned minor) +{ + unsigned subdevice_index; + comedi_device * dev; + + if((minor & COMEDI_SUBDEVICE_MINOR_MASK) == 0) return NULL; + dev = comedi_get_device_by_minor(minor); + if(dev == NULL) return NULL; + subdevice_index = ((minor & COMEDI_SUBDEVICE_MINOR_MASK) >> COMEDI_SUBDEVICE_MINOR_SHIFT) - COMEDI_SUBDEVICE_MINOR_OFFSET; + if(subdevice_index >= dev->n_subdevices) return NULL; + return dev->subdevices + subdevice_index; +} + +static inline unsigned comedi_construct_minor_for_subdevice(comedi_device *dev, unsigned subdevice_index) +{ + unsigned minor = 0; + minor |= dev->minor & COMEDI_DEVICE_MINOR_MASK; + minor |= ((subdevice_index + COMEDI_SUBDEVICE_MINOR_OFFSET) << COMEDI_SUBDEVICE_MINOR_SHIFT) & COMEDI_SUBDEVICE_MINOR_MASK; + BUG_ON(minor >= COMEDI_NUM_MINORS); + return minor; } int comedi_device_detach(comedi_device *dev); @@ -326,13 +371,18 @@ struct comedi_lrange_struct{ static inline int alloc_subdevices(comedi_device *dev, unsigned int num_subdevices) { - int size=sizeof(comedi_subdevice)*num_subdevices; + const int size = sizeof(comedi_subdevice) * num_subdevices; dev->n_subdevices = num_subdevices; - dev->subdevices=kmalloc(size,GFP_KERNEL); + dev->subdevices = kmalloc(size,GFP_KERNEL); if(!dev->subdevices) return -ENOMEM; memset(dev->subdevices,0,size); + unsigned i; + for(i = 0; i < num_subdevices; ++i) + { + dev->subdevices[i].device = dev; + } return 0; }