aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/misc/sgi-xp/xp.h80
-rw-r--r--drivers/misc/sgi-xp/xp_main.c98
-rw-r--r--drivers/misc/sgi-xp/xp_nofault.S1
-rw-r--r--drivers/misc/sgi-xp/xpc.h442
-rw-r--r--drivers/misc/sgi-xp/xpc_partition.c328
5 files changed, 396 insertions, 553 deletions
diff --git a/drivers/misc/sgi-xp/xp.h b/drivers/misc/sgi-xp/xp.h
index fb65981754c3..87171682664d 100644
--- a/drivers/misc/sgi-xp/xp.h
+++ b/drivers/misc/sgi-xp/xp.h
@@ -6,30 +6,25 @@
6 * Copyright (C) 2004-2008 Silicon Graphics, Inc. All rights reserved. 6 * Copyright (C) 2004-2008 Silicon Graphics, Inc. All rights reserved.
7 */ 7 */
8 8
9
10/* 9/*
11 * External Cross Partition (XP) structures and defines. 10 * External Cross Partition (XP) structures and defines.
12 */ 11 */
13 12
14
15#ifndef _DRIVERS_MISC_SGIXP_XP_H 13#ifndef _DRIVERS_MISC_SGIXP_XP_H
16#define _DRIVERS_MISC_SGIXP_XP_H 14#define _DRIVERS_MISC_SGIXP_XP_H
17 15
18
19#include <linux/cache.h> 16#include <linux/cache.h>
20#include <linux/hardirq.h> 17#include <linux/hardirq.h>
21#include <linux/mutex.h> 18#include <linux/mutex.h>
22#include <asm/sn/types.h> 19#include <asm/sn/types.h>
23#include <asm/sn/bte.h> 20#include <asm/sn/bte.h>
24 21
25
26#ifdef USE_DBUG_ON 22#ifdef USE_DBUG_ON
27#define DBUG_ON(condition) BUG_ON(condition) 23#define DBUG_ON(condition) BUG_ON(condition)
28#else 24#else
29#define DBUG_ON(condition) 25#define DBUG_ON(condition)
30#endif 26#endif
31 27
32
33/* 28/*
34 * Define the maximum number of logically defined partitions the system 29 * Define the maximum number of logically defined partitions the system
35 * can support. It is constrained by the maximum number of hardware 30 * can support. It is constrained by the maximum number of hardware
@@ -43,7 +38,6 @@
43 */ 38 */
44#define XP_MAX_PARTITIONS 64 39#define XP_MAX_PARTITIONS 64
45 40
46
47/* 41/*
48 * Define the number of u64s required to represent all the C-brick nasids 42 * Define the number of u64s required to represent all the C-brick nasids
49 * as a bitmap. The cross-partition kernel modules deal only with 43 * as a bitmap. The cross-partition kernel modules deal only with
@@ -54,7 +48,6 @@
54#define XP_NASID_MASK_BYTES ((XP_MAX_PHYSNODE_ID + 7) / 8) 48#define XP_NASID_MASK_BYTES ((XP_MAX_PHYSNODE_ID + 7) / 8)
55#define XP_NASID_MASK_WORDS ((XP_MAX_PHYSNODE_ID + 63) / 64) 49#define XP_NASID_MASK_WORDS ((XP_MAX_PHYSNODE_ID + 63) / 64)
56 50
57
58/* 51/*
59 * Wrapper for bte_copy() that should it return a failure status will retry 52 * Wrapper for bte_copy() that should it return a failure status will retry
60 * the bte_copy() once in the hope that the failure was due to a temporary 53 * the bte_copy() once in the hope that the failure was due to a temporary
@@ -74,7 +67,6 @@ xp_bte_copy(u64 src, u64 vdst, u64 len, u64 mode, void *notification)
74 bte_result_t ret; 67 bte_result_t ret;
75 u64 pdst = ia64_tpa(vdst); 68 u64 pdst = ia64_tpa(vdst);
76 69
77
78 /* 70 /*
79 * Ensure that the physically mapped memory is contiguous. 71 * Ensure that the physically mapped memory is contiguous.
80 * 72 *
@@ -96,7 +88,6 @@ xp_bte_copy(u64 src, u64 vdst, u64 len, u64 mode, void *notification)
96 return ret; 88 return ret;
97} 89}
98 90
99
100/* 91/*
101 * XPC establishes channel connections between the local partition and any 92 * XPC establishes channel connections between the local partition and any
102 * other partition that is currently up. Over these channels, kernel-level 93 * other partition that is currently up. Over these channels, kernel-level
@@ -122,7 +113,6 @@ xp_bte_copy(u64 src, u64 vdst, u64 len, u64 mode, void *notification)
122#error XPC_NCHANNELS exceeds MAXIMUM allowed. 113#error XPC_NCHANNELS exceeds MAXIMUM allowed.
123#endif 114#endif
124 115
125
126/* 116/*
127 * The format of an XPC message is as follows: 117 * The format of an XPC message is as follows:
128 * 118 *
@@ -160,12 +150,10 @@ struct xpc_msg {
160 u64 payload; /* user defined portion of message */ 150 u64 payload; /* user defined portion of message */
161}; 151};
162 152
163
164#define XPC_MSG_PAYLOAD_OFFSET (u64) (&((struct xpc_msg *)0)->payload) 153#define XPC_MSG_PAYLOAD_OFFSET (u64) (&((struct xpc_msg *)0)->payload)
165#define XPC_MSG_SIZE(_payload_size) \ 154#define XPC_MSG_SIZE(_payload_size) \
166 L1_CACHE_ALIGN(XPC_MSG_PAYLOAD_OFFSET + (_payload_size)) 155 L1_CACHE_ALIGN(XPC_MSG_PAYLOAD_OFFSET + (_payload_size))
167 156
168
169/* 157/*
170 * Define the return values and values passed to user's callout functions. 158 * Define the return values and values passed to user's callout functions.
171 * (It is important to add new value codes at the end just preceding 159 * (It is important to add new value codes at the end just preceding
@@ -270,7 +258,6 @@ enum xpc_retval {
270 xpcUnknownReason /* 116: unknown reason -- must be last in list */ 258 xpcUnknownReason /* 116: unknown reason -- must be last in list */
271}; 259};
272 260
273
274/* 261/*
275 * Define the callout function types used by XPC to update the user on 262 * Define the callout function types used by XPC to update the user on
276 * connection activity and state changes (via the user function registered by 263 * connection activity and state changes (via the user function registered by
@@ -375,12 +362,11 @@ enum xpc_retval {
375 * =====================+================================+===================== 362 * =====================+================================+=====================
376 */ 363 */
377 364
378typedef void (*xpc_channel_func)(enum xpc_retval reason, partid_t partid, 365typedef void (*xpc_channel_func) (enum xpc_retval reason, partid_t partid,
379 int ch_number, void *data, void *key); 366 int ch_number, void *data, void *key);
380
381typedef void (*xpc_notify_func)(enum xpc_retval reason, partid_t partid,
382 int ch_number, void *key);
383 367
368typedef void (*xpc_notify_func) (enum xpc_retval reason, partid_t partid,
369 int ch_number, void *key);
384 370
385/* 371/*
386 * The following is a registration entry. There is a global array of these, 372 * The following is a registration entry. There is a global array of these,
@@ -398,50 +384,45 @@ typedef void (*xpc_notify_func)(enum xpc_retval reason, partid_t partid,
398 */ 384 */
399struct xpc_registration { 385struct xpc_registration {
400 struct mutex mutex; 386 struct mutex mutex;
401 xpc_channel_func func; /* function to call */ 387 xpc_channel_func func; /* function to call */
402 void *key; /* pointer to user's key */ 388 void *key; /* pointer to user's key */
403 u16 nentries; /* #of msg entries in local msg queue */ 389 u16 nentries; /* #of msg entries in local msg queue */
404 u16 msg_size; /* message queue's message size */ 390 u16 msg_size; /* message queue's message size */
405 u32 assigned_limit; /* limit on #of assigned kthreads */ 391 u32 assigned_limit; /* limit on #of assigned kthreads */
406 u32 idle_limit; /* limit on #of idle kthreads */ 392 u32 idle_limit; /* limit on #of idle kthreads */
407} ____cacheline_aligned; 393} ____cacheline_aligned;
408 394
409
410#define XPC_CHANNEL_REGISTERED(_c) (xpc_registrations[_c].func != NULL) 395#define XPC_CHANNEL_REGISTERED(_c) (xpc_registrations[_c].func != NULL)
411 396
412
413/* the following are valid xpc_allocate() flags */ 397/* the following are valid xpc_allocate() flags */
414#define XPC_WAIT 0 /* wait flag */ 398#define XPC_WAIT 0 /* wait flag */
415#define XPC_NOWAIT 1 /* no wait flag */ 399#define XPC_NOWAIT 1 /* no wait flag */
416
417 400
418struct xpc_interface { 401struct xpc_interface {
419 void (*connect)(int); 402 void (*connect) (int);
420 void (*disconnect)(int); 403 void (*disconnect) (int);
421 enum xpc_retval (*allocate)(partid_t, int, u32, void **); 404 enum xpc_retval (*allocate) (partid_t, int, u32, void **);
422 enum xpc_retval (*send)(partid_t, int, void *); 405 enum xpc_retval (*send) (partid_t, int, void *);
423 enum xpc_retval (*send_notify)(partid_t, int, void *, 406 enum xpc_retval (*send_notify) (partid_t, int, void *,
424 xpc_notify_func, void *); 407 xpc_notify_func, void *);
425 void (*received)(partid_t, int, void *); 408 void (*received) (partid_t, int, void *);
426 enum xpc_retval (*partid_to_nasids)(partid_t, void *); 409 enum xpc_retval (*partid_to_nasids) (partid_t, void *);
427}; 410};
428 411
429
430extern struct xpc_interface xpc_interface; 412extern struct xpc_interface xpc_interface;
431 413
432extern void xpc_set_interface(void (*)(int), 414extern void xpc_set_interface(void (*)(int),
433 void (*)(int), 415 void (*)(int),
434 enum xpc_retval (*)(partid_t, int, u32, void **), 416 enum xpc_retval (*)(partid_t, int, u32, void **),
435 enum xpc_retval (*)(partid_t, int, void *), 417 enum xpc_retval (*)(partid_t, int, void *),
436 enum xpc_retval (*)(partid_t, int, void *, xpc_notify_func, 418 enum xpc_retval (*)(partid_t, int, void *,
437 void *), 419 xpc_notify_func, void *),
438 void (*)(partid_t, int, void *), 420 void (*)(partid_t, int, void *),
439 enum xpc_retval (*)(partid_t, void *)); 421 enum xpc_retval (*)(partid_t, void *));
440extern void xpc_clear_interface(void); 422extern void xpc_clear_interface(void);
441 423
442
443extern enum xpc_retval xpc_connect(int, xpc_channel_func, void *, u16, 424extern enum xpc_retval xpc_connect(int, xpc_channel_func, void *, u16,
444 u16, u32, u32); 425 u16, u32, u32);
445extern void xpc_disconnect(int); 426extern void xpc_disconnect(int);
446 427
447static inline enum xpc_retval 428static inline enum xpc_retval
@@ -458,7 +439,7 @@ xpc_send(partid_t partid, int ch_number, void *payload)
458 439
459static inline enum xpc_retval 440static inline enum xpc_retval
460xpc_send_notify(partid_t partid, int ch_number, void *payload, 441xpc_send_notify(partid_t partid, int ch_number, void *payload,
461 xpc_notify_func func, void *key) 442 xpc_notify_func func, void *key)
462{ 443{
463 return xpc_interface.send_notify(partid, ch_number, payload, func, key); 444 return xpc_interface.send_notify(partid, ch_number, payload, func, key);
464} 445}
@@ -475,11 +456,8 @@ xpc_partid_to_nasids(partid_t partid, void *nasids)
475 return xpc_interface.partid_to_nasids(partid, nasids); 456 return xpc_interface.partid_to_nasids(partid, nasids);
476} 457}
477 458
478
479extern u64 xp_nofault_PIOR_target; 459extern u64 xp_nofault_PIOR_target;
480extern int xp_nofault_PIOR(void *); 460extern int xp_nofault_PIOR(void *);
481extern int xp_error_PIOR(void); 461extern int xp_error_PIOR(void);
482 462
483
484#endif /* _DRIVERS_MISC_SGIXP_XP_H */ 463#endif /* _DRIVERS_MISC_SGIXP_XP_H */
485
diff --git a/drivers/misc/sgi-xp/xp_main.c b/drivers/misc/sgi-xp/xp_main.c
index 5f9f9c2e9298..bb9257642fcf 100644
--- a/drivers/misc/sgi-xp/xp_main.c
+++ b/drivers/misc/sgi-xp/xp_main.c
@@ -6,7 +6,6 @@
6 * Copyright (c) 2004-2008 Silicon Graphics, Inc. All Rights Reserved. 6 * Copyright (c) 2004-2008 Silicon Graphics, Inc. All Rights Reserved.
7 */ 7 */
8 8
9
10/* 9/*
11 * Cross Partition (XP) base. 10 * Cross Partition (XP) base.
12 * 11 *
@@ -15,7 +14,6 @@
15 * 14 *
16 */ 15 */
17 16
18
19#include <linux/kernel.h> 17#include <linux/kernel.h>
20#include <linux/interrupt.h> 18#include <linux/interrupt.h>
21#include <linux/module.h> 19#include <linux/module.h>
@@ -24,49 +22,49 @@
24#include <asm/sn/sn_sal.h> 22#include <asm/sn/sn_sal.h>
25#include "xp.h" 23#include "xp.h"
26 24
27
28/* 25/*
29 * Target of nofault PIO read. 26 * Target of nofault PIO read.
30 */ 27 */
31u64 xp_nofault_PIOR_target; 28u64 xp_nofault_PIOR_target;
32 29
33
34/* 30/*
35 * xpc_registrations[] keeps track of xpc_connect()'s done by the kernel-level 31 * xpc_registrations[] keeps track of xpc_connect()'s done by the kernel-level
36 * users of XPC. 32 * users of XPC.
37 */ 33 */
38struct xpc_registration xpc_registrations[XPC_NCHANNELS]; 34struct xpc_registration xpc_registrations[XPC_NCHANNELS];
39 35
40
41/* 36/*
42 * Initialize the XPC interface to indicate that XPC isn't loaded. 37 * Initialize the XPC interface to indicate that XPC isn't loaded.
43 */ 38 */
44static enum xpc_retval xpc_notloaded(void) { return xpcNotLoaded; } 39static enum xpc_retval
40xpc_notloaded(void)
41{
42 return xpcNotLoaded;
43}
45 44
46struct xpc_interface xpc_interface = { 45struct xpc_interface xpc_interface = {
47 (void (*)(int)) xpc_notloaded, 46 (void (*)(int))xpc_notloaded,
48 (void (*)(int)) xpc_notloaded, 47 (void (*)(int))xpc_notloaded,
49 (enum xpc_retval (*)(partid_t, int, u32, void **)) xpc_notloaded, 48 (enum xpc_retval(*)(partid_t, int, u32, void **))xpc_notloaded,
50 (enum xpc_retval (*)(partid_t, int, void *)) xpc_notloaded, 49 (enum xpc_retval(*)(partid_t, int, void *))xpc_notloaded,
51 (enum xpc_retval (*)(partid_t, int, void *, xpc_notify_func, void *)) 50 (enum xpc_retval(*)(partid_t, int, void *, xpc_notify_func, void *))
52 xpc_notloaded, 51 xpc_notloaded,
53 (void (*)(partid_t, int, void *)) xpc_notloaded, 52 (void (*)(partid_t, int, void *))xpc_notloaded,
54 (enum xpc_retval (*)(partid_t, void *)) xpc_notloaded 53 (enum xpc_retval(*)(partid_t, void *))xpc_notloaded
55}; 54};
56 55
57
58/* 56/*
59 * XPC calls this when it (the XPC module) has been loaded. 57 * XPC calls this when it (the XPC module) has been loaded.
60 */ 58 */
61void 59void
62xpc_set_interface(void (*connect)(int), 60xpc_set_interface(void (*connect) (int),
63 void (*disconnect)(int), 61 void (*disconnect) (int),
64 enum xpc_retval (*allocate)(partid_t, int, u32, void **), 62 enum xpc_retval (*allocate) (partid_t, int, u32, void **),
65 enum xpc_retval (*send)(partid_t, int, void *), 63 enum xpc_retval (*send) (partid_t, int, void *),
66 enum xpc_retval (*send_notify)(partid_t, int, void *, 64 enum xpc_retval (*send_notify) (partid_t, int, void *,
67 xpc_notify_func, void *), 65 xpc_notify_func, void *),
68 void (*received)(partid_t, int, void *), 66 void (*received) (partid_t, int, void *),
69 enum xpc_retval (*partid_to_nasids)(partid_t, void *)) 67 enum xpc_retval (*partid_to_nasids) (partid_t, void *))
70{ 68{
71 xpc_interface.connect = connect; 69 xpc_interface.connect = connect;
72 xpc_interface.disconnect = disconnect; 70 xpc_interface.disconnect = disconnect;
@@ -77,28 +75,27 @@ xpc_set_interface(void (*connect)(int),
77 xpc_interface.partid_to_nasids = partid_to_nasids; 75 xpc_interface.partid_to_nasids = partid_to_nasids;
78} 76}
79 77
80
81/* 78/*
82 * XPC calls this when it (the XPC module) is being unloaded. 79 * XPC calls this when it (the XPC module) is being unloaded.
83 */ 80 */
84void 81void
85xpc_clear_interface(void) 82xpc_clear_interface(void)
86{ 83{
87 xpc_interface.connect = (void (*)(int)) xpc_notloaded; 84 xpc_interface.connect = (void (*)(int))xpc_notloaded;
88 xpc_interface.disconnect = (void (*)(int)) xpc_notloaded; 85 xpc_interface.disconnect = (void (*)(int))xpc_notloaded;
89 xpc_interface.allocate = (enum xpc_retval (*)(partid_t, int, u32, 86 xpc_interface.allocate = (enum xpc_retval(*)(partid_t, int, u32,
90 void **)) xpc_notloaded; 87 void **))xpc_notloaded;
91 xpc_interface.send = (enum xpc_retval (*)(partid_t, int, void *)) 88 xpc_interface.send = (enum xpc_retval(*)(partid_t, int, void *))
92 xpc_notloaded; 89 xpc_notloaded;
93 xpc_interface.send_notify = (enum xpc_retval (*)(partid_t, int, void *, 90 xpc_interface.send_notify = (enum xpc_retval(*)(partid_t, int, void *,
94 xpc_notify_func, void *)) xpc_notloaded; 91 xpc_notify_func,
92 void *))xpc_notloaded;
95 xpc_interface.received = (void (*)(partid_t, int, void *)) 93 xpc_interface.received = (void (*)(partid_t, int, void *))
96 xpc_notloaded; 94 xpc_notloaded;
97 xpc_interface.partid_to_nasids = (enum xpc_retval (*)(partid_t, void *)) 95 xpc_interface.partid_to_nasids = (enum xpc_retval(*)(partid_t, void *))
98 xpc_notloaded; 96 xpc_notloaded;
99} 97}
100 98
101
102/* 99/*
103 * Register for automatic establishment of a channel connection whenever 100 * Register for automatic establishment of a channel connection whenever
104 * a partition comes up. 101 * a partition comes up.
@@ -125,11 +122,10 @@ xpc_clear_interface(void)
125 */ 122 */
126enum xpc_retval 123enum xpc_retval
127xpc_connect(int ch_number, xpc_channel_func func, void *key, u16 payload_size, 124xpc_connect(int ch_number, xpc_channel_func func, void *key, u16 payload_size,
128 u16 nentries, u32 assigned_limit, u32 idle_limit) 125 u16 nentries, u32 assigned_limit, u32 idle_limit)
129{ 126{
130 struct xpc_registration *registration; 127 struct xpc_registration *registration;
131 128
132
133 DBUG_ON(ch_number < 0 || ch_number >= XPC_NCHANNELS); 129 DBUG_ON(ch_number < 0 || ch_number >= XPC_NCHANNELS);
134 DBUG_ON(payload_size == 0 || nentries == 0); 130 DBUG_ON(payload_size == 0 || nentries == 0);
135 DBUG_ON(func == NULL); 131 DBUG_ON(func == NULL);
@@ -162,7 +158,6 @@ xpc_connect(int ch_number, xpc_channel_func func, void *key, u16 payload_size,
162 return xpcSuccess; 158 return xpcSuccess;
163} 159}
164 160
165
166/* 161/*
167 * Remove the registration for automatic connection of the specified channel 162 * Remove the registration for automatic connection of the specified channel
168 * when a partition comes up. 163 * when a partition comes up.
@@ -181,7 +176,6 @@ xpc_disconnect(int ch_number)
181{ 176{
182 struct xpc_registration *registration; 177 struct xpc_registration *registration;
183 178
184
185 DBUG_ON(ch_number < 0 || ch_number >= XPC_NCHANNELS); 179 DBUG_ON(ch_number < 0 || ch_number >= XPC_NCHANNELS);
186 180
187 registration = &xpc_registrations[ch_number]; 181 registration = &xpc_registrations[ch_number];
@@ -214,14 +208,12 @@ xpc_disconnect(int ch_number)
214 return; 208 return;
215} 209}
216 210
217
218int __init 211int __init
219xp_init(void) 212xp_init(void)
220{ 213{
221 int ret, ch_number; 214 int ret, ch_number;
222 u64 func_addr = *(u64 *) xp_nofault_PIOR; 215 u64 func_addr = *(u64 *)xp_nofault_PIOR;
223 u64 err_func_addr = *(u64 *) xp_error_PIOR; 216 u64 err_func_addr = *(u64 *)xp_error_PIOR;
224
225 217
226 if (!ia64_platform_is("sn2")) { 218 if (!ia64_platform_is("sn2")) {
227 return -ENODEV; 219 return -ENODEV;
@@ -237,9 +229,9 @@ xp_init(void)
237 * work around). 229 * work around).
238 */ 230 */
239 if ((ret = sn_register_nofault_code(func_addr, err_func_addr, 231 if ((ret = sn_register_nofault_code(func_addr, err_func_addr,
240 err_func_addr, 1, 1)) != 0) { 232 err_func_addr, 1, 1)) != 0) {
241 printk(KERN_ERR "XP: can't register nofault code, error=%d\n", 233 printk(KERN_ERR "XP: can't register nofault code, error=%d\n",
242 ret); 234 ret);
243 } 235 }
244 /* 236 /*
245 * Setup the nofault PIO read target. (There is no special reason why 237 * Setup the nofault PIO read target. (There is no special reason why
@@ -258,22 +250,21 @@ xp_init(void)
258 250
259 return 0; 251 return 0;
260} 252}
261module_init(xp_init);
262 253
254module_init(xp_init);
263 255
264void __exit 256void __exit
265xp_exit(void) 257xp_exit(void)
266{ 258{
267 u64 func_addr = *(u64 *) xp_nofault_PIOR; 259 u64 func_addr = *(u64 *)xp_nofault_PIOR;
268 u64 err_func_addr = *(u64 *) xp_error_PIOR; 260 u64 err_func_addr = *(u64 *)xp_error_PIOR;
269
270 261
271 /* unregister the PIO read nofault code region */ 262 /* unregister the PIO read nofault code region */
272 (void) sn_register_nofault_code(func_addr, err_func_addr, 263 (void)sn_register_nofault_code(func_addr, err_func_addr,
273 err_func_addr, 1, 0); 264 err_func_addr, 1, 0);
274} 265}
275module_exit(xp_exit);
276 266
267module_exit(xp_exit);
277 268
278MODULE_AUTHOR("Silicon Graphics, Inc."); 269MODULE_AUTHOR("Silicon Graphics, Inc.");
279MODULE_DESCRIPTION("Cross Partition (XP) base"); 270MODULE_DESCRIPTION("Cross Partition (XP) base");
@@ -287,4 +278,3 @@ EXPORT_SYMBOL(xpc_clear_interface);
287EXPORT_SYMBOL(xpc_set_interface); 278EXPORT_SYMBOL(xpc_set_interface);
288EXPORT_SYMBOL(xpc_connect); 279EXPORT_SYMBOL(xpc_connect);
289EXPORT_SYMBOL(xpc_disconnect); 280EXPORT_SYMBOL(xpc_disconnect);
290
diff --git a/drivers/misc/sgi-xp/xp_nofault.S b/drivers/misc/sgi-xp/xp_nofault.S
index c13a709c4db5..e38d43319429 100644
--- a/drivers/misc/sgi-xp/xp_nofault.S
+++ b/drivers/misc/sgi-xp/xp_nofault.S
@@ -6,7 +6,6 @@
6 * Copyright (c) 2004-2008 Silicon Graphics, Inc. All Rights Reserved. 6 * Copyright (c) 2004-2008 Silicon Graphics, Inc. All Rights Reserved.
7 */ 7 */
8 8
9
10/* 9/*
11 * The xp_nofault_PIOR function takes a pointer to a remote PIO register 10 * The xp_nofault_PIOR function takes a pointer to a remote PIO register
12 * and attempts to load and consume a value from it. This function 11 * and attempts to load and consume a value from it. This function
diff --git a/drivers/misc/sgi-xp/xpc.h b/drivers/misc/sgi-xp/xpc.h
index 14e70ee53ebe..64368bb88890 100644
--- a/drivers/misc/sgi-xp/xpc.h
+++ b/drivers/misc/sgi-xp/xpc.h
@@ -6,7 +6,6 @@
6 * Copyright (c) 2004-2008 Silicon Graphics, Inc. All Rights Reserved. 6 * Copyright (c) 2004-2008 Silicon Graphics, Inc. All Rights Reserved.
7 */ 7 */
8 8
9
10/* 9/*
11 * Cross Partition Communication (XPC) structures and macros. 10 * Cross Partition Communication (XPC) structures and macros.
12 */ 11 */
@@ -14,7 +13,6 @@
14#ifndef _DRIVERS_MISC_SGIXP_XPC_H 13#ifndef _DRIVERS_MISC_SGIXP_XPC_H
15#define _DRIVERS_MISC_SGIXP_XPC_H 14#define _DRIVERS_MISC_SGIXP_XPC_H
16 15
17
18#include <linux/interrupt.h> 16#include <linux/interrupt.h>
19#include <linux/sysctl.h> 17#include <linux/sysctl.h>
20#include <linux/device.h> 18#include <linux/device.h>
@@ -29,7 +27,6 @@
29#include <asm/sn/shub_mmr.h> 27#include <asm/sn/shub_mmr.h>
30#include "xp.h" 28#include "xp.h"
31 29
32
33/* 30/*
34 * XPC Version numbers consist of a major and minor number. XPC can always 31 * XPC Version numbers consist of a major and minor number. XPC can always
35 * talk to versions with same major #, and never talk to versions with a 32 * talk to versions with same major #, and never talk to versions with a
@@ -39,7 +36,6 @@
39#define XPC_VERSION_MAJOR(_v) ((_v) >> 4) 36#define XPC_VERSION_MAJOR(_v) ((_v) >> 4)
40#define XPC_VERSION_MINOR(_v) ((_v) & 0xf) 37#define XPC_VERSION_MINOR(_v) ((_v) & 0xf)
41 38
42
43/* 39/*
44 * The next macros define word or bit representations for given 40 * The next macros define word or bit representations for given
45 * C-brick nasid in either the SAL provided bit array representing 41 * C-brick nasid in either the SAL provided bit array representing
@@ -67,7 +63,6 @@
67/* define the process name of the discovery thread */ 63/* define the process name of the discovery thread */
68#define XPC_DISCOVERY_THREAD_NAME "xpc_discovery" 64#define XPC_DISCOVERY_THREAD_NAME "xpc_discovery"
69 65
70
71/* 66/*
72 * the reserved page 67 * the reserved page
73 * 68 *
@@ -121,7 +116,7 @@ struct xpc_rsvd_page {
121 u64 nasids_size; /* SAL: size of each nasid mask in bytes */ 116 u64 nasids_size; /* SAL: size of each nasid mask in bytes */
122}; 117};
123 118
124#define XPC_RP_VERSION _XPC_VERSION(1,1) /* version 1.1 of the reserved page */ 119#define XPC_RP_VERSION _XPC_VERSION(1,1) /* version 1.1 of the reserved page */
125 120
126#define XPC_SUPPORTS_RP_STAMP(_version) \ 121#define XPC_SUPPORTS_RP_STAMP(_version) \
127 (_version >= _XPC_VERSION(1,1)) 122 (_version >= _XPC_VERSION(1,1))
@@ -138,14 +133,12 @@ xpc_compare_stamps(struct timespec *stamp1, struct timespec *stamp2)
138{ 133{
139 int ret; 134 int ret;
140 135
141
142 if ((ret = stamp1->tv_sec - stamp2->tv_sec) == 0) { 136 if ((ret = stamp1->tv_sec - stamp2->tv_sec) == 0) {
143 ret = stamp1->tv_nsec - stamp2->tv_nsec; 137 ret = stamp1->tv_nsec - stamp2->tv_nsec;
144 } 138 }
145 return ret; 139 return ret;
146} 140}
147 141
148
149/* 142/*
150 * Define the structures by which XPC variables can be exported to other 143 * Define the structures by which XPC variables can be exported to other
151 * partitions. (There are two: struct xpc_vars and struct xpc_vars_part) 144 * partitions. (There are two: struct xpc_vars and struct xpc_vars_part)
@@ -172,12 +165,11 @@ struct xpc_vars {
172 AMO_t *amos_page; /* vaddr of page of AMOs from MSPEC driver */ 165 AMO_t *amos_page; /* vaddr of page of AMOs from MSPEC driver */
173}; 166};
174 167
175#define XPC_V_VERSION _XPC_VERSION(3,1) /* version 3.1 of the cross vars */ 168#define XPC_V_VERSION _XPC_VERSION(3,1) /* version 3.1 of the cross vars */
176 169
177#define XPC_SUPPORTS_DISENGAGE_REQUEST(_version) \ 170#define XPC_SUPPORTS_DISENGAGE_REQUEST(_version) \
178 (_version >= _XPC_VERSION(3,1)) 171 (_version >= _XPC_VERSION(3,1))
179 172
180
181static inline int 173static inline int
182xpc_hb_allowed(partid_t partid, struct xpc_vars *vars) 174xpc_hb_allowed(partid_t partid, struct xpc_vars *vars)
183{ 175{
@@ -193,7 +185,7 @@ xpc_allow_hb(partid_t partid, struct xpc_vars *vars)
193 old_mask = vars->heartbeating_to_mask; 185 old_mask = vars->heartbeating_to_mask;
194 new_mask = (old_mask | (1UL << partid)); 186 new_mask = (old_mask | (1UL << partid));
195 } while (cmpxchg(&vars->heartbeating_to_mask, old_mask, new_mask) != 187 } while (cmpxchg(&vars->heartbeating_to_mask, old_mask, new_mask) !=
196 old_mask); 188 old_mask);
197} 189}
198 190
199static inline void 191static inline void
@@ -205,10 +197,9 @@ xpc_disallow_hb(partid_t partid, struct xpc_vars *vars)
205 old_mask = vars->heartbeating_to_mask; 197 old_mask = vars->heartbeating_to_mask;
206 new_mask = (old_mask & ~(1UL << partid)); 198 new_mask = (old_mask & ~(1UL << partid));
207 } while (cmpxchg(&vars->heartbeating_to_mask, old_mask, new_mask) != 199 } while (cmpxchg(&vars->heartbeating_to_mask, old_mask, new_mask) !=
208 old_mask); 200 old_mask);
209} 201}
210 202
211
212/* 203/*
213 * The AMOs page consists of a number of AMO variables which are divided into 204 * The AMOs page consists of a number of AMO variables which are divided into
214 * four groups, The first two groups are used to identify an IRQ's sender. 205 * four groups, The first two groups are used to identify an IRQ's sender.
@@ -222,7 +213,6 @@ xpc_disallow_hb(partid_t partid, struct xpc_vars *vars)
222#define XPC_ENGAGED_PARTITIONS_AMO (XPC_ACTIVATE_IRQ_AMOS + XP_NASID_MASK_WORDS) 213#define XPC_ENGAGED_PARTITIONS_AMO (XPC_ACTIVATE_IRQ_AMOS + XP_NASID_MASK_WORDS)
223#define XPC_DISENGAGE_REQUEST_AMO (XPC_ENGAGED_PARTITIONS_AMO + 1) 214#define XPC_DISENGAGE_REQUEST_AMO (XPC_ENGAGED_PARTITIONS_AMO + 1)
224 215
225
226/* 216/*
227 * The following structure describes the per partition specific variables. 217 * The following structure describes the per partition specific variables.
228 * 218 *
@@ -257,9 +247,8 @@ struct xpc_vars_part {
257 * MAGIC2 indicates that this partition has pulled the remote partititions 247 * MAGIC2 indicates that this partition has pulled the remote partititions
258 * per partition variables that pertain to this partition. 248 * per partition variables that pertain to this partition.
259 */ 249 */
260#define XPC_VP_MAGIC1 0x0053524156435058L /* 'XPCVARS\0'L (little endian) */ 250#define XPC_VP_MAGIC1 0x0053524156435058L /* 'XPCVARS\0'L (little endian) */
261#define XPC_VP_MAGIC2 0x0073726176435058L /* 'XPCvars\0'L (little endian) */ 251#define XPC_VP_MAGIC2 0x0073726176435058L /* 'XPCvars\0'L (little endian) */
262
263 252
264/* the reserved page sizes and offsets */ 253/* the reserved page sizes and offsets */
265 254
@@ -271,7 +260,6 @@ struct xpc_vars_part {
271#define XPC_RP_VARS(_rp) ((struct xpc_vars *) XPC_RP_MACH_NASIDS(_rp) + xp_nasid_mask_words) 260#define XPC_RP_VARS(_rp) ((struct xpc_vars *) XPC_RP_MACH_NASIDS(_rp) + xp_nasid_mask_words)
272#define XPC_RP_VARS_PART(_rp) (struct xpc_vars_part *) ((u8 *) XPC_RP_VARS(rp) + XPC_RP_VARS_SIZE) 261#define XPC_RP_VARS_PART(_rp) (struct xpc_vars_part *) ((u8 *) XPC_RP_VARS(rp) + XPC_RP_VARS_SIZE)
273 262
274
275/* 263/*
276 * Functions registered by add_timer() or called by kernel_thread() only 264 * Functions registered by add_timer() or called by kernel_thread() only
277 * allow for a single 64-bit argument. The following macros can be used to 265 * allow for a single 64-bit argument. The following macros can be used to
@@ -285,8 +273,6 @@ struct xpc_vars_part {
285#define XPC_UNPACK_ARG1(_args) (((u64) _args) & 0xffffffff) 273#define XPC_UNPACK_ARG1(_args) (((u64) _args) & 0xffffffff)
286#define XPC_UNPACK_ARG2(_args) ((((u64) _args) >> 32) & 0xffffffff) 274#define XPC_UNPACK_ARG2(_args) ((((u64) _args) >> 32) & 0xffffffff)
287 275
288
289
290/* 276/*
291 * Define a Get/Put value pair (pointers) used with a message queue. 277 * Define a Get/Put value pair (pointers) used with a message queue.
292 */ 278 */
@@ -298,8 +284,6 @@ struct xpc_gp {
298#define XPC_GP_SIZE \ 284#define XPC_GP_SIZE \
299 L1_CACHE_ALIGN(sizeof(struct xpc_gp) * XPC_NCHANNELS) 285 L1_CACHE_ALIGN(sizeof(struct xpc_gp) * XPC_NCHANNELS)
300 286
301
302
303/* 287/*
304 * Define a structure that contains arguments associated with opening and 288 * Define a structure that contains arguments associated with opening and
305 * closing a channel. 289 * closing a channel.
@@ -315,20 +299,15 @@ struct xpc_openclose_args {
315#define XPC_OPENCLOSE_ARGS_SIZE \ 299#define XPC_OPENCLOSE_ARGS_SIZE \
316 L1_CACHE_ALIGN(sizeof(struct xpc_openclose_args) * XPC_NCHANNELS) 300 L1_CACHE_ALIGN(sizeof(struct xpc_openclose_args) * XPC_NCHANNELS)
317 301
318
319
320/* struct xpc_msg flags */ 302/* struct xpc_msg flags */
321 303
322#define XPC_M_DONE 0x01 /* msg has been received/consumed */ 304#define XPC_M_DONE 0x01 /* msg has been received/consumed */
323#define XPC_M_READY 0x02 /* msg is ready to be sent */ 305#define XPC_M_READY 0x02 /* msg is ready to be sent */
324#define XPC_M_INTERRUPT 0x04 /* send interrupt when msg consumed */ 306#define XPC_M_INTERRUPT 0x04 /* send interrupt when msg consumed */
325 307
326
327#define XPC_MSG_ADDRESS(_payload) \ 308#define XPC_MSG_ADDRESS(_payload) \
328 ((struct xpc_msg *)((u8 *)(_payload) - XPC_MSG_PAYLOAD_OFFSET)) 309 ((struct xpc_msg *)((u8 *)(_payload) - XPC_MSG_PAYLOAD_OFFSET))
329 310
330
331
332/* 311/*
333 * Defines notify entry. 312 * Defines notify entry.
334 * 313 *
@@ -336,19 +315,17 @@ struct xpc_openclose_args {
336 * and consumed by the intended recipient. 315 * and consumed by the intended recipient.
337 */ 316 */
338struct xpc_notify { 317struct xpc_notify {
339 volatile u8 type; /* type of notification */ 318 volatile u8 type; /* type of notification */
340 319
341 /* the following two fields are only used if type == XPC_N_CALL */ 320 /* the following two fields are only used if type == XPC_N_CALL */
342 xpc_notify_func func; /* user's notify function */ 321 xpc_notify_func func; /* user's notify function */
343 void *key; /* pointer to user's key */ 322 void *key; /* pointer to user's key */
344}; 323};
345 324
346/* struct xpc_notify type of notification */ 325/* struct xpc_notify type of notification */
347 326
348#define XPC_N_CALL 0x01 /* notify function provided by user */ 327#define XPC_N_CALL 0x01 /* notify function provided by user */
349 328
350
351
352/* 329/*
353 * Define the structure that manages all the stuff required by a channel. In 330 * Define the structure that manages all the stuff required by a channel. In
354 * particular, they are used to manage the messages sent across the channel. 331 * particular, they are used to manage the messages sent across the channel.
@@ -428,48 +405,48 @@ struct xpc_notify {
428 * messages. 405 * messages.
429 */ 406 */
430struct xpc_channel { 407struct xpc_channel {
431 partid_t partid; /* ID of remote partition connected */ 408 partid_t partid; /* ID of remote partition connected */
432 spinlock_t lock; /* lock for updating this structure */ 409 spinlock_t lock; /* lock for updating this structure */
433 u32 flags; /* general flags */ 410 u32 flags; /* general flags */
434 411
435 enum xpc_retval reason; /* reason why channel is disconnect'g */ 412 enum xpc_retval reason; /* reason why channel is disconnect'g */
436 int reason_line; /* line# disconnect initiated from */ 413 int reason_line; /* line# disconnect initiated from */
437 414
438 u16 number; /* channel # */ 415 u16 number; /* channel # */
439 416
440 u16 msg_size; /* sizeof each msg entry */ 417 u16 msg_size; /* sizeof each msg entry */
441 u16 local_nentries; /* #of msg entries in local msg queue */ 418 u16 local_nentries; /* #of msg entries in local msg queue */
442 u16 remote_nentries; /* #of msg entries in remote msg queue*/ 419 u16 remote_nentries; /* #of msg entries in remote msg queue */
443 420
444 void *local_msgqueue_base; /* base address of kmalloc'd space */ 421 void *local_msgqueue_base; /* base address of kmalloc'd space */
445 struct xpc_msg *local_msgqueue; /* local message queue */ 422 struct xpc_msg *local_msgqueue; /* local message queue */
446 void *remote_msgqueue_base; /* base address of kmalloc'd space */ 423 void *remote_msgqueue_base; /* base address of kmalloc'd space */
447 struct xpc_msg *remote_msgqueue;/* cached copy of remote partition's */ 424 struct xpc_msg *remote_msgqueue; /* cached copy of remote partition's */
448 /* local message queue */ 425 /* local message queue */
449 u64 remote_msgqueue_pa; /* phys addr of remote partition's */ 426 u64 remote_msgqueue_pa; /* phys addr of remote partition's */
450 /* local message queue */ 427 /* local message queue */
451 428
452 atomic_t references; /* #of external references to queues */ 429 atomic_t references; /* #of external references to queues */
453 430
454 atomic_t n_on_msg_allocate_wq; /* #on msg allocation wait queue */ 431 atomic_t n_on_msg_allocate_wq; /* #on msg allocation wait queue */
455 wait_queue_head_t msg_allocate_wq; /* msg allocation wait queue */ 432 wait_queue_head_t msg_allocate_wq; /* msg allocation wait queue */
456 433
457 u8 delayed_IPI_flags; /* IPI flags received, but delayed */ 434 u8 delayed_IPI_flags; /* IPI flags received, but delayed */
458 /* action until channel disconnected */ 435 /* action until channel disconnected */
459 436
460 /* queue of msg senders who want to be notified when msg received */ 437 /* queue of msg senders who want to be notified when msg received */
461 438
462 atomic_t n_to_notify; /* #of msg senders to notify */ 439 atomic_t n_to_notify; /* #of msg senders to notify */
463 struct xpc_notify *notify_queue;/* notify queue for messages sent */ 440 struct xpc_notify *notify_queue; /* notify queue for messages sent */
464 441
465 xpc_channel_func func; /* user's channel function */ 442 xpc_channel_func func; /* user's channel function */
466 void *key; /* pointer to user's key */ 443 void *key; /* pointer to user's key */
467 444
468 struct mutex msg_to_pull_mutex; /* next msg to pull serialization */ 445 struct mutex msg_to_pull_mutex; /* next msg to pull serialization */
469 struct completion wdisconnect_wait; /* wait for channel disconnect */ 446 struct completion wdisconnect_wait; /* wait for channel disconnect */
470 447
471 struct xpc_openclose_args *local_openclose_args; /* args passed on */ 448 struct xpc_openclose_args *local_openclose_args; /* args passed on */
472 /* opening or closing of channel */ 449 /* opening or closing of channel */
473 450
474 /* various flavors of local and remote Get/Put values */ 451 /* various flavors of local and remote Get/Put values */
475 452
@@ -477,7 +454,7 @@ struct xpc_channel {
477 struct xpc_gp remote_GP; /* remote Get/Put values */ 454 struct xpc_gp remote_GP; /* remote Get/Put values */
478 struct xpc_gp w_local_GP; /* working local Get/Put values */ 455 struct xpc_gp w_local_GP; /* working local Get/Put values */
479 struct xpc_gp w_remote_GP; /* working remote Get/Put values */ 456 struct xpc_gp w_remote_GP; /* working remote Get/Put values */
480 s64 next_msg_to_pull; /* Put value of next msg to pull */ 457 s64 next_msg_to_pull; /* Put value of next msg to pull */
481 458
482 /* kthread management related fields */ 459 /* kthread management related fields */
483 460
@@ -485,48 +462,45 @@ struct xpc_channel {
485// >>> allow the assigned limit be unbounded and let the idle limit be dynamic 462// >>> allow the assigned limit be unbounded and let the idle limit be dynamic
486// >>> dependent on activity over the last interval of time 463// >>> dependent on activity over the last interval of time
487 atomic_t kthreads_assigned; /* #of kthreads assigned to channel */ 464 atomic_t kthreads_assigned; /* #of kthreads assigned to channel */
488 u32 kthreads_assigned_limit; /* limit on #of kthreads assigned */ 465 u32 kthreads_assigned_limit; /* limit on #of kthreads assigned */
489 atomic_t kthreads_idle; /* #of kthreads idle waiting for work */ 466 atomic_t kthreads_idle; /* #of kthreads idle waiting for work */
490 u32 kthreads_idle_limit; /* limit on #of kthreads idle */ 467 u32 kthreads_idle_limit; /* limit on #of kthreads idle */
491 atomic_t kthreads_active; /* #of kthreads actively working */ 468 atomic_t kthreads_active; /* #of kthreads actively working */
492 // >>> following field is temporary 469 // >>> following field is temporary
493 u32 kthreads_created; /* total #of kthreads created */ 470 u32 kthreads_created; /* total #of kthreads created */
494 471
495 wait_queue_head_t idle_wq; /* idle kthread wait queue */ 472 wait_queue_head_t idle_wq; /* idle kthread wait queue */
496 473
497} ____cacheline_aligned; 474} ____cacheline_aligned;
498 475
499
500/* struct xpc_channel flags */ 476/* struct xpc_channel flags */
501 477
502#define XPC_C_WASCONNECTED 0x00000001 /* channel was connected */ 478#define XPC_C_WASCONNECTED 0x00000001 /* channel was connected */
503 479
504#define XPC_C_ROPENREPLY 0x00000002 /* remote open channel reply */ 480#define XPC_C_ROPENREPLY 0x00000002 /* remote open channel reply */
505#define XPC_C_OPENREPLY 0x00000004 /* local open channel reply */ 481#define XPC_C_OPENREPLY 0x00000004 /* local open channel reply */
506#define XPC_C_ROPENREQUEST 0x00000008 /* remote open channel request */ 482#define XPC_C_ROPENREQUEST 0x00000008 /* remote open channel request */
507#define XPC_C_OPENREQUEST 0x00000010 /* local open channel request */ 483#define XPC_C_OPENREQUEST 0x00000010 /* local open channel request */
508 484
509#define XPC_C_SETUP 0x00000020 /* channel's msgqueues are alloc'd */ 485#define XPC_C_SETUP 0x00000020 /* channel's msgqueues are alloc'd */
510#define XPC_C_CONNECTEDCALLOUT 0x00000040 /* connected callout initiated */ 486#define XPC_C_CONNECTEDCALLOUT 0x00000040 /* connected callout initiated */
511#define XPC_C_CONNECTEDCALLOUT_MADE \ 487#define XPC_C_CONNECTEDCALLOUT_MADE \
512 0x00000080 /* connected callout completed */ 488 0x00000080 /* connected callout completed */
513#define XPC_C_CONNECTED 0x00000100 /* local channel is connected */ 489#define XPC_C_CONNECTED 0x00000100 /* local channel is connected */
514#define XPC_C_CONNECTING 0x00000200 /* channel is being connected */ 490#define XPC_C_CONNECTING 0x00000200 /* channel is being connected */
515 491
516#define XPC_C_RCLOSEREPLY 0x00000400 /* remote close channel reply */ 492#define XPC_C_RCLOSEREPLY 0x00000400 /* remote close channel reply */
517#define XPC_C_CLOSEREPLY 0x00000800 /* local close channel reply */ 493#define XPC_C_CLOSEREPLY 0x00000800 /* local close channel reply */
518#define XPC_C_RCLOSEREQUEST 0x00001000 /* remote close channel request */ 494#define XPC_C_RCLOSEREQUEST 0x00001000 /* remote close channel request */
519#define XPC_C_CLOSEREQUEST 0x00002000 /* local close channel request */ 495#define XPC_C_CLOSEREQUEST 0x00002000 /* local close channel request */
520 496
521#define XPC_C_DISCONNECTED 0x00004000 /* channel is disconnected */ 497#define XPC_C_DISCONNECTED 0x00004000 /* channel is disconnected */
522#define XPC_C_DISCONNECTING 0x00008000 /* channel is being disconnected */ 498#define XPC_C_DISCONNECTING 0x00008000 /* channel is being disconnected */
523#define XPC_C_DISCONNECTINGCALLOUT \ 499#define XPC_C_DISCONNECTINGCALLOUT \
524 0x00010000 /* disconnecting callout initiated */ 500 0x00010000 /* disconnecting callout initiated */
525#define XPC_C_DISCONNECTINGCALLOUT_MADE \ 501#define XPC_C_DISCONNECTINGCALLOUT_MADE \
526 0x00020000 /* disconnecting callout completed */ 502 0x00020000 /* disconnecting callout completed */
527#define XPC_C_WDISCONNECT 0x00040000 /* waiting for channel disconnect */ 503#define XPC_C_WDISCONNECT 0x00040000 /* waiting for channel disconnect */
528
529
530 504
531/* 505/*
532 * Manages channels on a partition basis. There is one of these structures 506 * Manages channels on a partition basis. There is one of these structures
@@ -537,33 +511,31 @@ struct xpc_partition {
537 511
538 /* XPC HB infrastructure */ 512 /* XPC HB infrastructure */
539 513
540 u8 remote_rp_version; /* version# of partition's rsvd pg */ 514 u8 remote_rp_version; /* version# of partition's rsvd pg */
541 struct timespec remote_rp_stamp;/* time when rsvd pg was initialized */ 515 struct timespec remote_rp_stamp; /* time when rsvd pg was initialized */
542 u64 remote_rp_pa; /* phys addr of partition's rsvd pg */ 516 u64 remote_rp_pa; /* phys addr of partition's rsvd pg */
543 u64 remote_vars_pa; /* phys addr of partition's vars */ 517 u64 remote_vars_pa; /* phys addr of partition's vars */
544 u64 remote_vars_part_pa; /* phys addr of partition's vars part */ 518 u64 remote_vars_part_pa; /* phys addr of partition's vars part */
545 u64 last_heartbeat; /* HB at last read */ 519 u64 last_heartbeat; /* HB at last read */
546 u64 remote_amos_page_pa; /* phys addr of partition's amos page */ 520 u64 remote_amos_page_pa; /* phys addr of partition's amos page */
547 int remote_act_nasid; /* active part's act/deact nasid */ 521 int remote_act_nasid; /* active part's act/deact nasid */
548 int remote_act_phys_cpuid; /* active part's act/deact phys cpuid */ 522 int remote_act_phys_cpuid; /* active part's act/deact phys cpuid */
549 u32 act_IRQ_rcvd; /* IRQs since activation */ 523 u32 act_IRQ_rcvd; /* IRQs since activation */
550 spinlock_t act_lock; /* protect updating of act_state */ 524 spinlock_t act_lock; /* protect updating of act_state */
551 u8 act_state; /* from XPC HB viewpoint */ 525 u8 act_state; /* from XPC HB viewpoint */
552 u8 remote_vars_version; /* version# of partition's vars */ 526 u8 remote_vars_version; /* version# of partition's vars */
553 enum xpc_retval reason; /* reason partition is deactivating */ 527 enum xpc_retval reason; /* reason partition is deactivating */
554 int reason_line; /* line# deactivation initiated from */ 528 int reason_line; /* line# deactivation initiated from */
555 int reactivate_nasid; /* nasid in partition to reactivate */ 529 int reactivate_nasid; /* nasid in partition to reactivate */
556 530
557 unsigned long disengage_request_timeout; /* timeout in jiffies */ 531 unsigned long disengage_request_timeout; /* timeout in jiffies */
558 struct timer_list disengage_request_timer; 532 struct timer_list disengage_request_timer;
559 533
560
561 /* XPC infrastructure referencing and teardown control */ 534 /* XPC infrastructure referencing and teardown control */
562 535
563 volatile u8 setup_state; /* infrastructure setup state */ 536 volatile u8 setup_state; /* infrastructure setup state */
564 wait_queue_head_t teardown_wq; /* kthread waiting to teardown infra */ 537 wait_queue_head_t teardown_wq; /* kthread waiting to teardown infra */
565 atomic_t references; /* #of references to infrastructure */ 538 atomic_t references; /* #of references to infrastructure */
566
567 539
568 /* 540 /*
569 * NONE OF THE PRECEDING FIELDS OF THIS STRUCTURE WILL BE CLEARED WHEN 541 * NONE OF THE PRECEDING FIELDS OF THIS STRUCTURE WILL BE CLEARED WHEN
@@ -572,53 +544,48 @@ struct xpc_partition {
572 * 'nchannels' FIELD MUST BE THE FIRST OF THE FIELDS TO BE CLEARED.) 544 * 'nchannels' FIELD MUST BE THE FIRST OF THE FIELDS TO BE CLEARED.)
573 */ 545 */
574 546
575 547 u8 nchannels; /* #of defined channels supported */
576 u8 nchannels; /* #of defined channels supported */ 548 atomic_t nchannels_active; /* #of channels that are not DISCONNECTED */
577 atomic_t nchannels_active; /* #of channels that are not DISCONNECTED */ 549 atomic_t nchannels_engaged; /* #of channels engaged with remote part */
578 atomic_t nchannels_engaged;/* #of channels engaged with remote part */ 550 struct xpc_channel *channels; /* array of channel structures */
579 struct xpc_channel *channels;/* array of channel structures */ 551
580 552 void *local_GPs_base; /* base address of kmalloc'd space */
581 void *local_GPs_base; /* base address of kmalloc'd space */ 553 struct xpc_gp *local_GPs; /* local Get/Put values */
582 struct xpc_gp *local_GPs; /* local Get/Put values */ 554 void *remote_GPs_base; /* base address of kmalloc'd space */
583 void *remote_GPs_base; /* base address of kmalloc'd space */ 555 struct xpc_gp *remote_GPs; /* copy of remote partition's local Get/Put */
584 struct xpc_gp *remote_GPs;/* copy of remote partition's local Get/Put */ 556 /* values */
585 /* values */ 557 u64 remote_GPs_pa; /* phys address of remote partition's local */
586 u64 remote_GPs_pa; /* phys address of remote partition's local */ 558 /* Get/Put values */
587 /* Get/Put values */
588
589 559
590 /* fields used to pass args when opening or closing a channel */ 560 /* fields used to pass args when opening or closing a channel */
591 561
592 void *local_openclose_args_base; /* base address of kmalloc'd space */ 562 void *local_openclose_args_base; /* base address of kmalloc'd space */
593 struct xpc_openclose_args *local_openclose_args; /* local's args */ 563 struct xpc_openclose_args *local_openclose_args; /* local's args */
594 void *remote_openclose_args_base; /* base address of kmalloc'd space */ 564 void *remote_openclose_args_base; /* base address of kmalloc'd space */
595 struct xpc_openclose_args *remote_openclose_args; /* copy of remote's */ 565 struct xpc_openclose_args *remote_openclose_args; /* copy of remote's */
596 /* args */ 566 /* args */
597 u64 remote_openclose_args_pa; /* phys addr of remote's args */ 567 u64 remote_openclose_args_pa; /* phys addr of remote's args */
598
599 568
600 /* IPI sending, receiving and handling related fields */ 569 /* IPI sending, receiving and handling related fields */
601 570
602 int remote_IPI_nasid; /* nasid of where to send IPIs */ 571 int remote_IPI_nasid; /* nasid of where to send IPIs */
603 int remote_IPI_phys_cpuid; /* phys CPU ID of where to send IPIs */ 572 int remote_IPI_phys_cpuid; /* phys CPU ID of where to send IPIs */
604 AMO_t *remote_IPI_amo_va; /* address of remote IPI AMO_t structure */ 573 AMO_t *remote_IPI_amo_va; /* address of remote IPI AMO_t structure */
605 574
606 AMO_t *local_IPI_amo_va; /* address of IPI AMO_t structure */ 575 AMO_t *local_IPI_amo_va; /* address of IPI AMO_t structure */
607 u64 local_IPI_amo; /* IPI amo flags yet to be handled */ 576 u64 local_IPI_amo; /* IPI amo flags yet to be handled */
608 char IPI_owner[8]; /* IPI owner's name */ 577 char IPI_owner[8]; /* IPI owner's name */
609 struct timer_list dropped_IPI_timer; /* dropped IPI timer */ 578 struct timer_list dropped_IPI_timer; /* dropped IPI timer */
610
611 spinlock_t IPI_lock; /* IPI handler lock */
612 579
580 spinlock_t IPI_lock; /* IPI handler lock */
613 581
614 /* channel manager related fields */ 582 /* channel manager related fields */
615 583
616 atomic_t channel_mgr_requests; /* #of requests to activate chan mgr */ 584 atomic_t channel_mgr_requests; /* #of requests to activate chan mgr */
617 wait_queue_head_t channel_mgr_wq; /* channel mgr's wait queue */ 585 wait_queue_head_t channel_mgr_wq; /* channel mgr's wait queue */
618 586
619} ____cacheline_aligned; 587} ____cacheline_aligned;
620 588
621
622/* struct xpc_partition act_state values (for XPC HB) */ 589/* struct xpc_partition act_state values (for XPC HB) */
623 590
624#define XPC_P_INACTIVE 0x00 /* partition is not active */ 591#define XPC_P_INACTIVE 0x00 /* partition is not active */
@@ -627,11 +594,9 @@ struct xpc_partition {
627#define XPC_P_ACTIVE 0x03 /* xpc_partition_up() was called */ 594#define XPC_P_ACTIVE 0x03 /* xpc_partition_up() was called */
628#define XPC_P_DEACTIVATING 0x04 /* partition deactivation initiated */ 595#define XPC_P_DEACTIVATING 0x04 /* partition deactivation initiated */
629 596
630
631#define XPC_DEACTIVATE_PARTITION(_p, _reason) \ 597#define XPC_DEACTIVATE_PARTITION(_p, _reason) \
632 xpc_deactivate_partition(__LINE__, (_p), (_reason)) 598 xpc_deactivate_partition(__LINE__, (_p), (_reason))
633 599
634
635/* struct xpc_partition setup_state values */ 600/* struct xpc_partition setup_state values */
636 601
637#define XPC_P_UNSET 0x00 /* infrastructure was never setup */ 602#define XPC_P_UNSET 0x00 /* infrastructure was never setup */
@@ -639,8 +604,6 @@ struct xpc_partition {
639#define XPC_P_WTEARDOWN 0x02 /* waiting to teardown infrastructure */ 604#define XPC_P_WTEARDOWN 0x02 /* waiting to teardown infrastructure */
640#define XPC_P_TORNDOWN 0x03 /* infrastructure is torndown */ 605#define XPC_P_TORNDOWN 0x03 /* infrastructure is torndown */
641 606
642
643
644/* 607/*
645 * struct xpc_partition IPI_timer #of seconds to wait before checking for 608 * struct xpc_partition IPI_timer #of seconds to wait before checking for
646 * dropped IPIs. These occur whenever an IPI amo write doesn't complete until 609 * dropped IPIs. These occur whenever an IPI amo write doesn't complete until
@@ -648,22 +611,17 @@ struct xpc_partition {
648 */ 611 */
649#define XPC_P_DROPPED_IPI_WAIT (0.25 * HZ) 612#define XPC_P_DROPPED_IPI_WAIT (0.25 * HZ)
650 613
651
652/* number of seconds to wait for other partitions to disengage */ 614/* number of seconds to wait for other partitions to disengage */
653#define XPC_DISENGAGE_REQUEST_DEFAULT_TIMELIMIT 90 615#define XPC_DISENGAGE_REQUEST_DEFAULT_TIMELIMIT 90
654 616
655/* interval in seconds to print 'waiting disengagement' messages */ 617/* interval in seconds to print 'waiting disengagement' messages */
656#define XPC_DISENGAGE_PRINTMSG_INTERVAL 10 618#define XPC_DISENGAGE_PRINTMSG_INTERVAL 10
657 619
658
659#define XPC_PARTID(_p) ((partid_t) ((_p) - &xpc_partitions[0])) 620#define XPC_PARTID(_p) ((partid_t) ((_p) - &xpc_partitions[0]))
660 621
661
662
663/* found in xp_main.c */ 622/* found in xp_main.c */
664extern struct xpc_registration xpc_registrations[]; 623extern struct xpc_registration xpc_registrations[];
665 624
666
667/* found in xpc_main.c */ 625/* found in xpc_main.c */
668extern struct device *xpc_part; 626extern struct device *xpc_part;
669extern struct device *xpc_chan; 627extern struct device *xpc_chan;
@@ -676,7 +634,6 @@ extern void xpc_activate_kthreads(struct xpc_channel *, int);
676extern void xpc_create_kthreads(struct xpc_channel *, int, int); 634extern void xpc_create_kthreads(struct xpc_channel *, int, int);
677extern void xpc_disconnect_wait(int); 635extern void xpc_disconnect_wait(int);
678 636
679
680/* found in xpc_partition.c */ 637/* found in xpc_partition.c */
681extern int xpc_exiting; 638extern int xpc_exiting;
682extern struct xpc_vars *xpc_vars; 639extern struct xpc_vars *xpc_vars;
@@ -696,10 +653,9 @@ extern void xpc_mark_partition_inactive(struct xpc_partition *);
696extern void xpc_discovery(void); 653extern void xpc_discovery(void);
697extern void xpc_check_remote_hb(void); 654extern void xpc_check_remote_hb(void);
698extern void xpc_deactivate_partition(const int, struct xpc_partition *, 655extern void xpc_deactivate_partition(const int, struct xpc_partition *,
699 enum xpc_retval); 656 enum xpc_retval);
700extern enum xpc_retval xpc_initiate_partid_to_nasids(partid_t, void *); 657extern enum xpc_retval xpc_initiate_partid_to_nasids(partid_t, void *);
701 658
702
703/* found in xpc_channel.c */ 659/* found in xpc_channel.c */
704extern void xpc_initiate_connect(int); 660extern void xpc_initiate_connect(int);
705extern void xpc_initiate_disconnect(int); 661extern void xpc_initiate_disconnect(int);
@@ -714,13 +670,11 @@ extern void xpc_process_channel_activity(struct xpc_partition *);
714extern void xpc_connected_callout(struct xpc_channel *); 670extern void xpc_connected_callout(struct xpc_channel *);
715extern void xpc_deliver_msg(struct xpc_channel *); 671extern void xpc_deliver_msg(struct xpc_channel *);
716extern void xpc_disconnect_channel(const int, struct xpc_channel *, 672extern void xpc_disconnect_channel(const int, struct xpc_channel *,
717 enum xpc_retval, unsigned long *); 673 enum xpc_retval, unsigned long *);
718extern void xpc_disconnect_callout(struct xpc_channel *, enum xpc_retval); 674extern void xpc_disconnect_callout(struct xpc_channel *, enum xpc_retval);
719extern void xpc_partition_going_down(struct xpc_partition *, enum xpc_retval); 675extern void xpc_partition_going_down(struct xpc_partition *, enum xpc_retval);
720extern void xpc_teardown_infrastructure(struct xpc_partition *); 676extern void xpc_teardown_infrastructure(struct xpc_partition *);
721 677
722
723
724static inline void 678static inline void
725xpc_wakeup_channel_mgr(struct xpc_partition *part) 679xpc_wakeup_channel_mgr(struct xpc_partition *part)
726{ 680{
@@ -729,8 +683,6 @@ xpc_wakeup_channel_mgr(struct xpc_partition *part)
729 } 683 }
730} 684}
731 685
732
733
734/* 686/*
735 * These next two inlines are used to keep us from tearing down a channel's 687 * These next two inlines are used to keep us from tearing down a channel's
736 * msg queues while a thread may be referencing them. 688 * msg queues while a thread may be referencing them.
@@ -752,12 +704,9 @@ xpc_msgqueue_deref(struct xpc_channel *ch)
752 } 704 }
753} 705}
754 706
755
756
757#define XPC_DISCONNECT_CHANNEL(_ch, _reason, _irqflgs) \ 707#define XPC_DISCONNECT_CHANNEL(_ch, _reason, _irqflgs) \
758 xpc_disconnect_channel(__LINE__, _ch, _reason, _irqflgs) 708 xpc_disconnect_channel(__LINE__, _ch, _reason, _irqflgs)
759 709
760
761/* 710/*
762 * These two inlines are used to keep us from tearing down a partition's 711 * These two inlines are used to keep us from tearing down a partition's
763 * setup infrastructure while a thread may be referencing it. 712 * setup infrastructure while a thread may be referencing it.
@@ -767,7 +716,6 @@ xpc_part_deref(struct xpc_partition *part)
767{ 716{
768 s32 refs = atomic_dec_return(&part->references); 717 s32 refs = atomic_dec_return(&part->references);
769 718
770
771 DBUG_ON(refs < 0); 719 DBUG_ON(refs < 0);
772 if (refs == 0 && part->setup_state == XPC_P_WTEARDOWN) { 720 if (refs == 0 && part->setup_state == XPC_P_WTEARDOWN) {
773 wake_up(&part->teardown_wq); 721 wake_up(&part->teardown_wq);
@@ -779,7 +727,6 @@ xpc_part_ref(struct xpc_partition *part)
779{ 727{
780 int setup; 728 int setup;
781 729
782
783 atomic_inc(&part->references); 730 atomic_inc(&part->references);
784 setup = (part->setup_state == XPC_P_SETUP); 731 setup = (part->setup_state == XPC_P_SETUP);
785 if (!setup) { 732 if (!setup) {
@@ -788,8 +735,6 @@ xpc_part_ref(struct xpc_partition *part)
788 return setup; 735 return setup;
789} 736}
790 737
791
792
793/* 738/*
794 * The following macro is to be used for the setting of the reason and 739 * The following macro is to be used for the setting of the reason and
795 * reason_line fields in both the struct xpc_channel and struct xpc_partition 740 * reason_line fields in both the struct xpc_channel and struct xpc_partition
@@ -801,8 +746,6 @@ xpc_part_ref(struct xpc_partition *part)
801 (_p)->reason_line = _line; \ 746 (_p)->reason_line = _line; \
802 } 747 }
803 748
804
805
806/* 749/*
807 * This next set of inlines are used to keep track of when a partition is 750 * This next set of inlines are used to keep track of when a partition is
808 * potentially engaged in accessing memory belonging to another partition. 751 * potentially engaged in accessing memory belonging to another partition.
@@ -812,23 +755,24 @@ static inline void
812xpc_mark_partition_engaged(struct xpc_partition *part) 755xpc_mark_partition_engaged(struct xpc_partition *part)
813{ 756{
814 unsigned long irq_flags; 757 unsigned long irq_flags;
815 AMO_t *amo = (AMO_t *) __va(part->remote_amos_page_pa + 758 AMO_t *amo = (AMO_t *)__va(part->remote_amos_page_pa +
816 (XPC_ENGAGED_PARTITIONS_AMO * sizeof(AMO_t))); 759 (XPC_ENGAGED_PARTITIONS_AMO *
817 760 sizeof(AMO_t)));
818 761
819 local_irq_save(irq_flags); 762 local_irq_save(irq_flags);
820 763
821 /* set bit corresponding to our partid in remote partition's AMO */ 764 /* set bit corresponding to our partid in remote partition's AMO */
822 FETCHOP_STORE_OP(TO_AMO((u64) &amo->variable), FETCHOP_OR, 765 FETCHOP_STORE_OP(TO_AMO((u64)&amo->variable), FETCHOP_OR,
823 (1UL << sn_partition_id)); 766 (1UL << sn_partition_id));
824 /* 767 /*
825 * We must always use the nofault function regardless of whether we 768 * We must always use the nofault function regardless of whether we
826 * are on a Shub 1.1 system or a Shub 1.2 slice 0xc processor. If we 769 * are on a Shub 1.1 system or a Shub 1.2 slice 0xc processor. If we
827 * didn't, we'd never know that the other partition is down and would 770 * didn't, we'd never know that the other partition is down and would
828 * keep sending IPIs and AMOs to it until the heartbeat times out. 771 * keep sending IPIs and AMOs to it until the heartbeat times out.
829 */ 772 */
830 (void) xp_nofault_PIOR((u64 *) GLOBAL_MMR_ADDR(NASID_GET(&amo-> 773 (void)xp_nofault_PIOR((u64 *)GLOBAL_MMR_ADDR(NASID_GET(&amo->
831 variable), xp_nofault_PIOR_target)); 774 variable),
775 xp_nofault_PIOR_target));
832 776
833 local_irq_restore(irq_flags); 777 local_irq_restore(irq_flags);
834} 778}
@@ -837,23 +781,24 @@ static inline void
837xpc_mark_partition_disengaged(struct xpc_partition *part) 781xpc_mark_partition_disengaged(struct xpc_partition *part)
838{ 782{
839 unsigned long irq_flags; 783 unsigned long irq_flags;
840 AMO_t *amo = (AMO_t *) __va(part->remote_amos_page_pa + 784 AMO_t *amo = (AMO_t *)__va(part->remote_amos_page_pa +
841 (XPC_ENGAGED_PARTITIONS_AMO * sizeof(AMO_t))); 785 (XPC_ENGAGED_PARTITIONS_AMO *
842 786 sizeof(AMO_t)));
843 787
844 local_irq_save(irq_flags); 788 local_irq_save(irq_flags);
845 789
846 /* clear bit corresponding to our partid in remote partition's AMO */ 790 /* clear bit corresponding to our partid in remote partition's AMO */
847 FETCHOP_STORE_OP(TO_AMO((u64) &amo->variable), FETCHOP_AND, 791 FETCHOP_STORE_OP(TO_AMO((u64)&amo->variable), FETCHOP_AND,
848 ~(1UL << sn_partition_id)); 792 ~(1UL << sn_partition_id));
849 /* 793 /*
850 * We must always use the nofault function regardless of whether we 794 * We must always use the nofault function regardless of whether we
851 * are on a Shub 1.1 system or a Shub 1.2 slice 0xc processor. If we 795 * are on a Shub 1.1 system or a Shub 1.2 slice 0xc processor. If we
852 * didn't, we'd never know that the other partition is down and would 796 * didn't, we'd never know that the other partition is down and would
853 * keep sending IPIs and AMOs to it until the heartbeat times out. 797 * keep sending IPIs and AMOs to it until the heartbeat times out.
854 */ 798 */
855 (void) xp_nofault_PIOR((u64 *) GLOBAL_MMR_ADDR(NASID_GET(&amo-> 799 (void)xp_nofault_PIOR((u64 *)GLOBAL_MMR_ADDR(NASID_GET(&amo->
856 variable), xp_nofault_PIOR_target)); 800 variable),
801 xp_nofault_PIOR_target));
857 802
858 local_irq_restore(irq_flags); 803 local_irq_restore(irq_flags);
859} 804}
@@ -862,23 +807,23 @@ static inline void
862xpc_request_partition_disengage(struct xpc_partition *part) 807xpc_request_partition_disengage(struct xpc_partition *part)
863{ 808{
864 unsigned long irq_flags; 809 unsigned long irq_flags;
865 AMO_t *amo = (AMO_t *) __va(part->remote_amos_page_pa + 810 AMO_t *amo = (AMO_t *)__va(part->remote_amos_page_pa +
866 (XPC_DISENGAGE_REQUEST_AMO * sizeof(AMO_t))); 811 (XPC_DISENGAGE_REQUEST_AMO * sizeof(AMO_t)));
867
868 812
869 local_irq_save(irq_flags); 813 local_irq_save(irq_flags);
870 814
871 /* set bit corresponding to our partid in remote partition's AMO */ 815 /* set bit corresponding to our partid in remote partition's AMO */
872 FETCHOP_STORE_OP(TO_AMO((u64) &amo->variable), FETCHOP_OR, 816 FETCHOP_STORE_OP(TO_AMO((u64)&amo->variable), FETCHOP_OR,
873 (1UL << sn_partition_id)); 817 (1UL << sn_partition_id));
874 /* 818 /*
875 * We must always use the nofault function regardless of whether we 819 * We must always use the nofault function regardless of whether we
876 * are on a Shub 1.1 system or a Shub 1.2 slice 0xc processor. If we 820 * are on a Shub 1.1 system or a Shub 1.2 slice 0xc processor. If we
877 * didn't, we'd never know that the other partition is down and would 821 * didn't, we'd never know that the other partition is down and would
878 * keep sending IPIs and AMOs to it until the heartbeat times out. 822 * keep sending IPIs and AMOs to it until the heartbeat times out.
879 */ 823 */
880 (void) xp_nofault_PIOR((u64 *) GLOBAL_MMR_ADDR(NASID_GET(&amo-> 824 (void)xp_nofault_PIOR((u64 *)GLOBAL_MMR_ADDR(NASID_GET(&amo->
881 variable), xp_nofault_PIOR_target)); 825 variable),
826 xp_nofault_PIOR_target));
882 827
883 local_irq_restore(irq_flags); 828 local_irq_restore(irq_flags);
884} 829}
@@ -887,23 +832,23 @@ static inline void
887xpc_cancel_partition_disengage_request(struct xpc_partition *part) 832xpc_cancel_partition_disengage_request(struct xpc_partition *part)
888{ 833{
889 unsigned long irq_flags; 834 unsigned long irq_flags;
890 AMO_t *amo = (AMO_t *) __va(part->remote_amos_page_pa + 835 AMO_t *amo = (AMO_t *)__va(part->remote_amos_page_pa +
891 (XPC_DISENGAGE_REQUEST_AMO * sizeof(AMO_t))); 836 (XPC_DISENGAGE_REQUEST_AMO * sizeof(AMO_t)));
892
893 837
894 local_irq_save(irq_flags); 838 local_irq_save(irq_flags);
895 839
896 /* clear bit corresponding to our partid in remote partition's AMO */ 840 /* clear bit corresponding to our partid in remote partition's AMO */
897 FETCHOP_STORE_OP(TO_AMO((u64) &amo->variable), FETCHOP_AND, 841 FETCHOP_STORE_OP(TO_AMO((u64)&amo->variable), FETCHOP_AND,
898 ~(1UL << sn_partition_id)); 842 ~(1UL << sn_partition_id));
899 /* 843 /*
900 * We must always use the nofault function regardless of whether we 844 * We must always use the nofault function regardless of whether we
901 * are on a Shub 1.1 system or a Shub 1.2 slice 0xc processor. If we 845 * are on a Shub 1.1 system or a Shub 1.2 slice 0xc processor. If we
902 * didn't, we'd never know that the other partition is down and would 846 * didn't, we'd never know that the other partition is down and would
903 * keep sending IPIs and AMOs to it until the heartbeat times out. 847 * keep sending IPIs and AMOs to it until the heartbeat times out.
904 */ 848 */
905 (void) xp_nofault_PIOR((u64 *) GLOBAL_MMR_ADDR(NASID_GET(&amo-> 849 (void)xp_nofault_PIOR((u64 *)GLOBAL_MMR_ADDR(NASID_GET(&amo->
906 variable), xp_nofault_PIOR_target)); 850 variable),
851 xp_nofault_PIOR_target));
907 852
908 local_irq_restore(irq_flags); 853 local_irq_restore(irq_flags);
909} 854}
@@ -913,10 +858,9 @@ xpc_partition_engaged(u64 partid_mask)
913{ 858{
914 AMO_t *amo = xpc_vars->amos_page + XPC_ENGAGED_PARTITIONS_AMO; 859 AMO_t *amo = xpc_vars->amos_page + XPC_ENGAGED_PARTITIONS_AMO;
915 860
916
917 /* return our partition's AMO variable ANDed with partid_mask */ 861 /* return our partition's AMO variable ANDed with partid_mask */
918 return (FETCHOP_LOAD_OP(TO_AMO((u64) &amo->variable), FETCHOP_LOAD) & 862 return (FETCHOP_LOAD_OP(TO_AMO((u64)&amo->variable), FETCHOP_LOAD) &
919 partid_mask); 863 partid_mask);
920} 864}
921 865
922static inline u64 866static inline u64
@@ -924,10 +868,9 @@ xpc_partition_disengage_requested(u64 partid_mask)
924{ 868{
925 AMO_t *amo = xpc_vars->amos_page + XPC_DISENGAGE_REQUEST_AMO; 869 AMO_t *amo = xpc_vars->amos_page + XPC_DISENGAGE_REQUEST_AMO;
926 870
927
928 /* return our partition's AMO variable ANDed with partid_mask */ 871 /* return our partition's AMO variable ANDed with partid_mask */
929 return (FETCHOP_LOAD_OP(TO_AMO((u64) &amo->variable), FETCHOP_LOAD) & 872 return (FETCHOP_LOAD_OP(TO_AMO((u64)&amo->variable), FETCHOP_LOAD) &
930 partid_mask); 873 partid_mask);
931} 874}
932 875
933static inline void 876static inline void
@@ -935,10 +878,9 @@ xpc_clear_partition_engaged(u64 partid_mask)
935{ 878{
936 AMO_t *amo = xpc_vars->amos_page + XPC_ENGAGED_PARTITIONS_AMO; 879 AMO_t *amo = xpc_vars->amos_page + XPC_ENGAGED_PARTITIONS_AMO;
937 880
938
939 /* clear bit(s) based on partid_mask in our partition's AMO */ 881 /* clear bit(s) based on partid_mask in our partition's AMO */
940 FETCHOP_STORE_OP(TO_AMO((u64) &amo->variable), FETCHOP_AND, 882 FETCHOP_STORE_OP(TO_AMO((u64)&amo->variable), FETCHOP_AND,
941 ~partid_mask); 883 ~partid_mask);
942} 884}
943 885
944static inline void 886static inline void
@@ -946,14 +888,11 @@ xpc_clear_partition_disengage_request(u64 partid_mask)
946{ 888{
947 AMO_t *amo = xpc_vars->amos_page + XPC_DISENGAGE_REQUEST_AMO; 889 AMO_t *amo = xpc_vars->amos_page + XPC_DISENGAGE_REQUEST_AMO;
948 890
949
950 /* clear bit(s) based on partid_mask in our partition's AMO */ 891 /* clear bit(s) based on partid_mask in our partition's AMO */
951 FETCHOP_STORE_OP(TO_AMO((u64) &amo->variable), FETCHOP_AND, 892 FETCHOP_STORE_OP(TO_AMO((u64)&amo->variable), FETCHOP_AND,
952 ~partid_mask); 893 ~partid_mask);
953} 894}
954 895
955
956
957/* 896/*
958 * The following set of macros and inlines are used for the sending and 897 * The following set of macros and inlines are used for the sending and
959 * receiving of IPIs (also known as IRQs). There are two flavors of IPIs, 898 * receiving of IPIs (also known as IRQs). There are two flavors of IPIs,
@@ -964,20 +903,18 @@ xpc_clear_partition_disengage_request(u64 partid_mask)
964static inline u64 903static inline u64
965xpc_IPI_receive(AMO_t *amo) 904xpc_IPI_receive(AMO_t *amo)
966{ 905{
967 return FETCHOP_LOAD_OP(TO_AMO((u64) &amo->variable), FETCHOP_CLEAR); 906 return FETCHOP_LOAD_OP(TO_AMO((u64)&amo->variable), FETCHOP_CLEAR);
968} 907}
969 908
970
971static inline enum xpc_retval 909static inline enum xpc_retval
972xpc_IPI_send(AMO_t *amo, u64 flag, int nasid, int phys_cpuid, int vector) 910xpc_IPI_send(AMO_t *amo, u64 flag, int nasid, int phys_cpuid, int vector)
973{ 911{
974 int ret = 0; 912 int ret = 0;
975 unsigned long irq_flags; 913 unsigned long irq_flags;
976 914
977
978 local_irq_save(irq_flags); 915 local_irq_save(irq_flags);
979 916
980 FETCHOP_STORE_OP(TO_AMO((u64) &amo->variable), FETCHOP_OR, flag); 917 FETCHOP_STORE_OP(TO_AMO((u64)&amo->variable), FETCHOP_OR, flag);
981 sn_send_IPI_phys(nasid, phys_cpuid, vector, 0); 918 sn_send_IPI_phys(nasid, phys_cpuid, vector, 0);
982 919
983 /* 920 /*
@@ -986,15 +923,14 @@ xpc_IPI_send(AMO_t *amo, u64 flag, int nasid, int phys_cpuid, int vector)
986 * didn't, we'd never know that the other partition is down and would 923 * didn't, we'd never know that the other partition is down and would
987 * keep sending IPIs and AMOs to it until the heartbeat times out. 924 * keep sending IPIs and AMOs to it until the heartbeat times out.
988 */ 925 */
989 ret = xp_nofault_PIOR((u64 *) GLOBAL_MMR_ADDR(NASID_GET(&amo->variable), 926 ret = xp_nofault_PIOR((u64 *)GLOBAL_MMR_ADDR(NASID_GET(&amo->variable),
990 xp_nofault_PIOR_target)); 927 xp_nofault_PIOR_target));
991 928
992 local_irq_restore(irq_flags); 929 local_irq_restore(irq_flags);
993 930
994 return ((ret == 0) ? xpcSuccess : xpcPioReadError); 931 return ((ret == 0) ? xpcSuccess : xpcPioReadError);
995} 932}
996 933
997
998/* 934/*
999 * IPIs associated with SGI_XPC_ACTIVATE IRQ. 935 * IPIs associated with SGI_XPC_ACTIVATE IRQ.
1000 */ 936 */
@@ -1004,47 +940,47 @@ xpc_IPI_send(AMO_t *amo, u64 flag, int nasid, int phys_cpuid, int vector)
1004 */ 940 */
1005static inline void 941static inline void
1006xpc_activate_IRQ_send(u64 amos_page_pa, int from_nasid, int to_nasid, 942xpc_activate_IRQ_send(u64 amos_page_pa, int from_nasid, int to_nasid,
1007 int to_phys_cpuid) 943 int to_phys_cpuid)
1008{ 944{
1009 int w_index = XPC_NASID_W_INDEX(from_nasid); 945 int w_index = XPC_NASID_W_INDEX(from_nasid);
1010 int b_index = XPC_NASID_B_INDEX(from_nasid); 946 int b_index = XPC_NASID_B_INDEX(from_nasid);
1011 AMO_t *amos = (AMO_t *) __va(amos_page_pa + 947 AMO_t *amos = (AMO_t *)__va(amos_page_pa +
1012 (XPC_ACTIVATE_IRQ_AMOS * sizeof(AMO_t))); 948 (XPC_ACTIVATE_IRQ_AMOS * sizeof(AMO_t)));
1013
1014 949
1015 (void) xpc_IPI_send(&amos[w_index], (1UL << b_index), to_nasid, 950 (void)xpc_IPI_send(&amos[w_index], (1UL << b_index), to_nasid,
1016 to_phys_cpuid, SGI_XPC_ACTIVATE); 951 to_phys_cpuid, SGI_XPC_ACTIVATE);
1017} 952}
1018 953
1019static inline void 954static inline void
1020xpc_IPI_send_activate(struct xpc_vars *vars) 955xpc_IPI_send_activate(struct xpc_vars *vars)
1021{ 956{
1022 xpc_activate_IRQ_send(vars->amos_page_pa, cnodeid_to_nasid(0), 957 xpc_activate_IRQ_send(vars->amos_page_pa, cnodeid_to_nasid(0),
1023 vars->act_nasid, vars->act_phys_cpuid); 958 vars->act_nasid, vars->act_phys_cpuid);
1024} 959}
1025 960
1026static inline void 961static inline void
1027xpc_IPI_send_activated(struct xpc_partition *part) 962xpc_IPI_send_activated(struct xpc_partition *part)
1028{ 963{
1029 xpc_activate_IRQ_send(part->remote_amos_page_pa, cnodeid_to_nasid(0), 964 xpc_activate_IRQ_send(part->remote_amos_page_pa, cnodeid_to_nasid(0),
1030 part->remote_act_nasid, part->remote_act_phys_cpuid); 965 part->remote_act_nasid,
966 part->remote_act_phys_cpuid);
1031} 967}
1032 968
1033static inline void 969static inline void
1034xpc_IPI_send_reactivate(struct xpc_partition *part) 970xpc_IPI_send_reactivate(struct xpc_partition *part)
1035{ 971{
1036 xpc_activate_IRQ_send(xpc_vars->amos_page_pa, part->reactivate_nasid, 972 xpc_activate_IRQ_send(xpc_vars->amos_page_pa, part->reactivate_nasid,
1037 xpc_vars->act_nasid, xpc_vars->act_phys_cpuid); 973 xpc_vars->act_nasid, xpc_vars->act_phys_cpuid);
1038} 974}
1039 975
1040static inline void 976static inline void
1041xpc_IPI_send_disengage(struct xpc_partition *part) 977xpc_IPI_send_disengage(struct xpc_partition *part)
1042{ 978{
1043 xpc_activate_IRQ_send(part->remote_amos_page_pa, cnodeid_to_nasid(0), 979 xpc_activate_IRQ_send(part->remote_amos_page_pa, cnodeid_to_nasid(0),
1044 part->remote_act_nasid, part->remote_act_phys_cpuid); 980 part->remote_act_nasid,
981 part->remote_act_phys_cpuid);
1045} 982}
1046 983
1047
1048/* 984/*
1049 * IPIs associated with SGI_XPC_NOTIFY IRQ. 985 * IPIs associated with SGI_XPC_NOTIFY IRQ.
1050 */ 986 */
@@ -1058,18 +994,16 @@ xpc_IPI_send_disengage(struct xpc_partition *part)
1058 994
1059static inline void 995static inline void
1060xpc_notify_IRQ_send(struct xpc_channel *ch, u8 ipi_flag, char *ipi_flag_string, 996xpc_notify_IRQ_send(struct xpc_channel *ch, u8 ipi_flag, char *ipi_flag_string,
1061 unsigned long *irq_flags) 997 unsigned long *irq_flags)
1062{ 998{
1063 struct xpc_partition *part = &xpc_partitions[ch->partid]; 999 struct xpc_partition *part = &xpc_partitions[ch->partid];
1064 enum xpc_retval ret; 1000 enum xpc_retval ret;
1065 1001
1066
1067 if (likely(part->act_state != XPC_P_DEACTIVATING)) { 1002 if (likely(part->act_state != XPC_P_DEACTIVATING)) {
1068 ret = xpc_IPI_send(part->remote_IPI_amo_va, 1003 ret = xpc_IPI_send(part->remote_IPI_amo_va,
1069 (u64) ipi_flag << (ch->number * 8), 1004 (u64)ipi_flag << (ch->number * 8),
1070 part->remote_IPI_nasid, 1005 part->remote_IPI_nasid,
1071 part->remote_IPI_phys_cpuid, 1006 part->remote_IPI_phys_cpuid, SGI_XPC_NOTIFY);
1072 SGI_XPC_NOTIFY);
1073 dev_dbg(xpc_chan, "%s sent to partid=%d, channel=%d, ret=%d\n", 1007 dev_dbg(xpc_chan, "%s sent to partid=%d, channel=%d, ret=%d\n",
1074 ipi_flag_string, ch->partid, ch->number, ret); 1008 ipi_flag_string, ch->partid, ch->number, ret);
1075 if (unlikely(ret != xpcSuccess)) { 1009 if (unlikely(ret != xpcSuccess)) {
@@ -1084,7 +1018,6 @@ xpc_notify_IRQ_send(struct xpc_channel *ch, u8 ipi_flag, char *ipi_flag_string,
1084 } 1018 }
1085} 1019}
1086 1020
1087
1088/* 1021/*
1089 * Make it look like the remote partition, which is associated with the 1022 * Make it look like the remote partition, which is associated with the
1090 * specified channel, sent us an IPI. This faked IPI will be handled 1023 * specified channel, sent us an IPI. This faked IPI will be handled
@@ -1095,18 +1028,16 @@ xpc_notify_IRQ_send(struct xpc_channel *ch, u8 ipi_flag, char *ipi_flag_string,
1095 1028
1096static inline void 1029static inline void
1097xpc_notify_IRQ_send_local(struct xpc_channel *ch, u8 ipi_flag, 1030xpc_notify_IRQ_send_local(struct xpc_channel *ch, u8 ipi_flag,
1098 char *ipi_flag_string) 1031 char *ipi_flag_string)
1099{ 1032{
1100 struct xpc_partition *part = &xpc_partitions[ch->partid]; 1033 struct xpc_partition *part = &xpc_partitions[ch->partid];
1101 1034
1102 1035 FETCHOP_STORE_OP(TO_AMO((u64)&part->local_IPI_amo_va->variable),
1103 FETCHOP_STORE_OP(TO_AMO((u64) &part->local_IPI_amo_va->variable), 1036 FETCHOP_OR, ((u64)ipi_flag << (ch->number * 8)));
1104 FETCHOP_OR, ((u64) ipi_flag << (ch->number * 8)));
1105 dev_dbg(xpc_chan, "%s sent local from partid=%d, channel=%d\n", 1037 dev_dbg(xpc_chan, "%s sent local from partid=%d, channel=%d\n",
1106 ipi_flag_string, ch->partid, ch->number); 1038 ipi_flag_string, ch->partid, ch->number);
1107} 1039}
1108 1040
1109
1110/* 1041/*
1111 * The sending and receiving of IPIs includes the setting of an AMO variable 1042 * The sending and receiving of IPIs includes the setting of an AMO variable
1112 * to indicate the reason the IPI was sent. The 64-bit variable is divided 1043 * to indicate the reason the IPI was sent. The 64-bit variable is divided
@@ -1121,7 +1052,6 @@ xpc_notify_IRQ_send_local(struct xpc_channel *ch, u8 ipi_flag,
1121#define XPC_IPI_OPENREPLY 0x08 1052#define XPC_IPI_OPENREPLY 0x08
1122#define XPC_IPI_MSGREQUEST 0x10 1053#define XPC_IPI_MSGREQUEST 0x10
1123 1054
1124
1125/* given an AMO variable and a channel#, get its associated IPI flags */ 1055/* given an AMO variable and a channel#, get its associated IPI flags */
1126#define XPC_GET_IPI_FLAGS(_amo, _c) ((u8) (((_amo) >> ((_c) * 8)) & 0xff)) 1056#define XPC_GET_IPI_FLAGS(_amo, _c) ((u8) (((_amo) >> ((_c) * 8)) & 0xff))
1127#define XPC_SET_IPI_FLAGS(_amo, _c, _f) (_amo) |= ((u64) (_f) << ((_c) * 8)) 1057#define XPC_SET_IPI_FLAGS(_amo, _c, _f) (_amo) |= ((u64) (_f) << ((_c) * 8))
@@ -1129,13 +1059,11 @@ xpc_notify_IRQ_send_local(struct xpc_channel *ch, u8 ipi_flag,
1129#define XPC_ANY_OPENCLOSE_IPI_FLAGS_SET(_amo) ((_amo) & __IA64_UL_CONST(0x0f0f0f0f0f0f0f0f)) 1059#define XPC_ANY_OPENCLOSE_IPI_FLAGS_SET(_amo) ((_amo) & __IA64_UL_CONST(0x0f0f0f0f0f0f0f0f))
1130#define XPC_ANY_MSG_IPI_FLAGS_SET(_amo) ((_amo) & __IA64_UL_CONST(0x1010101010101010)) 1060#define XPC_ANY_MSG_IPI_FLAGS_SET(_amo) ((_amo) & __IA64_UL_CONST(0x1010101010101010))
1131 1061
1132
1133static inline void 1062static inline void
1134xpc_IPI_send_closerequest(struct xpc_channel *ch, unsigned long *irq_flags) 1063xpc_IPI_send_closerequest(struct xpc_channel *ch, unsigned long *irq_flags)
1135{ 1064{
1136 struct xpc_openclose_args *args = ch->local_openclose_args; 1065 struct xpc_openclose_args *args = ch->local_openclose_args;
1137 1066
1138
1139 args->reason = ch->reason; 1067 args->reason = ch->reason;
1140 1068
1141 XPC_NOTIFY_IRQ_SEND(ch, XPC_IPI_CLOSEREQUEST, irq_flags); 1069 XPC_NOTIFY_IRQ_SEND(ch, XPC_IPI_CLOSEREQUEST, irq_flags);
@@ -1152,7 +1080,6 @@ xpc_IPI_send_openrequest(struct xpc_channel *ch, unsigned long *irq_flags)
1152{ 1080{
1153 struct xpc_openclose_args *args = ch->local_openclose_args; 1081 struct xpc_openclose_args *args = ch->local_openclose_args;
1154 1082
1155
1156 args->msg_size = ch->msg_size; 1083 args->msg_size = ch->msg_size;
1157 args->local_nentries = ch->local_nentries; 1084 args->local_nentries = ch->local_nentries;
1158 1085
@@ -1164,7 +1091,6 @@ xpc_IPI_send_openreply(struct xpc_channel *ch, unsigned long *irq_flags)
1164{ 1091{
1165 struct xpc_openclose_args *args = ch->local_openclose_args; 1092 struct xpc_openclose_args *args = ch->local_openclose_args;
1166 1093
1167
1168 args->remote_nentries = ch->remote_nentries; 1094 args->remote_nentries = ch->remote_nentries;
1169 args->local_nentries = ch->local_nentries; 1095 args->local_nentries = ch->local_nentries;
1170 args->local_msgqueue_pa = __pa(ch->local_msgqueue); 1096 args->local_msgqueue_pa = __pa(ch->local_msgqueue);
@@ -1184,7 +1110,6 @@ xpc_IPI_send_local_msgrequest(struct xpc_channel *ch)
1184 XPC_NOTIFY_IRQ_SEND_LOCAL(ch, XPC_IPI_MSGREQUEST); 1110 XPC_NOTIFY_IRQ_SEND_LOCAL(ch, XPC_IPI_MSGREQUEST);
1185} 1111}
1186 1112
1187
1188/* 1113/*
1189 * Memory for XPC's AMO variables is allocated by the MSPEC driver. These 1114 * Memory for XPC's AMO variables is allocated by the MSPEC driver. These
1190 * pages are located in the lowest granule. The lowest granule uses 4k pages 1115 * pages are located in the lowest granule. The lowest granule uses 4k pages
@@ -1201,13 +1126,10 @@ xpc_IPI_init(int index)
1201{ 1126{
1202 AMO_t *amo = xpc_vars->amos_page + index; 1127 AMO_t *amo = xpc_vars->amos_page + index;
1203 1128
1204 1129 (void)xpc_IPI_receive(amo); /* clear AMO variable */
1205 (void) xpc_IPI_receive(amo); /* clear AMO variable */
1206 return amo; 1130 return amo;
1207} 1131}
1208 1132
1209
1210
1211static inline enum xpc_retval 1133static inline enum xpc_retval
1212xpc_map_bte_errors(bte_result_t error) 1134xpc_map_bte_errors(bte_result_t error)
1213{ 1135{
@@ -1220,22 +1142,31 @@ xpc_map_bte_errors(bte_result_t error)
1220 return xpcBteUnmappedError; 1142 return xpcBteUnmappedError;
1221 } 1143 }
1222 switch (error) { 1144 switch (error) {
1223 case BTE_SUCCESS: return xpcSuccess; 1145 case BTE_SUCCESS:
1224 case BTEFAIL_DIR: return xpcBteDirectoryError; 1146 return xpcSuccess;
1225 case BTEFAIL_POISON: return xpcBtePoisonError; 1147 case BTEFAIL_DIR:
1226 case BTEFAIL_WERR: return xpcBteWriteError; 1148 return xpcBteDirectoryError;
1227 case BTEFAIL_ACCESS: return xpcBteAccessError; 1149 case BTEFAIL_POISON:
1228 case BTEFAIL_PWERR: return xpcBtePWriteError; 1150 return xpcBtePoisonError;
1229 case BTEFAIL_PRERR: return xpcBtePReadError; 1151 case BTEFAIL_WERR:
1230 case BTEFAIL_TOUT: return xpcBteTimeOutError; 1152 return xpcBteWriteError;
1231 case BTEFAIL_XTERR: return xpcBteXtalkError; 1153 case BTEFAIL_ACCESS:
1232 case BTEFAIL_NOTAVAIL: return xpcBteNotAvailable; 1154 return xpcBteAccessError;
1233 default: return xpcBteUnmappedError; 1155 case BTEFAIL_PWERR:
1156 return xpcBtePWriteError;
1157 case BTEFAIL_PRERR:
1158 return xpcBtePReadError;
1159 case BTEFAIL_TOUT:
1160 return xpcBteTimeOutError;
1161 case BTEFAIL_XTERR:
1162 return xpcBteXtalkError;
1163 case BTEFAIL_NOTAVAIL:
1164 return xpcBteNotAvailable;
1165 default:
1166 return xpcBteUnmappedError;
1234 } 1167 }
1235} 1168}
1236 1169
1237
1238
1239/* 1170/*
1240 * Check to see if there is any channel activity to/from the specified 1171 * Check to see if there is any channel activity to/from the specified
1241 * partition. 1172 * partition.
@@ -1246,7 +1177,6 @@ xpc_check_for_channel_activity(struct xpc_partition *part)
1246 u64 IPI_amo; 1177 u64 IPI_amo;
1247 unsigned long irq_flags; 1178 unsigned long irq_flags;
1248 1179
1249
1250 IPI_amo = xpc_IPI_receive(part->local_IPI_amo_va); 1180 IPI_amo = xpc_IPI_receive(part->local_IPI_amo_va);
1251 if (IPI_amo == 0) { 1181 if (IPI_amo == 0) {
1252 return; 1182 return;
@@ -1262,6 +1192,4 @@ xpc_check_for_channel_activity(struct xpc_partition *part)
1262 xpc_wakeup_channel_mgr(part); 1192 xpc_wakeup_channel_mgr(part);
1263} 1193}
1264 1194
1265
1266#endif /* _DRIVERS_MISC_SGIXP_XPC_H */ 1195#endif /* _DRIVERS_MISC_SGIXP_XPC_H */
1267
diff --git a/drivers/misc/sgi-xp/xpc_partition.c b/drivers/misc/sgi-xp/xpc_partition.c
index 7412dc7351cd..57f1d0b3ac26 100644
--- a/drivers/misc/sgi-xp/xpc_partition.c
+++ b/drivers/misc/sgi-xp/xpc_partition.c
@@ -6,7 +6,6 @@
6 * Copyright (c) 2004-2008 Silicon Graphics, Inc. All Rights Reserved. 6 * Copyright (c) 2004-2008 Silicon Graphics, Inc. All Rights Reserved.
7 */ 7 */
8 8
9
10/* 9/*
11 * Cross Partition Communication (XPC) partition support. 10 * Cross Partition Communication (XPC) partition support.
12 * 11 *
@@ -16,7 +15,6 @@
16 * 15 *
17 */ 16 */
18 17
19
20#include <linux/kernel.h> 18#include <linux/kernel.h>
21#include <linux/sysctl.h> 19#include <linux/sysctl.h>
22#include <linux/cache.h> 20#include <linux/cache.h>
@@ -30,11 +28,9 @@
30#include <asm/sn/addrs.h> 28#include <asm/sn/addrs.h>
31#include "xpc.h" 29#include "xpc.h"
32 30
33
34/* XPC is exiting flag */ 31/* XPC is exiting flag */
35int xpc_exiting; 32int xpc_exiting;
36 33
37
38/* SH_IPI_ACCESS shub register value on startup */ 34/* SH_IPI_ACCESS shub register value on startup */
39static u64 xpc_sh1_IPI_access; 35static u64 xpc_sh1_IPI_access;
40static u64 xpc_sh2_IPI_access0; 36static u64 xpc_sh2_IPI_access0;
@@ -42,11 +38,9 @@ static u64 xpc_sh2_IPI_access1;
42static u64 xpc_sh2_IPI_access2; 38static u64 xpc_sh2_IPI_access2;
43static u64 xpc_sh2_IPI_access3; 39static u64 xpc_sh2_IPI_access3;
44 40
45
46/* original protection values for each node */ 41/* original protection values for each node */
47u64 xpc_prot_vec[MAX_NUMNODES]; 42u64 xpc_prot_vec[MAX_NUMNODES];
48 43
49
50/* this partition's reserved page pointers */ 44/* this partition's reserved page pointers */
51struct xpc_rsvd_page *xpc_rsvd_page; 45struct xpc_rsvd_page *xpc_rsvd_page;
52static u64 *xpc_part_nasids; 46static u64 *xpc_part_nasids;
@@ -57,7 +51,6 @@ struct xpc_vars_part *xpc_vars_part;
57static int xp_nasid_mask_bytes; /* actual size in bytes of nasid mask */ 51static int xp_nasid_mask_bytes; /* actual size in bytes of nasid mask */
58static int xp_nasid_mask_words; /* actual size in words of nasid mask */ 52static int xp_nasid_mask_words; /* actual size in words of nasid mask */
59 53
60
61/* 54/*
62 * For performance reasons, each entry of xpc_partitions[] is cacheline 55 * For performance reasons, each entry of xpc_partitions[] is cacheline
63 * aligned. And xpc_partitions[] is padded with an additional entry at the 56 * aligned. And xpc_partitions[] is padded with an additional entry at the
@@ -66,7 +59,6 @@ static int xp_nasid_mask_words; /* actual size in words of nasid mask */
66 */ 59 */
67struct xpc_partition xpc_partitions[XP_MAX_PARTITIONS + 1]; 60struct xpc_partition xpc_partitions[XP_MAX_PARTITIONS + 1];
68 61
69
70/* 62/*
71 * Generic buffer used to store a local copy of portions of a remote 63 * Generic buffer used to store a local copy of portions of a remote
72 * partition's reserved page (either its header and part_nasids mask, 64 * partition's reserved page (either its header and part_nasids mask,
@@ -75,7 +67,6 @@ struct xpc_partition xpc_partitions[XP_MAX_PARTITIONS + 1];
75char *xpc_remote_copy_buffer; 67char *xpc_remote_copy_buffer;
76void *xpc_remote_copy_buffer_base; 68void *xpc_remote_copy_buffer_base;
77 69
78
79/* 70/*
80 * Guarantee that the kmalloc'd memory is cacheline aligned. 71 * Guarantee that the kmalloc'd memory is cacheline aligned.
81 */ 72 */
@@ -87,7 +78,7 @@ xpc_kmalloc_cacheline_aligned(size_t size, gfp_t flags, void **base)
87 if (*base == NULL) { 78 if (*base == NULL) {
88 return NULL; 79 return NULL;
89 } 80 }
90 if ((u64) *base == L1_CACHE_ALIGN((u64) *base)) { 81 if ((u64)*base == L1_CACHE_ALIGN((u64)*base)) {
91 return *base; 82 return *base;
92 } 83 }
93 kfree(*base); 84 kfree(*base);
@@ -97,10 +88,9 @@ xpc_kmalloc_cacheline_aligned(size_t size, gfp_t flags, void **base)
97 if (*base == NULL) { 88 if (*base == NULL) {
98 return NULL; 89 return NULL;
99 } 90 }
100 return (void *) L1_CACHE_ALIGN((u64) *base); 91 return (void *)L1_CACHE_ALIGN((u64)*base);
101} 92}
102 93
103
104/* 94/*
105 * Given a nasid, get the physical address of the partition's reserved page 95 * Given a nasid, get the physical address of the partition's reserved page
106 * for that nasid. This function returns 0 on any error. 96 * for that nasid. This function returns 0 on any error.
@@ -117,11 +107,10 @@ xpc_get_rsvd_page_pa(int nasid)
117 u64 buf_len = 0; 107 u64 buf_len = 0;
118 void *buf_base = NULL; 108 void *buf_base = NULL;
119 109
120
121 while (1) { 110 while (1) {
122 111
123 status = sn_partition_reserved_page_pa(buf, &cookie, &rp_pa, 112 status = sn_partition_reserved_page_pa(buf, &cookie, &rp_pa,
124 &len); 113 &len);
125 114
126 dev_dbg(xpc_part, "SAL returned with status=%li, cookie=" 115 dev_dbg(xpc_part, "SAL returned with status=%li, cookie="
127 "0x%016lx, address=0x%016lx, len=0x%016lx\n", 116 "0x%016lx, address=0x%016lx, len=0x%016lx\n",
@@ -134,8 +123,9 @@ xpc_get_rsvd_page_pa(int nasid)
134 if (L1_CACHE_ALIGN(len) > buf_len) { 123 if (L1_CACHE_ALIGN(len) > buf_len) {
135 kfree(buf_base); 124 kfree(buf_base);
136 buf_len = L1_CACHE_ALIGN(len); 125 buf_len = L1_CACHE_ALIGN(len);
137 buf = (u64) xpc_kmalloc_cacheline_aligned(buf_len, 126 buf = (u64)xpc_kmalloc_cacheline_aligned(buf_len,
138 GFP_KERNEL, &buf_base); 127 GFP_KERNEL,
128 &buf_base);
139 if (buf_base == NULL) { 129 if (buf_base == NULL) {
140 dev_err(xpc_part, "unable to kmalloc " 130 dev_err(xpc_part, "unable to kmalloc "
141 "len=0x%016lx\n", buf_len); 131 "len=0x%016lx\n", buf_len);
@@ -145,7 +135,7 @@ xpc_get_rsvd_page_pa(int nasid)
145 } 135 }
146 136
147 bte_res = xp_bte_copy(rp_pa, buf, buf_len, 137 bte_res = xp_bte_copy(rp_pa, buf, buf_len,
148 (BTE_NOTIFY | BTE_WACQUIRE), NULL); 138 (BTE_NOTIFY | BTE_WACQUIRE), NULL);
149 if (bte_res != BTE_SUCCESS) { 139 if (bte_res != BTE_SUCCESS) {
150 dev_dbg(xpc_part, "xp_bte_copy failed %i\n", bte_res); 140 dev_dbg(xpc_part, "xp_bte_copy failed %i\n", bte_res);
151 status = SALRET_ERROR; 141 status = SALRET_ERROR;
@@ -162,7 +152,6 @@ xpc_get_rsvd_page_pa(int nasid)
162 return rp_pa; 152 return rp_pa;
163} 153}
164 154
165
166/* 155/*
167 * Fill the partition reserved page with the information needed by 156 * Fill the partition reserved page with the information needed by
168 * other partitions to discover we are alive and establish initial 157 * other partitions to discover we are alive and establish initial
@@ -176,7 +165,6 @@ xpc_rsvd_page_init(void)
176 u64 rp_pa, nasid_array = 0; 165 u64 rp_pa, nasid_array = 0;
177 int i, ret; 166 int i, ret;
178 167
179
180 /* get the local reserved page's address */ 168 /* get the local reserved page's address */
181 169
182 preempt_disable(); 170 preempt_disable();
@@ -186,7 +174,7 @@ xpc_rsvd_page_init(void)
186 dev_err(xpc_part, "SAL failed to locate the reserved page\n"); 174 dev_err(xpc_part, "SAL failed to locate the reserved page\n");
187 return NULL; 175 return NULL;
188 } 176 }
189 rp = (struct xpc_rsvd_page *) __va(rp_pa); 177 rp = (struct xpc_rsvd_page *)__va(rp_pa);
190 178
191 if (rp->partid != sn_partition_id) { 179 if (rp->partid != sn_partition_id) {
192 dev_err(xpc_part, "the reserved page's partid of %d should be " 180 dev_err(xpc_part, "the reserved page's partid of %d should be "
@@ -223,7 +211,7 @@ xpc_rsvd_page_init(void)
223 * memory protections are never restricted. 211 * memory protections are never restricted.
224 */ 212 */
225 if ((amos_page = xpc_vars->amos_page) == NULL) { 213 if ((amos_page = xpc_vars->amos_page) == NULL) {
226 amos_page = (AMO_t *) TO_AMO(uncached_alloc_page(0)); 214 amos_page = (AMO_t *)TO_AMO(uncached_alloc_page(0));
227 if (amos_page == NULL) { 215 if (amos_page == NULL) {
228 dev_err(xpc_part, "can't allocate page of AMOs\n"); 216 dev_err(xpc_part, "can't allocate page of AMOs\n");
229 return NULL; 217 return NULL;
@@ -234,30 +222,31 @@ xpc_rsvd_page_init(void)
234 * when xpc_allow_IPI_ops() is called via xpc_hb_init(). 222 * when xpc_allow_IPI_ops() is called via xpc_hb_init().
235 */ 223 */
236 if (!enable_shub_wars_1_1()) { 224 if (!enable_shub_wars_1_1()) {
237 ret = sn_change_memprotect(ia64_tpa((u64) amos_page), 225 ret = sn_change_memprotect(ia64_tpa((u64)amos_page),
238 PAGE_SIZE, SN_MEMPROT_ACCESS_CLASS_1, 226 PAGE_SIZE,
239 &nasid_array); 227 SN_MEMPROT_ACCESS_CLASS_1,
228 &nasid_array);
240 if (ret != 0) { 229 if (ret != 0) {
241 dev_err(xpc_part, "can't change memory " 230 dev_err(xpc_part, "can't change memory "
242 "protections\n"); 231 "protections\n");
243 uncached_free_page(__IA64_UNCACHED_OFFSET | 232 uncached_free_page(__IA64_UNCACHED_OFFSET |
244 TO_PHYS((u64) amos_page)); 233 TO_PHYS((u64)amos_page));
245 return NULL; 234 return NULL;
246 } 235 }
247 } 236 }
248 } else if (!IS_AMO_ADDRESS((u64) amos_page)) { 237 } else if (!IS_AMO_ADDRESS((u64)amos_page)) {
249 /* 238 /*
250 * EFI's XPBOOT can also set amos_page in the reserved page, 239 * EFI's XPBOOT can also set amos_page in the reserved page,
251 * but it happens to leave it as an uncached physical address 240 * but it happens to leave it as an uncached physical address
252 * and we need it to be an uncached virtual, so we'll have to 241 * and we need it to be an uncached virtual, so we'll have to
253 * convert it. 242 * convert it.
254 */ 243 */
255 if (!IS_AMO_PHYS_ADDRESS((u64) amos_page)) { 244 if (!IS_AMO_PHYS_ADDRESS((u64)amos_page)) {
256 dev_err(xpc_part, "previously used amos_page address " 245 dev_err(xpc_part, "previously used amos_page address "
257 "is bad = 0x%p\n", (void *) amos_page); 246 "is bad = 0x%p\n", (void *)amos_page);
258 return NULL; 247 return NULL;
259 } 248 }
260 amos_page = (AMO_t *) TO_AMO((u64) amos_page); 249 amos_page = (AMO_t *)TO_AMO((u64)amos_page);
261 } 250 }
262 251
263 /* clear xpc_vars */ 252 /* clear xpc_vars */
@@ -267,22 +256,21 @@ xpc_rsvd_page_init(void)
267 xpc_vars->act_nasid = cpuid_to_nasid(0); 256 xpc_vars->act_nasid = cpuid_to_nasid(0);
268 xpc_vars->act_phys_cpuid = cpu_physical_id(0); 257 xpc_vars->act_phys_cpuid = cpu_physical_id(0);
269 xpc_vars->vars_part_pa = __pa(xpc_vars_part); 258 xpc_vars->vars_part_pa = __pa(xpc_vars_part);
270 xpc_vars->amos_page_pa = ia64_tpa((u64) amos_page); 259 xpc_vars->amos_page_pa = ia64_tpa((u64)amos_page);
271 xpc_vars->amos_page = amos_page; /* save for next load of XPC */ 260 xpc_vars->amos_page = amos_page; /* save for next load of XPC */
272
273 261
274 /* clear xpc_vars_part */ 262 /* clear xpc_vars_part */
275 memset((u64 *) xpc_vars_part, 0, sizeof(struct xpc_vars_part) * 263 memset((u64 *)xpc_vars_part, 0, sizeof(struct xpc_vars_part) *
276 XP_MAX_PARTITIONS); 264 XP_MAX_PARTITIONS);
277 265
278 /* initialize the activate IRQ related AMO variables */ 266 /* initialize the activate IRQ related AMO variables */
279 for (i = 0; i < xp_nasid_mask_words; i++) { 267 for (i = 0; i < xp_nasid_mask_words; i++) {
280 (void) xpc_IPI_init(XPC_ACTIVATE_IRQ_AMOS + i); 268 (void)xpc_IPI_init(XPC_ACTIVATE_IRQ_AMOS + i);
281 } 269 }
282 270
283 /* initialize the engaged remote partitions related AMO variables */ 271 /* initialize the engaged remote partitions related AMO variables */
284 (void) xpc_IPI_init(XPC_ENGAGED_PARTITIONS_AMO); 272 (void)xpc_IPI_init(XPC_ENGAGED_PARTITIONS_AMO);
285 (void) xpc_IPI_init(XPC_DISENGAGE_REQUEST_AMO); 273 (void)xpc_IPI_init(XPC_DISENGAGE_REQUEST_AMO);
286 274
287 /* timestamp of when reserved page was setup by XPC */ 275 /* timestamp of when reserved page was setup by XPC */
288 rp->stamp = CURRENT_TIME; 276 rp->stamp = CURRENT_TIME;
@@ -296,7 +284,6 @@ xpc_rsvd_page_init(void)
296 return rp; 284 return rp;
297} 285}
298 286
299
300/* 287/*
301 * Change protections to allow IPI operations (and AMO operations on 288 * Change protections to allow IPI operations (and AMO operations on
302 * Shub 1.1 systems). 289 * Shub 1.1 systems).
@@ -307,39 +294,38 @@ xpc_allow_IPI_ops(void)
307 int node; 294 int node;
308 int nasid; 295 int nasid;
309 296
310
311 // >>> Change SH_IPI_ACCESS code to use SAL call once it is available. 297 // >>> Change SH_IPI_ACCESS code to use SAL call once it is available.
312 298
313 if (is_shub2()) { 299 if (is_shub2()) {
314 xpc_sh2_IPI_access0 = 300 xpc_sh2_IPI_access0 =
315 (u64) HUB_L((u64 *) LOCAL_MMR_ADDR(SH2_IPI_ACCESS0)); 301 (u64)HUB_L((u64 *)LOCAL_MMR_ADDR(SH2_IPI_ACCESS0));
316 xpc_sh2_IPI_access1 = 302 xpc_sh2_IPI_access1 =
317 (u64) HUB_L((u64 *) LOCAL_MMR_ADDR(SH2_IPI_ACCESS1)); 303 (u64)HUB_L((u64 *)LOCAL_MMR_ADDR(SH2_IPI_ACCESS1));
318 xpc_sh2_IPI_access2 = 304 xpc_sh2_IPI_access2 =
319 (u64) HUB_L((u64 *) LOCAL_MMR_ADDR(SH2_IPI_ACCESS2)); 305 (u64)HUB_L((u64 *)LOCAL_MMR_ADDR(SH2_IPI_ACCESS2));
320 xpc_sh2_IPI_access3 = 306 xpc_sh2_IPI_access3 =
321 (u64) HUB_L((u64 *) LOCAL_MMR_ADDR(SH2_IPI_ACCESS3)); 307 (u64)HUB_L((u64 *)LOCAL_MMR_ADDR(SH2_IPI_ACCESS3));
322 308
323 for_each_online_node(node) { 309 for_each_online_node(node) {
324 nasid = cnodeid_to_nasid(node); 310 nasid = cnodeid_to_nasid(node);
325 HUB_S((u64 *) GLOBAL_MMR_ADDR(nasid, SH2_IPI_ACCESS0), 311 HUB_S((u64 *)GLOBAL_MMR_ADDR(nasid, SH2_IPI_ACCESS0),
326 -1UL); 312 -1UL);
327 HUB_S((u64 *) GLOBAL_MMR_ADDR(nasid, SH2_IPI_ACCESS1), 313 HUB_S((u64 *)GLOBAL_MMR_ADDR(nasid, SH2_IPI_ACCESS1),
328 -1UL); 314 -1UL);
329 HUB_S((u64 *) GLOBAL_MMR_ADDR(nasid, SH2_IPI_ACCESS2), 315 HUB_S((u64 *)GLOBAL_MMR_ADDR(nasid, SH2_IPI_ACCESS2),
330 -1UL); 316 -1UL);
331 HUB_S((u64 *) GLOBAL_MMR_ADDR(nasid, SH2_IPI_ACCESS3), 317 HUB_S((u64 *)GLOBAL_MMR_ADDR(nasid, SH2_IPI_ACCESS3),
332 -1UL); 318 -1UL);
333 } 319 }
334 320
335 } else { 321 } else {
336 xpc_sh1_IPI_access = 322 xpc_sh1_IPI_access =
337 (u64) HUB_L((u64 *) LOCAL_MMR_ADDR(SH1_IPI_ACCESS)); 323 (u64)HUB_L((u64 *)LOCAL_MMR_ADDR(SH1_IPI_ACCESS));
338 324
339 for_each_online_node(node) { 325 for_each_online_node(node) {
340 nasid = cnodeid_to_nasid(node); 326 nasid = cnodeid_to_nasid(node);
341 HUB_S((u64 *) GLOBAL_MMR_ADDR(nasid, SH1_IPI_ACCESS), 327 HUB_S((u64 *)GLOBAL_MMR_ADDR(nasid, SH1_IPI_ACCESS),
342 -1UL); 328 -1UL);
343 329
344 /* 330 /*
345 * Since the BIST collides with memory operations on 331 * Since the BIST collides with memory operations on
@@ -347,21 +333,23 @@ xpc_allow_IPI_ops(void)
347 */ 333 */
348 if (enable_shub_wars_1_1()) { 334 if (enable_shub_wars_1_1()) {
349 /* open up everything */ 335 /* open up everything */
350 xpc_prot_vec[node] = (u64) HUB_L((u64 *) 336 xpc_prot_vec[node] = (u64)HUB_L((u64 *)
351 GLOBAL_MMR_ADDR(nasid, 337 GLOBAL_MMR_ADDR
352 SH1_MD_DQLP_MMR_DIR_PRIVEC0)); 338 (nasid,
353 HUB_S((u64 *) GLOBAL_MMR_ADDR(nasid, 339 SH1_MD_DQLP_MMR_DIR_PRIVEC0));
354 SH1_MD_DQLP_MMR_DIR_PRIVEC0), 340 HUB_S((u64 *)
355 -1UL); 341 GLOBAL_MMR_ADDR(nasid,
356 HUB_S((u64 *) GLOBAL_MMR_ADDR(nasid, 342 SH1_MD_DQLP_MMR_DIR_PRIVEC0),
357 SH1_MD_DQRP_MMR_DIR_PRIVEC0), 343 -1UL);
358 -1UL); 344 HUB_S((u64 *)
345 GLOBAL_MMR_ADDR(nasid,
346 SH1_MD_DQRP_MMR_DIR_PRIVEC0),
347 -1UL);
359 } 348 }
360 } 349 }
361 } 350 }
362} 351}
363 352
364
365/* 353/*
366 * Restrict protections to disallow IPI operations (and AMO operations on 354 * Restrict protections to disallow IPI operations (and AMO operations on
367 * Shub 1.1 systems). 355 * Shub 1.1 systems).
@@ -372,43 +360,41 @@ xpc_restrict_IPI_ops(void)
372 int node; 360 int node;
373 int nasid; 361 int nasid;
374 362
375
376 // >>> Change SH_IPI_ACCESS code to use SAL call once it is available. 363 // >>> Change SH_IPI_ACCESS code to use SAL call once it is available.
377 364
378 if (is_shub2()) { 365 if (is_shub2()) {
379 366
380 for_each_online_node(node) { 367 for_each_online_node(node) {
381 nasid = cnodeid_to_nasid(node); 368 nasid = cnodeid_to_nasid(node);
382 HUB_S((u64 *) GLOBAL_MMR_ADDR(nasid, SH2_IPI_ACCESS0), 369 HUB_S((u64 *)GLOBAL_MMR_ADDR(nasid, SH2_IPI_ACCESS0),
383 xpc_sh2_IPI_access0); 370 xpc_sh2_IPI_access0);
384 HUB_S((u64 *) GLOBAL_MMR_ADDR(nasid, SH2_IPI_ACCESS1), 371 HUB_S((u64 *)GLOBAL_MMR_ADDR(nasid, SH2_IPI_ACCESS1),
385 xpc_sh2_IPI_access1); 372 xpc_sh2_IPI_access1);
386 HUB_S((u64 *) GLOBAL_MMR_ADDR(nasid, SH2_IPI_ACCESS2), 373 HUB_S((u64 *)GLOBAL_MMR_ADDR(nasid, SH2_IPI_ACCESS2),
387 xpc_sh2_IPI_access2); 374 xpc_sh2_IPI_access2);
388 HUB_S((u64 *) GLOBAL_MMR_ADDR(nasid, SH2_IPI_ACCESS3), 375 HUB_S((u64 *)GLOBAL_MMR_ADDR(nasid, SH2_IPI_ACCESS3),
389 xpc_sh2_IPI_access3); 376 xpc_sh2_IPI_access3);
390 } 377 }
391 378
392 } else { 379 } else {
393 380
394 for_each_online_node(node) { 381 for_each_online_node(node) {
395 nasid = cnodeid_to_nasid(node); 382 nasid = cnodeid_to_nasid(node);
396 HUB_S((u64 *) GLOBAL_MMR_ADDR(nasid, SH1_IPI_ACCESS), 383 HUB_S((u64 *)GLOBAL_MMR_ADDR(nasid, SH1_IPI_ACCESS),
397 xpc_sh1_IPI_access); 384 xpc_sh1_IPI_access);
398 385
399 if (enable_shub_wars_1_1()) { 386 if (enable_shub_wars_1_1()) {
400 HUB_S((u64 *) GLOBAL_MMR_ADDR(nasid, 387 HUB_S((u64 *)GLOBAL_MMR_ADDR(nasid,
401 SH1_MD_DQLP_MMR_DIR_PRIVEC0), 388 SH1_MD_DQLP_MMR_DIR_PRIVEC0),
402 xpc_prot_vec[node]); 389 xpc_prot_vec[node]);
403 HUB_S((u64 *) GLOBAL_MMR_ADDR(nasid, 390 HUB_S((u64 *)GLOBAL_MMR_ADDR(nasid,
404 SH1_MD_DQRP_MMR_DIR_PRIVEC0), 391 SH1_MD_DQRP_MMR_DIR_PRIVEC0),
405 xpc_prot_vec[node]); 392 xpc_prot_vec[node]);
406 } 393 }
407 } 394 }
408 } 395 }
409} 396}
410 397
411
412/* 398/*
413 * At periodic intervals, scan through all active partitions and ensure 399 * At periodic intervals, scan through all active partitions and ensure
414 * their heartbeat is still active. If not, the partition is deactivated. 400 * their heartbeat is still active. If not, the partition is deactivated.
@@ -421,8 +407,7 @@ xpc_check_remote_hb(void)
421 partid_t partid; 407 partid_t partid;
422 bte_result_t bres; 408 bte_result_t bres;
423 409
424 410 remote_vars = (struct xpc_vars *)xpc_remote_copy_buffer;
425 remote_vars = (struct xpc_vars *) xpc_remote_copy_buffer;
426 411
427 for (partid = 1; partid < XP_MAX_PARTITIONS; partid++) { 412 for (partid = 1; partid < XP_MAX_PARTITIONS; partid++) {
428 413
@@ -437,18 +422,18 @@ xpc_check_remote_hb(void)
437 part = &xpc_partitions[partid]; 422 part = &xpc_partitions[partid];
438 423
439 if (part->act_state == XPC_P_INACTIVE || 424 if (part->act_state == XPC_P_INACTIVE ||
440 part->act_state == XPC_P_DEACTIVATING) { 425 part->act_state == XPC_P_DEACTIVATING) {
441 continue; 426 continue;
442 } 427 }
443 428
444 /* pull the remote_hb cache line */ 429 /* pull the remote_hb cache line */
445 bres = xp_bte_copy(part->remote_vars_pa, 430 bres = xp_bte_copy(part->remote_vars_pa,
446 (u64) remote_vars, 431 (u64)remote_vars,
447 XPC_RP_VARS_SIZE, 432 XPC_RP_VARS_SIZE,
448 (BTE_NOTIFY | BTE_WACQUIRE), NULL); 433 (BTE_NOTIFY | BTE_WACQUIRE), NULL);
449 if (bres != BTE_SUCCESS) { 434 if (bres != BTE_SUCCESS) {
450 XPC_DEACTIVATE_PARTITION(part, 435 XPC_DEACTIVATE_PARTITION(part,
451 xpc_map_bte_errors(bres)); 436 xpc_map_bte_errors(bres));
452 continue; 437 continue;
453 } 438 }
454 439
@@ -459,8 +444,8 @@ xpc_check_remote_hb(void)
459 remote_vars->heartbeating_to_mask); 444 remote_vars->heartbeating_to_mask);
460 445
461 if (((remote_vars->heartbeat == part->last_heartbeat) && 446 if (((remote_vars->heartbeat == part->last_heartbeat) &&
462 (remote_vars->heartbeat_offline == 0)) || 447 (remote_vars->heartbeat_offline == 0)) ||
463 !xpc_hb_allowed(sn_partition_id, remote_vars)) { 448 !xpc_hb_allowed(sn_partition_id, remote_vars)) {
464 449
465 XPC_DEACTIVATE_PARTITION(part, xpcNoHeartbeat); 450 XPC_DEACTIVATE_PARTITION(part, xpcNoHeartbeat);
466 continue; 451 continue;
@@ -470,7 +455,6 @@ xpc_check_remote_hb(void)
470 } 455 }
471} 456}
472 457
473
474/* 458/*
475 * Get a copy of a portion of the remote partition's rsvd page. 459 * Get a copy of a portion of the remote partition's rsvd page.
476 * 460 *
@@ -480,11 +464,10 @@ xpc_check_remote_hb(void)
480 */ 464 */
481static enum xpc_retval 465static enum xpc_retval
482xpc_get_remote_rp(int nasid, u64 *discovered_nasids, 466xpc_get_remote_rp(int nasid, u64 *discovered_nasids,
483 struct xpc_rsvd_page *remote_rp, u64 *remote_rp_pa) 467 struct xpc_rsvd_page *remote_rp, u64 *remote_rp_pa)
484{ 468{
485 int bres, i; 469 int bres, i;
486 470
487
488 /* get the reserved page's physical address */ 471 /* get the reserved page's physical address */
489 472
490 *remote_rp_pa = xpc_get_rsvd_page_pa(nasid); 473 *remote_rp_pa = xpc_get_rsvd_page_pa(nasid);
@@ -492,30 +475,26 @@ xpc_get_remote_rp(int nasid, u64 *discovered_nasids,
492 return xpcNoRsvdPageAddr; 475 return xpcNoRsvdPageAddr;
493 } 476 }
494 477
495
496 /* pull over the reserved page header and part_nasids mask */ 478 /* pull over the reserved page header and part_nasids mask */
497 bres = xp_bte_copy(*remote_rp_pa, (u64) remote_rp, 479 bres = xp_bte_copy(*remote_rp_pa, (u64)remote_rp,
498 XPC_RP_HEADER_SIZE + xp_nasid_mask_bytes, 480 XPC_RP_HEADER_SIZE + xp_nasid_mask_bytes,
499 (BTE_NOTIFY | BTE_WACQUIRE), NULL); 481 (BTE_NOTIFY | BTE_WACQUIRE), NULL);
500 if (bres != BTE_SUCCESS) { 482 if (bres != BTE_SUCCESS) {
501 return xpc_map_bte_errors(bres); 483 return xpc_map_bte_errors(bres);
502 } 484 }
503 485
504
505 if (discovered_nasids != NULL) { 486 if (discovered_nasids != NULL) {
506 u64 *remote_part_nasids = XPC_RP_PART_NASIDS(remote_rp); 487 u64 *remote_part_nasids = XPC_RP_PART_NASIDS(remote_rp);
507 488
508
509 for (i = 0; i < xp_nasid_mask_words; i++) { 489 for (i = 0; i < xp_nasid_mask_words; i++) {
510 discovered_nasids[i] |= remote_part_nasids[i]; 490 discovered_nasids[i] |= remote_part_nasids[i];
511 } 491 }
512 } 492 }
513 493
514
515 /* check that the partid is for another partition */ 494 /* check that the partid is for another partition */
516 495
517 if (remote_rp->partid < 1 || 496 if (remote_rp->partid < 1 ||
518 remote_rp->partid > (XP_MAX_PARTITIONS - 1)) { 497 remote_rp->partid > (XP_MAX_PARTITIONS - 1)) {
519 return xpcInvalidPartid; 498 return xpcInvalidPartid;
520 } 499 }
521 500
@@ -523,16 +502,14 @@ xpc_get_remote_rp(int nasid, u64 *discovered_nasids,
523 return xpcLocalPartid; 502 return xpcLocalPartid;
524 } 503 }
525 504
526
527 if (XPC_VERSION_MAJOR(remote_rp->version) != 505 if (XPC_VERSION_MAJOR(remote_rp->version) !=
528 XPC_VERSION_MAJOR(XPC_RP_VERSION)) { 506 XPC_VERSION_MAJOR(XPC_RP_VERSION)) {
529 return xpcBadVersion; 507 return xpcBadVersion;
530 } 508 }
531 509
532 return xpcSuccess; 510 return xpcSuccess;
533} 511}
534 512
535
536/* 513/*
537 * Get a copy of the remote partition's XPC variables from the reserved page. 514 * Get a copy of the remote partition's XPC variables from the reserved page.
538 * 515 *
@@ -544,34 +521,32 @@ xpc_get_remote_vars(u64 remote_vars_pa, struct xpc_vars *remote_vars)
544{ 521{
545 int bres; 522 int bres;
546 523
547
548 if (remote_vars_pa == 0) { 524 if (remote_vars_pa == 0) {
549 return xpcVarsNotSet; 525 return xpcVarsNotSet;
550 } 526 }
551 527
552 /* pull over the cross partition variables */ 528 /* pull over the cross partition variables */
553 bres = xp_bte_copy(remote_vars_pa, (u64) remote_vars, XPC_RP_VARS_SIZE, 529 bres = xp_bte_copy(remote_vars_pa, (u64)remote_vars, XPC_RP_VARS_SIZE,
554 (BTE_NOTIFY | BTE_WACQUIRE), NULL); 530 (BTE_NOTIFY | BTE_WACQUIRE), NULL);
555 if (bres != BTE_SUCCESS) { 531 if (bres != BTE_SUCCESS) {
556 return xpc_map_bte_errors(bres); 532 return xpc_map_bte_errors(bres);
557 } 533 }
558 534
559 if (XPC_VERSION_MAJOR(remote_vars->version) != 535 if (XPC_VERSION_MAJOR(remote_vars->version) !=
560 XPC_VERSION_MAJOR(XPC_V_VERSION)) { 536 XPC_VERSION_MAJOR(XPC_V_VERSION)) {
561 return xpcBadVersion; 537 return xpcBadVersion;
562 } 538 }
563 539
564 return xpcSuccess; 540 return xpcSuccess;
565} 541}
566 542
567
568/* 543/*
569 * Update the remote partition's info. 544 * Update the remote partition's info.
570 */ 545 */
571static void 546static void
572xpc_update_partition_info(struct xpc_partition *part, u8 remote_rp_version, 547xpc_update_partition_info(struct xpc_partition *part, u8 remote_rp_version,
573 struct timespec *remote_rp_stamp, u64 remote_rp_pa, 548 struct timespec *remote_rp_stamp, u64 remote_rp_pa,
574 u64 remote_vars_pa, struct xpc_vars *remote_vars) 549 u64 remote_vars_pa, struct xpc_vars *remote_vars)
575{ 550{
576 part->remote_rp_version = remote_rp_version; 551 part->remote_rp_version = remote_rp_version;
577 dev_dbg(xpc_part, " remote_rp_version = 0x%016x\n", 552 dev_dbg(xpc_part, " remote_rp_version = 0x%016x\n",
@@ -613,7 +588,6 @@ xpc_update_partition_info(struct xpc_partition *part, u8 remote_rp_version,
613 part->remote_vars_version); 588 part->remote_vars_version);
614} 589}
615 590
616
617/* 591/*
618 * Prior code has determined the nasid which generated an IPI. Inspect 592 * Prior code has determined the nasid which generated an IPI. Inspect
619 * that nasid to determine if its partition needs to be activated or 593 * that nasid to determine if its partition needs to be activated or
@@ -643,15 +617,14 @@ xpc_identify_act_IRQ_req(int nasid)
643 struct xpc_partition *part; 617 struct xpc_partition *part;
644 enum xpc_retval ret; 618 enum xpc_retval ret;
645 619
646
647 /* pull over the reserved page structure */ 620 /* pull over the reserved page structure */
648 621
649 remote_rp = (struct xpc_rsvd_page *) xpc_remote_copy_buffer; 622 remote_rp = (struct xpc_rsvd_page *)xpc_remote_copy_buffer;
650 623
651 ret = xpc_get_remote_rp(nasid, NULL, remote_rp, &remote_rp_pa); 624 ret = xpc_get_remote_rp(nasid, NULL, remote_rp, &remote_rp_pa);
652 if (ret != xpcSuccess) { 625 if (ret != xpcSuccess) {
653 dev_warn(xpc_part, "unable to get reserved page from nasid %d, " 626 dev_warn(xpc_part, "unable to get reserved page from nasid %d, "
654 "which sent interrupt, reason=%d\n", nasid, ret); 627 "which sent interrupt, reason=%d\n", nasid, ret);
655 return; 628 return;
656 } 629 }
657 630
@@ -663,34 +636,31 @@ xpc_identify_act_IRQ_req(int nasid)
663 partid = remote_rp->partid; 636 partid = remote_rp->partid;
664 part = &xpc_partitions[partid]; 637 part = &xpc_partitions[partid];
665 638
666
667 /* pull over the cross partition variables */ 639 /* pull over the cross partition variables */
668 640
669 remote_vars = (struct xpc_vars *) xpc_remote_copy_buffer; 641 remote_vars = (struct xpc_vars *)xpc_remote_copy_buffer;
670 642
671 ret = xpc_get_remote_vars(remote_vars_pa, remote_vars); 643 ret = xpc_get_remote_vars(remote_vars_pa, remote_vars);
672 if (ret != xpcSuccess) { 644 if (ret != xpcSuccess) {
673 645
674 dev_warn(xpc_part, "unable to get XPC variables from nasid %d, " 646 dev_warn(xpc_part, "unable to get XPC variables from nasid %d, "
675 "which sent interrupt, reason=%d\n", nasid, ret); 647 "which sent interrupt, reason=%d\n", nasid, ret);
676 648
677 XPC_DEACTIVATE_PARTITION(part, ret); 649 XPC_DEACTIVATE_PARTITION(part, ret);
678 return; 650 return;
679 } 651 }
680 652
681
682 part->act_IRQ_rcvd++; 653 part->act_IRQ_rcvd++;
683 654
684 dev_dbg(xpc_part, "partid for nasid %d is %d; IRQs = %d; HB = " 655 dev_dbg(xpc_part, "partid for nasid %d is %d; IRQs = %d; HB = "
685 "%ld:0x%lx\n", (int) nasid, (int) partid, part->act_IRQ_rcvd, 656 "%ld:0x%lx\n", (int)nasid, (int)partid, part->act_IRQ_rcvd,
686 remote_vars->heartbeat, remote_vars->heartbeating_to_mask); 657 remote_vars->heartbeat, remote_vars->heartbeating_to_mask);
687 658
688 if (xpc_partition_disengaged(part) && 659 if (xpc_partition_disengaged(part) && part->act_state == XPC_P_INACTIVE) {
689 part->act_state == XPC_P_INACTIVE) {
690 660
691 xpc_update_partition_info(part, remote_rp_version, 661 xpc_update_partition_info(part, remote_rp_version,
692 &remote_rp_stamp, remote_rp_pa, 662 &remote_rp_stamp, remote_rp_pa,
693 remote_vars_pa, remote_vars); 663 remote_vars_pa, remote_vars);
694 664
695 if (XPC_SUPPORTS_DISENGAGE_REQUEST(part->remote_vars_version)) { 665 if (XPC_SUPPORTS_DISENGAGE_REQUEST(part->remote_vars_version)) {
696 if (xpc_partition_disengage_requested(1UL << partid)) { 666 if (xpc_partition_disengage_requested(1UL << partid)) {
@@ -714,16 +684,15 @@ xpc_identify_act_IRQ_req(int nasid)
714 684
715 if (!XPC_SUPPORTS_RP_STAMP(part->remote_rp_version)) { 685 if (!XPC_SUPPORTS_RP_STAMP(part->remote_rp_version)) {
716 DBUG_ON(XPC_SUPPORTS_DISENGAGE_REQUEST(part-> 686 DBUG_ON(XPC_SUPPORTS_DISENGAGE_REQUEST(part->
717 remote_vars_version)); 687 remote_vars_version));
718 688
719 if (!XPC_SUPPORTS_RP_STAMP(remote_rp_version)) { 689 if (!XPC_SUPPORTS_RP_STAMP(remote_rp_version)) {
720 DBUG_ON(XPC_SUPPORTS_DISENGAGE_REQUEST(remote_vars-> 690 DBUG_ON(XPC_SUPPORTS_DISENGAGE_REQUEST(remote_vars->
721 version)); 691 version));
722 /* see if the other side rebooted */ 692 /* see if the other side rebooted */
723 if (part->remote_amos_page_pa == 693 if (part->remote_amos_page_pa ==
724 remote_vars->amos_page_pa && 694 remote_vars->amos_page_pa &&
725 xpc_hb_allowed(sn_partition_id, 695 xpc_hb_allowed(sn_partition_id, remote_vars)) {
726 remote_vars)) {
727 /* doesn't look that way, so ignore the IPI */ 696 /* doesn't look that way, so ignore the IPI */
728 return; 697 return;
729 } 698 }
@@ -735,8 +704,8 @@ xpc_identify_act_IRQ_req(int nasid)
735 */ 704 */
736 705
737 xpc_update_partition_info(part, remote_rp_version, 706 xpc_update_partition_info(part, remote_rp_version,
738 &remote_rp_stamp, remote_rp_pa, 707 &remote_rp_stamp, remote_rp_pa,
739 remote_vars_pa, remote_vars); 708 remote_vars_pa, remote_vars);
740 part->reactivate_nasid = nasid; 709 part->reactivate_nasid = nasid;
741 XPC_DEACTIVATE_PARTITION(part, xpcReactivating); 710 XPC_DEACTIVATE_PARTITION(part, xpcReactivating);
742 return; 711 return;
@@ -756,15 +725,15 @@ xpc_identify_act_IRQ_req(int nasid)
756 xpc_clear_partition_disengage_request(1UL << partid); 725 xpc_clear_partition_disengage_request(1UL << partid);
757 726
758 xpc_update_partition_info(part, remote_rp_version, 727 xpc_update_partition_info(part, remote_rp_version,
759 &remote_rp_stamp, remote_rp_pa, 728 &remote_rp_stamp, remote_rp_pa,
760 remote_vars_pa, remote_vars); 729 remote_vars_pa, remote_vars);
761 reactivate = 1; 730 reactivate = 1;
762 731
763 } else { 732 } else {
764 DBUG_ON(!XPC_SUPPORTS_DISENGAGE_REQUEST(remote_vars->version)); 733 DBUG_ON(!XPC_SUPPORTS_DISENGAGE_REQUEST(remote_vars->version));
765 734
766 stamp_diff = xpc_compare_stamps(&part->remote_rp_stamp, 735 stamp_diff = xpc_compare_stamps(&part->remote_rp_stamp,
767 &remote_rp_stamp); 736 &remote_rp_stamp);
768 if (stamp_diff != 0) { 737 if (stamp_diff != 0) {
769 DBUG_ON(stamp_diff >= 0); 738 DBUG_ON(stamp_diff >= 0);
770 739
@@ -775,17 +744,18 @@ xpc_identify_act_IRQ_req(int nasid)
775 744
776 DBUG_ON(xpc_partition_engaged(1UL << partid)); 745 DBUG_ON(xpc_partition_engaged(1UL << partid));
777 DBUG_ON(xpc_partition_disengage_requested(1UL << 746 DBUG_ON(xpc_partition_disengage_requested(1UL <<
778 partid)); 747 partid));
779 748
780 xpc_update_partition_info(part, remote_rp_version, 749 xpc_update_partition_info(part, remote_rp_version,
781 &remote_rp_stamp, remote_rp_pa, 750 &remote_rp_stamp,
782 remote_vars_pa, remote_vars); 751 remote_rp_pa, remote_vars_pa,
752 remote_vars);
783 reactivate = 1; 753 reactivate = 1;
784 } 754 }
785 } 755 }
786 756
787 if (part->disengage_request_timeout > 0 && 757 if (part->disengage_request_timeout > 0 &&
788 !xpc_partition_disengaged(part)) { 758 !xpc_partition_disengaged(part)) {
789 /* still waiting on other side to disengage from us */ 759 /* still waiting on other side to disengage from us */
790 return; 760 return;
791 } 761 }
@@ -795,12 +765,11 @@ xpc_identify_act_IRQ_req(int nasid)
795 XPC_DEACTIVATE_PARTITION(part, xpcReactivating); 765 XPC_DEACTIVATE_PARTITION(part, xpcReactivating);
796 766
797 } else if (XPC_SUPPORTS_DISENGAGE_REQUEST(part->remote_vars_version) && 767 } else if (XPC_SUPPORTS_DISENGAGE_REQUEST(part->remote_vars_version) &&
798 xpc_partition_disengage_requested(1UL << partid)) { 768 xpc_partition_disengage_requested(1UL << partid)) {
799 XPC_DEACTIVATE_PARTITION(part, xpcOtherGoingDown); 769 XPC_DEACTIVATE_PARTITION(part, xpcOtherGoingDown);
800 } 770 }
801} 771}
802 772
803
804/* 773/*
805 * Loop through the activation AMO variables and process any bits 774 * Loop through the activation AMO variables and process any bits
806 * which are set. Each bit indicates a nasid sending a partition 775 * which are set. Each bit indicates a nasid sending a partition
@@ -813,14 +782,12 @@ xpc_identify_act_IRQ_sender(void)
813{ 782{
814 int word, bit; 783 int word, bit;
815 u64 nasid_mask; 784 u64 nasid_mask;
816 u64 nasid; /* remote nasid */ 785 u64 nasid; /* remote nasid */
817 int n_IRQs_detected = 0; 786 int n_IRQs_detected = 0;
818 AMO_t *act_amos; 787 AMO_t *act_amos;
819 788
820
821 act_amos = xpc_vars->amos_page + XPC_ACTIVATE_IRQ_AMOS; 789 act_amos = xpc_vars->amos_page + XPC_ACTIVATE_IRQ_AMOS;
822 790
823
824 /* scan through act AMO variable looking for non-zero entries */ 791 /* scan through act AMO variable looking for non-zero entries */
825 for (word = 0; word < xp_nasid_mask_words; word++) { 792 for (word = 0; word < xp_nasid_mask_words; word++) {
826 793
@@ -837,7 +804,6 @@ xpc_identify_act_IRQ_sender(void)
837 dev_dbg(xpc_part, "AMO[%d] gave back 0x%lx\n", word, 804 dev_dbg(xpc_part, "AMO[%d] gave back 0x%lx\n", word,
838 nasid_mask); 805 nasid_mask);
839 806
840
841 /* 807 /*
842 * If this nasid has been added to the machine since 808 * If this nasid has been added to the machine since
843 * our partition was reset, this will retain the 809 * our partition was reset, this will retain the
@@ -846,7 +812,6 @@ xpc_identify_act_IRQ_sender(void)
846 */ 812 */
847 xpc_mach_nasids[word] |= nasid_mask; 813 xpc_mach_nasids[word] |= nasid_mask;
848 814
849
850 /* locate the nasid(s) which sent interrupts */ 815 /* locate the nasid(s) which sent interrupts */
851 816
852 for (bit = 0; bit < (8 * sizeof(u64)); bit++) { 817 for (bit = 0; bit < (8 * sizeof(u64)); bit++) {
@@ -862,7 +827,6 @@ xpc_identify_act_IRQ_sender(void)
862 return n_IRQs_detected; 827 return n_IRQs_detected;
863} 828}
864 829
865
866/* 830/*
867 * See if the other side has responded to a partition disengage request 831 * See if the other side has responded to a partition disengage request
868 * from us. 832 * from us.
@@ -873,7 +837,6 @@ xpc_partition_disengaged(struct xpc_partition *part)
873 partid_t partid = XPC_PARTID(part); 837 partid_t partid = XPC_PARTID(part);
874 int disengaged; 838 int disengaged;
875 839
876
877 disengaged = (xpc_partition_engaged(1UL << partid) == 0); 840 disengaged = (xpc_partition_engaged(1UL << partid) == 0);
878 if (part->disengage_request_timeout) { 841 if (part->disengage_request_timeout) {
879 if (!disengaged) { 842 if (!disengaged) {
@@ -888,7 +851,7 @@ xpc_partition_disengaged(struct xpc_partition *part)
888 */ 851 */
889 852
890 dev_info(xpc_part, "disengage from remote partition %d " 853 dev_info(xpc_part, "disengage from remote partition %d "
891 "timed out\n", partid); 854 "timed out\n", partid);
892 xpc_disengage_request_timedout = 1; 855 xpc_disengage_request_timedout = 1;
893 xpc_clear_partition_engaged(1UL << partid); 856 xpc_clear_partition_engaged(1UL << partid);
894 disengaged = 1; 857 disengaged = 1;
@@ -898,11 +861,11 @@ xpc_partition_disengaged(struct xpc_partition *part)
898 /* cancel the timer function, provided it's not us */ 861 /* cancel the timer function, provided it's not us */
899 if (!in_interrupt()) { 862 if (!in_interrupt()) {
900 del_singleshot_timer_sync(&part-> 863 del_singleshot_timer_sync(&part->
901 disengage_request_timer); 864 disengage_request_timer);
902 } 865 }
903 866
904 DBUG_ON(part->act_state != XPC_P_DEACTIVATING && 867 DBUG_ON(part->act_state != XPC_P_DEACTIVATING &&
905 part->act_state != XPC_P_INACTIVE); 868 part->act_state != XPC_P_INACTIVE);
906 if (part->act_state != XPC_P_INACTIVE) { 869 if (part->act_state != XPC_P_INACTIVE) {
907 xpc_wakeup_channel_mgr(part); 870 xpc_wakeup_channel_mgr(part);
908 } 871 }
@@ -914,7 +877,6 @@ xpc_partition_disengaged(struct xpc_partition *part)
914 return disengaged; 877 return disengaged;
915} 878}
916 879
917
918/* 880/*
919 * Mark specified partition as active. 881 * Mark specified partition as active.
920 */ 882 */
@@ -924,7 +886,6 @@ xpc_mark_partition_active(struct xpc_partition *part)
924 unsigned long irq_flags; 886 unsigned long irq_flags;
925 enum xpc_retval ret; 887 enum xpc_retval ret;
926 888
927
928 dev_dbg(xpc_part, "setting partition %d to ACTIVE\n", XPC_PARTID(part)); 889 dev_dbg(xpc_part, "setting partition %d to ACTIVE\n", XPC_PARTID(part));
929 890
930 spin_lock_irqsave(&part->act_lock, irq_flags); 891 spin_lock_irqsave(&part->act_lock, irq_flags);
@@ -940,17 +901,15 @@ xpc_mark_partition_active(struct xpc_partition *part)
940 return ret; 901 return ret;
941} 902}
942 903
943
944/* 904/*
945 * Notify XPC that the partition is down. 905 * Notify XPC that the partition is down.
946 */ 906 */
947void 907void
948xpc_deactivate_partition(const int line, struct xpc_partition *part, 908xpc_deactivate_partition(const int line, struct xpc_partition *part,
949 enum xpc_retval reason) 909 enum xpc_retval reason)
950{ 910{
951 unsigned long irq_flags; 911 unsigned long irq_flags;
952 912
953
954 spin_lock_irqsave(&part->act_lock, irq_flags); 913 spin_lock_irqsave(&part->act_lock, irq_flags);
955 914
956 if (part->act_state == XPC_P_INACTIVE) { 915 if (part->act_state == XPC_P_INACTIVE) {
@@ -964,7 +923,7 @@ xpc_deactivate_partition(const int line, struct xpc_partition *part,
964 } 923 }
965 if (part->act_state == XPC_P_DEACTIVATING) { 924 if (part->act_state == XPC_P_DEACTIVATING) {
966 if ((part->reason == xpcUnloading && reason != xpcUnloading) || 925 if ((part->reason == xpcUnloading && reason != xpcUnloading) ||
967 reason == xpcReactivating) { 926 reason == xpcReactivating) {
968 XPC_SET_REASON(part, reason, line); 927 XPC_SET_REASON(part, reason, line);
969 } 928 }
970 spin_unlock_irqrestore(&part->act_lock, irq_flags); 929 spin_unlock_irqrestore(&part->act_lock, irq_flags);
@@ -982,9 +941,9 @@ xpc_deactivate_partition(const int line, struct xpc_partition *part,
982 941
983 /* set a timelimit on the disengage request */ 942 /* set a timelimit on the disengage request */
984 part->disengage_request_timeout = jiffies + 943 part->disengage_request_timeout = jiffies +
985 (xpc_disengage_request_timelimit * HZ); 944 (xpc_disengage_request_timelimit * HZ);
986 part->disengage_request_timer.expires = 945 part->disengage_request_timer.expires =
987 part->disengage_request_timeout; 946 part->disengage_request_timeout;
988 add_timer(&part->disengage_request_timer); 947 add_timer(&part->disengage_request_timer);
989 } 948 }
990 949
@@ -994,7 +953,6 @@ xpc_deactivate_partition(const int line, struct xpc_partition *part,
994 xpc_partition_going_down(part, reason); 953 xpc_partition_going_down(part, reason);
995} 954}
996 955
997
998/* 956/*
999 * Mark specified partition as inactive. 957 * Mark specified partition as inactive.
1000 */ 958 */
@@ -1003,7 +961,6 @@ xpc_mark_partition_inactive(struct xpc_partition *part)
1003{ 961{
1004 unsigned long irq_flags; 962 unsigned long irq_flags;
1005 963
1006
1007 dev_dbg(xpc_part, "setting partition %d to INACTIVE\n", 964 dev_dbg(xpc_part, "setting partition %d to INACTIVE\n",
1008 XPC_PARTID(part)); 965 XPC_PARTID(part));
1009 966
@@ -1013,7 +970,6 @@ xpc_mark_partition_inactive(struct xpc_partition *part)
1013 part->remote_rp_pa = 0; 970 part->remote_rp_pa = 0;
1014} 971}
1015 972
1016
1017/* 973/*
1018 * SAL has provided a partition and machine mask. The partition mask 974 * SAL has provided a partition and machine mask. The partition mask
1019 * contains a bit for each even nasid in our partition. The machine 975 * contains a bit for each even nasid in our partition. The machine
@@ -1041,24 +997,22 @@ xpc_discovery(void)
1041 u64 *discovered_nasids; 997 u64 *discovered_nasids;
1042 enum xpc_retval ret; 998 enum xpc_retval ret;
1043 999
1044
1045 remote_rp = xpc_kmalloc_cacheline_aligned(XPC_RP_HEADER_SIZE + 1000 remote_rp = xpc_kmalloc_cacheline_aligned(XPC_RP_HEADER_SIZE +
1046 xp_nasid_mask_bytes, 1001 xp_nasid_mask_bytes,
1047 GFP_KERNEL, &remote_rp_base); 1002 GFP_KERNEL, &remote_rp_base);
1048 if (remote_rp == NULL) { 1003 if (remote_rp == NULL) {
1049 return; 1004 return;
1050 } 1005 }
1051 remote_vars = (struct xpc_vars *) remote_rp; 1006 remote_vars = (struct xpc_vars *)remote_rp;
1052
1053 1007
1054 discovered_nasids = kzalloc(sizeof(u64) * xp_nasid_mask_words, 1008 discovered_nasids = kzalloc(sizeof(u64) * xp_nasid_mask_words,
1055 GFP_KERNEL); 1009 GFP_KERNEL);
1056 if (discovered_nasids == NULL) { 1010 if (discovered_nasids == NULL) {
1057 kfree(remote_rp_base); 1011 kfree(remote_rp_base);
1058 return; 1012 return;
1059 } 1013 }
1060 1014
1061 rp = (struct xpc_rsvd_page *) xpc_rsvd_page; 1015 rp = (struct xpc_rsvd_page *)xpc_rsvd_page;
1062 1016
1063 /* 1017 /*
1064 * The term 'region' in this context refers to the minimum number of 1018 * The term 'region' in this context refers to the minimum number of
@@ -1081,23 +1035,21 @@ xpc_discovery(void)
1081 1035
1082 for (region = 0; region < max_regions; region++) { 1036 for (region = 0; region < max_regions; region++) {
1083 1037
1084 if ((volatile int) xpc_exiting) { 1038 if ((volatile int)xpc_exiting) {
1085 break; 1039 break;
1086 } 1040 }
1087 1041
1088 dev_dbg(xpc_part, "searching region %d\n", region); 1042 dev_dbg(xpc_part, "searching region %d\n", region);
1089 1043
1090 for (nasid = (region * region_size * 2); 1044 for (nasid = (region * region_size * 2);
1091 nasid < ((region + 1) * region_size * 2); 1045 nasid < ((region + 1) * region_size * 2); nasid += 2) {
1092 nasid += 2) {
1093 1046
1094 if ((volatile int) xpc_exiting) { 1047 if ((volatile int)xpc_exiting) {
1095 break; 1048 break;
1096 } 1049 }
1097 1050
1098 dev_dbg(xpc_part, "checking nasid %d\n", nasid); 1051 dev_dbg(xpc_part, "checking nasid %d\n", nasid);
1099 1052
1100
1101 if (XPC_NASID_IN_ARRAY(nasid, xpc_part_nasids)) { 1053 if (XPC_NASID_IN_ARRAY(nasid, xpc_part_nasids)) {
1102 dev_dbg(xpc_part, "PROM indicates Nasid %d is " 1054 dev_dbg(xpc_part, "PROM indicates Nasid %d is "
1103 "part of the local partition; skipping " 1055 "part of the local partition; skipping "
@@ -1119,11 +1071,10 @@ xpc_discovery(void)
1119 continue; 1071 continue;
1120 } 1072 }
1121 1073
1122
1123 /* pull over the reserved page structure */ 1074 /* pull over the reserved page structure */
1124 1075
1125 ret = xpc_get_remote_rp(nasid, discovered_nasids, 1076 ret = xpc_get_remote_rp(nasid, discovered_nasids,
1126 remote_rp, &remote_rp_pa); 1077 remote_rp, &remote_rp_pa);
1127 if (ret != xpcSuccess) { 1078 if (ret != xpcSuccess) {
1128 dev_dbg(xpc_part, "unable to get reserved page " 1079 dev_dbg(xpc_part, "unable to get reserved page "
1129 "from nasid %d, reason=%d\n", nasid, 1080 "from nasid %d, reason=%d\n", nasid,
@@ -1140,7 +1091,6 @@ xpc_discovery(void)
1140 partid = remote_rp->partid; 1091 partid = remote_rp->partid;
1141 part = &xpc_partitions[partid]; 1092 part = &xpc_partitions[partid];
1142 1093
1143
1144 /* pull over the cross partition variables */ 1094 /* pull over the cross partition variables */
1145 1095
1146 ret = xpc_get_remote_vars(remote_vars_pa, remote_vars); 1096 ret = xpc_get_remote_vars(remote_vars_pa, remote_vars);
@@ -1171,15 +1121,15 @@ xpc_discovery(void)
1171 * get the same page for remote_act_amos_pa after 1121 * get the same page for remote_act_amos_pa after
1172 * module reloads and system reboots. 1122 * module reloads and system reboots.
1173 */ 1123 */
1174 if (sn_register_xp_addr_region( 1124 if (sn_register_xp_addr_region
1175 remote_vars->amos_page_pa, 1125 (remote_vars->amos_page_pa, PAGE_SIZE, 1) < 0) {
1176 PAGE_SIZE, 1) < 0) { 1126 dev_dbg(xpc_part,
1177 dev_dbg(xpc_part, "partition %d failed to " 1127 "partition %d failed to "
1178 "register xp_addr region 0x%016lx\n", 1128 "register xp_addr region 0x%016lx\n",
1179 partid, remote_vars->amos_page_pa); 1129 partid, remote_vars->amos_page_pa);
1180 1130
1181 XPC_SET_REASON(part, xpcPhysAddrRegFailed, 1131 XPC_SET_REASON(part, xpcPhysAddrRegFailed,
1182 __LINE__); 1132 __LINE__);
1183 break; 1133 break;
1184 } 1134 }
1185 1135
@@ -1195,9 +1145,9 @@ xpc_discovery(void)
1195 remote_vars->act_phys_cpuid); 1145 remote_vars->act_phys_cpuid);
1196 1146
1197 if (XPC_SUPPORTS_DISENGAGE_REQUEST(remote_vars-> 1147 if (XPC_SUPPORTS_DISENGAGE_REQUEST(remote_vars->
1198 version)) { 1148 version)) {
1199 part->remote_amos_page_pa = 1149 part->remote_amos_page_pa =
1200 remote_vars->amos_page_pa; 1150 remote_vars->amos_page_pa;
1201 xpc_mark_partition_disengaged(part); 1151 xpc_mark_partition_disengaged(part);
1202 xpc_cancel_partition_disengage_request(part); 1152 xpc_cancel_partition_disengage_request(part);
1203 } 1153 }
@@ -1209,7 +1159,6 @@ xpc_discovery(void)
1209 kfree(remote_rp_base); 1159 kfree(remote_rp_base);
1210} 1160}
1211 1161
1212
1213/* 1162/*
1214 * Given a partid, get the nasids owned by that partition from the 1163 * Given a partid, get the nasids owned by that partition from the
1215 * remote partition's reserved page. 1164 * remote partition's reserved page.
@@ -1221,7 +1170,6 @@ xpc_initiate_partid_to_nasids(partid_t partid, void *nasid_mask)
1221 u64 part_nasid_pa; 1170 u64 part_nasid_pa;
1222 int bte_res; 1171 int bte_res;
1223 1172
1224
1225 part = &xpc_partitions[partid]; 1173 part = &xpc_partitions[partid];
1226 if (part->remote_rp_pa == 0) { 1174 if (part->remote_rp_pa == 0) {
1227 return xpcPartitionDown; 1175 return xpcPartitionDown;
@@ -1229,11 +1177,11 @@ xpc_initiate_partid_to_nasids(partid_t partid, void *nasid_mask)
1229 1177
1230 memset(nasid_mask, 0, XP_NASID_MASK_BYTES); 1178 memset(nasid_mask, 0, XP_NASID_MASK_BYTES);
1231 1179
1232 part_nasid_pa = (u64) XPC_RP_PART_NASIDS(part->remote_rp_pa); 1180 part_nasid_pa = (u64)XPC_RP_PART_NASIDS(part->remote_rp_pa);
1233 1181
1234 bte_res = xp_bte_copy(part_nasid_pa, (u64) nasid_mask, 1182 bte_res = xp_bte_copy(part_nasid_pa, (u64)nasid_mask,
1235 xp_nasid_mask_bytes, (BTE_NOTIFY | BTE_WACQUIRE), NULL); 1183 xp_nasid_mask_bytes, (BTE_NOTIFY | BTE_WACQUIRE),
1184 NULL);
1236 1185
1237 return xpc_map_bte_errors(bte_res); 1186 return xpc_map_bte_errors(bte_res);
1238} 1187}
1239