Commit b7887f05 authored by Miguel Jimenez Lopez's avatar Miguel Jimenez Lopez

sw/kernel: Add new blocking mode for ioctl() syscall

Now, a timeout can be specified to block until new events reach a single channel
or the specific timeout expires.
parent 2f4f2de6
......@@ -19,6 +19,7 @@
#include <linux/wait.h>
#include <linux/ktime.h>
#include <linux/atomic.h>
#include <linux/jiffies.h>
#include <linux/platform_device.h>
#include <linux/uaccess.h>
#include <linux/fmc.h>
......@@ -299,10 +300,23 @@ again:
/* The user may asketo wait for timestamps, but for 1 channel only */
if (!nstamp && cmd->flags & WR_DIO_F_WAIT) {
int ret_wait;
ch--; c--; /* The for above incremeted them */
try_module_get(THIS_MODULE);
wait_event_interruptible(c->q, c->bhead != c->btail);
if(cmd->wait_mode_flags & WR_DIO_F_WAIT_MODE_TIMEOUT) {
unsigned long tmo = timespec_to_jiffies(cmd->wait_mode_timeout);
ret_wait = wait_event_interruptible_timeout(c->q, c->bhead != c->btail, tmo);
if(!ret_wait)
ret_wait = -ETIMEDOUT;
else
ret_wait = 0;
}
else {
ret_wait = wait_event_interruptible(c->q, c->bhead != c->btail);
}
module_put(THIS_MODULE);
if(ret_wait)
return ret_wait;
if (signal_pending(current))
return -ERESTARTSYS;
goto again;
......
......@@ -162,6 +162,8 @@ struct wr_dio_cmd {
uint32_t nstamp; /* from kernel, if IN_STAMP */
struct timespec t[WR_DIO_N_STAMP];
struct wr_timestamp_info wr_ts_info_buf[WR_DIO_N_STAMP];
uint32_t wait_mode_flags;
struct timespec wait_mode_timeout;
};
#define WR_DIO_F_NOW 0x01 /* Output is now, t[0] ignored */
......@@ -171,4 +173,6 @@ struct wr_dio_cmd {
#define WR_DIO_F_WAIT 0x10 /* Wait for event */
#define WR_DIO_F_MASK_READ_IRQ 0x20
#define WR_DIO_F_MASK_ENABLE_IRQ 0x40
#define WR_DIO_F_MASK_DISABLE_IRQ 0x80
\ No newline at end of file
#define WR_DIO_F_MASK_DISABLE_IRQ 0x80
#define WR_DIO_F_WAIT_MODE_NORM 0x00
#define WR_DIO_F_WAIT_MODE_TIMEOUT 0x01
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment