/*
 * This file is subject to the terms and conditions of the GNU General Public
 * License.  See the file "COPYING" in the main directory of this archive
 * for more details.
 *
 * Copyright (c) 2000-2004 Silicon Graphics, Inc.  All Rights Reserved.
 */

#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/timer.h>
#include <linux/vmalloc.h>
#include <asm/mca.h>
#include <asm/sal.h>
#include <asm/sn/sn_sal.h>

/*
 * Interval for calling SAL to poll for errors that do NOT cause error
 * interrupts. SAL will raise a CPEI if any errors are present that
 * need to be logged.
 */
#define CPEI_INTERVAL	(5*HZ)

struct timer_list sn_cpei_timer;
void sn_init_cpei_timer(void);

/* Printing oemdata from mca uses data that is not passed through SAL, it is
 * global.  Only one user at a time.
 */
static DECLARE_MUTEX(sn_oemdata_mutex);
static u8 **sn_oemdata;
static u64 *sn_oemdata_size, sn_oemdata_bufsize;

/*
 * print_hook
 *
 * This function is the callback routine that SAL calls to log error
 * info for platform errors.  buf is appended to sn_oemdata, resizing as
 * required.
 * Note: this is a SAL to OS callback, running under the same rules as the SAL
 * code.  SAL calls are run with preempt disabled so this routine must not
 * sleep.  vmalloc can sleep so print_hook cannot resize the output buffer
 * itself, instead it must set the required size and return to let the caller
 * resize the buffer then redrive the SAL call.
 */
static int print_hook(const char *fmt, ...)
{
	char buf[400];
	int len;
	va_list args;
	va_start(args, fmt);
	vsnprintf(buf, sizeof(buf), fmt, args);
	va_end(args);
	len = strlen(buf);
	if (*sn_oemdata_size + len <= sn_oemdata_bufsize)
		memcpy(*sn_oemdata + *sn_oemdata_size, buf, len);
	*sn_oemdata_size += len;
	return 0;
}

static void sn_cpei_handler(int irq, void *devid, struct pt_regs *regs)
{
	/*
	 * this function's sole purpose is to call SAL when we receive
	 * a CE interrupt from SHUB or when the timer routine decides
	 * we need to call SAL to check for CEs.
	 */

	/* CALL SAL_LOG_CE */

	ia64_sn_plat_cpei_handler();
}

static void sn_cpei_timer_handler(unsigned long dummy)
{
	sn_cpei_handler(-1, NULL, NULL);
	mod_timer(&sn_cpei_timer, jiffies + CPEI_INTERVAL);
}

void sn_init_cpei_timer(void)
{
	init_timer(&sn_cpei_timer);
	sn_cpei_timer.expires = jiffies + CPEI_INTERVAL;
	sn_cpei_timer.function = sn_cpei_timer_handler;
	add_timer(&sn_cpei_timer);
}

static int
sn_platform_plat_specific_err_print(const u8 * sect_header, u8 ** oemdata,
				    u64 * oemdata_size)
{
	down(&sn_oemdata_mutex);
	sn_oemdata = oemdata;
	sn_oemdata_size = oemdata_size;
	sn_oemdata_bufsize = 0;
	*sn_oemdata_size = PAGE_SIZE;	/* first guess at how much data will be generated */
	while (*sn_oemdata_size > sn_oemdata_bufsize) {
		u8 *newbuf = vmalloc(*sn_oemdata_size);
		if (!newbuf) {
			printk(KERN_ERR "%s: unable to extend sn_oemdata\n",
			       __FUNCTION__);
			return 1;
		}
		vfree(*sn_oemdata);
		*sn_oemdata = newbuf;
		sn_oemdata_bufsize = *sn_oemdata_size;
		*sn_oemdata_size = 0;
		ia64_sn_plat_specific_err_print(print_hook, (char *)sect_header);
	}
	up(&sn_oemdata_mutex);
	return 0;
}

/* Callback when userspace salinfo wants to decode oem data via the platform
 * kernel and/or prom.
 */
int sn_salinfo_platform_oemdata(const u8 *sect_header, u8 **oemdata, u64 *oemdata_size)
{
	efi_guid_t guid = *(efi_guid_t *)sect_header;
	int valid = 0;
	*oemdata_size = 0;
	vfree(*oemdata);
	*oemdata = NULL;
	if (efi_guidcmp(guid, SAL_PLAT_SPECIFIC_ERR_SECT_GUID) == 0) {
		sal_log_plat_specific_err_info_t *psei = (sal_log_plat_specific_err_info_t *)sect_header;
		valid = psei->valid.oem_data;
	} else if (efi_guidcmp(guid, SAL_PLAT_MEM_DEV_ERR_SECT_GUID) == 0) {
		sal_log_mem_dev_err_info_t *mdei = (sal_log_mem_dev_err_info_t *)sect_header;
		valid = mdei->valid.oem_data;
	}
	if (valid)
		return sn_platform_plat_specific_err_print(sect_header, oemdata, oemdata_size);
	else
		return 0;
}

static int __init sn_salinfo_init(void)
{
	salinfo_platform_oemdata = &sn_salinfo_platform_oemdata;
	return 0;
}

module_init(sn_salinfo_init)
