Esempio n. 1
0
/* 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;
}
Esempio n. 2
0
/* 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;
}