/* This will check if all events are logged, if they are then, we * know that we can safely clear the events in NVRAM. * Next we'll sit and wait for something else to log. */ static ssize_t rtas_log_read(struct file * file, char __user * buf, size_t count, loff_t *ppos) { int error; char *tmp; unsigned long s; unsigned long offset; if (!buf || count < rtas_error_log_buffer_max) return -EINVAL; count = rtas_error_log_buffer_max; if (!access_ok(VERIFY_WRITE, buf, count)) return -EFAULT; tmp = kmalloc(count, GFP_KERNEL); if (!tmp) return -ENOMEM; spin_lock_irqsave(&rtasd_log_lock, s); /* if it's 0, then we know we got the last one (the one in NVRAM) */ while (rtas_log_size == 0) { if (file->f_flags & O_NONBLOCK) { spin_unlock_irqrestore(&rtasd_log_lock, s); error = -EAGAIN; goto out; } if (!logging_enabled) { spin_unlock_irqrestore(&rtasd_log_lock, s); error = -ENODATA; goto out; } #ifdef CONFIG_PPC64 nvram_clear_error_log(); #endif /* CONFIG_PPC64 */ spin_unlock_irqrestore(&rtasd_log_lock, s); error = wait_event_interruptible(rtas_log_wait, rtas_log_size); if (error) goto out; spin_lock_irqsave(&rtasd_log_lock, s); } offset = rtas_error_log_buffer_max * (rtas_log_start & LOG_NUMBER_MASK); memcpy(tmp, &rtas_log_buf[offset], count); rtas_log_start += 1; rtas_log_size -= 1; spin_unlock_irqrestore(&rtasd_log_lock, s); error = copy_to_user(buf, tmp, count) ? -EFAULT : count; out: kfree(tmp); return error; }
/* This will check if all events are logged, if they are then, we * know that we can safely clear the events in NVRAM. * Next we'll sit and wait for something else to log. */ static ssize_t rtas_log_read(struct file * file, char * buf, size_t count, loff_t *ppos) { int error; char *tmp; unsigned long s; unsigned long offset; if (!buf || count < rtas_error_log_buffer_max) return -EINVAL; count = rtas_error_log_buffer_max; error = verify_area(VERIFY_WRITE, buf, count); if (error) return -EFAULT; tmp = kmalloc(count, GFP_KERNEL); if (!tmp) return -ENOMEM; spin_lock_irqsave(&log_lock, s); /* if it's 0, then we know we got the last one (the one in NVRAM) */ if (rtas_log_size == 0 && !no_more_logging) nvram_clear_error_log(); spin_unlock_irqrestore(&log_lock, s); error = wait_event_interruptible(rtas_log_wait, rtas_log_size); if (error) goto out; spin_lock_irqsave(&log_lock, s); offset = rtas_error_log_buffer_max * (rtas_log_start & LOG_NUMBER_MASK); memcpy(tmp, &rtas_log_buf[offset], count); rtas_log_start += 1; rtas_log_size -= 1; spin_unlock_irqrestore(&log_lock, s); error = copy_to_user(buf, tmp, count) ? -EFAULT : count; out: kfree(tmp); return error; }