Each comedi_async struct should have its own wait_queue_head_t.
authorFrank Mori Hess <fmhess@speakeasy.net>
Wed, 24 Oct 2007 21:29:10 +0000 (21:29 +0000)
committerFrank Mori Hess <fmhess@speakeasy.net>
Wed, 24 Oct 2007 21:29:10 +0000 (21:29 +0000)
comedi/comedi_fops.c
comedi/drivers.c
include/linux/comedidev.h

index 4eebe26e4dfd6bafe72a175e83a5db942c0c63e7..d1a69a86af7491e93f2c11cd312afddcf37ad8c3 100644 (file)
@@ -1191,6 +1191,8 @@ static int do_cancel_ioctl(comedi_device *dev,unsigned int arg,void *file)
        if(arg>=dev->n_subdevices)
                return -EINVAL;
        s=dev->subdevices+arg;
+       if(s->async == NULL)
+               return -EINVAL;
 
        if(s->lock && s->lock!=file)
                return -EACCES;
@@ -1326,11 +1328,11 @@ static int comedi_mmap(struct file * file, struct vm_area_struct *vma)
 
 static unsigned int comedi_poll(struct file *file, poll_table * wait)
 {
-       comedi_subdevice *s;
-       comedi_async *async;
        unsigned int mask;
        const unsigned minor = iminor(file->f_dentry->d_inode);
        comedi_device *dev = comedi_get_device_by_minor(minor);
+       comedi_subdevice *read_subdev = comedi_get_read_subdevice(dev, minor);
+       comedi_subdevice *write_subdev = comedi_get_write_subdevice(dev, minor);
 
        if(!dev->attached)
        {
@@ -1338,24 +1340,20 @@ static unsigned int comedi_poll(struct file *file, poll_table * wait)
                return -ENODEV;
        }
 
-       poll_wait(file, &dev->read_wait, wait);
-       poll_wait(file, &dev->write_wait, wait);
        mask = 0;
-       if(dev->read_subdev && dev->read_subdev->async){
-               s = dev->read_subdev;
-               async = s->async;
-               if(!s->busy
-                  || comedi_buf_read_n_available(async)>0
-                  || !(comedi_get_subdevice_runflags(s) & SRF_RUNNING)){
+       if(read_subdev){
+               poll_wait(file, &read_subdev->async->wait_head, wait);
+               if(!read_subdev->busy
+                       || comedi_buf_read_n_available(read_subdev->async) > 0
+                       || !(comedi_get_subdevice_runflags(read_subdev) & SRF_RUNNING)){
                        mask |= POLLIN | POLLRDNORM;
                }
        }
-       if(dev->write_subdev && dev->write_subdev->async){
-               s = dev->write_subdev;
-               async = s->async;
-               if(!s->busy
-                  || !(comedi_get_subdevice_runflags(s) & SRF_RUNNING)
-                  || comedi_buf_write_n_available(async) > 0){
+       if(write_subdev){
+               poll_wait(file, &write_subdev->async->wait_head, wait);
+               if(!write_subdev->busy
+                       || !(comedi_get_subdevice_runflags(write_subdev) & SRF_RUNNING)
+                       || comedi_buf_write_n_available(write_subdev->async) > 0){
                        mask |= POLLOUT | POLLWRNORM;
                }
        }
@@ -1393,9 +1391,9 @@ static ssize_t comedi_write(struct file *file,const char *buf,size_t nbytes,loff
 
        if(s->busy != file)
                return -EACCES;
-       add_wait_queue(&dev->write_wait,&wait);
+       add_wait_queue(&async->wait_head, &wait);
        while(nbytes>0 && !retval){
-               current->state=TASK_INTERRUPTIBLE;
+               set_current_state(TASK_INTERRUPTIBLE);
 
                n=nbytes;
 
@@ -1415,10 +1413,6 @@ static ssize_t comedi_write(struct file *file,const char *buf,size_t nbytes,loff
                                retval=-EAGAIN;
                                break;
                        }
-                       if(signal_pending(current)){
-                               retval=-ERESTARTSYS;
-                               break;
-                       }
                        if(!(comedi_get_subdevice_runflags(s) & SRF_RUNNING)){
                                if(comedi_get_subdevice_runflags(s) & SRF_ERROR){
                                        retval = -EPIPE;
@@ -1428,6 +1422,10 @@ static ssize_t comedi_write(struct file *file,const char *buf,size_t nbytes,loff
                                do_become_nonbusy(dev,s);
                                break;
                        }
+                       if(signal_pending(current)){
+                               retval=-ERESTARTSYS;
+                               break;
+                       }
                        schedule();
                        continue;
                }
@@ -1446,8 +1444,8 @@ static ssize_t comedi_write(struct file *file,const char *buf,size_t nbytes,loff
                buf+=n;
                break;  /* makes device work like a pipe */
        }
-       current->state=TASK_RUNNING;
-       remove_wait_queue(&dev->write_wait,&wait);
+       set_current_state(TASK_RUNNING);
+       remove_wait_queue(&async->wait_head, &wait);
 
        return (count ? count : retval);
 }
@@ -1479,9 +1477,9 @@ static ssize_t comedi_read(struct file * file,char *buf,size_t nbytes,loff_t *of
        if(s->busy != file)
                return -EACCES;
 
-       add_wait_queue(&dev->read_wait,&wait);
+       add_wait_queue(&async->wait_head, &wait);
        while(nbytes>0 && !retval){
-               current->state=TASK_INTERRUPTIBLE;
+               set_current_state(TASK_INTERRUPTIBLE);
 
                n=nbytes;
 
@@ -1494,6 +1492,10 @@ static ssize_t comedi_read(struct file * file,char *buf,size_t nbytes,loff_t *of
                if(m<n)n=m;
 
                if(n==0){
+                       if(file->f_flags&O_NONBLOCK){
+                               retval=-EAGAIN;
+                               break;
+                       }
                        if(!(comedi_get_subdevice_runflags(s) & SRF_RUNNING)){
                                do_become_nonbusy(dev,s);
                                if(comedi_get_subdevice_runflags(s) & SRF_ERROR){
@@ -1503,10 +1505,6 @@ static ssize_t comedi_read(struct file * file,char *buf,size_t nbytes,loff_t *of
                                }
                                break;
                        }
-                       if(file->f_flags&O_NONBLOCK){
-                               retval=-EAGAIN;
-                               break;
-                       }
                        if(signal_pending(current)){
                                retval=-ERESTARTSYS;
                                break;
@@ -1535,8 +1533,8 @@ static ssize_t comedi_read(struct file * file,char *buf,size_t nbytes,loff_t *of
        {
                do_become_nonbusy(dev,s);
        }
-       current->state=TASK_RUNNING;
-       remove_wait_queue(&dev->read_wait,&wait);
+       set_current_state(TASK_RUNNING);
+       remove_wait_queue(&async->wait_head, &wait);
 
        return (count ? count : retval);
 }
@@ -1812,20 +1810,16 @@ void comedi_event(comedi_device *dev, comedi_subdevice *s)
                        if(dev->rt){
 #ifdef CONFIG_COMEDI_RT
                                // pend wake up
-                               if(s->subdev_flags & SDF_CMD_READ)
-                                       comedi_rt_pend_wakeup(&dev->read_wait);
-                               if(s->subdev_flags & SDF_CMD_WRITE)
-                                       comedi_rt_pend_wakeup(&dev->write_wait);
+                               comedi_rt_pend_wakeup(&async->wait_head);
 #else
                                printk("BUG: comedi_event() code unreachable\n");
 #endif
                        }else{
+                               wake_up_interruptible(&async->wait_head);
                                if(s->subdev_flags & SDF_CMD_READ){
-                                       wake_up_interruptible(&dev->read_wait);
                                        kill_fasync(&dev->async_queue, SIGIO, POLL_IN);
                                }
                                if(s->subdev_flags & SDF_CMD_WRITE){
-                                       wake_up_interruptible(&dev->write_wait);
                                        kill_fasync(&dev->async_queue, SIGIO, POLL_OUT);
                                }
                        }
index 2250f868a08223782b4df4115c99b83a5138f563..5b9152e08a82e84e8a002acfda329c28dfd4f629 100644 (file)
@@ -183,9 +183,6 @@ attached:
                return ret;
        }
 
-       init_waitqueue_head(&dev->read_wait);
-       init_waitqueue_head(&dev->write_wait);
-
        if(!dev->board_name){
                printk("BUG: dev->board_name=<%p>\n",dev->board_name);
                dev->board_name="BUG";
@@ -274,6 +271,7 @@ static int postconfig(comedi_device *dev)
                                printk("failed to allocate async struct\n");
                                return -ENOMEM;
                        }
+                       init_waitqueue_head(&async->wait_head);
                        async->subdevice = s;
                        s->async = async;
 
index 1f45b161c58ca144accb3963a923c32481162d07..fe885f6083f1c80a3f22facdbb43fd7d0fcc572f 100644 (file)
@@ -189,6 +189,8 @@ struct comedi_async_struct{
 
        comedi_cmd cmd;
 
+       wait_queue_head_t wait_head;
+
        // callback stuff
        unsigned int cb_mask;
        int (*cb_func)(unsigned int flags,void *);
@@ -238,10 +240,7 @@ struct comedi_device_struct{
        unsigned int irq;
 
        comedi_subdevice *read_subdev;
-       wait_queue_head_t read_wait;
-
        comedi_subdevice *write_subdev;
-       wait_queue_head_t write_wait;
 
        struct fasync_struct *async_queue;