static unsigned int ls_poll(struct file *filp, poll_table *wait) { unsigned int mask = 0; #if DEBUG printk("%s poll request\n", DEV_NAME); #endif mutex_lock(&ls.update_lock); poll_wait(filp, &waitQ, wait); if (!(ls.state & (LS_DATA_READY | LS_ANY_RESULT) || check_sensor_value())) { mod_timer(&ls.tmr, jiffies + msecs_to_jiffies(ls.conf.poll_period_ms)); goto data_not_ready; } #if DEBUG printk("%s poll request - data ready\n", DEV_NAME); #endif mask |= POLLIN | POLLRDNORM; /* readable */ data_not_ready: mutex_unlock(&ls.update_lock); return mask; }
static ssize_t ls_read(struct file *file, char __user *buf, size_t count, loff_t *offset) { int ok; #if DEBUG printk("%s read request.\n", DEV_NAME); #endif mutex_lock(&ls.update_lock); if (ls.state & LS_SUSPEND) { #if DEBUG printk(KERN_ERR "%s: is suspended!\n", DEV_NAME); #endif mutex_unlock(&ls.update_lock); return -EBUSY; } ok = check_sensor_value(); if (ok || ls.state & LS_ANY_RESULT) goto data_ready; if (file->f_flags & O_NONBLOCK) { mutex_unlock(&ls.update_lock); return -EAGAIN; } mod_timer(&ls.tmr, jiffies + msecs_to_jiffies(ls.conf.poll_period_ms)); mutex_unlock(&ls.update_lock); #if DEBUG printk("%s read request in a wait queue\n", DEV_NAME); #endif if (-ERESTARTSYS == wait_event_interruptible(waitQ, ls.state & LS_DATA_READY)) return -ERESTARTSYS; mutex_lock(&ls.update_lock); data_ready: #if DEBUG printk("%s sensor value %d\n", DEV_NAME, ls.sensor_value); #endif ls.state &= ~LS_DATA_READY; ok = count >= sizeof(ls.sensor_value) && !copy_to_user(buf, &ls.sensor_value, sizeof(ls.sensor_value)); ok = ok ? sizeof(ls.sensor_value) : -EFAULT; mutex_unlock(&ls.update_lock); return ok; }
static void timer_bh(struct work_struct *work) { mutex_lock(&ls.update_lock); if (!(ls.state & LS_SUSPEND)) { if (check_sensor_value()) { wake_up_interruptible(&waitQ); goto out; } if (ls.state & LS_DEVICE_OPENED && !(ls.state & LS_DATA_READY)) mod_timer(&ls.tmr, jiffies + msecs_to_jiffies(ls.conf.poll_period_ms)); } out: mutex_unlock(&ls.update_lock); }