/*
* 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) 2004-2008 Silicon Graphics, Inc. All Rights Reserved.
*/
/*
* Cross Partition Communication (XPC) support - standard version.
*
* XPC provides a message passing capability that crosses partition
* boundaries. This module is made up of two parts:
*
* partition This part detects the presence/absence of other
* partitions. It provides a heartbeat and monitors
* the heartbeats of other partitions.
*
* channel This part manages the channels and sends/receives
* messages across them to/from other partitions.
*
* There are a couple of additional functions residing in XP, which
* provide an interface to XPC for its users.
*
*
* Caveats:
*
* . We currently have no way to determine which nasid an IPI came
* from. Thus, xpc_IPI_send() does a remote AMO write followed by
* an IPI. The AMO indicates where data is to be pulled from, so
* after the IPI arrives, the remote partition checks the AMO word.
* The IPI can actually arrive before the AMO however, so other code
* must periodically check for this case. Also, remote AMO operations
* do not reliably time out. Thus we do a remote PIO read solely to
* know whether the remote partition is down and whether we should
* stop sending IPIs to it. This remote PIO read operation is set up
* in a special nofault region so SAL knows to ignore (and cleanup)
* any errors due to the remote AMO write, PIO read, and/or PIO
* write operations.
*
* If/when new hardware solves this IPI problem, we should abandon
* the current approach.
*
*/
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/cache.h>
#include <linux/interrupt.h>
#include <linux/delay.h>
#include <linux/reboot.h>
#include <linux/completion.h>
#include <linux/kdebug.h>
#include <linux/kthread.h>
#include <linux/uaccess.h>
#include <asm/sn/intr.h>
#include <asm/sn/sn_sal.h>
#include "xpc.h"
/* define two XPC debug device structures to be used with dev_dbg() et al */
struct device_driver xpc_dbg_name = {
.name = "xpc"
};
struct device xpc_part_dbg_subname = {
.bus_id = {0}, /* set to "part" at xpc_init() time */
.driver = &xpc_dbg_name
};
struct device xpc_chan_dbg_subname = {
.bus_id = {0}, /* set to "chan" at xpc_init() time */
.driver = &xpc_dbg_name
};
struct device *xpc_part = &xpc_part_dbg_subname;
struct device *xpc_chan = &xpc_chan_dbg_subname;
static int xpc_kdebug_ignore;
/* systune related variables for /proc/sys directories */
static int xpc_hb_interval = XPC_HB_DEFAULT_INTERVAL;
static int xpc_hb_min_interval = 1;
static int xpc_hb_max_interval = 10;
static int xpc_hb_check_interval = XPC_HB_CHECK_DEFAULT_INTERVAL;
static int xpc_hb_check_min_interval = 10;
static int xpc_hb_check_max_interval = 120;
int xpc_disengage_request_timelimit = XPC_DISENGAGE_REQUEST_DEFAULT_TIMELIMIT;
static int xpc_disengage_request_min_timelimit; /* = 0 */
static int xpc_disengage_request_max_timelimit = 120;
static ctl_table xpc_sys_xpc_hb_dir[] = {
{
.ctl_name = CTL_UNNUMBERED,
.procname = "hb_interval",
.data = &xpc_hb_interval,
.maxlen