]> pilppa.org Git - linux-2.6-omap-h63xx.git/blob - drivers/misc/sgi-xp/xp.h
sgi-xp: support runtime selection of xp_max_npartitions
[linux-2.6-omap-h63xx.git] / drivers / misc / sgi-xp / xp.h
1 /*
2  * This file is subject to the terms and conditions of the GNU General Public
3  * License.  See the file "COPYING" in the main directory of this archive
4  * for more details.
5  *
6  * Copyright (C) 2004-2008 Silicon Graphics, Inc. All rights reserved.
7  */
8
9 /*
10  * External Cross Partition (XP) structures and defines.
11  */
12
13 #ifndef _DRIVERS_MISC_SGIXP_XP_H
14 #define _DRIVERS_MISC_SGIXP_XP_H
15
16 #include <linux/cache.h>
17 #include <linux/hardirq.h>
18 #include <linux/mutex.h>
19 #include <asm/sn/types.h>
20 #include <asm/sn/bte.h>
21 #ifdef CONFIG_IA64
22 #include <asm/sn/arch.h>
23 #endif
24
25 /* >>> Add this #define to some linux header file some day. */
26 #define BYTES_PER_WORD  sizeof(void *)
27
28 #ifdef USE_DBUG_ON
29 #define DBUG_ON(condition)      BUG_ON(condition)
30 #else
31 #define DBUG_ON(condition)
32 #endif
33
34 #ifndef is_shub1
35 #define is_shub1()      0
36 #endif
37
38 #ifndef is_shub2
39 #define is_shub2()      0
40 #endif
41
42 #ifndef is_shub
43 #define is_shub()       (is_shub1() || is_shub2())
44 #endif
45
46 #ifndef is_uv
47 #define is_uv()         0
48 #endif
49
50 /*
51  * Define the maximum number of partitions the system can possibly support.
52  * It is based on the maximum number of hardware partitionable regions. The
53  * term 'region' in this context refers to the minimum number of nodes that
54  * can comprise an access protection grouping. The access protection is in
55  * regards to memory, IPI and IOI.
56  *
57  * The maximum number of hardware partitionable regions is equal to the
58  * maximum number of nodes in the entire system divided by the minimum number
59  * of nodes that comprise an access protection grouping.
60  */
61 #define XP_MAX_NPARTITIONS_SN2  64
62 #define XP_MAX_NPARTITIONS_UV   256
63
64 /*
65  * Define the number of u64s required to represent all the C-brick nasids
66  * as a bitmap.  The cross-partition kernel modules deal only with
67  * C-brick nasids, thus the need for bitmaps which don't account for
68  * odd-numbered (non C-brick) nasids.
69  */
70 #define XP_MAX_PHYSNODE_ID      (MAX_NUMALINK_NODES / 2)
71 #define XP_NASID_MASK_BYTES     ((XP_MAX_PHYSNODE_ID + 7) / 8)
72 #define XP_NASID_MASK_WORDS     ((XP_MAX_PHYSNODE_ID + 63) / 64)
73
74 /*
75  * Wrapper for bte_copy() that should it return a failure status will retry
76  * the bte_copy() once in the hope that the failure was due to a temporary
77  * aberration (i.e., the link going down temporarily).
78  *
79  *      src - physical address of the source of the transfer.
80  *      vdst - virtual address of the destination of the transfer.
81  *      len - number of bytes to transfer from source to destination.
82  *      mode - see bte_copy() for definition.
83  *      notification - see bte_copy() for definition.
84  *
85  * Note: xp_bte_copy() should never be called while holding a spinlock.
86  */
87 static inline bte_result_t
88 xp_bte_copy(u64 src, u64 vdst, u64 len, u64 mode, void *notification)
89 {
90         bte_result_t ret;
91         u64 pdst = ia64_tpa(vdst);
92
93         /*
94          * Ensure that the physically mapped memory is contiguous.
95          *
96          * We do this by ensuring that the memory is from region 7 only.
97          * If the need should arise to use memory from one of the other
98          * regions, then modify the BUG_ON() statement to ensure that the
99          * memory from that region is always physically contiguous.
100          */
101         BUG_ON(REGION_NUMBER(vdst) != RGN_KERNEL);
102
103         ret = bte_copy(src, pdst, len, mode, notification);
104         if ((ret != BTE_SUCCESS) && BTE_ERROR_RETRY(ret)) {
105                 if (!in_interrupt())
106                         cond_resched();
107
108                 ret = bte_copy(src, pdst, len, mode, notification);
109         }
110
111         return ret;
112 }
113
114 /*
115  * XPC establishes channel connections between the local partition and any
116  * other partition that is currently up. Over these channels, kernel-level
117  * `users' can communicate with their counterparts on the other partitions.
118  *
119 >>> The following described limitation of a max of eight channels possible
120 >>> pertains only to ia64-sn2. THIS ISN'T TRUE SINCE I'M PLANNING TO JUST
121 >>> TIE INTO THE EXISTING MECHANISM ONCE THE CHANNEL MESSAGES ARE RECEIVED.
122 >>> THE 128-BYTE CACHELINE PERFORMANCE ISSUE IS TIED TO IA64-SN2.
123  *
124  * If the need for additional channels arises, one can simply increase
125  * XPC_MAX_NCHANNELS accordingly. If the day should come where that number
126  * exceeds the absolute MAXIMUM number of channels possible (eight), then one
127  * will need to make changes to the XPC code to accommodate for this.
128  *
129  * The absolute maximum number of channels possible is currently limited to
130  * eight for performance reasons. The internal cross partition structures
131  * require sixteen bytes per channel, and eight allows all of this
132  * interface-shared info to fit in one 128-byte cacheline.
133  */
134 #define XPC_MEM_CHANNEL         0       /* memory channel number */
135 #define XPC_NET_CHANNEL         1       /* network channel number */
136
137 #define XPC_MAX_NCHANNELS       2       /* max #of channels allowed */
138
139 #if XPC_MAX_NCHANNELS > 8
140 #error  XPC_MAX_NCHANNELS exceeds absolute MAXIMUM possible.
141 #endif
142
143 /*
144  * The format of an XPC message is as follows:
145  *
146  *      +-------+--------------------------------+
147  *      | flags |////////////////////////////////|
148  *      +-------+--------------------------------+
149  *      |             message #                  |
150  *      +----------------------------------------+
151  *      |     payload (user-defined message)     |
152  *      |                                        |
153  *                      :
154  *      |                                        |
155  *      +----------------------------------------+
156  *
157  * The size of the payload is defined by the user via xpc_connect(). A user-
158  * defined message resides in the payload area.
159  *
160  * The user should have no dealings with the message header, but only the
161  * message's payload. When a message entry is allocated (via xpc_allocate())
162  * a pointer to the payload area is returned and not the actual beginning of
163  * the XPC message. The user then constructs a message in the payload area
164  * and passes that pointer as an argument on xpc_send() or xpc_send_notify().
165  *
166  * The size of a message entry (within a message queue) must be a cacheline
167  * sized multiple in order to facilitate the BTE transfer of messages from one
168  * message queue to another. A macro, XPC_MSG_SIZE(), is provided for the user
169  * that wants to fit as many msg entries as possible in a given memory size
170  * (e.g. a memory page).
171  */
172 struct xpc_msg {
173         u8 flags;               /* FOR XPC INTERNAL USE ONLY */
174         u8 reserved[7];         /* FOR XPC INTERNAL USE ONLY */
175         s64 number;             /* FOR XPC INTERNAL USE ONLY */
176
177         u64 payload;            /* user defined portion of message */
178 };
179
180 #define XPC_MSG_PAYLOAD_OFFSET  (u64) (&((struct xpc_msg *)0)->payload)
181 #define XPC_MSG_SIZE(_payload_size) \
182                 L1_CACHE_ALIGN(XPC_MSG_PAYLOAD_OFFSET + (_payload_size))
183
184 /*
185  * Define the return values and values passed to user's callout functions.
186  * (It is important to add new value codes at the end just preceding
187  * xpUnknownReason, which must have the highest numerical value.)
188  */
189 enum xp_retval {
190         xpSuccess = 0,
191
192         xpNotConnected,         /*  1: channel is not connected */
193         xpConnected,            /*  2: channel connected (opened) */
194         xpRETIRED1,             /*  3: (formerly xpDisconnected) */
195
196         xpMsgReceived,          /*  4: message received */
197         xpMsgDelivered,         /*  5: message delivered and acknowledged */
198
199         xpRETIRED2,             /*  6: (formerly xpTransferFailed) */
200
201         xpNoWait,               /*  7: operation would require wait */
202         xpRetry,                /*  8: retry operation */
203         xpTimeout,              /*  9: timeout in xpc_allocate_msg_wait() */
204         xpInterrupted,          /* 10: interrupted wait */
205
206         xpUnequalMsgSizes,      /* 11: message size disparity between sides */
207         xpInvalidAddress,       /* 12: invalid address */
208
209         xpNoMemory,             /* 13: no memory available for XPC structures */
210         xpLackOfResources,      /* 14: insufficient resources for operation */
211         xpUnregistered,         /* 15: channel is not registered */
212         xpAlreadyRegistered,    /* 16: channel is already registered */
213
214         xpPartitionDown,        /* 17: remote partition is down */
215         xpNotLoaded,            /* 18: XPC module is not loaded */
216         xpUnloading,            /* 19: this side is unloading XPC module */
217
218         xpBadMagic,             /* 20: XPC MAGIC string not found */
219
220         xpReactivating,         /* 21: remote partition was reactivated */
221
222         xpUnregistering,        /* 22: this side is unregistering channel */
223         xpOtherUnregistering,   /* 23: other side is unregistering channel */
224
225         xpCloneKThread,         /* 24: cloning kernel thread */
226         xpCloneKThreadFailed,   /* 25: cloning kernel thread failed */
227
228         xpNoHeartbeat,          /* 26: remote partition has no heartbeat */
229
230         xpPioReadError,         /* 27: PIO read error */
231         xpPhysAddrRegFailed,    /* 28: registration of phys addr range failed */
232
233         xpRETIRED3,             /* 29: (formerly xpBteDirectoryError) */
234         xpRETIRED4,             /* 30: (formerly xpBtePoisonError) */
235         xpRETIRED5,             /* 31: (formerly xpBteWriteError) */
236         xpRETIRED6,             /* 32: (formerly xpBteAccessError) */
237         xpRETIRED7,             /* 33: (formerly xpBtePWriteError) */
238         xpRETIRED8,             /* 34: (formerly xpBtePReadError) */
239         xpRETIRED9,             /* 35: (formerly xpBteTimeOutError) */
240         xpRETIRED10,            /* 36: (formerly xpBteXtalkError) */
241         xpRETIRED11,            /* 37: (formerly xpBteNotAvailable) */
242         xpRETIRED12,            /* 38: (formerly xpBteUnmappedError) */
243
244         xpBadVersion,           /* 39: bad version number */
245         xpVarsNotSet,           /* 40: the XPC variables are not set up */
246         xpNoRsvdPageAddr,       /* 41: unable to get rsvd page's phys addr */
247         xpInvalidPartid,        /* 42: invalid partition ID */
248         xpLocalPartid,          /* 43: local partition ID */
249
250         xpOtherGoingDown,       /* 44: other side going down, reason unknown */
251         xpSystemGoingDown,      /* 45: system is going down, reason unknown */
252         xpSystemHalt,           /* 46: system is being halted */
253         xpSystemReboot,         /* 47: system is being rebooted */
254         xpSystemPoweroff,       /* 48: system is being powered off */
255
256         xpDisconnecting,        /* 49: channel disconnecting (closing) */
257
258         xpOpenCloseError,       /* 50: channel open/close protocol error */
259
260         xpDisconnected,         /* 51: channel disconnected (closed) */
261
262         xpBteCopyError,         /* 52: bte_copy() returned error */
263         xpSalError,             /* 53: sn SAL error */
264
265         xpUnsupported,          /* 54: unsupported functionality or resource */
266         xpUnknownReason         /* 55: unknown reason - must be last in enum */
267 };
268
269 /*
270  * Define the callout function type used by XPC to update the user on
271  * connection activity and state changes via the user function registered
272  * by xpc_connect().
273  *
274  * Arguments:
275  *
276  *      reason - reason code.
277  *      partid - partition ID associated with condition.
278  *      ch_number - channel # associated with condition.
279  *      data - pointer to optional data.
280  *      key - pointer to optional user-defined value provided as the "key"
281  *            argument to xpc_connect().
282  *
283  * A reason code of xpConnected indicates that a connection has been
284  * established to the specified partition on the specified channel. The data
285  * argument indicates the max number of entries allowed in the message queue.
286  *
287  * A reason code of xpMsgReceived indicates that a XPC message arrived from
288  * the specified partition on the specified channel. The data argument
289  * specifies the address of the message's payload. The user must call
290  * xpc_received() when finished with the payload.
291  *
292  * All other reason codes indicate failure. The data argmument is NULL.
293  * When a failure reason code is received, one can assume that the channel
294  * is not connected.
295  */
296 typedef void (*xpc_channel_func) (enum xp_retval reason, short partid,
297                                   int ch_number, void *data, void *key);
298
299 /*
300  * Define the callout function type used by XPC to notify the user of
301  * messages received and delivered via the user function registered by
302  * xpc_send_notify().
303  *
304  * Arguments:
305  *
306  *      reason - reason code.
307  *      partid - partition ID associated with condition.
308  *      ch_number - channel # associated with condition.
309  *      key - pointer to optional user-defined value provided as the "key"
310  *            argument to xpc_send_notify().
311  *
312  * A reason code of xpMsgDelivered indicates that the message was delivered
313  * to the intended recipient and that they have acknowledged its receipt by
314  * calling xpc_received().
315  *
316  * All other reason codes indicate failure.
317  */
318 typedef void (*xpc_notify_func) (enum xp_retval reason, short partid,
319                                  int ch_number, void *key);
320
321 /*
322  * The following is a registration entry. There is a global array of these,
323  * one per channel. It is used to record the connection registration made
324  * by the users of XPC. As long as a registration entry exists, for any
325  * partition that comes up, XPC will attempt to establish a connection on
326  * that channel. Notification that a connection has been made will occur via
327  * the xpc_channel_func function.
328  *
329  * The 'func' field points to the function to call when aynchronous
330  * notification is required for such events as: a connection established/lost,
331  * or an incoming message received, or an error condition encountered. A
332  * non-NULL 'func' field indicates that there is an active registration for
333  * the channel.
334  */
335 struct xpc_registration {
336         struct mutex mutex;
337         xpc_channel_func func;  /* function to call */
338         void *key;              /* pointer to user's key */
339         u16 nentries;           /* #of msg entries in local msg queue */
340         u16 msg_size;           /* message queue's message size */
341         u32 assigned_limit;     /* limit on #of assigned kthreads */
342         u32 idle_limit;         /* limit on #of idle kthreads */
343 } ____cacheline_aligned;
344
345 #define XPC_CHANNEL_REGISTERED(_c)      (xpc_registrations[_c].func != NULL)
346
347 /* the following are valid xpc_allocate() flags */
348 #define XPC_WAIT        0       /* wait flag */
349 #define XPC_NOWAIT      1       /* no wait flag */
350
351 struct xpc_interface {
352         void (*connect) (int);
353         void (*disconnect) (int);
354         enum xp_retval (*allocate) (short, int, u32, void **);
355         enum xp_retval (*send) (short, int, void *);
356         enum xp_retval (*send_notify) (short, int, void *,
357                                         xpc_notify_func, void *);
358         void (*received) (short, int, void *);
359         enum xp_retval (*partid_to_nasids) (short, void *);
360 };
361
362 extern struct xpc_interface xpc_interface;
363
364 extern void xpc_set_interface(void (*)(int),
365                               void (*)(int),
366                               enum xp_retval (*)(short, int, u32, void **),
367                               enum xp_retval (*)(short, int, void *),
368                               enum xp_retval (*)(short, int, void *,
369                                                   xpc_notify_func, void *),
370                               void (*)(short, int, void *),
371                               enum xp_retval (*)(short, void *));
372 extern void xpc_clear_interface(void);
373
374 extern enum xp_retval xpc_connect(int, xpc_channel_func, void *, u16,
375                                    u16, u32, u32);
376 extern void xpc_disconnect(int);
377
378 static inline enum xp_retval
379 xpc_allocate(short partid, int ch_number, u32 flags, void **payload)
380 {
381         return xpc_interface.allocate(partid, ch_number, flags, payload);
382 }
383
384 static inline enum xp_retval
385 xpc_send(short partid, int ch_number, void *payload)
386 {
387         return xpc_interface.send(partid, ch_number, payload);
388 }
389
390 static inline enum xp_retval
391 xpc_send_notify(short partid, int ch_number, void *payload,
392                 xpc_notify_func func, void *key)
393 {
394         return xpc_interface.send_notify(partid, ch_number, payload, func, key);
395 }
396
397 static inline void
398 xpc_received(short partid, int ch_number, void *payload)
399 {
400         return xpc_interface.received(partid, ch_number, payload);
401 }
402
403 static inline enum xp_retval
404 xpc_partid_to_nasids(short partid, void *nasids)
405 {
406         return xpc_interface.partid_to_nasids(partid, nasids);
407 }
408
409 extern short xp_max_npartitions;
410
411 extern u64 xp_nofault_PIOR_target;
412 extern int xp_nofault_PIOR(void *);
413 extern int xp_error_PIOR(void);
414
415 extern struct device *xp;
416 extern enum xp_retval xp_init_sn2(void);
417 extern enum xp_retval xp_init_uv(void);
418 extern void xp_exit_sn2(void);
419 extern void xp_exit_uv(void);
420
421 #endif /* _DRIVERS_MISC_SGIXP_XP_H */