All of lore.kernel.org
 help / color / mirror / Atom feed
From: Dean Nelson <dcn@sgi.com>
To: akpm@linux-foundation.org
Cc: linux-kernel@vger.kernel.org
Subject: [Patch 12/18] isolate additional sn2 specific code
Date: Fri, 6 Jun 2008 11:55:23 -0500	[thread overview]
Message-ID: <20080606165523.GM13695@sgi.com> (raw)
In-Reply-To: <20080606164034.GA13695@sgi.com>

Move additional sn2 specific code into xpc_sn2.c.

Signed-off-by: Dean Nelson <dcn@sgi.com>

---

 drivers/misc/sgi-xp/xpc.h           |  173 +++---
 drivers/misc/sgi-xp/xpc_channel.c   |  214 --------
 drivers/misc/sgi-xp/xpc_main.c      |  278 +++-------
 drivers/misc/sgi-xp/xpc_partition.c |   61 +-
 drivers/misc/sgi-xp/xpc_sn2.c       |  853 ++++++++++++++++++++------------
 drivers/misc/sgi-xp/xpc_uv.c        |   15 
 6 files changed, 786 insertions(+), 808 deletions(-)

Index: linux-2.6/drivers/misc/sgi-xp/xpc.h
===================================================================
--- linux-2.6.orig/drivers/misc/sgi-xp/xpc.h	2008-06-05 12:51:17.175807359 -0500
+++ linux-2.6/drivers/misc/sgi-xp/xpc.h	2008-06-06 08:10:50.969262778 -0500
@@ -122,9 +122,6 @@ struct xpc_rsvd_page {
 
 #define XPC_RP_VERSION _XPC_VERSION(2, 0) /* version 2.0 of the reserved page */
 
-#define XPC_SUPPORTS_RP_STAMP(_version) \
-			(_version >= _XPC_VERSION(1, 1))
-
 /*
  * Define the structures by which XPC variables can be exported to other
  * partitions. (There are two: struct xpc_vars and struct xpc_vars_part)
@@ -144,8 +141,8 @@ struct xpc_vars_sn2 {
 	u64 heartbeat;
 	DECLARE_BITMAP(heartbeating_to_mask, XP_MAX_NPARTITIONS_SN2);
 	u64 heartbeat_offline;	/* if 0, heartbeat should be changing */
-	int act_nasid;
-	int act_phys_cpuid;
+	int activate_IRQ_nasid;
+	int activate_IRQ_phys_cpuid;
 	u64 vars_part_pa;
 	u64 amos_page_pa;	/* paddr of page of AMOs from MSPEC driver */
 	AMO_t *amos_page;	/* vaddr of page of AMOs from MSPEC driver */
@@ -153,9 +150,6 @@ struct xpc_vars_sn2 {
 
 #define XPC_V_VERSION _XPC_VERSION(3, 1)    /* version 3.1 of the cross vars */
 
-#define XPC_SUPPORTS_DISENGAGE_REQUEST(_version) \
-			(_version >= _XPC_VERSION(3, 1))
-
 /*
  * The following pertains to ia64-sn2 only.
  *
@@ -167,14 +161,14 @@ struct xpc_vars_sn2 {
  * a PI FSB Protocol error to be generated by the SHUB. For XPC, we need 64
  * AMO variables (based on XP_MAX_NPARTITIONS_SN2) to identify the senders of
  * NOTIFY IRQs, 128 AMO variables (based on XP_NASID_MASK_WORDS) to identify
- * the senders of ACTIVATE IRQs, and 2 AMO variables to identify which remote
+ * the senders of ACTIVATE IRQs, 1 AMO variable to identify which remote
  * partitions (i.e., XPCs) consider themselves currently engaged with the
- * local XPC.
+ * local XPC and 1 AMO variable to request partition deactivation.
  */
 #define XPC_NOTIFY_IRQ_AMOS	0
 #define XPC_ACTIVATE_IRQ_AMOS	(XPC_NOTIFY_IRQ_AMOS + XP_MAX_NPARTITIONS_SN2)
 #define XPC_ENGAGED_PARTITIONS_AMO (XPC_ACTIVATE_IRQ_AMOS + XP_NASID_MASK_WORDS)
-#define XPC_DISENGAGE_REQUEST_AMO  (XPC_ENGAGED_PARTITIONS_AMO + 1)
+#define XPC_DEACTIVATE_REQUEST_AMO  (XPC_ENGAGED_PARTITIONS_AMO + 1)
 
 /*
  * The following structure describes the per partition specific variables.
@@ -369,6 +363,23 @@ struct xpc_notify {
  *	new messages, by the clearing of the message flags of the acknowledged
  *	messages.
  */
+struct xpc_channel_sn2 {
+
+	/* various flavors of local and remote Get/Put values */
+
+	struct xpc_gp *local_GP;	/* local Get/Put values */
+	struct xpc_gp remote_GP;	/* remote Get/Put values */
+	struct xpc_gp w_local_GP;	/* working local Get/Put values */
+	struct xpc_gp w_remote_GP;	/* working remote Get/Put values */
+	s64 next_msg_to_pull;	/* Put value of next msg to pull */
+
+	struct mutex msg_to_pull_mutex;	/* next msg to pull serialization */
+};
+
+struct xpc_channel_uv {
+	/* >>> code is coming */
+};
+
 struct xpc_channel {
 	short partid;		/* ID of remote partition connected */
 	spinlock_t lock;	/* lock for updating this structure */
@@ -407,20 +418,11 @@ struct xpc_channel {
 	xpc_channel_func func;	/* user's channel function */
 	void *key;		/* pointer to user's key */
 
-	struct mutex msg_to_pull_mutex;	/* next msg to pull serialization */
 	struct completion wdisconnect_wait;    /* wait for channel disconnect */
 
 	struct xpc_openclose_args *local_openclose_args; /* args passed on */
 					     /* opening or closing of channel */
 
-	/* various flavors of local and remote Get/Put values */
-
-	struct xpc_gp *local_GP;	/* local Get/Put values */
-	struct xpc_gp remote_GP;	/* remote Get/Put values */
-	struct xpc_gp w_local_GP;	/* working local Get/Put values */
-	struct xpc_gp w_remote_GP;	/* working remote Get/Put values */
-	s64 next_msg_to_pull;	/* Put value of next msg to pull */
-
 	/* kthread management related fields */
 
 	atomic_t kthreads_assigned;	/* #of kthreads assigned to channel */
@@ -431,6 +433,11 @@ struct xpc_channel {
 
 	wait_queue_head_t idle_wq;	/* idle kthread wait queue */
 
+	union {
+		struct xpc_channel_sn2 sn2;
+		struct xpc_channel_uv uv;
+	} sn;
+
 } ____cacheline_aligned;
 
 /* struct xpc_channel flags */
@@ -467,6 +474,40 @@ struct xpc_channel {
  * for each partition (a partition will never utilize the structure that
  * represents itself).
  */
+
+struct xpc_partition_sn2 {
+	u64 remote_amos_page_pa;	/* phys addr of partition's amos page */
+	int activate_IRQ_nasid;	/* active partition's act/deact nasid */
+	int activate_IRQ_phys_cpuid;	/* active part's act/deact phys cpuid */
+
+	u64 remote_vars_pa;	/* phys addr of partition's vars */
+	u64 remote_vars_part_pa;	/* phys addr of partition's vars part */
+	u8 remote_vars_version;	/* version# of partition's vars */
+
+	void *local_GPs_base;	/* base address of kmalloc'd space */
+	struct xpc_gp *local_GPs;	/* local Get/Put values */
+	void *remote_GPs_base;	/* base address of kmalloc'd space */
+	struct xpc_gp *remote_GPs;	/* copy of remote partition's local */
+					/* Get/Put values */
+	u64 remote_GPs_pa;	/* phys address of remote partition's local */
+				/* Get/Put values */
+
+	u64 remote_openclose_args_pa;	/* phys addr of remote's args */
+
+	int remote_IPI_nasid;	/* nasid of where to send IPIs */
+	int remote_IPI_phys_cpuid;	/* phys CPU ID of where to send IPIs */
+	char IPI_owner[8];	/* IPI owner's name */
+
+	AMO_t *remote_IPI_amo_va;    /* address of remote IPI AMO_t structure */
+	AMO_t *local_IPI_amo_va;	/* address of IPI AMO_t structure */
+
+	struct timer_list dropped_notify_IRQ_timer;	/* dropped IRQ timer */
+};
+
+struct xpc_partition_uv {
+	/* >>> code is coming */
+};
+
 struct xpc_partition {
 
 	/* XPC HB infrastructure */
@@ -474,22 +515,15 @@ struct xpc_partition {
 	u8 remote_rp_version;	/* version# of partition's rsvd pg */
 	unsigned long remote_rp_stamp; /* time when rsvd pg was initialized */
 	u64 remote_rp_pa;	/* phys addr of partition's rsvd pg */
-	u64 remote_vars_pa;	/* phys addr of partition's vars */
-	u64 remote_vars_part_pa;	/* phys addr of partition's vars part */
 	u64 last_heartbeat;	/* HB at last read */
-	u64 remote_amos_page_pa;	/* phys addr of partition's amos page */
-	int remote_act_nasid;	/* active part's act/deact nasid */
-	int remote_act_phys_cpuid;	/* active part's act/deact phys cpuid */
 	u32 activate_IRQ_rcvd;	/* IRQs since activation */
 	spinlock_t act_lock;	/* protect updating of act_state */
 	u8 act_state;		/* from XPC HB viewpoint */
-	u8 remote_vars_version;	/* version# of partition's vars */
 	enum xp_retval reason;	/* reason partition is deactivating */
 	int reason_line;	/* line# deactivation initiated from */
-	int reactivate_nasid;	/* nasid in partition to reactivate */
 
-	unsigned long disengage_request_timeout;	/* timeout in jiffies */
-	struct timer_list disengage_request_timer;
+	unsigned long disengage_timeout;	/* timeout in jiffies */
+	struct timer_list disengage_timer;
 
 	/* XPC infrastructure referencing and teardown control */
 
@@ -502,14 +536,6 @@ struct xpc_partition {
 	atomic_t nchannels_engaged;  /* #of channels engaged with remote part */
 	struct xpc_channel *channels;	/* array of channel structures */
 
-	void *local_GPs_base;	/* base address of kmalloc'd space */
-	struct xpc_gp *local_GPs;	/* local Get/Put values */
-	void *remote_GPs_base;	/* base address of kmalloc'd space */
-	struct xpc_gp *remote_GPs;	/* copy of remote partition's local */
-					/* Get/Put values */
-	u64 remote_GPs_pa;	/* phys address of remote partition's local */
-				/* Get/Put values */
-
 	/* fields used to pass args when opening or closing a channel */
 
 	void *local_openclose_args_base;   /* base address of kmalloc'd space */
@@ -517,19 +543,10 @@ struct xpc_partition {
 	void *remote_openclose_args_base;  /* base address of kmalloc'd space */
 	struct xpc_openclose_args *remote_openclose_args; /* copy of remote's */
 							  /* args */
-	u64 remote_openclose_args_pa;	/* phys addr of remote's args */
 
 	/* IPI sending, receiving and handling related fields */
 
-	int remote_IPI_nasid;	/* nasid of where to send IPIs */
-	int remote_IPI_phys_cpuid;	/* phys CPU ID of where to send IPIs */
-	AMO_t *remote_IPI_amo_va;    /* address of remote IPI AMO_t structure */
-
-	AMO_t *local_IPI_amo_va;	/* address of IPI AMO_t structure */
 	u64 local_IPI_amo;	/* IPI amo flags yet to be handled */
-	char IPI_owner[8];	/* IPI owner's name */
-	struct timer_list dropped_IPI_timer;	/* dropped IPI timer */
-
 	spinlock_t IPI_lock;	/* IPI handler lock */
 
 	/* channel manager related fields */
@@ -537,6 +554,11 @@ struct xpc_partition {
 	atomic_t channel_mgr_requests;	/* #of requests to activate chan mgr */
 	wait_queue_head_t channel_mgr_wq;	/* channel mgr's wait queue */
 
+	union {
+		struct xpc_partition_sn2 sn2;
+		struct xpc_partition_uv uv;
+	} sn;
+
 } ____cacheline_aligned;
 
 /* struct xpc_partition act_state values (for XPC HB) */
@@ -565,10 +587,10 @@ struct xpc_partition {
 #define XPC_P_DROPPED_IPI_WAIT_INTERVAL	(0.25 * HZ)
 
 /* number of seconds to wait for other partitions to disengage */
-#define XPC_DISENGAGE_REQUEST_DEFAULT_TIMELIMIT	90
+#define XPC_DISENGAGE_DEFAULT_TIMELIMIT		90
 
-/* interval in seconds to print 'waiting disengagement' messages */
-#define XPC_DISENGAGE_PRINTMSG_INTERVAL		10
+/* interval in seconds to print 'waiting deactivation' messages */
+#define XPC_DEACTIVATE_PRINTMSG_INTERVAL	10
 
 #define XPC_PARTID(_p)	((short)((_p) - &xpc_partitions[0]))
 
@@ -578,13 +600,11 @@ extern struct xpc_registration xpc_regis
 /* found in xpc_main.c */
 extern struct device *xpc_part;
 extern struct device *xpc_chan;
-extern int xpc_disengage_request_timelimit;
-extern int xpc_disengage_request_timedout;
+extern int xpc_disengage_timelimit;
+extern int xpc_disengage_timedout;
 extern atomic_t xpc_activate_IRQ_rcvd;
 extern wait_queue_head_t xpc_activate_IRQ_wq;
 extern void *xpc_heartbeating_to_mask;
-extern irqreturn_t xpc_notify_IRQ_handler(int, void *);
-extern void xpc_dropped_IPI_check(struct xpc_partition *);
 extern void xpc_activate_partition(struct xpc_partition *);
 extern void xpc_activate_kthreads(struct xpc_channel *, int);
 extern void xpc_create_kthreads(struct xpc_channel *, int, int);
@@ -598,31 +618,34 @@ extern void (*xpc_online_heartbeat) (voi
 extern void (*xpc_check_remote_hb) (void);
 extern enum xp_retval (*xpc_make_first_contact) (struct xpc_partition *);
 extern u64 (*xpc_get_IPI_flags) (struct xpc_partition *);
+extern void (*xpc_notify_senders_of_disconnect) (struct xpc_channel *);
+extern void (*xpc_process_msg_IPI) (struct xpc_partition *, int);
+extern int (*xpc_n_of_deliverable_msgs) (struct xpc_channel *);
 extern struct xpc_msg *(*xpc_get_deliverable_msg) (struct xpc_channel *);
-extern void (*xpc_initiate_partition_activation) (struct xpc_rsvd_page *, u64,
-						  int);
+extern void (*xpc_request_partition_activation) (struct xpc_rsvd_page *, u64,
+						 int);
+extern void (*xpc_request_partition_reactivation) (struct xpc_partition *);
+extern void (*xpc_request_partition_deactivation) (struct xpc_partition *);
+extern void (*xpc_cancel_partition_deactivation_request) (
+							struct xpc_partition *);
 extern void (*xpc_process_activate_IRQ_rcvd) (int);
 extern enum xp_retval (*xpc_setup_infrastructure) (struct xpc_partition *);
 extern void (*xpc_teardown_infrastructure) (struct xpc_partition *);
-extern void (*xpc_mark_partition_engaged) (struct xpc_partition *);
-extern void (*xpc_mark_partition_disengaged) (struct xpc_partition *);
-extern void (*xpc_request_partition_disengage) (struct xpc_partition *);
-extern void (*xpc_cancel_partition_disengage_request) (struct xpc_partition *);
-extern u64 (*xpc_partition_engaged) (u64);
-extern u64 (*xpc_partition_disengage_requested) (u64);;
-extern void (*xpc_clear_partition_engaged) (u64);
-extern void (*xpc_clear_partition_disengage_request) (u64);
-
-extern void (*xpc_IPI_send_local_activate) (int);
-extern void (*xpc_IPI_send_activated) (struct xpc_partition *);
-extern void (*xpc_IPI_send_local_reactivate) (int);
-extern void (*xpc_IPI_send_disengage) (struct xpc_partition *);
-
-extern void (*xpc_IPI_send_closerequest) (struct xpc_channel *,
-					  unsigned long *);
-extern void (*xpc_IPI_send_closereply) (struct xpc_channel *, unsigned long *);
-extern void (*xpc_IPI_send_openrequest) (struct xpc_channel *, unsigned long *);
-extern void (*xpc_IPI_send_openreply) (struct xpc_channel *, unsigned long *);
+
+extern void (*xpc_indicate_partition_engaged) (struct xpc_partition *);
+extern int (*xpc_partition_engaged) (short);
+extern int (*xpc_any_partition_engaged) (void);
+extern void (*xpc_indicate_partition_disengaged) (struct xpc_partition *);
+extern void (*xpc_assume_partition_disengaged) (short);
+
+extern void (*xpc_send_channel_closerequest) (struct xpc_channel *,
+					      unsigned long *);
+extern void (*xpc_send_channel_closereply) (struct xpc_channel *,
+					    unsigned long *);
+extern void (*xpc_send_channel_openrequest) (struct xpc_channel *,
+					     unsigned long *);
+extern void (*xpc_send_channel_openreply) (struct xpc_channel *,
+					   unsigned long *);
 
 extern enum xp_retval (*xpc_send_msg) (struct xpc_channel *, u32, void *, u16,
 				       u8, xpc_notify_func, void *);
@@ -646,8 +669,6 @@ extern char *xpc_remote_copy_buffer;
 extern void *xpc_remote_copy_buffer_base;
 extern void *xpc_kmalloc_cacheline_aligned(size_t, gfp_t, void **);
 extern struct xpc_rsvd_page *xpc_setup_rsvd_page(void);
-extern void xpc_allow_IPI_ops(void);
-extern void xpc_restrict_IPI_ops(void);
 extern int xpc_identify_activate_IRQ_sender(void);
 extern int xpc_partition_disengaged(struct xpc_partition *);
 extern enum xp_retval xpc_mark_partition_active(struct xpc_partition *);
Index: linux-2.6/drivers/misc/sgi-xp/xpc_channel.c
===================================================================
--- linux-2.6.orig/drivers/misc/sgi-xp/xpc_channel.c	2008-06-05 12:51:17.075794869 -0500
+++ linux-2.6/drivers/misc/sgi-xp/xpc_channel.c	2008-06-06 08:08:28.696424737 -0500
@@ -201,7 +201,7 @@ xpc_process_connect(struct xpc_channel *
 
 	if (!(ch->flags & XPC_C_OPENREPLY)) {
 		ch->flags |= XPC_C_OPENREPLY;
-		xpc_IPI_send_openreply(ch, irq_flags);
+		xpc_send_channel_openreply(ch, irq_flags);
 	}
 
 	if (!(ch->flags & XPC_C_ROPENREPLY))
@@ -220,52 +220,6 @@ xpc_process_connect(struct xpc_channel *
 }
 
 /*
- * Notify those who wanted to be notified upon delivery of their message.
- */
-static void
-xpc_notify_senders(struct xpc_channel *ch, enum xp_retval reason, s64 put)
-{
-	struct xpc_notify *notify;
-	u8 notify_type;
-	s64 get = ch->w_remote_GP.get - 1;
-
-	while (++get < put && atomic_read(&ch->n_to_notify) > 0) {
-
-		notify = &ch->notify_queue[get % ch->local_nentries];
-
-		/*
-		 * See if the notify entry indicates it was associated with
-		 * a message who's sender wants to be notified. It is possible
-		 * that it is, but someone else is doing or has done the
-		 * notification.
-		 */
-		notify_type = notify->type;
-		if (notify_type == 0 ||
-		    cmpxchg(&notify->type, notify_type, 0) != notify_type) {
-			continue;
-		}
-
-		DBUG_ON(notify_type != XPC_N_CALL);
-
-		atomic_dec(&ch->n_to_notify);
-
-		if (notify->func != NULL) {
-			dev_dbg(xpc_chan, "notify->func() called, notify=0x%p, "
-				"msg_number=%ld, partid=%d, channel=%d\n",
-				(void *)notify, get, ch->partid, ch->number);
-
-			notify->func(reason, ch->partid, ch->number,
-				     notify->key);
-
-			dev_dbg(xpc_chan, "notify->func() returned, "
-				"notify=0x%p, msg_number=%ld, partid=%d, "
-				"channel=%d\n", (void *)notify, get,
-				ch->partid, ch->number);
-		}
-	}
-}
-
-/*
  * Free up message queues and other stuff that were allocated for the specified
  * channel.
  *
@@ -275,6 +229,8 @@ xpc_notify_senders(struct xpc_channel *c
 static void
 xpc_free_msgqueues(struct xpc_channel *ch)
 {
+	struct xpc_channel_sn2 *ch_sn2 = &ch->sn.sn2;
+
 	DBUG_ON(!spin_is_locked(&ch->lock));
 	DBUG_ON(atomic_read(&ch->n_to_notify) != 0);
 
@@ -287,15 +243,15 @@ xpc_free_msgqueues(struct xpc_channel *c
 	ch->kthreads_assigned_limit = 0;
 	ch->kthreads_idle_limit = 0;
 
-	ch->local_GP->get = 0;
-	ch->local_GP->put = 0;
-	ch->remote_GP.get = 0;
-	ch->remote_GP.put = 0;
-	ch->w_local_GP.get = 0;
-	ch->w_local_GP.put = 0;
-	ch->w_remote_GP.get = 0;
-	ch->w_remote_GP.put = 0;
-	ch->next_msg_to_pull = 0;
+	ch_sn2->local_GP->get = 0;
+	ch_sn2->local_GP->put = 0;
+	ch_sn2->remote_GP.get = 0;
+	ch_sn2->remote_GP.put = 0;
+	ch_sn2->w_local_GP.get = 0;
+	ch_sn2->w_local_GP.put = 0;
+	ch_sn2->w_remote_GP.get = 0;
+	ch_sn2->w_remote_GP.put = 0;
+	ch_sn2->next_msg_to_pull = 0;
 
 	if (ch->flags & XPC_C_SETUP) {
 		ch->flags &= ~XPC_C_SETUP;
@@ -339,7 +295,7 @@ xpc_process_disconnect(struct xpc_channe
 
 	if (part->act_state == XPC_P_DEACTIVATING) {
 		/* can't proceed until the other side disengages from us */
-		if (xpc_partition_engaged(1UL << ch->partid))
+		if (xpc_partition_engaged(ch->partid))
 			return;
 
 	} else {
@@ -351,7 +307,7 @@ xpc_process_disconnect(struct xpc_channe
 
 		if (!(ch->flags & XPC_C_CLOSEREPLY)) {
 			ch->flags |= XPC_C_CLOSEREPLY;
-			xpc_IPI_send_closereply(ch, irq_flags);
+			xpc_send_channel_closereply(ch, irq_flags);
 		}
 
 		if (!(ch->flags & XPC_C_RCLOSEREPLY))
@@ -361,7 +317,7 @@ xpc_process_disconnect(struct xpc_channe
 	/* wake those waiting for notify completion */
 	if (atomic_read(&ch->n_to_notify) > 0) {
 		/* >>> we do callout while holding ch->lock */
-		xpc_notify_senders(ch, ch->reason, ch->w_local_GP.put);
+		xpc_notify_senders_of_disconnect(ch);
 	}
 
 	/* both sides are disconnected now */
@@ -734,7 +690,7 @@ xpc_connect_channel(struct xpc_channel *
 	/* initiate the connection */
 
 	ch->flags |= (XPC_C_OPENREQUEST | XPC_C_CONNECTING);
-	xpc_IPI_send_openrequest(ch, &irq_flags);
+	xpc_send_channel_openrequest(ch, &irq_flags);
 
 	xpc_process_connect(ch, &irq_flags);
 
@@ -743,142 +699,6 @@ xpc_connect_channel(struct xpc_channel *
 	return xpSuccess;
 }
 
-/*
- * Clear some of the msg flags in the local message queue.
- */
-static inline void
-xpc_clear_local_msgqueue_flags(struct xpc_channel *ch)
-{
-	struct xpc_msg *msg;
-	s64 get;
-
-	get = ch->w_remote_GP.get;
-	do {
-		msg = (struct xpc_msg *)((u64)ch->local_msgqueue +
-					 (get % ch->local_nentries) *
-					 ch->msg_size);
-		msg->flags = 0;
-	} while (++get < ch->remote_GP.get);
-}
-
-/*
- * Clear some of the msg flags in the remote message queue.
- */
-static inline void
-xpc_clear_remote_msgqueue_flags(struct xpc_channel *ch)
-{
-	struct xpc_msg *msg;
-	s64 put;
-
-	put = ch->w_remote_GP.put;
-	do {
-		msg = (struct xpc_msg *)((u64)ch->remote_msgqueue +
-					 (put % ch->remote_nentries) *
-					 ch->msg_size);
-		msg->flags = 0;
-	} while (++put < ch->remote_GP.put);
-}
-
-static void
-xpc_process_msg_IPI(struct xpc_partition *part, int ch_number)
-{
-	struct xpc_channel *ch = &part->channels[ch_number];
-	int nmsgs_sent;
-
-	ch->remote_GP = part->remote_GPs[ch_number];
-
-	/* See what, if anything, has changed for each connected channel */
-
-	xpc_msgqueue_ref(ch);
-
-	if (ch->w_remote_GP.get == ch->remote_GP.get &&
-	    ch->w_remote_GP.put == ch->remote_GP.put) {
-		/* nothing changed since GPs were last pulled */
-		xpc_msgqueue_deref(ch);
-		return;
-	}
-
-	if (!(ch->flags & XPC_C_CONNECTED)) {
-		xpc_msgqueue_deref(ch);
-		return;
-	}
-
-	/*
-	 * First check to see if messages recently sent by us have been
-	 * received by the other side. (The remote GET value will have
-	 * changed since we last looked at it.)
-	 */
-
-	if (ch->w_remote_GP.get != ch->remote_GP.get) {
-
-		/*
-		 * We need to notify any senders that want to be notified
-		 * that their sent messages have been received by their
-		 * intended recipients. We need to do this before updating
-		 * w_remote_GP.get so that we don't allocate the same message
-		 * queue entries prematurely (see xpc_allocate_msg()).
-		 */
-		if (atomic_read(&ch->n_to_notify) > 0) {
-			/*
-			 * Notify senders that messages sent have been
-			 * received and delivered by the other side.
-			 */
-			xpc_notify_senders(ch, xpMsgDelivered,
-					   ch->remote_GP.get);
-		}
-
-		/*
-		 * Clear msg->flags in previously sent messages, so that
-		 * they're ready for xpc_allocate_msg().
-		 */
-		xpc_clear_local_msgqueue_flags(ch);
-
-		ch->w_remote_GP.get = ch->remote_GP.get;
-
-		dev_dbg(xpc_chan, "w_remote_GP.get changed to %ld, partid=%d, "
-			"channel=%d\n", ch->w_remote_GP.get, ch->partid,
-			ch->number);
-
-		/*
-		 * If anyone was waiting for message queue entries to become
-		 * available, wake them up.
-		 */
-		if (atomic_read(&ch->n_on_msg_allocate_wq) > 0)
-			wake_up(&ch->msg_allocate_wq);
-	}
-
-	/*
-	 * Now check for newly sent messages by the other side. (The remote
-	 * PUT value will have changed since we last looked at it.)
-	 */
-
-	if (ch->w_remote_GP.put != ch->remote_GP.put) {
-		/*
-		 * Clear msg->flags in previously received messages, so that
-		 * they're ready for xpc_get_deliverable_msg().
-		 */
-		xpc_clear_remote_msgqueue_flags(ch);
-
-		ch->w_remote_GP.put = ch->remote_GP.put;
-
-		dev_dbg(xpc_chan, "w_remote_GP.put changed to %ld, partid=%d, "
-			"channel=%d\n", ch->w_remote_GP.put, ch->partid,
-			ch->number);
-
-		nmsgs_sent = ch->w_remote_GP.put - ch->w_local_GP.get;
-		if (nmsgs_sent > 0) {
-			dev_dbg(xpc_chan, "msgs waiting to be copied and "
-				"delivered=%d, partid=%d, channel=%d\n",
-				nmsgs_sent, ch->partid, ch->number);
-
-			if (ch->flags & XPC_C_CONNECTEDCALLOUT_MADE)
-				xpc_activate_kthreads(ch, nmsgs_sent);
-		}
-	}
-
-	xpc_msgqueue_deref(ch);
-}
-
 void
 xpc_process_channel_activity(struct xpc_partition *part)
 {
@@ -1117,7 +937,7 @@ xpc_disconnect_channel(const int line, s
 		       XPC_C_ROPENREQUEST | XPC_C_ROPENREPLY |
 		       XPC_C_CONNECTING | XPC_C_CONNECTED);
 
-	xpc_IPI_send_closerequest(ch, irq_flags);
+	xpc_send_channel_closerequest(ch, irq_flags);
 
 	if (channel_was_connected)
 		ch->flags |= XPC_C_WASCONNECTED;
Index: linux-2.6/drivers/misc/sgi-xp/xpc_main.c
===================================================================
--- linux-2.6.orig/drivers/misc/sgi-xp/xpc_main.c	2008-06-05 12:51:17.111799366 -0500
+++ linux-2.6/drivers/misc/sgi-xp/xpc_main.c	2008-06-06 08:10:50.969262778 -0500
@@ -26,7 +26,7 @@
  *	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
+ *	    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
@@ -89,9 +89,9 @@ static int xpc_hb_check_interval = XPC_H
 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;
+int xpc_disengage_timelimit = XPC_DISENGAGE_DEFAULT_TIMELIMIT;
+static int xpc_disengage_min_timelimit;	/* = 0 */
+static int xpc_disengage_max_timelimit = 120;
 
 static ctl_table xpc_sys_xpc_hb_dir[] = {
 	{
@@ -124,14 +124,14 @@ static ctl_table xpc_sys_xpc_dir[] = {
 	 .child = xpc_sys_xpc_hb_dir},
 	{
 	 .ctl_name = CTL_UNNUMBERED,
-	 .procname = "disengage_request_timelimit",
-	 .data = &xpc_disengage_request_timelimit,
+	 .procname = "disengage_timelimit",
+	 .data = &xpc_disengage_timelimit,
 	 .maxlen = sizeof(int),
 	 .mode = 0644,
 	 .proc_handler = &proc_dointvec_minmax,
 	 .strategy = &sysctl_intvec,
-	 .extra1 = &xpc_disengage_request_min_timelimit,
-	 .extra2 = &xpc_disengage_request_max_timelimit},
+	 .extra1 = &xpc_disengage_min_timelimit,
+	 .extra2 = &xpc_disengage_max_timelimit},
 	{}
 };
 static ctl_table xpc_sys_dir[] = {
@@ -144,8 +144,8 @@ static ctl_table xpc_sys_dir[] = {
 };
 static struct ctl_table_header *xpc_sysctl;
 
-/* non-zero if any remote partition disengage request was timed out */
-int xpc_disengage_request_timedout;
+/* non-zero if any remote partition disengage was timed out */
+int xpc_disengage_timedout;
 
 /* #of activate IRQs received */
 atomic_t xpc_activate_IRQ_rcvd = ATOMIC_INIT(0);
@@ -184,38 +184,36 @@ void (*xpc_online_heartbeat) (void);
 void (*xpc_check_remote_hb) (void);
 
 enum xp_retval (*xpc_make_first_contact) (struct xpc_partition *part);
+void (*xpc_notify_senders_of_disconnect) (struct xpc_channel *ch);
 u64 (*xpc_get_IPI_flags) (struct xpc_partition *part);
+void (*xpc_process_msg_IPI) (struct xpc_partition *part, int ch_number);
+int (*xpc_n_of_deliverable_msgs) (struct xpc_channel *ch);
 struct xpc_msg *(*xpc_get_deliverable_msg) (struct xpc_channel *ch);
 
-void (*xpc_initiate_partition_activation) (struct xpc_rsvd_page *remote_rp,
-					   u64 remote_rp_pa, int nasid);
+void (*xpc_request_partition_activation) (struct xpc_rsvd_page *remote_rp,
+					  u64 remote_rp_pa, int nasid);
+void (*xpc_request_partition_reactivation) (struct xpc_partition *part);
+void (*xpc_request_partition_deactivation) (struct xpc_partition *part);
+void (*xpc_cancel_partition_deactivation_request) (struct xpc_partition *part);
 
 void (*xpc_process_activate_IRQ_rcvd) (int n_IRQs_expected);
 enum xp_retval (*xpc_setup_infrastructure) (struct xpc_partition *part);
 void (*xpc_teardown_infrastructure) (struct xpc_partition *part);
 
-void (*xpc_mark_partition_engaged) (struct xpc_partition *part);
-void (*xpc_mark_partition_disengaged) (struct xpc_partition *part);
-void (*xpc_request_partition_disengage) (struct xpc_partition *part);
-void (*xpc_cancel_partition_disengage_request) (struct xpc_partition *part);
-u64 (*xpc_partition_engaged) (u64 partid_mask);
-u64 (*xpc_partition_disengage_requested) (u64 partid_mask);
-void (*xpc_clear_partition_engaged) (u64 partid_mask);
-void (*xpc_clear_partition_disengage_request) (u64 partid_mask);
-
-void (*xpc_IPI_send_local_activate) (int from_nasid);
-void (*xpc_IPI_send_activated) (struct xpc_partition *part);
-void (*xpc_IPI_send_local_reactivate) (int from_nasid);
-void (*xpc_IPI_send_disengage) (struct xpc_partition *part);
-
-void (*xpc_IPI_send_closerequest) (struct xpc_channel *ch,
-				   unsigned long *irq_flags);
-void (*xpc_IPI_send_closereply) (struct xpc_channel *ch,
-				 unsigned long *irq_flags);
-void (*xpc_IPI_send_openrequest) (struct xpc_channel *ch,
-				  unsigned long *irq_flags);
-void (*xpc_IPI_send_openreply) (struct xpc_channel *ch,
-				unsigned long *irq_flags);
+void (*xpc_indicate_partition_engaged) (struct xpc_partition *part);
+int (*xpc_partition_engaged) (short partid);
+int (*xpc_any_partition_engaged) (void);
+void (*xpc_indicate_partition_disengaged) (struct xpc_partition *part);
+void (*xpc_assume_partition_disengaged) (short partid);
+
+void (*xpc_send_channel_closerequest) (struct xpc_channel *ch,
+				       unsigned long *irq_flags);
+void (*xpc_send_channel_closereply) (struct xpc_channel *ch,
+				     unsigned long *irq_flags);
+void (*xpc_send_channel_openrequest) (struct xpc_channel *ch,
+				      unsigned long *irq_flags);
+void (*xpc_send_channel_openreply) (struct xpc_channel *ch,
+				    unsigned long *irq_flags);
 
 enum xp_retval (*xpc_send_msg) (struct xpc_channel *ch, u32 flags,
 				void *payload, u16 payload_size, u8 notify_type,
@@ -223,19 +221,19 @@ enum xp_retval (*xpc_send_msg) (struct x
 void (*xpc_received_msg) (struct xpc_channel *ch, struct xpc_msg *msg);
 
 /*
- * Timer function to enforce the timelimit on the partition disengage request.
+ * Timer function to enforce the timelimit on the partition disengage.
  */
 static void
-xpc_timeout_partition_disengage_request(unsigned long data)
+xpc_timeout_partition_disengage(unsigned long data)
 {
 	struct xpc_partition *part = (struct xpc_partition *)data;
 
-	DBUG_ON(time_is_after_jiffies(part->disengage_request_timeout));
+	DBUG_ON(time_is_after_jiffies(part->disengage_timeout));
 
 	(void)xpc_partition_disengaged(part);
 
-	DBUG_ON(part->disengage_request_timeout != 0);
-	DBUG_ON(xpc_partition_engaged(1UL << XPC_PARTID(part)) != 0);
+	DBUG_ON(part->disengage_timeout != 0);
+	DBUG_ON(xpc_partition_engaged(XPC_PARTID(part)));
 }
 
 /*
@@ -464,7 +462,7 @@ xpc_activating(void *__partid)
 
 	if (part->reason == xpReactivating) {
 		/* interrupting ourselves results in activating partition */
-		xpc_IPI_send_local_reactivate(part->reactivate_nasid);
+		xpc_request_partition_reactivation(part);
 	}
 
 	return 0;
@@ -496,82 +494,6 @@ xpc_activate_partition(struct xpc_partit
 	}
 }
 
-/*
- * Check to see if there is any channel activity to/from the specified
- * partition.
- */
-static void
-xpc_check_for_channel_activity(struct xpc_partition *part)
-{
-	u64 IPI_amo;
-	unsigned long irq_flags;
-
-/* this needs to be uncommented, but I'm thinking this function and the */
-/* ones that call it need to be moved into xpc_sn2.c... */
-	IPI_amo = 0; /* = xpc_IPI_receive(part->local_IPI_amo_va); */
-	if (IPI_amo == 0)
-		return;
-
-	spin_lock_irqsave(&part->IPI_lock, irq_flags);
-	part->local_IPI_amo |= IPI_amo;
-	spin_unlock_irqrestore(&part->IPI_lock, irq_flags);
-
-	dev_dbg(xpc_chan, "received IPI from partid=%d, IPI_amo=0x%lx\n",
-		XPC_PARTID(part), IPI_amo);
-
-	xpc_wakeup_channel_mgr(part);
-}
-
-/*
- * Handle the receipt of a SGI_XPC_NOTIFY IRQ by seeing whether the specified
- * partition actually sent it. Since SGI_XPC_NOTIFY IRQs may be shared by more
- * than one partition, we use an AMO_t structure per partition to indicate
- * whether a partition has sent an IPI or not.  If it has, then wake up the
- * associated kthread to handle it.
- *
- * All SGI_XPC_NOTIFY IRQs received by XPC are the result of IPIs sent by XPC
- * running on other partitions.
- *
- * Noteworthy Arguments:
- *
- *	irq - Interrupt ReQuest number. NOT USED.
- *
- *	dev_id - partid of IPI's potential sender.
- */
-irqreturn_t
-xpc_notify_IRQ_handler(int irq, void *dev_id)
-{
-	short partid = (short)(u64)dev_id;
-	struct xpc_partition *part = &xpc_partitions[partid];
-
-	DBUG_ON(partid < 0 || partid >= xp_max_npartitions);
-
-	if (xpc_part_ref(part)) {
-		xpc_check_for_channel_activity(part);
-
-		xpc_part_deref(part);
-	}
-	return IRQ_HANDLED;
-}
-
-/*
- * Check to see if xpc_notify_IRQ_handler() dropped any IPIs on the floor
- * because the write to their associated IPI amo completed after the IRQ/IPI
- * was received.
- */
-void
-xpc_dropped_IPI_check(struct xpc_partition *part)
-{
-	if (xpc_part_ref(part)) {
-		xpc_check_for_channel_activity(part);
-
-		part->dropped_IPI_timer.expires = jiffies +
-		    XPC_P_DROPPED_IPI_WAIT_INTERVAL;
-		add_timer(&part->dropped_IPI_timer);
-		xpc_part_deref(part);
-	}
-}
-
 void
 xpc_activate_kthreads(struct xpc_channel *ch, int needed)
 {
@@ -616,7 +538,7 @@ xpc_kthread_waitmsgs(struct xpc_partitio
 	do {
 		/* deliver messages to their intended recipients */
 
-		while (ch->w_local_GP.get < ch->w_remote_GP.put &&
+		while (xpc_n_of_deliverable_msgs(ch) > 0 &&
 		       !(ch->flags & XPC_C_DISCONNECTING)) {
 			xpc_deliver_msg(ch);
 		}
@@ -632,7 +554,7 @@ xpc_kthread_waitmsgs(struct xpc_partitio
 			"wait_event_interruptible_exclusive()\n");
 
 		(void)wait_event_interruptible_exclusive(ch->idle_wq,
-				(ch->w_local_GP.get < ch->w_remote_GP.put ||
+				(xpc_n_of_deliverable_msgs(ch) > 0 ||
 				 (ch->flags & XPC_C_DISCONNECTING)));
 
 		atomic_dec(&ch->kthreads_idle);
@@ -677,7 +599,7 @@ xpc_kthread_start(void *args)
 			 * additional kthreads to help deliver them. We only
 			 * need one less than total #of messages to deliver.
 			 */
-			n_needed = ch->w_remote_GP.put - ch->w_local_GP.get - 1;
+			n_needed = xpc_n_of_deliverable_msgs(ch) - 1;
 			if (n_needed > 0 && !(ch->flags & XPC_C_DISCONNECTING))
 				xpc_activate_kthreads(ch, n_needed);
 
@@ -703,11 +625,9 @@ xpc_kthread_start(void *args)
 	}
 	spin_unlock_irqrestore(&ch->lock, irq_flags);
 
-	if (atomic_dec_return(&ch->kthreads_assigned) == 0) {
-		if (atomic_dec_return(&part->nchannels_engaged) == 0) {
-			xpc_mark_partition_disengaged(part);
-			xpc_IPI_send_disengage(part);
-		}
+	if (atomic_dec_return(&ch->kthreads_assigned) == 0 &&
+	    atomic_dec_return(&part->nchannels_engaged) == 0) {
+		xpc_indicate_partition_disengaged(part);
 	}
 
 	xpc_msgqueue_deref(ch);
@@ -758,9 +678,9 @@ xpc_create_kthreads(struct xpc_channel *
 		} else if (ch->flags & XPC_C_DISCONNECTING) {
 			break;
 
-		} else if (atomic_inc_return(&ch->kthreads_assigned) == 1) {
-			if (atomic_inc_return(&part->nchannels_engaged) == 1)
-				xpc_mark_partition_engaged(part);
+		} else if (atomic_inc_return(&ch->kthreads_assigned) == 1 &&
+			   atomic_inc_return(&part->nchannels_engaged) == 1) {
+				xpc_indicate_partition_engaged(part);
 		}
 		(void)xpc_part_ref(part);
 		xpc_msgqueue_ref(ch);
@@ -782,8 +702,7 @@ xpc_create_kthreads(struct xpc_channel *
 
 			if (atomic_dec_return(&ch->kthreads_assigned) == 0 &&
 			    atomic_dec_return(&part->nchannels_engaged) == 0) {
-				xpc_mark_partition_disengaged(part);
-				xpc_IPI_send_disengage(part);
+				xpc_indicate_partition_disengaged(part);
 			}
 			xpc_msgqueue_deref(ch);
 			xpc_part_deref(part);
@@ -862,7 +781,7 @@ xpc_do_exit(enum xp_retval reason)
 	short partid;
 	int active_part_count, printed_waiting_msg = 0;
 	struct xpc_partition *part;
-	unsigned long printmsg_time, disengage_request_timeout = 0;
+	unsigned long printmsg_time, disengage_timeout = 0;
 
 	/* a 'rmmod XPC' and a 'reboot' cannot both end up here together */
 	DBUG_ON(xpc_exiting == 1);
@@ -886,8 +805,8 @@ xpc_do_exit(enum xp_retval reason)
 
 	/* wait for all partitions to become inactive */
 
-	printmsg_time = jiffies + (XPC_DISENGAGE_PRINTMSG_INTERVAL * HZ);
-	xpc_disengage_request_timedout = 0;
+	printmsg_time = jiffies + (XPC_DEACTIVATE_PRINTMSG_INTERVAL * HZ);
+	xpc_disengage_timedout = 0;
 
 	do {
 		active_part_count = 0;
@@ -904,36 +823,32 @@ xpc_do_exit(enum xp_retval reason)
 
 			XPC_DEACTIVATE_PARTITION(part, reason);
 
-			if (part->disengage_request_timeout >
-			    disengage_request_timeout) {
-				disengage_request_timeout =
-				    part->disengage_request_timeout;
-			}
+			if (part->disengage_timeout > disengage_timeout)
+				disengage_timeout = part->disengage_timeout;
 		}
 
-		if (xpc_partition_engaged(-1UL)) {
+		if (xpc_any_partition_engaged()) {
 			if (time_is_before_jiffies(printmsg_time)) {
 				dev_info(xpc_part, "waiting for remote "
-					 "partitions to disengage, timeout in "
-					 "%ld seconds\n",
-					 (disengage_request_timeout - jiffies)
-					 / HZ);
+					 "partitions to deactivate, timeout in "
+					 "%ld seconds\n", (disengage_timeout -
+					 jiffies) / HZ);
 				printmsg_time = jiffies +
-				    (XPC_DISENGAGE_PRINTMSG_INTERVAL * HZ);
+				    (XPC_DEACTIVATE_PRINTMSG_INTERVAL * HZ);
 				printed_waiting_msg = 1;
 			}
 
 		} else if (active_part_count > 0) {
 			if (printed_waiting_msg) {
 				dev_info(xpc_part, "waiting for local partition"
-					 " to disengage\n");
+					 " to deactivate\n");
 				printed_waiting_msg = 0;
 			}
 
 		} else {
-			if (!xpc_disengage_request_timedout) {
+			if (!xpc_disengage_timedout) {
 				dev_info(xpc_part, "all partitions have "
-					 "disengaged\n");
+					 "deactivated\n");
 			}
 			break;
 		}
@@ -943,7 +858,7 @@ xpc_do_exit(enum xp_retval reason)
 
 	} while (1);
 
-	DBUG_ON(xpc_partition_engaged(-1UL));
+	DBUG_ON(xpc_any_partition_engaged());
 	DBUG_ON(xpc_any_hbs_allowed() != 0);
 
 	/* indicate to others that our reserved page is uninitialized */
@@ -996,15 +911,16 @@ xpc_system_reboot(struct notifier_block 
 }
 
 /*
- * Notify other partitions to disengage from all references to our memory.
+ * Notify other partitions to deactivate from us by first disengaging from all
+ * references to our memory.
  */
 static void
-xpc_die_disengage(void)
+xpc_die_deactivate(void)
 {
 	struct xpc_partition *part;
 	short partid;
-	unsigned long engaged;
-	long time, printmsg_time, disengage_request_timeout;
+	int any_engaged;
+	long time, printmsg_time, disengage_timeout;
 
 	/* keep xpc_hb_checker thread from doing anything (just in case) */
 	xpc_exiting = 1;
@@ -1014,43 +930,37 @@ xpc_die_disengage(void)
 	for (partid = 0; partid < xp_max_npartitions; partid++) {
 		part = &xpc_partitions[partid];
 
-		if (!XPC_SUPPORTS_DISENGAGE_REQUEST(part->
-		    remote_vars_version)) {
-
-			/* just in case it was left set by an earlier XPC */
-			xpc_clear_partition_engaged(1UL << partid);
-			continue;
-		}
-
-		if (xpc_partition_engaged(1UL << partid) ||
+		if (xpc_partition_engaged(partid) ||
 		    part->act_state != XPC_P_INACTIVE) {
-			xpc_request_partition_disengage(part);
-			xpc_mark_partition_disengaged(part);
-			xpc_IPI_send_disengage(part);
+			xpc_request_partition_deactivation(part);
+			xpc_indicate_partition_disengaged(part);
 		}
 	}
 
 	time = rtc_time();
 	printmsg_time = time +
-	    (XPC_DISENGAGE_PRINTMSG_INTERVAL * sn_rtc_cycles_per_second);
-	disengage_request_timeout = time +
-	    (xpc_disengage_request_timelimit * sn_rtc_cycles_per_second);
+	    (XPC_DEACTIVATE_PRINTMSG_INTERVAL * sn_rtc_cycles_per_second);
+	disengage_timeout = time +
+	    (xpc_disengage_timelimit * sn_rtc_cycles_per_second);
 
-	/* wait for all other partitions to disengage from us */
+	/*
+	 * Though we requested that all other partitions deactivate from us,
+	 * we only wait until they've all disengaged.
+	 */
 
 	while (1) {
-		engaged = xpc_partition_engaged(-1UL);
-		if (!engaged) {
-			dev_info(xpc_part, "all partitions have disengaged\n");
+		any_engaged = xpc_any_partition_engaged();
+		if (!any_engaged) {
+			dev_info(xpc_part, "all partitions have deactivated\n");
 			break;
 		}
 
 		time = rtc_time();
-		if (time >= disengage_request_timeout) {
+		if (time >= disengage_timeout) {
 			for (partid = 0; partid < xp_max_npartitions;
 			     partid++) {
-				if (engaged & (1UL << partid)) {
-					dev_info(xpc_part, "disengage from "
+				if (xpc_partition_engaged(partid)) {
+					dev_info(xpc_part, "deactivate from "
 						 "remote partition %d timed "
 						 "out\n", partid);
 				}
@@ -1060,11 +970,11 @@ xpc_die_disengage(void)
 
 		if (time >= printmsg_time) {
 			dev_info(xpc_part, "waiting for remote partitions to "
-				 "disengage, timeout in %ld seconds\n",
-				 (disengage_request_timeout - time) /
+				 "deactivate, timeout in %ld seconds\n",
+				 (disengage_timeout - time) /
 				 sn_rtc_cycles_per_second);
 			printmsg_time = time +
-			    (XPC_DISENGAGE_PRINTMSG_INTERVAL *
+			    (XPC_DEACTIVATE_PRINTMSG_INTERVAL *
 			     sn_rtc_cycles_per_second);
 		}
 	}
@@ -1084,7 +994,7 @@ xpc_system_die(struct notifier_block *nb
 	switch (event) {
 	case DIE_MACHINE_RESTART:
 	case DIE_MACHINE_HALT:
-		xpc_die_disengage();
+		xpc_die_deactivate();
 		break;
 
 	case DIE_KDEBUG_ENTER:
@@ -1183,10 +1093,10 @@ xpc_init(void)
 		part->act_state = XPC_P_INACTIVE;
 		XPC_SET_REASON(part, 0, 0);
 
-		init_timer(&part->disengage_request_timer);
-		part->disengage_request_timer.function =
-		    xpc_timeout_partition_disengage_request;
-		part->disengage_request_timer.data = (unsigned long)part;
+		init_timer(&part->disengage_timer);
+		part->disengage_timer.function =
+		    xpc_timeout_partition_disengage;
+		part->disengage_timer.data = (unsigned long)part;
 
 		part->setup_state = XPC_P_UNSET;
 		init_waitqueue_head(&part->teardown_wq);
@@ -1295,9 +1205,9 @@ module_param(xpc_hb_check_interval, int,
 MODULE_PARM_DESC(xpc_hb_check_interval, "Number of seconds between "
 		 "heartbeat checks.");
 
-module_param(xpc_disengage_request_timelimit, int, 0);
-MODULE_PARM_DESC(xpc_disengage_request_timelimit, "Number of seconds to wait "
-		 "for disengage request to complete.");
+module_param(xpc_disengage_timelimit, int, 0);
+MODULE_PARM_DESC(xpc_disengage_timelimit, "Number of seconds to wait "
+		 "for disengage to complete.");
 
 module_param(xpc_kdebug_ignore, int, 0);
 MODULE_PARM_DESC(xpc_kdebug_ignore, "Should lack of heartbeat be ignored by "
Index: linux-2.6/drivers/misc/sgi-xp/xpc_sn2.c
===================================================================
--- linux-2.6.orig/drivers/misc/sgi-xp/xpc_sn2.c	2008-06-05 12:51:17.151804361 -0500
+++ linux-2.6/drivers/misc/sgi-xp/xpc_sn2.c	2008-06-06 08:10:50.973263248 -0500
@@ -196,37 +196,85 @@ xpc_activate_IRQ_send_local_sn2(int from
 	wake_up_interruptible(&xpc_activate_IRQ_wq);
 }
 
-static void
-xpc_IPI_send_local_activate_sn2(int from_nasid)
-{
-	xpc_activate_IRQ_send_local_sn2(from_nasid);
-}
+/*
+ * IPIs associated with SGI_XPC_NOTIFY IRQ.
+ */
 
+/*
+ * Check to see if there is any channel activity to/from the specified
+ * partition.
+ */
 static void
-xpc_IPI_send_activated_sn2(struct xpc_partition *part)
+xpc_check_for_channel_activity_sn2(struct xpc_partition *part)
 {
-	xpc_activate_IRQ_send_sn2(part->remote_amos_page_pa,
-				  cnodeid_to_nasid(0), part->remote_act_nasid,
-				  part->remote_act_phys_cpuid);
-}
+	u64 IPI_amo;
+	unsigned long irq_flags;
 
-static void
-xpc_IPI_send_local_reactivate_sn2(int from_nasid)
-{
-	xpc_activate_IRQ_send_local_sn2(from_nasid);
+	IPI_amo = xpc_IPI_receive_sn2(part->sn.sn2.local_IPI_amo_va);
+	if (IPI_amo == 0)
+		return;
+
+	spin_lock_irqsave(&part->IPI_lock, irq_flags);
+	part->local_IPI_amo |= IPI_amo;
+	spin_unlock_irqrestore(&part->IPI_lock, irq_flags);
+
+	dev_dbg(xpc_chan, "received IPI from partid=%d, IPI_amo=0x%lx\n",
+		XPC_PARTID(part), IPI_amo);
+
+	xpc_wakeup_channel_mgr(part);
 }
 
-static void
-xpc_IPI_send_disengage_sn2(struct xpc_partition *part)
+/*
+ * Handle the receipt of a SGI_XPC_NOTIFY IRQ by seeing whether the specified
+ * partition actually sent it. Since SGI_XPC_NOTIFY IRQs may be shared by more
+ * than one partition, we use an AMO_t structure per partition to indicate
+ * whether a partition has sent an IPI or not.  If it has, then wake up the
+ * associated kthread to handle it.
+ *
+ * All SGI_XPC_NOTIFY IRQs received by XPC are the result of IPIs sent by XPC
+ * running on other partitions.
+ *
+ * Noteworthy Arguments:
+ *
+ *	irq - Interrupt ReQuest number. NOT USED.
+ *
+ *	dev_id - partid of IPI's potential sender.
+ */
+static irqreturn_t
+xpc_handle_notify_IRQ_sn2(int irq, void *dev_id)
 {
-	xpc_activate_IRQ_send_sn2(part->remote_amos_page_pa,
-				  cnodeid_to_nasid(0), part->remote_act_nasid,
-				  part->remote_act_phys_cpuid);
+	short partid = (short)(u64)dev_id;
+	struct xpc_partition *part = &xpc_partitions[partid];
+
+	DBUG_ON(partid < 0 || partid >= xp_max_npartitions);
+
+	if (xpc_part_ref(part)) {
+		xpc_check_for_channel_activity_sn2(part);
+
+		xpc_part_deref(part);
+	}
+	return IRQ_HANDLED;
 }
 
 /*
- * IPIs associated with SGI_XPC_NOTIFY IRQ.
+ * Check to see if xpc_handle_notify_IRQ_sn2() dropped any IPIs on the floor
+ * because the write to their associated IPI amo completed after the IRQ/IPI
+ * was received.
  */
+static void
+xpc_dropped_notify_IRQ_check_sn2(struct xpc_partition *part)
+{
+	struct xpc_partition_sn2 *part_sn2 = &part->sn.sn2;
+
+	if (xpc_part_ref(part)) {
+		xpc_check_for_channel_activity_sn2(part);
+
+		part_sn2->dropped_notify_IRQ_timer.expires = jiffies +
+		    XPC_P_DROPPED_IPI_WAIT_INTERVAL;
+		add_timer(&part_sn2->dropped_notify_IRQ_timer);
+		xpc_part_deref(part);
+	}
+}
 
 /*
  * Send an IPI to the remote partition that is associated with the
@@ -237,13 +285,14 @@ xpc_notify_IRQ_send_sn2(struct xpc_chann
 			char *ipi_flag_string, unsigned long *irq_flags)
 {
 	struct xpc_partition *part = &xpc_partitions[ch->partid];
+	struct xpc_partition_sn2 *part_sn2 = &part->sn.sn2;
 	enum xp_retval ret;
 
 	if (likely(part->act_state != XPC_P_DEACTIVATING)) {
-		ret = xpc_IPI_send_sn2(part->remote_IPI_amo_va,
+		ret = xpc_IPI_send_sn2(part_sn2->remote_IPI_amo_va,
 				       (u64)ipi_flag << (ch->number * 8),
-				       part->remote_IPI_nasid,
-				       part->remote_IPI_phys_cpuid,
+				       part_sn2->remote_IPI_nasid,
+				       part_sn2->remote_IPI_phys_cpuid,
 				       SGI_XPC_NOTIFY);
 		dev_dbg(xpc_chan, "%s sent to partid=%d, channel=%d, ret=%d\n",
 			ipi_flag_string, ch->partid, ch->number, ret);
@@ -263,7 +312,7 @@ xpc_notify_IRQ_send_sn2(struct xpc_chann
 /*
  * Make it look like the remote partition, which is associated with the
  * specified channel, sent us an IPI. This faked IPI will be handled
- * by xpc_dropped_IPI_check().
+ * by xpc_dropped_notify_IRQ_check_sn2().
  */
 static void
 xpc_notify_IRQ_send_local_sn2(struct xpc_channel *ch, u8 ipi_flag,
@@ -271,7 +320,7 @@ xpc_notify_IRQ_send_local_sn2(struct xpc
 {
 	struct xpc_partition *part = &xpc_partitions[ch->partid];
 
-	FETCHOP_STORE_OP(TO_AMO((u64)&part->local_IPI_amo_va->variable),
+	FETCHOP_STORE_OP(TO_AMO((u64)&part->sn.sn2.local_IPI_amo_va->variable),
 			 FETCHOP_OR, ((u64)ipi_flag << (ch->number * 8)));
 	dev_dbg(xpc_chan, "%s sent local from partid=%d, channel=%d\n",
 		ipi_flag_string, ch->partid, ch->number);
@@ -281,7 +330,8 @@ xpc_notify_IRQ_send_local_sn2(struct xpc
 		xpc_notify_IRQ_send_local_sn2(_ch, _ipi_f, #_ipi_f)
 
 static void
-xpc_IPI_send_closerequest_sn2(struct xpc_channel *ch, unsigned long *irq_flags)
+xpc_send_channel_closerequest_sn2(struct xpc_channel *ch,
+				  unsigned long *irq_flags)
 {
 	struct xpc_openclose_args *args = ch->local_openclose_args;
 
@@ -290,13 +340,15 @@ xpc_IPI_send_closerequest_sn2(struct xpc
 }
 
 static void
-xpc_IPI_send_closereply_sn2(struct xpc_channel *ch, unsigned long *irq_flags)
+xpc_send_channel_closereply_sn2(struct xpc_channel *ch,
+				unsigned long *irq_flags)
 {
 	XPC_NOTIFY_IRQ_SEND_SN2(ch, XPC_IPI_CLOSEREPLY, irq_flags);
 }
 
 static void
-xpc_IPI_send_openrequest_sn2(struct xpc_channel *ch, unsigned long *irq_flags)
+xpc_send_channel_openrequest_sn2(struct xpc_channel *ch,
+				 unsigned long *irq_flags)
 {
 	struct xpc_openclose_args *args = ch->local_openclose_args;
 
@@ -306,7 +358,7 @@ xpc_IPI_send_openrequest_sn2(struct xpc_
 }
 
 static void
-xpc_IPI_send_openreply_sn2(struct xpc_channel *ch, unsigned long *irq_flags)
+xpc_send_channel_openreply_sn2(struct xpc_channel *ch, unsigned long *irq_flags)
 {
 	struct xpc_openclose_args *args = ch->local_openclose_args;
 
@@ -317,13 +369,13 @@ xpc_IPI_send_openreply_sn2(struct xpc_ch
 }
 
 static void
-xpc_IPI_send_msgrequest_sn2(struct xpc_channel *ch)
+xpc_send_channel_msgrequest_sn2(struct xpc_channel *ch)
 {
 	XPC_NOTIFY_IRQ_SEND_SN2(ch, XPC_IPI_MSGREQUEST, NULL);
 }
 
 static void
-xpc_IPI_send_local_msgrequest_sn2(struct xpc_channel *ch)
+xpc_send_channel_local_msgrequest_sn2(struct xpc_channel *ch)
 {
 	XPC_NOTIFY_IRQ_SEND_LOCAL_SN2(ch, XPC_IPI_MSGREQUEST);
 }
@@ -334,10 +386,10 @@ xpc_IPI_send_local_msgrequest_sn2(struct
  */
 
 static void
-xpc_mark_partition_engaged_sn2(struct xpc_partition *part)
+xpc_indicate_partition_engaged_sn2(struct xpc_partition *part)
 {
 	unsigned long irq_flags;
-	AMO_t *amo = (AMO_t *)__va(part->remote_amos_page_pa +
+	AMO_t *amo = (AMO_t *)__va(part->sn.sn2.remote_amos_page_pa +
 				   (XPC_ENGAGED_PARTITIONS_AMO *
 				    sizeof(AMO_t)));
 
@@ -360,10 +412,11 @@ xpc_mark_partition_engaged_sn2(struct xp
 }
 
 static void
-xpc_mark_partition_disengaged_sn2(struct xpc_partition *part)
+xpc_indicate_partition_disengaged_sn2(struct xpc_partition *part)
 {
+	struct xpc_partition_sn2 *part_sn2 = &part->sn.sn2;
 	unsigned long irq_flags;
-	AMO_t *amo = (AMO_t *)__va(part->remote_amos_page_pa +
+	AMO_t *amo = (AMO_t *)__va(part_sn2->remote_amos_page_pa +
 				   (XPC_ENGAGED_PARTITIONS_AMO *
 				    sizeof(AMO_t)));
 
@@ -383,96 +436,44 @@ xpc_mark_partition_disengaged_sn2(struct
 						     xp_nofault_PIOR_target));
 
 	local_irq_restore(irq_flags);
-}
-
-static void
-xpc_request_partition_disengage_sn2(struct xpc_partition *part)
-{
-	unsigned long irq_flags;
-	AMO_t *amo = (AMO_t *)__va(part->remote_amos_page_pa +
-				   (XPC_DISENGAGE_REQUEST_AMO * sizeof(AMO_t)));
-
-	local_irq_save(irq_flags);
-
-	/* set bit corresponding to our partid in remote partition's AMO */
-	FETCHOP_STORE_OP(TO_AMO((u64)&amo->variable), FETCHOP_OR,
-			 (1UL << sn_partition_id));
-	/*
-	 * We must always use the nofault function regardless of whether we
-	 * are on a Shub 1.1 system or a Shub 1.2 slice 0xc processor. If we
-	 * didn't, we'd never know that the other partition is down and would
-	 * keep sending IPIs and AMOs to it until the heartbeat times out.
-	 */
-	(void)xp_nofault_PIOR((u64 *)GLOBAL_MMR_ADDR(NASID_GET(&amo->
-							       variable),
-						     xp_nofault_PIOR_target));
-
-	local_irq_restore(irq_flags);
-}
 
-static void
-xpc_cancel_partition_disengage_request_sn2(struct xpc_partition *part)
-{
-	unsigned long irq_flags;
-	AMO_t *amo = (AMO_t *)__va(part->remote_amos_page_pa +
-				   (XPC_DISENGAGE_REQUEST_AMO * sizeof(AMO_t)));
-
-	local_irq_save(irq_flags);
-
-	/* clear bit corresponding to our partid in remote partition's AMO */
-	FETCHOP_STORE_OP(TO_AMO((u64)&amo->variable), FETCHOP_AND,
-			 ~(1UL << sn_partition_id));
 	/*
-	 * We must always use the nofault function regardless of whether we
-	 * are on a Shub 1.1 system or a Shub 1.2 slice 0xc processor. If we
-	 * didn't, we'd never know that the other partition is down and would
-	 * keep sending IPIs and AMOs to it until the heartbeat times out.
+	 * Send activate IRQ to get other side to see that we've cleared our
+	 * bit in their engaged partitions AMO.
 	 */
-	(void)xp_nofault_PIOR((u64 *)GLOBAL_MMR_ADDR(NASID_GET(&amo->
-							       variable),
-						     xp_nofault_PIOR_target));
-
-	local_irq_restore(irq_flags);
+	xpc_activate_IRQ_send_sn2(part_sn2->remote_amos_page_pa,
+				  cnodeid_to_nasid(0),
+				  part_sn2->activate_IRQ_nasid,
+				  part_sn2->activate_IRQ_phys_cpuid);
 }
 
-static u64
-xpc_partition_engaged_sn2(u64 partid_mask)
+static int
+xpc_partition_engaged_sn2(short partid)
 {
 	AMO_t *amo = xpc_vars->amos_page + XPC_ENGAGED_PARTITIONS_AMO;
 
-	/* return our partition's AMO variable ANDed with partid_mask */
+	/* our partition's AMO variable ANDed with partid mask */
 	return (FETCHOP_LOAD_OP(TO_AMO((u64)&amo->variable), FETCHOP_LOAD) &
-		partid_mask);
+		(1UL << partid)) != 0;
 }
 
-static u64
-xpc_partition_disengage_requested_sn2(u64 partid_mask)
-{
-	AMO_t *amo = xpc_vars->amos_page + XPC_DISENGAGE_REQUEST_AMO;
-
-	/* return our partition's AMO variable ANDed with partid_mask */
-	return (FETCHOP_LOAD_OP(TO_AMO((u64)&amo->variable), FETCHOP_LOAD) &
-		partid_mask);
-}
-
-static void
-xpc_clear_partition_engaged_sn2(u64 partid_mask)
+static int
+xpc_any_partition_engaged_sn2(void)
 {
 	AMO_t *amo = xpc_vars->amos_page + XPC_ENGAGED_PARTITIONS_AMO;
 
-	/* clear bit(s) based on partid_mask in our partition's AMO */
-	FETCHOP_STORE_OP(TO_AMO((u64)&amo->variable), FETCHOP_AND,
-			 ~partid_mask);
+	/* our partition's AMO variable */
+	return FETCHOP_LOAD_OP(TO_AMO((u64)&amo->variable), FETCHOP_LOAD) != 0;
 }
 
 static void
-xpc_clear_partition_disengage_request_sn2(u64 partid_mask)
+xpc_assume_partition_disengaged_sn2(short partid)
 {
-	AMO_t *amo = xpc_vars->amos_page + XPC_DISENGAGE_REQUEST_AMO;
+	AMO_t *amo = xpc_vars->amos_page + XPC_ENGAGED_PARTITIONS_AMO;
 
-	/* clear bit(s) based on partid_mask in our partition's AMO */
+	/* clear bit(s) based on partid mask in our partition's AMO */
 	FETCHOP_STORE_OP(TO_AMO((u64)&amo->variable), FETCHOP_AND,
-			 ~partid_mask);
+			 ~(1UL << partid));
 }
 
 /* original protection values for each node */
@@ -545,7 +546,6 @@ xpc_rsvd_page_init_sn2(struct xpc_rsvd_p
 	xpc_vars_part = (struct xpc_vars_part_sn2 *)((u8 *)XPC_RP_VARS(rp) +
 						     XPC_RP_VARS_SIZE);
 
-
 	/*
 	 * Before clearing xpc_vars, see if a page of AMOs had been previously
 	 * allocated. If not we'll need to allocate one and set permissions
@@ -583,8 +583,8 @@ xpc_rsvd_page_init_sn2(struct xpc_rsvd_p
 	memset(xpc_vars, 0, sizeof(struct xpc_vars_sn2));
 
 	xpc_vars->version = XPC_V_VERSION;
-	xpc_vars->act_nasid = cpuid_to_nasid(0);
-	xpc_vars->act_phys_cpuid = cpu_physical_id(0);
+	xpc_vars->activate_IRQ_nasid = cpuid_to_nasid(0);
+	xpc_vars->activate_IRQ_phys_cpuid = cpu_physical_id(0);
 	xpc_vars->vars_part_pa = __pa(xpc_vars_part);
 	xpc_vars->amos_page_pa = ia64_tpa((u64)amos_page);
 	xpc_vars->amos_page = amos_page;	/* save for next load of XPC */
@@ -599,7 +599,7 @@ xpc_rsvd_page_init_sn2(struct xpc_rsvd_p
 
 	/* initialize the engaged remote partitions related AMO variables */
 	(void)xpc_IPI_init_sn2(XPC_ENGAGED_PARTITIONS_AMO);
-	(void)xpc_IPI_init_sn2(XPC_DISENGAGE_REQUEST_AMO);
+	(void)xpc_IPI_init_sn2(XPC_DEACTIVATE_REQUEST_AMO);
 
 	return xpSuccess;
 }
@@ -671,7 +671,7 @@ xpc_check_remote_hb_sn2(void)
 
 		/* pull the remote_hb cache line */
 		ret = xp_remote_memcpy(remote_vars,
-				       (void *)part->remote_vars_pa,
+				       (void *)part->sn.sn2.remote_vars_pa,
 				       XPC_RP_VARS_SIZE);
 		if (ret != xpSuccess) {
 			XPC_DEACTIVATE_PARTITION(part, ret);
@@ -726,10 +726,86 @@ xpc_get_remote_vars_sn2(u64 remote_vars_
 }
 
 static void
-xpc_initiate_partition_activation_sn2(struct xpc_rsvd_page *remote_rp,
-				      u64 remote_rp_pa, int nasid)
+xpc_request_partition_activation_sn2(struct xpc_rsvd_page *remote_rp,
+				     u64 remote_rp_pa, int nasid)
 {
-	xpc_IPI_send_local_activate(nasid);
+	xpc_activate_IRQ_send_local_sn2(nasid);
+}
+
+static void
+xpc_request_partition_reactivation_sn2(struct xpc_partition *part)
+{
+	xpc_activate_IRQ_send_local_sn2(part->sn.sn2.activate_IRQ_nasid);
+}
+
+static void
+xpc_request_partition_deactivation_sn2(struct xpc_partition *part)
+{
+	struct xpc_partition_sn2 *part_sn2 = &part->sn.sn2;
+	unsigned long irq_flags;
+	AMO_t *amo = (AMO_t *)__va(part_sn2->remote_amos_page_pa +
+				  (XPC_DEACTIVATE_REQUEST_AMO * sizeof(AMO_t)));
+
+	local_irq_save(irq_flags);
+
+	/* set bit corresponding to our partid in remote partition's AMO */
+	FETCHOP_STORE_OP(TO_AMO((u64)&amo->variable), FETCHOP_OR,
+			 (1UL << sn_partition_id));
+	/*
+	 * We must always use the nofault function regardless of whether we
+	 * are on a Shub 1.1 system or a Shub 1.2 slice 0xc processor. If we
+	 * didn't, we'd never know that the other partition is down and would
+	 * keep sending IPIs and AMOs to it until the heartbeat times out.
+	 */
+	(void)xp_nofault_PIOR((u64 *)GLOBAL_MMR_ADDR(NASID_GET(&amo->
+							       variable),
+						     xp_nofault_PIOR_target));
+
+	local_irq_restore(irq_flags);
+
+	/*
+	 * Send activate IRQ to get other side to see that we've set our
+	 * bit in their deactivate request AMO.
+	 */
+	xpc_activate_IRQ_send_sn2(part_sn2->remote_amos_page_pa,
+				  cnodeid_to_nasid(0),
+				  part_sn2->activate_IRQ_nasid,
+				  part_sn2->activate_IRQ_phys_cpuid);
+}
+
+static void
+xpc_cancel_partition_deactivation_request_sn2(struct xpc_partition *part)
+{
+	unsigned long irq_flags;
+	AMO_t *amo = (AMO_t *)__va(part->sn.sn2.remote_amos_page_pa +
+				  (XPC_DEACTIVATE_REQUEST_AMO * sizeof(AMO_t)));
+
+	local_irq_save(irq_flags);
+
+	/* clear bit corresponding to our partid in remote partition's AMO */
+	FETCHOP_STORE_OP(TO_AMO((u64)&amo->variable), FETCHOP_AND,
+			 ~(1UL << sn_partition_id));
+	/*
+	 * We must always use the nofault function regardless of whether we
+	 * are on a Shub 1.1 system or a Shub 1.2 slice 0xc processor. If we
+	 * didn't, we'd never know that the other partition is down and would
+	 * keep sending IPIs and AMOs to it until the heartbeat times out.
+	 */
+	(void)xp_nofault_PIOR((u64 *)GLOBAL_MMR_ADDR(NASID_GET(&amo->
+							       variable),
+						     xp_nofault_PIOR_target));
+
+	local_irq_restore(irq_flags);
+}
+
+static int
+xpc_partition_deactivation_requested_sn2(short partid)
+{
+	AMO_t *amo = xpc_vars->amos_page + XPC_DEACTIVATE_REQUEST_AMO;
+
+	/* our partition's AMO variable ANDed with partid mask */
+	return (FETCHOP_LOAD_OP(TO_AMO((u64)&amo->variable), FETCHOP_LOAD) &
+		(1UL << partid)) != 0;
 }
 
 /*
@@ -741,6 +817,8 @@ xpc_update_partition_info_sn2(struct xpc
 			      u64 remote_vars_pa,
 			      struct xpc_vars_sn2 *remote_vars)
 {
+	struct xpc_partition_sn2 *part_sn2 = &part->sn.sn2;
+
 	part->remote_rp_version = remote_rp_version;
 	dev_dbg(xpc_part, "  remote_rp_version = 0x%016x\n",
 		part->remote_rp_version);
@@ -752,33 +830,34 @@ xpc_update_partition_info_sn2(struct xpc
 	part->remote_rp_pa = remote_rp_pa;
 	dev_dbg(xpc_part, "  remote_rp_pa = 0x%016lx\n", part->remote_rp_pa);
 
-	part->remote_vars_pa = remote_vars_pa;
+	part_sn2->remote_vars_pa = remote_vars_pa;
 	dev_dbg(xpc_part, "  remote_vars_pa = 0x%016lx\n",
-		part->remote_vars_pa);
+		part_sn2->remote_vars_pa);
 
 	part->last_heartbeat = remote_vars->heartbeat;
 	dev_dbg(xpc_part, "  last_heartbeat = 0x%016lx\n",
 		part->last_heartbeat);
 
-	part->remote_vars_part_pa = remote_vars->vars_part_pa;
+	part_sn2->remote_vars_part_pa = remote_vars->vars_part_pa;
 	dev_dbg(xpc_part, "  remote_vars_part_pa = 0x%016lx\n",
-		part->remote_vars_part_pa);
+		part_sn2->remote_vars_part_pa);
 
-	part->remote_act_nasid = remote_vars->act_nasid;
-	dev_dbg(xpc_part, "  remote_act_nasid = 0x%x\n",
-		part->remote_act_nasid);
+	part_sn2->activate_IRQ_nasid = remote_vars->activate_IRQ_nasid;
+	dev_dbg(xpc_part, "  activate_IRQ_nasid = 0x%x\n",
+		part_sn2->activate_IRQ_nasid);
+
+	part_sn2->activate_IRQ_phys_cpuid =
+	    remote_vars->activate_IRQ_phys_cpuid;
+	dev_dbg(xpc_part, "  activate_IRQ_phys_cpuid = 0x%x\n",
+		part_sn2->activate_IRQ_phys_cpuid);
 
-	part->remote_act_phys_cpuid = remote_vars->act_phys_cpuid;
-	dev_dbg(xpc_part, "  remote_act_phys_cpuid = 0x%x\n",
-		part->remote_act_phys_cpuid);
-
-	part->remote_amos_page_pa = remote_vars->amos_page_pa;
+	part_sn2->remote_amos_page_pa = remote_vars->amos_page_pa;
 	dev_dbg(xpc_part, "  remote_amos_page_pa = 0x%lx\n",
-		part->remote_amos_page_pa);
+		part_sn2->remote_amos_page_pa);
 
-	part->remote_vars_version = remote_vars->version;
+	part_sn2->remote_vars_version = remote_vars->version;
 	dev_dbg(xpc_part, "  remote_vars_version = 0x%x\n",
-		part->remote_vars_version);
+		part_sn2->remote_vars_version);
 }
 
 /*
@@ -807,6 +886,7 @@ xpc_identify_activate_IRQ_req_sn2(int na
 	unsigned long remote_rp_stamp = 0;
 	short partid;
 	struct xpc_partition *part;
+	struct xpc_partition_sn2 *part_sn2;
 	enum xp_retval ret;
 
 	/* pull over the reserved page structure */
@@ -822,11 +902,11 @@ xpc_identify_activate_IRQ_req_sn2(int na
 
 	remote_vars_pa = remote_rp->sn.vars_pa;
 	remote_rp_version = remote_rp->version;
-	if (XPC_SUPPORTS_RP_STAMP(remote_rp_version))
-		remote_rp_stamp = remote_rp->stamp;
+	remote_rp_stamp = remote_rp->stamp;
 
 	partid = remote_rp->SAL_partid;
 	part = &xpc_partitions[partid];
+	part_sn2 = &part->sn.sn2;
 
 	/* pull over the cross partition variables */
 
@@ -834,7 +914,6 @@ xpc_identify_activate_IRQ_req_sn2(int na
 
 	ret = xpc_get_remote_vars_sn2(remote_vars_pa, remote_vars);
 	if (ret != xpSuccess) {
-
 		dev_warn(xpc_part, "unable to get XPC variables from nasid %d, "
 			 "which sent interrupt, reason=%d\n", nasid, ret);
 
@@ -855,18 +934,12 @@ xpc_identify_activate_IRQ_req_sn2(int na
 					      &remote_rp_stamp, remote_rp_pa,
 					      remote_vars_pa, remote_vars);
 
-		if (XPC_SUPPORTS_DISENGAGE_REQUEST(part->remote_vars_version)) {
-			if (xpc_partition_disengage_requested(1UL << partid)) {
-				/*
-				 * Other side is waiting on us to disengage,
-				 * even though we already have.
-				 */
-				return;
-			}
-
-		} else {
-			/* other side doesn't support disengage requests */
-			xpc_clear_partition_disengage_request(1UL << partid);
+		if (xpc_partition_deactivation_requested_sn2(partid)) {
+			/*
+			 * Other side is waiting on us to deactivate even though
+			 * we already have.
+			 */
+			return;
 		}
 
 		xpc_activate_partition(part);
@@ -874,93 +947,30 @@ xpc_identify_activate_IRQ_req_sn2(int na
 	}
 
 	DBUG_ON(part->remote_rp_version == 0);
-	DBUG_ON(part->remote_vars_version == 0);
+	DBUG_ON(part_sn2->remote_vars_version == 0);
 
-	if (!XPC_SUPPORTS_RP_STAMP(part->remote_rp_version)) {
-		DBUG_ON(XPC_SUPPORTS_DISENGAGE_REQUEST(part->
-						       remote_vars_version));
-
-		if (!XPC_SUPPORTS_RP_STAMP(remote_rp_version)) {
-			DBUG_ON(XPC_SUPPORTS_DISENGAGE_REQUEST(remote_vars->
-							       version));
-			/* see if the other side rebooted */
-			if (part->remote_amos_page_pa ==
-			    remote_vars->amos_page_pa &&
-			    xpc_hb_allowed(sn_partition_id,
-					  &remote_vars->heartbeating_to_mask)) {
-				/* doesn't look that way, so ignore the IPI */
-				return;
-			}
-		}
+	if (remote_rp_stamp != part->remote_rp_stamp) {
 
-		/*
-		 * Other side rebooted and previous XPC didn't support the
-		 * disengage request, so we don't need to do anything special.
-		 */
-
-		xpc_update_partition_info_sn2(part, remote_rp_version,
-					      &remote_rp_stamp, remote_rp_pa,
-					      remote_vars_pa, remote_vars);
-		part->reactivate_nasid = nasid;
-		XPC_DEACTIVATE_PARTITION(part, xpReactivating);
-		return;
-	}
-
-	DBUG_ON(!XPC_SUPPORTS_DISENGAGE_REQUEST(part->remote_vars_version));
+		/* the other side rebooted */
 
-	if (!XPC_SUPPORTS_RP_STAMP(remote_rp_version)) {
-		DBUG_ON(!XPC_SUPPORTS_DISENGAGE_REQUEST(remote_vars->version));
-
-		/*
-		 * Other side rebooted and previous XPC did support the
-		 * disengage request, but the new one doesn't.
-		 */
-
-		xpc_clear_partition_engaged(1UL << partid);
-		xpc_clear_partition_disengage_request(1UL << partid);
+		DBUG_ON(xpc_partition_engaged_sn2(partid));
+		DBUG_ON(xpc_partition_deactivation_requested_sn2(partid));
 
 		xpc_update_partition_info_sn2(part, remote_rp_version,
 					      &remote_rp_stamp, remote_rp_pa,
 					      remote_vars_pa, remote_vars);
 		reactivate = 1;
-
-	} else {
-		DBUG_ON(!XPC_SUPPORTS_DISENGAGE_REQUEST(remote_vars->version));
-
-		if (remote_rp_stamp != part->remote_rp_stamp) {
-
-			/*
-			 * Other side rebooted and the previous XPC did support
-			 * the disengage request, as does the new one.
-			 */
-
-			DBUG_ON(xpc_partition_engaged(1UL << partid));
-			DBUG_ON(xpc_partition_disengage_requested(1UL <<
-								  partid));
-
-			xpc_update_partition_info_sn2(part, remote_rp_version,
-						      &remote_rp_stamp,
-						      remote_rp_pa,
-						      remote_vars_pa,
-						      remote_vars);
-			reactivate = 1;
-		}
 	}
 
-	if (part->disengage_request_timeout > 0 &&
-	    !xpc_partition_disengaged(part)) {
+	if (part->disengage_timeout > 0 && !xpc_partition_disengaged(part)) {
 		/* still waiting on other side to disengage from us */
 		return;
 	}
 
-	if (reactivate) {
-		part->reactivate_nasid = nasid;
+	if (reactivate)
 		XPC_DEACTIVATE_PARTITION(part, xpReactivating);
-
-	} else if (XPC_SUPPORTS_DISENGAGE_REQUEST(part->remote_vars_version) &&
-		   xpc_partition_disengage_requested(1UL << partid)) {
+	else if (xpc_partition_deactivation_requested_sn2(partid))
 		XPC_DEACTIVATE_PARTITION(part, xpOtherGoingDown);
-	}
 }
 
 /*
@@ -1038,6 +1048,7 @@ xpc_process_activate_IRQ_rcvd_sn2(int n_
 static enum xp_retval
 xpc_setup_infrastructure_sn2(struct xpc_partition *part)
 {
+	struct xpc_partition_sn2 *part_sn2 = &part->sn.sn2;
 	enum xp_retval retval;
 	int ret;
 	int cpuid;
@@ -1060,28 +1071,29 @@ xpc_setup_infrastructure_sn2(struct xpc_
 
 	/* allocate all the required GET/PUT values */
 
-	part->local_GPs = xpc_kzalloc_cacheline_aligned(XPC_GP_SIZE,
-							GFP_KERNEL,
-							&part->local_GPs_base);
-	if (part->local_GPs == NULL) {
+	part_sn2->local_GPs = xpc_kzalloc_cacheline_aligned(XPC_GP_SIZE,
+							    GFP_KERNEL,
+							    &part_sn2->
+							    local_GPs_base);
+	if (part_sn2->local_GPs == NULL) {
 		dev_err(xpc_chan, "can't get memory for local get/put "
 			"values\n");
 		retval = xpNoMemory;
 		goto out_1;
 	}
 
-	part->remote_GPs = xpc_kzalloc_cacheline_aligned(XPC_GP_SIZE,
-							 GFP_KERNEL,
-							 &part->
-							 remote_GPs_base);
-	if (part->remote_GPs == NULL) {
+	part_sn2->remote_GPs = xpc_kzalloc_cacheline_aligned(XPC_GP_SIZE,
+							     GFP_KERNEL,
+							     &part_sn2->
+							     remote_GPs_base);
+	if (part_sn2->remote_GPs == NULL) {
 		dev_err(xpc_chan, "can't get memory for remote get/put "
 			"values\n");
 		retval = xpNoMemory;
 		goto out_2;
 	}
 
-	part->remote_GPs_pa = 0;
+	part_sn2->remote_GPs_pa = 0;
 
 	/* allocate all the required open and close args */
 
@@ -1103,22 +1115,23 @@ xpc_setup_infrastructure_sn2(struct xpc_
 		goto out_4;
 	}
 
-	part->remote_openclose_args_pa = 0;
+	part_sn2->remote_openclose_args_pa = 0;
 
-	part->local_IPI_amo_va = xpc_IPI_init_sn2(partid);
+	part_sn2->local_IPI_amo_va = xpc_IPI_init_sn2(partid);
 	part->local_IPI_amo = 0;
 	spin_lock_init(&part->IPI_lock);
 
-	part->remote_IPI_nasid = 0;
-	part->remote_IPI_phys_cpuid = 0;
-	part->remote_IPI_amo_va = NULL;
+	part_sn2->remote_IPI_nasid = 0;
+	part_sn2->remote_IPI_phys_cpuid = 0;
+	part_sn2->remote_IPI_amo_va = NULL;
 
 	atomic_set(&part->channel_mgr_requests, 1);
 	init_waitqueue_head(&part->channel_mgr_wq);
 
-	sprintf(part->IPI_owner, "xpc%02d", partid);
-	ret = request_irq(SGI_XPC_NOTIFY, xpc_notify_IRQ_handler, IRQF_SHARED,
-			  part->IPI_owner, (void *)(u64)partid);
+	sprintf(part_sn2->IPI_owner, "xpc%02d", partid);
+	ret = request_irq(SGI_XPC_NOTIFY, xpc_handle_notify_IRQ_sn2,
+			  IRQF_SHARED, part_sn2->IPI_owner,
+			  (void *)(u64)partid);
 	if (ret != 0) {
 		dev_err(xpc_chan, "can't register NOTIFY IRQ handler, "
 			"errno=%d\n", -ret);
@@ -1127,9 +1140,10 @@ xpc_setup_infrastructure_sn2(struct xpc_
 	}
 
 	/* Setup a timer to check for dropped IPIs */
-	timer = &part->dropped_IPI_timer;
+	timer = &part_sn2->dropped_notify_IRQ_timer;
 	init_timer(timer);
-	timer->function = (void (*)(unsigned long))xpc_dropped_IPI_check;
+	timer->function =
+	    (void (*)(unsigned long))xpc_dropped_notify_IRQ_check_sn2;
 	timer->data = (unsigned long)part;
 	timer->expires = jiffies + XPC_P_DROPPED_IPI_WAIT_INTERVAL;
 	add_timer(timer);
@@ -1146,7 +1160,7 @@ xpc_setup_infrastructure_sn2(struct xpc_
 		ch->number = ch_number;
 		ch->flags = XPC_C_DISCONNECTED;
 
-		ch->local_GP = &part->local_GPs[ch_number];
+		ch->sn.sn2.local_GP = &part_sn2->local_GPs[ch_number];
 		ch->local_openclose_args =
 		    &part->local_openclose_args[ch_number];
 
@@ -1158,7 +1172,7 @@ xpc_setup_infrastructure_sn2(struct xpc_
 		atomic_set(&ch->n_to_notify, 0);
 
 		spin_lock_init(&ch->lock);
-		mutex_init(&ch->msg_to_pull_mutex);
+		mutex_init(&ch->sn.sn2.msg_to_pull_mutex);
 		init_completion(&ch->wdisconnect_wait);
 
 		atomic_set(&ch->n_on_msg_allocate_wq, 0);
@@ -1179,10 +1193,10 @@ xpc_setup_infrastructure_sn2(struct xpc_
 	 * The setting of the magic # indicates that these per partition
 	 * specific variables are ready to be used.
 	 */
-	xpc_vars_part[partid].GPs_pa = __pa(part->local_GPs);
+	xpc_vars_part[partid].GPs_pa = __pa(part_sn2->local_GPs);
 	xpc_vars_part[partid].openclose_args_pa =
 	    __pa(part->local_openclose_args);
-	xpc_vars_part[partid].IPI_amo_pa = __pa(part->local_IPI_amo_va);
+	xpc_vars_part[partid].IPI_amo_pa = __pa(part_sn2->local_IPI_amo_va);
 	cpuid = raw_smp_processor_id();	/* any CPU in this partition will do */
 	xpc_vars_part[partid].IPI_nasid = cpuid_to_nasid(cpuid);
 	xpc_vars_part[partid].IPI_phys_cpuid = cpu_physical_id(cpuid);
@@ -1199,11 +1213,11 @@ out_4:
 	kfree(part->local_openclose_args_base);
 	part->local_openclose_args = NULL;
 out_3:
-	kfree(part->remote_GPs_base);
-	part->remote_GPs = NULL;
+	kfree(part_sn2->remote_GPs_base);
+	part_sn2->remote_GPs = NULL;
 out_2:
-	kfree(part->local_GPs_base);
-	part->local_GPs = NULL;
+	kfree(part_sn2->local_GPs_base);
+	part_sn2->local_GPs = NULL;
 out_1:
 	kfree(part->channels);
 	part->channels = NULL;
@@ -1217,6 +1231,7 @@ out_1:
 static void
 xpc_teardown_infrastructure_sn2(struct xpc_partition *part)
 {
+	struct xpc_partition_sn2 *part_sn2 = &part->sn.sn2;
 	short partid = XPC_PARTID(part);
 
 	/*
@@ -1248,19 +1263,19 @@ xpc_teardown_infrastructure_sn2(struct x
 	part->setup_state = XPC_P_TORNDOWN;
 
 	/* in case we've still got outstanding timers registered... */
-	del_timer_sync(&part->dropped_IPI_timer);
+	del_timer_sync(&part_sn2->dropped_notify_IRQ_timer);
 
 	kfree(part->remote_openclose_args_base);
 	part->remote_openclose_args = NULL;
 	kfree(part->local_openclose_args_base);
 	part->local_openclose_args = NULL;
-	kfree(part->remote_GPs_base);
-	part->remote_GPs = NULL;
-	kfree(part->local_GPs_base);
-	part->local_GPs = NULL;
+	kfree(part_sn2->remote_GPs_base);
+	part_sn2->remote_GPs = NULL;
+	kfree(part_sn2->local_GPs_base);
+	part_sn2->local_GPs = NULL;
 	kfree(part->channels);
 	part->channels = NULL;
-	part->local_IPI_amo_va = NULL;
+	part_sn2->local_IPI_amo_va = NULL;
 }
 
 /*
@@ -1300,6 +1315,7 @@ xpc_pull_remote_cachelines_sn2(struct xp
 static enum xp_retval
 xpc_pull_remote_vars_part_sn2(struct xpc_partition *part)
 {
+	struct xpc_partition_sn2 *part_sn2 = &part->sn.sn2;
 	u8 buffer[L1_CACHE_BYTES * 2];
 	struct xpc_vars_part_sn2 *pulled_entry_cacheline =
 	    (struct xpc_vars_part_sn2 *)L1_CACHE_ALIGN((u64)buffer);
@@ -1310,11 +1326,11 @@ xpc_pull_remote_vars_part_sn2(struct xpc
 
 	/* pull the cacheline that contains the variables we're interested in */
 
-	DBUG_ON(part->remote_vars_part_pa !=
-		L1_CACHE_ALIGN(part->remote_vars_part_pa));
+	DBUG_ON(part_sn2->remote_vars_part_pa !=
+		L1_CACHE_ALIGN(part_sn2->remote_vars_part_pa));
 	DBUG_ON(sizeof(struct xpc_vars_part_sn2) != L1_CACHE_BYTES / 2);
 
-	remote_entry_pa = part->remote_vars_part_pa +
+	remote_entry_pa = part_sn2->remote_vars_part_pa +
 	    sn_partition_id * sizeof(struct xpc_vars_part_sn2);
 
 	remote_entry_cacheline_pa = (remote_entry_pa & ~(L1_CACHE_BYTES - 1));
@@ -1364,13 +1380,13 @@ xpc_pull_remote_vars_part_sn2(struct xpc
 
 		/* the variables we imported look to be valid */
 
-		part->remote_GPs_pa = pulled_entry->GPs_pa;
-		part->remote_openclose_args_pa =
+		part_sn2->remote_GPs_pa = pulled_entry->GPs_pa;
+		part_sn2->remote_openclose_args_pa =
 		    pulled_entry->openclose_args_pa;
-		part->remote_IPI_amo_va =
+		part_sn2->remote_IPI_amo_va =
 		    (AMO_t *)__va(pulled_entry->IPI_amo_pa);
-		part->remote_IPI_nasid = pulled_entry->IPI_nasid;
-		part->remote_IPI_phys_cpuid = pulled_entry->IPI_phys_cpuid;
+		part_sn2->remote_IPI_nasid = pulled_entry->IPI_nasid;
+		part_sn2->remote_IPI_phys_cpuid = pulled_entry->IPI_phys_cpuid;
 
 		if (part->nchannels > pulled_entry->nchannels)
 			part->nchannels = pulled_entry->nchannels;
@@ -1394,6 +1410,7 @@ xpc_pull_remote_vars_part_sn2(struct xpc
 static enum xp_retval
 xpc_make_first_contact_sn2(struct xpc_partition *part)
 {
+	struct xpc_partition_sn2 *part_sn2 = &part->sn.sn2;
 	enum xp_retval ret;
 
 	/*
@@ -1406,7 +1423,7 @@ xpc_make_first_contact_sn2(struct xpc_pa
 	 * we should get the same page for remote_amos_page_pa after module
 	 * reloads and system reboots.
 	 */
-	if (sn_register_xp_addr_region(part->remote_amos_page_pa,
+	if (sn_register_xp_addr_region(part_sn2->remote_amos_page_pa,
 				       PAGE_SIZE, 1) < 0) {
 		dev_warn(xpc_part, "xpc_activating(%d) failed to register "
 			 "xp_addr region\n", XPC_PARTID(part));
@@ -1416,7 +1433,14 @@ xpc_make_first_contact_sn2(struct xpc_pa
 		return ret;
 	}
 
-	xpc_IPI_send_activated(part);
+	/*
+	 * Send activate IRQ to get other side to activate if they've not
+	 * already begun to do so.
+	 */
+	xpc_activate_IRQ_send_sn2(part_sn2->remote_amos_page_pa,
+				  cnodeid_to_nasid(0),
+				  part_sn2->activate_IRQ_nasid,
+				  part_sn2->activate_IRQ_phys_cpuid);
 
 	while ((ret = xpc_pull_remote_vars_part_sn2(part)) != xpSuccess) {
 		if (ret != xpRetry) {
@@ -1443,6 +1467,7 @@ xpc_make_first_contact_sn2(struct xpc_pa
 static u64
 xpc_get_IPI_flags_sn2(struct xpc_partition *part)
 {
+	struct xpc_partition_sn2 *part_sn2 = &part->sn.sn2;
 	unsigned long irq_flags;
 	u64 IPI_amo;
 	enum xp_retval ret;
@@ -1459,9 +1484,9 @@ xpc_get_IPI_flags_sn2(struct xpc_partiti
 	spin_unlock_irqrestore(&part->IPI_lock, irq_flags);
 
 	if (XPC_ANY_OPENCLOSE_IPI_FLAGS_SET(IPI_amo)) {
-		ret = xpc_pull_remote_cachelines_sn2(part,
-						    part->remote_openclose_args,
-						     (void *)part->
+		ret = xpc_pull_remote_cachelines_sn2(part, part->
+						     remote_openclose_args,
+						     (void *)part_sn2->
 						     remote_openclose_args_pa,
 						     XPC_OPENCLOSE_ARGS_SIZE);
 		if (ret != xpSuccess) {
@@ -1477,8 +1502,8 @@ xpc_get_IPI_flags_sn2(struct xpc_partiti
 	}
 
 	if (XPC_ANY_MSG_IPI_FLAGS_SET(IPI_amo)) {
-		ret = xpc_pull_remote_cachelines_sn2(part, part->remote_GPs,
-						    (void *)part->remote_GPs_pa,
+		ret = xpc_pull_remote_cachelines_sn2(part, part_sn2->remote_GPs,
+						(void *)part_sn2->remote_GPs_pa,
 						     XPC_GP_SIZE);
 		if (ret != xpSuccess) {
 			XPC_DEACTIVATE_PARTITION(part, ret);
@@ -1494,28 +1519,220 @@ xpc_get_IPI_flags_sn2(struct xpc_partiti
 	return IPI_amo;
 }
 
+/*
+ * Notify those who wanted to be notified upon delivery of their message.
+ */
+static void
+xpc_notify_senders_sn2(struct xpc_channel *ch, enum xp_retval reason, s64 put)
+{
+	struct xpc_notify *notify;
+	u8 notify_type;
+	s64 get = ch->sn.sn2.w_remote_GP.get - 1;
+
+	while (++get < put && atomic_read(&ch->n_to_notify) > 0) {
+
+		notify = &ch->notify_queue[get % ch->local_nentries];
+
+		/*
+		 * See if the notify entry indicates it was associated with
+		 * a message who's sender wants to be notified. It is possible
+		 * that it is, but someone else is doing or has done the
+		 * notification.
+		 */
+		notify_type = notify->type;
+		if (notify_type == 0 ||
+		    cmpxchg(&notify->type, notify_type, 0) != notify_type) {
+			continue;
+		}
+
+		DBUG_ON(notify_type != XPC_N_CALL);
+
+		atomic_dec(&ch->n_to_notify);
+
+		if (notify->func != NULL) {
+			dev_dbg(xpc_chan, "notify->func() called, notify=0x%p, "
+				"msg_number=%ld, partid=%d, channel=%d\n",
+				(void *)notify, get, ch->partid, ch->number);
+
+			notify->func(reason, ch->partid, ch->number,
+				     notify->key);
+
+			dev_dbg(xpc_chan, "notify->func() returned, "
+				"notify=0x%p, msg_number=%ld, partid=%d, "
+				"channel=%d\n", (void *)notify, get,
+				ch->partid, ch->number);
+		}
+	}
+}
+
+static void
+xpc_notify_senders_of_disconnect_sn2(struct xpc_channel *ch)
+{
+	xpc_notify_senders_sn2(ch, ch->reason, ch->sn.sn2.w_local_GP.put);
+}
+
+/*
+ * Clear some of the msg flags in the local message queue.
+ */
+static inline void
+xpc_clear_local_msgqueue_flags_sn2(struct xpc_channel *ch)
+{
+	struct xpc_channel_sn2 *ch_sn2 = &ch->sn.sn2;
+	struct xpc_msg *msg;
+	s64 get;
+
+	get = ch_sn2->w_remote_GP.get;
+	do {
+		msg = (struct xpc_msg *)((u64)ch->local_msgqueue +
+					 (get % ch->local_nentries) *
+					 ch->msg_size);
+		msg->flags = 0;
+	} while (++get < ch_sn2->remote_GP.get);
+}
+
+/*
+ * Clear some of the msg flags in the remote message queue.
+ */
+static inline void
+xpc_clear_remote_msgqueue_flags_sn2(struct xpc_channel *ch)
+{
+	struct xpc_channel_sn2 *ch_sn2 = &ch->sn.sn2;
+	struct xpc_msg *msg;
+	s64 put;
+
+	put = ch_sn2->w_remote_GP.put;
+	do {
+		msg = (struct xpc_msg *)((u64)ch->remote_msgqueue +
+					 (put % ch->remote_nentries) *
+					 ch->msg_size);
+		msg->flags = 0;
+	} while (++put < ch_sn2->remote_GP.put);
+}
+
+static void
+xpc_process_msg_IPI_sn2(struct xpc_partition *part, int ch_number)
+{
+	struct xpc_channel *ch = &part->channels[ch_number];
+	struct xpc_channel_sn2 *ch_sn2 = &ch->sn.sn2;
+	int nmsgs_sent;
+
+	ch_sn2->remote_GP = part->sn.sn2.remote_GPs[ch_number];
+
+	/* See what, if anything, has changed for each connected channel */
+
+	xpc_msgqueue_ref(ch);
+
+	if (ch_sn2->w_remote_GP.get == ch_sn2->remote_GP.get &&
+	    ch_sn2->w_remote_GP.put == ch_sn2->remote_GP.put) {
+		/* nothing changed since GPs were last pulled */
+		xpc_msgqueue_deref(ch);
+		return;
+	}
+
+	if (!(ch->flags & XPC_C_CONNECTED)) {
+		xpc_msgqueue_deref(ch);
+		return;
+	}
+
+	/*
+	 * First check to see if messages recently sent by us have been
+	 * received by the other side. (The remote GET value will have
+	 * changed since we last looked at it.)
+	 */
+
+	if (ch_sn2->w_remote_GP.get != ch_sn2->remote_GP.get) {
+
+		/*
+		 * We need to notify any senders that want to be notified
+		 * that their sent messages have been received by their
+		 * intended recipients. We need to do this before updating
+		 * w_remote_GP.get so that we don't allocate the same message
+		 * queue entries prematurely (see xpc_allocate_msg()).
+		 */
+		if (atomic_read(&ch->n_to_notify) > 0) {
+			/*
+			 * Notify senders that messages sent have been
+			 * received and delivered by the other side.
+			 */
+			xpc_notify_senders_sn2(ch, xpMsgDelivered,
+					       ch_sn2->remote_GP.get);
+		}
+
+		/*
+		 * Clear msg->flags in previously sent messages, so that
+		 * they're ready for xpc_allocate_msg().
+		 */
+		xpc_clear_local_msgqueue_flags_sn2(ch);
+
+		ch_sn2->w_remote_GP.get = ch_sn2->remote_GP.get;
+
+		dev_dbg(xpc_chan, "w_remote_GP.get changed to %ld, partid=%d, "
+			"channel=%d\n", ch_sn2->w_remote_GP.get, ch->partid,
+			ch->number);
+
+		/*
+		 * If anyone was waiting for message queue entries to become
+		 * available, wake them up.
+		 */
+		if (atomic_read(&ch->n_on_msg_allocate_wq) > 0)
+			wake_up(&ch->msg_allocate_wq);
+	}
+
+	/*
+	 * Now check for newly sent messages by the other side. (The remote
+	 * PUT value will have changed since we last looked at it.)
+	 */
+
+	if (ch_sn2->w_remote_GP.put != ch_sn2->remote_GP.put) {
+		/*
+		 * Clear msg->flags in previously received messages, so that
+		 * they're ready for xpc_get_deliverable_msg().
+		 */
+		xpc_clear_remote_msgqueue_flags_sn2(ch);
+
+		ch_sn2->w_remote_GP.put = ch_sn2->remote_GP.put;
+
+		dev_dbg(xpc_chan, "w_remote_GP.put changed to %ld, partid=%d, "
+			"channel=%d\n", ch_sn2->w_remote_GP.put, ch->partid,
+			ch->number);
+
+		nmsgs_sent = ch_sn2->w_remote_GP.put - ch_sn2->w_local_GP.get;
+		if (nmsgs_sent > 0) {
+			dev_dbg(xpc_chan, "msgs waiting to be copied and "
+				"delivered=%d, partid=%d, channel=%d\n",
+				nmsgs_sent, ch->partid, ch->number);
+
+			if (ch->flags & XPC_C_CONNECTEDCALLOUT_MADE)
+				xpc_activate_kthreads(ch, nmsgs_sent);
+		}
+	}
+
+	xpc_msgqueue_deref(ch);
+}
+
 static struct xpc_msg *
 xpc_pull_remote_msg_sn2(struct xpc_channel *ch, s64 get)
 {
 	struct xpc_partition *part = &xpc_partitions[ch->partid];
+	struct xpc_channel_sn2 *ch_sn2 = &ch->sn.sn2;
 	struct xpc_msg *remote_msg, *msg;
 	u32 msg_index, nmsgs;
 	u64 msg_offset;
 	enum xp_retval ret;
 
-	if (mutex_lock_interruptible(&ch->msg_to_pull_mutex) != 0) {
+	if (mutex_lock_interruptible(&ch_sn2->msg_to_pull_mutex) != 0) {
 		/* we were interrupted by a signal */
 		return NULL;
 	}
 
-	while (get >= ch->next_msg_to_pull) {
+	while (get >= ch_sn2->next_msg_to_pull) {
 
 		/* pull as many messages as are ready and able to be pulled */
 
-		msg_index = ch->next_msg_to_pull % ch->remote_nentries;
+		msg_index = ch_sn2->next_msg_to_pull % ch->remote_nentries;
 
-		DBUG_ON(ch->next_msg_to_pull >= ch->w_remote_GP.put);
-		nmsgs = ch->w_remote_GP.put - ch->next_msg_to_pull;
+		DBUG_ON(ch_sn2->next_msg_to_pull >= ch_sn2->w_remote_GP.put);
+		nmsgs = ch_sn2->w_remote_GP.put - ch_sn2->next_msg_to_pull;
 		if (msg_index + nmsgs > ch->remote_nentries) {
 			/* ignore the ones that wrap the msg queue for now */
 			nmsgs = ch->remote_nentries - msg_index;
@@ -1532,19 +1749,19 @@ xpc_pull_remote_msg_sn2(struct xpc_chann
 
 			dev_dbg(xpc_chan, "failed to pull %d msgs starting with"
 				" msg %ld from partition %d, channel=%d, "
-				"ret=%d\n", nmsgs, ch->next_msg_to_pull,
+				"ret=%d\n", nmsgs, ch_sn2->next_msg_to_pull,
 				ch->partid, ch->number, ret);
 
 			XPC_DEACTIVATE_PARTITION(part, ret);
 
-			mutex_unlock(&ch->msg_to_pull_mutex);
+			mutex_unlock(&ch_sn2->msg_to_pull_mutex);
 			return NULL;
 		}
 
-		ch->next_msg_to_pull += nmsgs;
+		ch_sn2->next_msg_to_pull += nmsgs;
 	}
 
-	mutex_unlock(&ch->msg_to_pull_mutex);
+	mutex_unlock(&ch_sn2->msg_to_pull_mutex);
 
 	/* return the message we were looking for */
 	msg_offset = (get % ch->remote_nentries) * ch->msg_size;
@@ -1553,12 +1770,19 @@ xpc_pull_remote_msg_sn2(struct xpc_chann
 	return msg;
 }
 
+static int
+xpc_n_of_deliverable_msgs_sn2(struct xpc_channel *ch)
+{
+	return ch->sn.sn2.w_remote_GP.put - ch->sn.sn2.w_local_GP.get;
+}
+
 /*
  * Get a message to be delivered.
  */
 static struct xpc_msg *
 xpc_get_deliverable_msg_sn2(struct xpc_channel *ch)
 {
+	struct xpc_channel_sn2 *ch_sn2 = &ch->sn.sn2;
 	struct xpc_msg *msg = NULL;
 	s64 get;
 
@@ -1566,9 +1790,9 @@ xpc_get_deliverable_msg_sn2(struct xpc_c
 		if (ch->flags & XPC_C_DISCONNECTING)
 			break;
 
-		get = ch->w_local_GP.get;
+		get = ch_sn2->w_local_GP.get;
 		rmb();	/* guarantee that .get loads before .put */
-		if (get == ch->w_remote_GP.put)
+		if (get == ch_sn2->w_remote_GP.put)
 			break;
 
 		/* There are messages waiting to be pulled and delivered.
@@ -1578,7 +1802,7 @@ xpc_get_deliverable_msg_sn2(struct xpc_c
 		 * to try again for the next one.
 		 */
 
-		if (cmpxchg(&ch->w_local_GP.get, get, get + 1) == get) {
+		if (cmpxchg(&ch_sn2->w_local_GP.get, get, get + 1) == get) {
 			/* we got the entry referenced by get */
 
 			dev_dbg(xpc_chan, "w_local_GP.get changed to %ld, "
@@ -1609,6 +1833,7 @@ xpc_get_deliverable_msg_sn2(struct xpc_c
 static void
 xpc_send_msgs_sn2(struct xpc_channel *ch, s64 initial_put)
 {
+	struct xpc_channel_sn2 *ch_sn2 = &ch->sn.sn2;
 	struct xpc_msg *msg;
 	s64 put = initial_put + 1;
 	int send_IPI = 0;
@@ -1616,7 +1841,7 @@ xpc_send_msgs_sn2(struct xpc_channel *ch
 	while (1) {
 
 		while (1) {
-			if (put == ch->w_local_GP.put)
+			if (put == ch_sn2->w_local_GP.put)
 				break;
 
 			msg = (struct xpc_msg *)((u64)ch->local_msgqueue +
@@ -1634,10 +1859,10 @@ xpc_send_msgs_sn2(struct xpc_channel *ch
 			break;
 		}
 
-		if (cmpxchg_rel(&ch->local_GP->put, initial_put, put) !=
+		if (cmpxchg_rel(&ch_sn2->local_GP->put, initial_put, put) !=
 		    initial_put) {
 			/* someone else beat us to it */
-			DBUG_ON(ch->local_GP->put < initial_put);
+			DBUG_ON(ch_sn2->local_GP->put < initial_put);
 			break;
 		}
 
@@ -1657,7 +1882,7 @@ xpc_send_msgs_sn2(struct xpc_channel *ch
 	}
 
 	if (send_IPI)
-		xpc_IPI_send_msgrequest_sn2(ch);
+		xpc_send_channel_msgrequest_sn2(ch);
 }
 
 /*
@@ -1668,6 +1893,7 @@ static enum xp_retval
 xpc_allocate_msg_sn2(struct xpc_channel *ch, u32 flags,
 		     struct xpc_msg **address_of_msg)
 {
+	struct xpc_channel_sn2 *ch_sn2 = &ch->sn.sn2;
 	struct xpc_msg *msg;
 	enum xp_retval ret;
 	s64 put;
@@ -1681,9 +1907,9 @@ xpc_allocate_msg_sn2(struct xpc_channel 
 
 	while (1) {
 
-		put = ch->w_local_GP.put;
+		put = ch_sn2->w_local_GP.put;
 		rmb();	/* guarantee that .put loads before .get */
-		if (put - ch->w_remote_GP.get < ch->local_nentries) {
+		if (put - ch_sn2->w_remote_GP.get < ch->local_nentries) {
 
 			/* There are available message entries. We need to try
 			 * to secure one for ourselves. We'll do this by trying
@@ -1691,7 +1917,8 @@ xpc_allocate_msg_sn2(struct xpc_channel 
 			 * doesn't beat us to it. If they do, we'll have to
 			 * try again.
 			 */
-			if (cmpxchg(&ch->w_local_GP.put, put, put + 1) == put) {
+			if (cmpxchg(&ch_sn2->w_local_GP.put, put, put + 1) ==
+			    put) {
 				/* we got the entry referenced by put */
 				break;
 			}
@@ -1708,7 +1935,7 @@ xpc_allocate_msg_sn2(struct xpc_channel 
 		 * GP values as if an IPI was sent by the other side.
 		 */
 		if (ret == xpTimeout)
-			xpc_IPI_send_local_msgrequest_sn2(ch);
+			xpc_send_channel_local_msgrequest_sn2(ch);
 
 		if (flags & XPC_NOWAIT)
 			return xpNoWait;
@@ -1810,13 +2037,13 @@ xpc_send_msg_sn2(struct xpc_channel *ch,
 
 	/*
 	 * The preceding store of msg->flags must occur before the following
-	 * load of ch->local_GP->put.
+	 * load of local_GP->put.
 	 */
 	mb();
 
 	/* see if the message is next in line to be sent, if so send it */
 
-	put = ch->local_GP->put;
+	put = ch->sn.sn2.local_GP->put;
 	if (put == msg_number)
 		xpc_send_msgs_sn2(ch, put);
 
@@ -1833,6 +2060,7 @@ out_1:
 static void
 xpc_acknowledge_msgs_sn2(struct xpc_channel *ch, s64 initial_get, u8 msg_flags)
 {
+	struct xpc_channel_sn2 *ch_sn2 = &ch->sn.sn2;
 	struct xpc_msg *msg;
 	s64 get = initial_get + 1;
 	int send_IPI = 0;
@@ -1840,7 +2068,7 @@ xpc_acknowledge_msgs_sn2(struct xpc_chan
 	while (1) {
 
 		while (1) {
-			if (get == ch->w_local_GP.get)
+			if (get == ch_sn2->w_local_GP.get)
 				break;
 
 			msg = (struct xpc_msg *)((u64)ch->remote_msgqueue +
@@ -1859,10 +2087,10 @@ xpc_acknowledge_msgs_sn2(struct xpc_chan
 			break;
 		}
 
-		if (cmpxchg_rel(&ch->local_GP->get, initial_get, get) !=
+		if (cmpxchg_rel(&ch_sn2->local_GP->get, initial_get, get) !=
 		    initial_get) {
 			/* someone else beat us to it */
-			DBUG_ON(ch->local_GP->get <= initial_get);
+			DBUG_ON(ch_sn2->local_GP->get <= initial_get);
 			break;
 		}
 
@@ -1882,7 +2110,7 @@ xpc_acknowledge_msgs_sn2(struct xpc_chan
 	}
 
 	if (send_IPI)
-		xpc_IPI_send_msgrequest_sn2(ch);
+		xpc_send_channel_msgrequest_sn2(ch);
 }
 
 static void
@@ -1902,7 +2130,7 @@ xpc_received_msg_sn2(struct xpc_channel 
 
 	/*
 	 * The preceding store of msg->flags must occur before the following
-	 * load of ch->local_GP->get.
+	 * load of local_GP->get.
 	 */
 	mb();
 
@@ -1910,7 +2138,7 @@ xpc_received_msg_sn2(struct xpc_channel 
 	 * See if this message is next in line to be acknowledged as having
 	 * been delivered.
 	 */
-	get = ch->local_GP->get;
+	get = ch->sn.sn2.local_GP->get;
 	if (get == msg_number)
 		xpc_acknowledge_msgs_sn2(ch, get, msg->flags);
 }
@@ -1928,36 +2156,35 @@ xpc_init_sn2(void)
 	xpc_heartbeat_exit = xpc_heartbeat_exit_sn2;
 	xpc_check_remote_hb = xpc_check_remote_hb_sn2;
 
-	xpc_initiate_partition_activation =
-	    xpc_initiate_partition_activation_sn2;
+	xpc_request_partition_activation = xpc_request_partition_activation_sn2;
+	xpc_request_partition_reactivation =
+	    xpc_request_partition_reactivation_sn2;
+	xpc_request_partition_deactivation =
+	    xpc_request_partition_deactivation_sn2;
+	xpc_cancel_partition_deactivation_request =
+	    xpc_cancel_partition_deactivation_request_sn2;
+
 	xpc_process_activate_IRQ_rcvd = xpc_process_activate_IRQ_rcvd_sn2;
 	xpc_setup_infrastructure = xpc_setup_infrastructure_sn2;
 	xpc_teardown_infrastructure = xpc_teardown_infrastructure_sn2;
 	xpc_make_first_contact = xpc_make_first_contact_sn2;
 	xpc_get_IPI_flags = xpc_get_IPI_flags_sn2;
+	xpc_notify_senders_of_disconnect = xpc_notify_senders_of_disconnect_sn2;
+	xpc_process_msg_IPI = xpc_process_msg_IPI_sn2;
+	xpc_n_of_deliverable_msgs = xpc_n_of_deliverable_msgs_sn2;
 	xpc_get_deliverable_msg = xpc_get_deliverable_msg_sn2;
 
-	xpc_mark_partition_engaged = xpc_mark_partition_engaged_sn2;
-	xpc_mark_partition_disengaged = xpc_mark_partition_disengaged_sn2;
-	xpc_request_partition_disengage = xpc_request_partition_disengage_sn2;
-	xpc_cancel_partition_disengage_request =
-	    xpc_cancel_partition_disengage_request_sn2;
+	xpc_indicate_partition_engaged = xpc_indicate_partition_engaged_sn2;
 	xpc_partition_engaged = xpc_partition_engaged_sn2;
-	xpc_partition_disengage_requested =
-	    xpc_partition_disengage_requested_sn2;
-	xpc_clear_partition_engaged = xpc_clear_partition_engaged_sn2;
-	xpc_clear_partition_disengage_request =
-	    xpc_clear_partition_disengage_request_sn2;
-
-	xpc_IPI_send_local_activate = xpc_IPI_send_local_activate_sn2;
-	xpc_IPI_send_activated = xpc_IPI_send_activated_sn2;
-	xpc_IPI_send_local_reactivate = xpc_IPI_send_local_reactivate_sn2;
-	xpc_IPI_send_disengage = xpc_IPI_send_disengage_sn2;
-
-	xpc_IPI_send_closerequest = xpc_IPI_send_closerequest_sn2;
-	xpc_IPI_send_closereply = xpc_IPI_send_closereply_sn2;
-	xpc_IPI_send_openrequest = xpc_IPI_send_openrequest_sn2;
-	xpc_IPI_send_openreply = xpc_IPI_send_openreply_sn2;
+	xpc_any_partition_engaged = xpc_any_partition_engaged_sn2;
+	xpc_indicate_partition_disengaged =
+	    xpc_indicate_partition_disengaged_sn2;
+	xpc_assume_partition_disengaged = xpc_assume_partition_disengaged_sn2;
+
+	xpc_send_channel_closerequest = xpc_send_channel_closerequest_sn2;
+	xpc_send_channel_closereply = xpc_send_channel_closereply_sn2;
+	xpc_send_channel_openrequest = xpc_send_channel_openrequest_sn2;
+	xpc_send_channel_openreply = xpc_send_channel_openreply_sn2;
 
 	xpc_send_msg = xpc_send_msg_sn2;
 	xpc_received_msg = xpc_received_msg_sn2;
Index: linux-2.6/drivers/misc/sgi-xp/xpc_partition.c
===================================================================
--- linux-2.6.orig/drivers/misc/sgi-xp/xpc_partition.c	2008-06-05 12:51:17.127801364 -0500
+++ linux-2.6/drivers/misc/sgi-xp/xpc_partition.c	2008-06-06 08:10:50.969262778 -0500
@@ -242,7 +242,7 @@ xpc_get_remote_rp(int nasid, u64 *discov
 		return xpBadVersion;
 	}
 
-	/* check that both local and remote partids are valid for each side */
+	/* check that both remote and local partids are valid for each side */
 	if (remote_rp->SAL_partid < 0 ||
 	    remote_rp->SAL_partid >= xp_max_npartitions ||
 	    remote_rp->max_npartitions <= sn_partition_id) {
@@ -256,8 +256,9 @@ xpc_get_remote_rp(int nasid, u64 *discov
 }
 
 /*
- * See if the other side has responded to a partition disengage request
- * from us.
+ * See if the other side has responded to a partition deactivate request
+ * from us. Though we requested the remote partition to deactivate with regard
+ * to us, we really only need to wait for the other side to disengage from us.
  */
 int
 xpc_partition_disengaged(struct xpc_partition *part)
@@ -265,41 +266,37 @@ xpc_partition_disengaged(struct xpc_part
 	short partid = XPC_PARTID(part);
 	int disengaged;
 
-	disengaged = (xpc_partition_engaged(1UL << partid) == 0);
-	if (part->disengage_request_timeout) {
+	disengaged = !xpc_partition_engaged(partid);
+	if (part->disengage_timeout) {
 		if (!disengaged) {
-			if (time_is_after_jiffies(part->
-						  disengage_request_timeout)) {
+			if (time_is_after_jiffies(part->disengage_timeout)) {
 				/* timelimit hasn't been reached yet */
 				return 0;
 			}
 
 			/*
-			 * Other side hasn't responded to our disengage
+			 * Other side hasn't responded to our deactivate
 			 * request in a timely fashion, so assume it's dead.
 			 */
 
-			dev_info(xpc_part, "disengage from remote partition %d "
-				 "timed out\n", partid);
-			xpc_disengage_request_timedout = 1;
-			xpc_clear_partition_engaged(1UL << partid);
+			dev_info(xpc_part, "deactivate request to remote "
+				 "partition %d timed out\n", partid);
+			xpc_disengage_timedout = 1;
+			xpc_assume_partition_disengaged(partid);
 			disengaged = 1;
 		}
-		part->disengage_request_timeout = 0;
+		part->disengage_timeout = 0;
 
 		/* cancel the timer function, provided it's not us */
-		if (!in_interrupt()) {
-			del_singleshot_timer_sync(&part->
-						  disengage_request_timer);
-		}
+		if (!in_interrupt())
+			del_singleshot_timer_sync(&part->disengage_timer);
 
 		DBUG_ON(part->act_state != XPC_P_DEACTIVATING &&
 			part->act_state != XPC_P_INACTIVE);
 		if (part->act_state != XPC_P_INACTIVE)
 			xpc_wakeup_channel_mgr(part);
 
-		if (XPC_SUPPORTS_DISENGAGE_REQUEST(part->remote_vars_version))
-			xpc_cancel_partition_disengage_request(part);
+		xpc_cancel_partition_deactivation_request(part);
 	}
 	return disengaged;
 }
@@ -329,7 +326,7 @@ xpc_mark_partition_active(struct xpc_par
 }
 
 /*
- * Notify XPC that the partition is down.
+ * Start the process of deactivating the specified partition.
  */
 void
 xpc_deactivate_partition(const int line, struct xpc_partition *part,
@@ -344,7 +341,7 @@ xpc_deactivate_partition(const int line,
 		spin_unlock_irqrestore(&part->act_lock, irq_flags);
 		if (reason == xpReactivating) {
 			/* we interrupt ourselves to reactivate partition */
-			xpc_IPI_send_local_reactivate(part->reactivate_nasid);
+			xpc_request_partition_reactivation(part);
 		}
 		return;
 	}
@@ -362,17 +359,13 @@ xpc_deactivate_partition(const int line,
 
 	spin_unlock_irqrestore(&part->act_lock, irq_flags);
 
-	if (XPC_SUPPORTS_DISENGAGE_REQUEST(part->remote_vars_version)) {
-		xpc_request_partition_disengage(part);
-		xpc_IPI_send_disengage(part);
-
-		/* set a timelimit on the disengage request */
-		part->disengage_request_timeout = jiffies +
-		    (xpc_disengage_request_timelimit * HZ);
-		part->disengage_request_timer.expires =
-		    part->disengage_request_timeout;
-		add_timer(&part->disengage_request_timer);
-	}
+	/* ask remote partition to deactivate with regard to us */
+	xpc_request_partition_deactivation(part);
+
+	/* set a timelimit on the disengage phase of the deactivation request */
+	part->disengage_timeout = jiffies + (xpc_disengage_timelimit * HZ);
+	part->disengage_timer.expires = part->disengage_timeout;
+	add_timer(&part->disengage_timer);
 
 	dev_dbg(xpc_part, "bringing partition %d down, reason = %d\n",
 		XPC_PARTID(part), reason);
@@ -505,8 +498,8 @@ xpc_discovery(void)
 				continue;
 			}
 
-			xpc_initiate_partition_activation(remote_rp,
-							  remote_rp_pa, nasid);
+			xpc_request_partition_activation(remote_rp,
+							 remote_rp_pa, nasid);
 		}
 	}
 
Index: linux-2.6/drivers/misc/sgi-xp/xpc_uv.c
===================================================================
--- linux-2.6.orig/drivers/misc/sgi-xp/xpc_uv.c	2008-06-05 12:51:16.767756403 -0500
+++ linux-2.6/drivers/misc/sgi-xp/xpc_uv.c	2008-06-06 08:08:28.700425233 -0500
@@ -63,8 +63,8 @@ xpc_heartbeat_exit_uv(void)
 }
 
 static void
-xpc_initiate_partition_activation_uv(struct xpc_rsvd_page *remote_rp,
-				     u64 remote_rp_pa, int nasid)
+xpc_request_partition_activation_uv(struct xpc_rsvd_page *remote_rp,
+				    u64 remote_rp_pa, int nasid)
 {
 	short partid = remote_rp->SAL_partid;
 	struct xpc_partition *part = &xpc_partitions[partid];
@@ -78,6 +78,12 @@ xpc_initiate_partition_activation_uv(str
 	xpc_IPI_send_local_activate_uv(part);
 }
 
+static void
+xpc_request_partition_reactivation_uv(struct xpc_partition *part)
+{
+	xpc_IPI_send_local_activate_uv(part);
+}
+
 /*
  * Setup the infrastructure necessary to support XPartition Communication
  * between the specified remote partition and the local one.
@@ -128,8 +134,9 @@ xpc_init_uv(void)
 	xpc_increment_heartbeat = xpc_increment_heartbeat_uv;
 	xpc_heartbeat_init = xpc_heartbeat_init_uv;
 	xpc_heartbeat_exit = xpc_heartbeat_exit_uv;
-	xpc_initiate_partition_activation =
-	    xpc_initiate_partition_activation_uv;
+	xpc_request_partition_activation = xpc_request_partition_activation_uv;
+	xpc_request_partition_reactivation =
+	    xpc_request_partition_reactivation_uv;
 	xpc_setup_infrastructure = xpc_setup_infrastructure_uv;
 	xpc_teardown_infrastructure = xpc_teardown_infrastructure_uv;
 	xpc_make_first_contact = xpc_make_first_contact_uv;

  parent reply	other threads:[~2008-06-06 16:55 UTC|newest]

Thread overview: 21+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2008-06-06 16:40 [Patch 00/18] continued prepartion of XPC/XPNET to support SGI UV Dean Nelson
2008-06-06 16:42 ` [Patch 01/18] define is_shub() and is_uv() macros Dean Nelson
2008-06-06 16:43 ` [Patch 02/18] define xpSalError reason code Dean Nelson
2008-06-06 16:44 ` [Patch 03/18] define BYTES_PER_WORD Dean Nelson
2008-06-09  0:12   ` Andrew Morton
2008-06-06 16:46 ` [Patch 04/18] support runtime selection of xp_max_npartitions Dean Nelson
2008-06-06 16:47 ` [Patch 05/18] create a common xp_remote_memcpy() function Dean Nelson
2008-06-06 16:48 ` [Patch 06/18] prepare xpc_rsvd_page to work on either sn2 or uv hardware Dean Nelson
2008-06-06 16:49 ` [Patch 07/18] isolate xpc_vars_part structure to sn2 only Dean Nelson
2008-06-06 16:51 ` [Patch 08/18] isolate xpc_vars " Dean Nelson
2008-06-06 16:52 ` [Patch 09/18] base xpc_rsvd_page's timestamp on jiffies Dean Nelson
2008-06-09  0:15   ` Andrew Morton
2008-06-06 16:53 ` [Patch 10/18] move xpc_allocate() into xpc_send()/xpc_send_notify() Dean Nelson
2008-06-06 16:54 ` [Patch 11/18] isolate activate IRQ's hardware specific components Dean Nelson
2008-06-06 16:55 ` Dean Nelson [this message]
2008-06-06 16:56 ` [Patch 13/18] separate chctl_flags from XPC's notify IRQ Dean Nelson
2008-06-06 16:58 ` [Patch 14/18] replace AMO_t typedef by struct amo Dean Nelson
2008-06-06 16:59 ` [Patch 15/18] isolate allocation of XPC's msgqueues to sn2 only Dean Nelson
2008-06-06 17:00 ` [Patch 16/18] enable XPNET to handle more than 64 partitions Dean Nelson
2008-06-06 17:02 ` [Patch 17/18] isolate remote copy buffer to sn2 only Dean Nelson
2008-06-06 17:03 ` [Patch 18/18] add _sn2 suffix to a few variables Dean Nelson

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20080606165523.GM13695@sgi.com \
    --to=dcn@sgi.com \
    --cc=akpm@linux-foundation.org \
    --cc=linux-kernel@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.