diff options
Diffstat (limited to 'drivers/iio/industrialio-buffer.c')
| -rw-r--r-- | drivers/iio/industrialio-buffer.c | 27 | 
1 files changed, 19 insertions, 8 deletions
diff --git a/drivers/iio/industrialio-buffer.c b/drivers/iio/industrialio-buffer.c index 90462fcf5436..158aaf44dd95 100644 --- a/drivers/iio/industrialio-buffer.c +++ b/drivers/iio/industrialio-buffer.c @@ -107,9 +107,10 @@ ssize_t iio_buffer_read_first_n_outer(struct file *filp, char __user *buf,  {  	struct iio_dev *indio_dev = filp->private_data;  	struct iio_buffer *rb = indio_dev->buffer; +	DEFINE_WAIT_FUNC(wait, woken_wake_function);  	size_t datum_size;  	size_t to_wait; -	int ret; +	int ret = 0;  	if (!indio_dev->info)  		return -ENODEV; @@ -131,19 +132,29 @@ ssize_t iio_buffer_read_first_n_outer(struct file *filp, char __user *buf,  	else  		to_wait = min_t(size_t, n / datum_size, rb->watermark); +	add_wait_queue(&rb->pollq, &wait);  	do { -		ret = wait_event_interruptible(rb->pollq, -		      iio_buffer_ready(indio_dev, rb, to_wait, n / datum_size)); -		if (ret) -			return ret; +		if (!indio_dev->info) { +			ret = -ENODEV; +			break; +		} -		if (!indio_dev->info) -			return -ENODEV; +		if (!iio_buffer_ready(indio_dev, rb, to_wait, n / datum_size)) { +			if (signal_pending(current)) { +				ret = -ERESTARTSYS; +				break; +			} + +			wait_woken(&wait, TASK_INTERRUPTIBLE, +				   MAX_SCHEDULE_TIMEOUT); +			continue; +		}  		ret = rb->access->read_first_n(rb, n, buf);  		if (ret == 0 && (filp->f_flags & O_NONBLOCK))  			ret = -EAGAIN; -	 } while (ret == 0); +	} while (ret == 0); +	remove_wait_queue(&rb->pollq, &wait);  	return ret;  }  | 
