if(rsd->busy)
return -EBUSY;
- if(rsd->subdev_flags & SDF_MMAPPED){
+ if(rsd->mmap_count){
DPRINTK("read subdevice is mmapped, cannot resize buffer\n");
return -EBUSY;
}
if(wsd->busy)
return -EBUSY;
- if(wsd->subdev_flags & SDF_MMAPPED){
+ if(wsd->mmap_count){
DPRINTK("write subdevice is mmapped, cannot resize buffer\n");
return -EBUSY;
}
static int do_unlock_ioctl(comedi_device *dev,unsigned int arg,void * file)
{
comedi_subdevice *s;
-
+
if(arg>=dev->n_subdevices)
return -EINVAL;
s=dev->subdevices+arg;
static int do_cancel_ioctl(comedi_device *dev,unsigned int arg,void *file)
{
comedi_subdevice *s;
-
+
if(arg>=dev->n_subdevices)
return -EINVAL;
s=dev->subdevices+arg;
-
+
if(s->lock && s->lock!=file)
return -EACCES;
-
+
if(!s->busy)
return 0;
return ret;
}
+struct comedi_file_private {
+ unsigned int read_mmap_count;
+ unsigned int write_mmap_count;
+};
+
#ifdef LINUX_V22
/*
comedi_mmap_v22
comedi_device *dev=comedi_get_device_by_minor(minor);
comedi_subdevice *s;
int subdev;
+ struct comedi_file_private *cfp;
if(vma->vm_flags & VM_WRITE){
subdev=dev->write_subdev;
return -EINVAL;
}
+ cfp = (struct comedi_file_private*) file->private_data;
+ if(subdev == dev->read_subdev)
+ cfp->read_mmap_count++;
+ else if(subdev == dev->write_subdev)
+ cfp->write_mmap_count++;
+
rvmmap(s->prealloc_buf,s->prealloc_bufsz,vma);
//vma->vm_file = file;
//vma->vm_ops = &comedi_vm_ops;
//file_atomic_inc(&file->f_count);
- /* mark subdev as mapped */
- s->subdev_flags |= SDF_MMAPPED;
+ s->mmap_count++;
return 0;
}
comedi_device *dev;
static int in_comedi_open=0;
char mod[32];
+ struct comedi_file_private *cfp;
if(minor>=COMEDI_NDEVICES)return -ENODEV;
ok:
MOD_INC_USE_COUNT;
+
+ cfp = kmalloc(sizeof(struct comedi_file_private), GFP_KERNEL);
+ if(cfp == NULL)
+ {
+ MOD_DEC_USE_COUNT;
+ return -ENOMEM;
+ }
+ memset(cfp, 0, sizeof(struct comedi_file_private));
+ file->private_data = cfp;
+
if(dev->attached && dev->driver->module){
__MOD_INC_USE_COUNT(dev->driver->module);
}
static int comedi_close_v22(struct inode *inode,struct file *file)
{
comedi_device *dev=comedi_get_device_by_minor(MINOR(inode->i_rdev));
- comedi_subdevice *s;
+ comedi_subdevice *s=NULL;
+ struct comedi_file_private *cfp = (struct comedi_file_private*) file->private_data;
int i;
for(i=0;i<dev->n_subdevices;i++){
}
dev->use_count--;
-
+
+ // decrement mmap_counts
+ if(cfp->read_mmap_count)
+ {
+ s = dev->subdevices + dev->read_subdev;
+ s->mmap_count -= cfp->read_mmap_count;
+ }
+ if(cfp->write_mmap_count)
+ {
+ s = dev->subdevices + dev->write_subdev;
+ s->mmap_count -= cfp->write_mmap_count;
+ }
+
return 0;
}