diff --git a/userspace/wrsw_rtud/rtu_drv.c b/userspace/wrsw_rtud/rtu_drv.c index 8739edb113e0d959c3252ee49f5240f864f05574..de7448e94efbe1a14a4edb0600a9e9343949f707 100644 --- a/userspace/wrsw_rtud/rtu_drv.c +++ b/userspace/wrsw_rtud/rtu_drv.c @@ -227,6 +227,7 @@ static int irq_disabled = 1; int rtu_read_learning_queue(struct rtu_request *req) { int err; + int errno_local; if (irq_disabled) { ioctl(fd, WR_RTU_IRQENA); @@ -235,8 +236,22 @@ int rtu_read_learning_queue(struct rtu_request *req) // If learning queue is empty, wait for UFIFO IRQ if (rtu_ufifo_is_empty()) { err = ioctl(fd, WR_RTU_IRQWAIT); - if (err && (err != -EAGAIN)) + errno_local = errno; + /* Check if ioctl was interrupted by a signal. Please note that + * the driver's function returns -ERESTARTSYS, but userspace + * gets -1 (and errno == EINTR) from the ioctl call. */ + if (err == -1 && errno_local == EINTR) + return 1; + + /* IRQ disabled, driver/ioctl sets errno to EAGAIN */ + if (err == -1 && errno_local == EAGAIN) + return 2; + + /* Other error */ + if (err) { + pr_error("%s: error %d errno %s (%d)\n", __func__, err, strerror(errno_local), errno_local); return err; + } } // read data from mapped IO memory diff --git a/userspace/wrsw_rtud/rtud.c b/userspace/wrsw_rtud/rtud.c index 7b602e9f8f4cb3742e84eecb5334d62b8815bbba..117efe77cbd09f564dedcd8b09fbaf10e4d193e9 100644 --- a/userspace/wrsw_rtud/rtud.c +++ b/userspace/wrsw_rtud/rtud.c @@ -280,9 +280,11 @@ static int rtu_daemon_learning_process(void) err); break; } - } else { + } else if (err < 0) { pr_error("Read learning queue: error %d\n", err); } + /* If err > 0 retry rtu_read_learning_queue in the next loop + * iteration. */ } return err; }