Пример #1
0
static int
salinfo_log_clear(struct salinfo_data *data, int cpu)
{
	sal_log_record_header_t *rh;
	data->state = STATE_NO_DATA;
	if (!test_bit(cpu, &data->cpu_event))
		return 0;
	down(&data->sem);
	clear_bit(cpu, &data->cpu_event);
	if (data->saved_num) {
		unsigned long flags;
		spin_lock_irqsave(&data_saved_lock, flags);
		shift1_data_saved(data, data->saved_num - 1 );
		data->saved_num = 0;
		spin_unlock_irqrestore(&data_saved_lock, flags);
	}
	rh = (sal_log_record_header_t *)(data->log_buffer);
	/* Corrected errors have already been cleared from SAL */
	if (rh->severity != sal_log_severity_corrected)
		call_on_cpu(cpu, salinfo_log_clear_cpu, data);
	/* clearing a record may make a new record visible */
	salinfo_log_new_read(cpu, data);
	if (data->state == STATE_LOG_RECORD &&
	    !test_and_set_bit(cpu,  &data->cpu_event))
		up(&data->sem);
	return 0;
}
Пример #2
0
static int
salinfo_log_clear(struct salinfo_data *data, int cpu)
{
	data->state = STATE_NO_DATA;
	if (!test_bit(cpu, &data->cpu_event))
		return 0;
	down(&data->sem);
	clear_bit(cpu, &data->cpu_event);
	if (data->saved_num) {
		unsigned long flags;
		spin_lock_irqsave(&data_saved_lock, flags);
		shift1_data_saved(data, data->saved_num - 1 );
		data->saved_num = 0;
		spin_unlock_irqrestore(&data_saved_lock, flags);
	}
	/* ia64_mca_log_sal_error_record or salinfo_log_read_cpu already cleared
	 * CPE and CMC errors
	 */
	if (data->type != SAL_INFO_TYPE_CPE && data->type != SAL_INFO_TYPE_CMC)
		call_on_cpu(cpu, salinfo_log_clear_cpu, data);
	/* clearing a record may make a new record visible */
	salinfo_log_new_read(cpu, data);
	if (data->state == STATE_LOG_RECORD &&
	    !test_and_set_bit(cpu,  &data->cpu_event))
		up(&data->sem);
	return 0;
}
Пример #3
0
static ssize_t
salinfo_log_write(struct file *file, const char __user *buffer, size_t count, loff_t *ppos)
{
	struct inode *inode = file->f_dentry->d_inode;
	struct proc_dir_entry *entry = PDE(inode);
	struct salinfo_data *data = entry->data;
	char cmd[32];
	size_t size;
	u32 offset;
	int cpu;

	size = sizeof(cmd);
	if (count < size)
		size = count;
	if (copy_from_user(cmd, buffer, size))
		return -EFAULT;

	if (sscanf(cmd, "read %d", &cpu) == 1) {
		salinfo_log_new_read(cpu, data);
	} else if (sscanf(cmd, "clear %d", &cpu) == 1) {
		int ret;
		if ((ret = salinfo_log_clear(data, cpu)))
			count = ret;
	} else if (sscanf(cmd, "oemdata %d %d", &cpu, &offset) == 2) {
		if (data->state != STATE_LOG_RECORD && data->state != STATE_OEMDATA)
			return -EINVAL;
		if (offset > data->log_size - sizeof(efi_guid_t))
			return -EINVAL;
		data->state = STATE_OEMDATA;
		if (salinfo_platform_oemdata) {
			struct salinfo_platform_oemdata_parms parms = {
				.efi_guid = data->log_buffer + offset,
				.oemdata = &data->oemdata,
				.oemdata_size = &data->oemdata_size
			};
			call_on_cpu(cpu, salinfo_platform_oemdata_cpu, &parms);
			if (parms.ret)
				count = parms.ret;
		} else
			data->oemdata_size = 0;
	} else
		return -EINVAL;
Пример #4
0
static void
salinfo_log_new_read(int cpu, struct salinfo_data *data)
{
	struct salinfo_data_saved *data_saved;
	unsigned long flags;
	int i;
	int saved_size = ARRAY_SIZE(data->data_saved);

	data->saved_num = 0;
	spin_lock_irqsave(&data_saved_lock, flags);
retry:
	for (i = 0, data_saved = data->data_saved; i < saved_size; ++i, ++data_saved) {
		if (data_saved->buffer && data_saved->cpu == cpu) {
			sal_log_record_header_t *rh = (sal_log_record_header_t *)(data_saved->buffer);
			data->log_size = data_saved->size;
			memcpy(data->log_buffer, rh, data->log_size);
			barrier();	/* id check must not be moved */
			if (rh->id == data_saved->id) {
				data->saved_num = i+1;
				break;
			}
			/* saved record changed by mca.c since interrupt, discard it */
			shift1_data_saved(data, i);
			goto retry;
		}
	}
	spin_unlock_irqrestore(&data_saved_lock, flags);

	if (!data->saved_num)
		call_on_cpu(cpu, salinfo_log_read_cpu, data);
	if (!data->log_size) {
	        data->state = STATE_NO_DATA;
	        clear_bit(cpu, &data->cpu_event);
	} else {
	        data->state = STATE_LOG_RECORD;
	}
}