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 @@ ...@@ -19,6 +19,7 @@
#include <linux/wait.h> #include <linux/wait.h>
#include <linux/ktime.h> #include <linux/ktime.h>
#include <linux/atomic.h> #include <linux/atomic.h>
#include <linux/jiffies.h>
#include <linux/platform_device.h> #include <linux/platform_device.h>
#include <linux/uaccess.h> #include <linux/uaccess.h>
#include <linux/fmc.h> #include <linux/fmc.h>
...@@ -299,10 +300,23 @@ again: ...@@ -299,10 +300,23 @@ again:
/* The user may asketo wait for timestamps, but for 1 channel only */ /* The user may asketo wait for timestamps, but for 1 channel only */
if (!nstamp && cmd->flags & WR_DIO_F_WAIT) { if (!nstamp && cmd->flags & WR_DIO_F_WAIT) {
int ret_wait;
ch--; c--; /* The for above incremeted them */ ch--; c--; /* The for above incremeted them */
try_module_get(THIS_MODULE); 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); module_put(THIS_MODULE);
if(ret_wait)
return ret_wait;
if (signal_pending(current)) if (signal_pending(current))
return -ERESTARTSYS; return -ERESTARTSYS;
goto again; goto again;
......
...@@ -162,6 +162,8 @@ struct wr_dio_cmd { ...@@ -162,6 +162,8 @@ struct wr_dio_cmd {
uint32_t nstamp; /* from kernel, if IN_STAMP */ uint32_t nstamp; /* from kernel, if IN_STAMP */
struct timespec t[WR_DIO_N_STAMP]; struct timespec t[WR_DIO_N_STAMP];
struct wr_timestamp_info wr_ts_info_buf[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 */ #define WR_DIO_F_NOW 0x01 /* Output is now, t[0] ignored */
...@@ -171,4 +173,6 @@ struct wr_dio_cmd { ...@@ -171,4 +173,6 @@ struct wr_dio_cmd {
#define WR_DIO_F_WAIT 0x10 /* Wait for event */ #define WR_DIO_F_WAIT 0x10 /* Wait for event */
#define WR_DIO_F_MASK_READ_IRQ 0x20 #define WR_DIO_F_MASK_READ_IRQ 0x20
#define WR_DIO_F_MASK_ENABLE_IRQ 0x40 #define WR_DIO_F_MASK_ENABLE_IRQ 0x40
#define WR_DIO_F_MASK_DISABLE_IRQ 0x80 #define WR_DIO_F_MASK_DISABLE_IRQ 0x80
\ No newline at end of file #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