]> bbs.cooldavid.org Git - net-next-2.6.git/blob - drivers/misc/sgi-xp/xpc.h
da32bbe8caafa4ec48a7a4795fe83f15ac434b59
[net-next-2.6.git] / drivers / misc / sgi-xp / xpc.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-2009 Silicon Graphics, Inc.  All Rights Reserved.
7  */
8
9 /*
10  * Cross Partition Communication (XPC) structures and macros.
11  */
12
13 #ifndef _DRIVERS_MISC_SGIXP_XPC_H
14 #define _DRIVERS_MISC_SGIXP_XPC_H
15
16 #include <linux/wait.h>
17 #include <linux/completion.h>
18 #include <linux/timer.h>
19 #include <linux/sched.h>
20 #include "xp.h"
21
22 /*
23  * XPC Version numbers consist of a major and minor number. XPC can always
24  * talk to versions with same major #, and never talk to versions with a
25  * different major #.
26  */
27 #define _XPC_VERSION(_maj, _min)        (((_maj) << 4) | ((_min) & 0xf))
28 #define XPC_VERSION_MAJOR(_v)           ((_v) >> 4)
29 #define XPC_VERSION_MINOR(_v)           ((_v) & 0xf)
30
31 /* define frequency of the heartbeat and frequency how often it's checked */
32 #define XPC_HB_DEFAULT_INTERVAL         5       /* incr HB every x secs */
33 #define XPC_HB_CHECK_DEFAULT_INTERVAL   20      /* check HB every x secs */
34
35 /* define the process name of HB checker and the CPU it is pinned to */
36 #define XPC_HB_CHECK_THREAD_NAME        "xpc_hb"
37 #define XPC_HB_CHECK_CPU                0
38
39 /* define the process name of the discovery thread */
40 #define XPC_DISCOVERY_THREAD_NAME       "xpc_discovery"
41
42 /*
43  * the reserved page
44  *
45  *   SAL reserves one page of memory per partition for XPC. Though a full page
46  *   in length (16384 bytes), its starting address is not page aligned, but it
47  *   is cacheline aligned. The reserved page consists of the following:
48  *
49  *   reserved page header
50  *
51  *     The first two 64-byte cachelines of the reserved page contain the
52  *     header (struct xpc_rsvd_page). Before SAL initialization has completed,
53  *     SAL has set up the following fields of the reserved page header:
54  *     SAL_signature, SAL_version, SAL_partid, and SAL_nasids_size. The
55  *     other fields are set up by XPC. (xpc_rsvd_page points to the local
56  *     partition's reserved page.)
57  *
58  *   part_nasids mask
59  *   mach_nasids mask
60  *
61  *     SAL also sets up two bitmaps (or masks), one that reflects the actual
62  *     nasids in this partition (part_nasids), and the other that reflects
63  *     the actual nasids in the entire machine (mach_nasids). We're only
64  *     interested in the even numbered nasids (which contain the processors
65  *     and/or memory), so we only need half as many bits to represent the
66  *     nasids. When mapping nasid to bit in a mask (or bit to nasid) be sure
67  *     to either divide or multiply by 2. The part_nasids mask is located
68  *     starting at the first cacheline following the reserved page header. The
69  *     mach_nasids mask follows right after the part_nasids mask. The size in
70  *     bytes of each mask is reflected by the reserved page header field
71  *     'SAL_nasids_size'. (Local partition's mask pointers are xpc_part_nasids
72  *     and xpc_mach_nasids.)
73  *
74  *   vars       (ia64-sn2 only)
75  *   vars part  (ia64-sn2 only)
76  *
77  *     Immediately following the mach_nasids mask are the XPC variables
78  *     required by other partitions. First are those that are generic to all
79  *     partitions (vars), followed on the next available cacheline by those
80  *     which are partition specific (vars part). These are setup by XPC.
81  *     (Local partition's vars pointers are xpc_vars and xpc_vars_part.)
82  *
83  * Note: Until 'ts_jiffies' is set non-zero, the partition XPC code has not been
84  *       initialized.
85  */
86 struct xpc_rsvd_page {
87         u64 SAL_signature;      /* SAL: unique signature */
88         u64 SAL_version;        /* SAL: version */
89         short SAL_partid;       /* SAL: partition ID */
90         short max_npartitions;  /* value of XPC_MAX_PARTITIONS */
91         u8 version;
92         u8 pad1[3];             /* align to next u64 in 1st 64-byte cacheline */
93         unsigned long ts_jiffies; /* timestamp when rsvd pg was setup by XPC */
94         union {
95                 struct {
96                         unsigned long vars_pa;  /* phys addr */
97                 } sn2;
98                 struct {
99                         unsigned long heartbeat_gpa; /* phys addr */
100                         unsigned long activate_gru_mq_desc_gpa; /* phys addr */
101                 } uv;
102         } sn;
103         u64 pad2[9];            /* align to last u64 in 2nd 64-byte cacheline */
104         u64 SAL_nasids_size;    /* SAL: size of each nasid mask in bytes */
105 };
106
107 #define XPC_RP_VERSION _XPC_VERSION(3, 0) /* version 3.0 of the reserved page */
108
109 /*
110  * Define the structures by which XPC variables can be exported to other
111  * partitions. (There are two: struct xpc_vars and struct xpc_vars_part)
112  */
113
114 /*
115  * The following structure describes the partition generic variables
116  * needed by other partitions in order to properly initialize.
117  *
118  * struct xpc_vars version number also applies to struct xpc_vars_part.
119  * Changes to either structure and/or related functionality should be
120  * reflected by incrementing either the major or minor version numbers
121  * of struct xpc_vars.
122  */
123 struct xpc_vars_sn2 {
124         u8 version;
125         u64 heartbeat;
126         DECLARE_BITMAP(heartbeating_to_mask, XP_MAX_NPARTITIONS_SN2);
127         u64 heartbeat_offline;  /* if 0, heartbeat should be changing */
128         int activate_IRQ_nasid;
129         int activate_IRQ_phys_cpuid;
130         unsigned long vars_part_pa;
131         unsigned long amos_page_pa;/* paddr of page of amos from MSPEC driver */
132         struct amo *amos_page;  /* vaddr of page of amos from MSPEC driver */
133 };
134
135 #define XPC_V_VERSION _XPC_VERSION(3, 1)    /* version 3.1 of the cross vars */
136
137 /*
138  * The following structure describes the per partition specific variables.
139  *
140  * An array of these structures, one per partition, will be defined. As a
141  * partition becomes active XPC will copy the array entry corresponding to
142  * itself from that partition. It is desirable that the size of this structure
143  * evenly divides into a 128-byte cacheline, such that none of the entries in
144  * this array crosses a 128-byte cacheline boundary. As it is now, each entry
145  * occupies 64-bytes.
146  */
147 struct xpc_vars_part_sn2 {
148         u64 magic;
149
150         unsigned long openclose_args_pa; /* phys addr of open and close args */
151         unsigned long GPs_pa;   /* physical address of Get/Put values */
152
153         unsigned long chctl_amo_pa; /* physical address of chctl flags' amo */
154
155         int notify_IRQ_nasid;   /* nasid of where to send notify IRQs */
156         int notify_IRQ_phys_cpuid;      /* CPUID of where to send notify IRQs */
157
158         u8 nchannels;           /* #of defined channels supported */
159
160         u8 reserved[23];        /* pad to a full 64 bytes */
161 };
162
163 /*
164  * The vars_part MAGIC numbers play a part in the first contact protocol.
165  *
166  * MAGIC1 indicates that the per partition specific variables for a remote
167  * partition have been initialized by this partition.
168  *
169  * MAGIC2 indicates that this partition has pulled the remote partititions
170  * per partition variables that pertain to this partition.
171  */
172 #define XPC_VP_MAGIC1_SN2 0x0053524156435058L /* 'XPCVARS\0'L (little endian) */
173 #define XPC_VP_MAGIC2_SN2 0x0073726176435058L /* 'XPCvars\0'L (little endian) */
174
175 /* the reserved page sizes and offsets */
176
177 #define XPC_RP_HEADER_SIZE      L1_CACHE_ALIGN(sizeof(struct xpc_rsvd_page))
178 #define XPC_RP_VARS_SIZE        L1_CACHE_ALIGN(sizeof(struct xpc_vars_sn2))
179
180 #define XPC_RP_PART_NASIDS(_rp) ((unsigned long *)((u8 *)(_rp) + \
181                                  XPC_RP_HEADER_SIZE))
182 #define XPC_RP_MACH_NASIDS(_rp) (XPC_RP_PART_NASIDS(_rp) + \
183                                  xpc_nasid_mask_nlongs)
184 #define XPC_RP_VARS(_rp)        ((struct xpc_vars_sn2 *) \
185                                  (XPC_RP_MACH_NASIDS(_rp) + \
186                                   xpc_nasid_mask_nlongs))
187
188
189 /*
190  * The following structure describes the partition's heartbeat info which
191  * will be periodically read by other partitions to determine whether this
192  * XPC is still 'alive'.
193  */
194 struct xpc_heartbeat_uv {
195         unsigned long value;
196         unsigned long offline;  /* if 0, heartbeat should be changing */
197 };
198
199 /*
200  * Info pertinent to a GRU message queue using a watch list for irq generation.
201  */
202 struct xpc_gru_mq_uv {
203         void *address;          /* address of GRU message queue */
204         unsigned int order;     /* size of GRU message queue as a power of 2 */
205         int irq;                /* irq raised when message is received in mq */
206         int mmr_blade;          /* blade where watchlist was allocated from */
207         unsigned long mmr_offset; /* offset of irq mmr located on mmr_blade */
208         unsigned long mmr_value; /* value of irq mmr located on mmr_blade */
209         int watchlist_num;      /* number of watchlist allocatd by BIOS */
210         void *gru_mq_desc;      /* opaque structure used by the GRU driver */
211 };
212
213 /*
214  * The activate_mq is used to send/receive GRU messages that affect XPC's
215  * partition active state and channel state. This is uv only.
216  */
217 struct xpc_activate_mq_msghdr_uv {
218         unsigned int gru_msg_hdr; /* FOR GRU INTERNAL USE ONLY */
219         short partid;           /* sender's partid */
220         u8 act_state;           /* sender's act_state at time msg sent */
221         u8 type;                /* message's type */
222         unsigned long rp_ts_jiffies; /* timestamp of sender's rp setup by XPC */
223 };
224
225 /* activate_mq defined message types */
226 #define XPC_ACTIVATE_MQ_MSG_SYNC_ACT_STATE_UV           0
227
228 #define XPC_ACTIVATE_MQ_MSG_ACTIVATE_REQ_UV             1
229 #define XPC_ACTIVATE_MQ_MSG_DEACTIVATE_REQ_UV           2
230
231 #define XPC_ACTIVATE_MQ_MSG_CHCTL_CLOSEREQUEST_UV       3
232 #define XPC_ACTIVATE_MQ_MSG_CHCTL_CLOSEREPLY_UV         4
233 #define XPC_ACTIVATE_MQ_MSG_CHCTL_OPENREQUEST_UV        5
234 #define XPC_ACTIVATE_MQ_MSG_CHCTL_OPENREPLY_UV          6
235
236 #define XPC_ACTIVATE_MQ_MSG_MARK_ENGAGED_UV             7
237 #define XPC_ACTIVATE_MQ_MSG_MARK_DISENGAGED_UV          8
238
239 struct xpc_activate_mq_msg_uv {
240         struct xpc_activate_mq_msghdr_uv hdr;
241 };
242
243 struct xpc_activate_mq_msg_activate_req_uv {
244         struct xpc_activate_mq_msghdr_uv hdr;
245         unsigned long rp_gpa;
246         unsigned long heartbeat_gpa;
247         unsigned long activate_gru_mq_desc_gpa;
248 };
249
250 struct xpc_activate_mq_msg_deactivate_req_uv {
251         struct xpc_activate_mq_msghdr_uv hdr;
252         enum xp_retval reason;
253 };
254
255 struct xpc_activate_mq_msg_chctl_closerequest_uv {
256         struct xpc_activate_mq_msghdr_uv hdr;
257         short ch_number;
258         enum xp_retval reason;
259 };
260
261 struct xpc_activate_mq_msg_chctl_closereply_uv {
262         struct xpc_activate_mq_msghdr_uv hdr;
263         short ch_number;
264 };
265
266 struct xpc_activate_mq_msg_chctl_openrequest_uv {
267         struct xpc_activate_mq_msghdr_uv hdr;
268         short ch_number;
269         short entry_size;       /* size of notify_mq's GRU messages */
270         short local_nentries;   /* ??? Is this needed? What is? */
271 };
272
273 struct xpc_activate_mq_msg_chctl_openreply_uv {
274         struct xpc_activate_mq_msghdr_uv hdr;
275         short ch_number;
276         short remote_nentries;  /* ??? Is this needed? What is? */
277         short local_nentries;   /* ??? Is this needed? What is? */
278         unsigned long notify_gru_mq_desc_gpa;
279 };
280
281 /*
282  * Functions registered by add_timer() or called by kernel_thread() only
283  * allow for a single 64-bit argument. The following macros can be used to
284  * pack and unpack two (32-bit, 16-bit or 8-bit) arguments into or out from
285  * the passed argument.
286  */
287 #define XPC_PACK_ARGS(_arg1, _arg2) \
288                         ((((u64)_arg1) & 0xffffffff) | \
289                         ((((u64)_arg2) & 0xffffffff) << 32))
290
291 #define XPC_UNPACK_ARG1(_args)  (((u64)_args) & 0xffffffff)
292 #define XPC_UNPACK_ARG2(_args)  ((((u64)_args) >> 32) & 0xffffffff)
293
294 /*
295  * Define a Get/Put value pair (pointers) used with a message queue.
296  */
297 struct xpc_gp_sn2 {
298         s64 get;                /* Get value */
299         s64 put;                /* Put value */
300 };
301
302 #define XPC_GP_SIZE \
303                 L1_CACHE_ALIGN(sizeof(struct xpc_gp_sn2) * XPC_MAX_NCHANNELS)
304
305 /*
306  * Define a structure that contains arguments associated with opening and
307  * closing a channel.
308  */
309 struct xpc_openclose_args {
310         u16 reason;             /* reason why channel is closing */
311         u16 entry_size;         /* sizeof each message entry */
312         u16 remote_nentries;    /* #of message entries in remote msg queue */
313         u16 local_nentries;     /* #of message entries in local msg queue */
314         unsigned long local_msgqueue_pa; /* phys addr of local message queue */
315 };
316
317 #define XPC_OPENCLOSE_ARGS_SIZE \
318               L1_CACHE_ALIGN(sizeof(struct xpc_openclose_args) * \
319               XPC_MAX_NCHANNELS)
320
321
322 /*
323  * Structures to define a fifo singly-linked list.
324  */
325
326 struct xpc_fifo_entry_uv {
327         struct xpc_fifo_entry_uv *next;
328 };
329
330 struct xpc_fifo_head_uv {
331         struct xpc_fifo_entry_uv *first;
332         struct xpc_fifo_entry_uv *last;
333         spinlock_t lock;
334         int n_entries;
335 };
336
337 /*
338  * Define a sn2 styled message.
339  *
340  * A user-defined message resides in the payload area. The max size of the
341  * payload is defined by the user via xpc_connect().
342  *
343  * The size of a message entry (within a message queue) must be a 128-byte
344  * cacheline sized multiple in order to facilitate the BTE transfer of messages
345  * from one message queue to another.
346  */
347 struct xpc_msg_sn2 {
348         u8 flags;               /* FOR XPC INTERNAL USE ONLY */
349         u8 reserved[7];         /* FOR XPC INTERNAL USE ONLY */
350         s64 number;             /* FOR XPC INTERNAL USE ONLY */
351
352         u64 payload;            /* user defined portion of message */
353 };
354
355 /* struct xpc_msg_sn2 flags */
356
357 #define XPC_M_SN2_DONE          0x01    /* msg has been received/consumed */
358 #define XPC_M_SN2_READY         0x02    /* msg is ready to be sent */
359 #define XPC_M_SN2_INTERRUPT     0x04    /* send interrupt when msg consumed */
360
361 /*
362  * The format of a uv XPC notify_mq GRU message is as follows:
363  *
364  * A user-defined message resides in the payload area. The max size of the
365  * payload is defined by the user via xpc_connect().
366  *
367  * The size of a message (payload and header) sent via the GRU must be either 1
368  * or 2 GRU_CACHE_LINE_BYTES in length.
369  */
370
371 struct xpc_notify_mq_msghdr_uv {
372         union {
373                 unsigned int gru_msg_hdr;       /* FOR GRU INTERNAL USE ONLY */
374                 struct xpc_fifo_entry_uv next;  /* FOR XPC INTERNAL USE ONLY */
375         } u;
376         short partid;           /* FOR XPC INTERNAL USE ONLY */
377         u8 ch_number;           /* FOR XPC INTERNAL USE ONLY */
378         u8 size;                /* FOR XPC INTERNAL USE ONLY */
379         unsigned int msg_slot_number;   /* FOR XPC INTERNAL USE ONLY */
380 };
381
382 struct xpc_notify_mq_msg_uv {
383         struct xpc_notify_mq_msghdr_uv hdr;
384         unsigned long payload;
385 };
386
387 /*
388  * Define sn2's notify entry.
389  *
390  * This is used to notify a message's sender that their message was received
391  * and consumed by the intended recipient.
392  */
393 struct xpc_notify_sn2 {
394         u8 type;                /* type of notification */
395
396         /* the following two fields are only used if type == XPC_N_CALL */
397         xpc_notify_func func;   /* user's notify function */
398         void *key;              /* pointer to user's key */
399 };
400
401 /* struct xpc_notify_sn2 type of notification */
402
403 #define XPC_N_CALL      0x01    /* notify function provided by user */
404
405 /*
406  * Define uv's version of the notify entry. It additionally is used to allocate
407  * a msg slot on the remote partition into which is copied a sent message.
408  */
409 struct xpc_send_msg_slot_uv {
410         struct xpc_fifo_entry_uv next;
411         unsigned int msg_slot_number;
412         xpc_notify_func func;   /* user's notify function */
413         void *key;              /* pointer to user's key */
414 };
415
416 /*
417  * Define the structure that manages all the stuff required by a channel. In
418  * particular, they are used to manage the messages sent across the channel.
419  *
420  * This structure is private to a partition, and is NOT shared across the
421  * partition boundary.
422  *
423  * There is an array of these structures for each remote partition. It is
424  * allocated at the time a partition becomes active. The array contains one
425  * of these structures for each potential channel connection to that partition.
426  */
427
428 /*
429  * The following is sn2 only.
430  *
431  * Each channel structure manages two message queues (circular buffers).
432  * They are allocated at the time a channel connection is made. One of
433  * these message queues (local_msgqueue) holds the locally created messages
434  * that are destined for the remote partition. The other of these message
435  * queues (remote_msgqueue) is a locally cached copy of the remote partition's
436  * own local_msgqueue.
437  *
438  * The following is a description of the Get/Put pointers used to manage these
439  * two message queues. Consider the local_msgqueue to be on one partition
440  * and the remote_msgqueue to be its cached copy on another partition. A
441  * description of what each of the lettered areas contains is included.
442  *
443  *
444  *                     local_msgqueue      remote_msgqueue
445  *
446  *                        |/////////|      |/////////|
447  *    w_remote_GP.get --> +---------+      |/////////|
448  *                        |    F    |      |/////////|
449  *     remote_GP.get  --> +---------+      +---------+ <-- local_GP->get
450  *                        |         |      |         |
451  *                        |         |      |    E    |
452  *                        |         |      |         |
453  *                        |         |      +---------+ <-- w_local_GP.get
454  *                        |    B    |      |/////////|
455  *                        |         |      |////D////|
456  *                        |         |      |/////////|
457  *                        |         |      +---------+ <-- w_remote_GP.put
458  *                        |         |      |////C////|
459  *      local_GP->put --> +---------+      +---------+ <-- remote_GP.put
460  *                        |         |      |/////////|
461  *                        |    A    |      |/////////|
462  *                        |         |      |/////////|
463  *     w_local_GP.put --> +---------+      |/////////|
464  *                        |/////////|      |/////////|
465  *
466  *
467  *          ( remote_GP.[get|put] are cached copies of the remote
468  *            partition's local_GP->[get|put], and thus their values can
469  *            lag behind their counterparts on the remote partition. )
470  *
471  *
472  *  A - Messages that have been allocated, but have not yet been sent to the
473  *      remote partition.
474  *
475  *  B - Messages that have been sent, but have not yet been acknowledged by the
476  *      remote partition as having been received.
477  *
478  *  C - Area that needs to be prepared for the copying of sent messages, by
479  *      the clearing of the message flags of any previously received messages.
480  *
481  *  D - Area into which sent messages are to be copied from the remote
482  *      partition's local_msgqueue and then delivered to their intended
483  *      recipients. [ To allow for a multi-message copy, another pointer
484  *      (next_msg_to_pull) has been added to keep track of the next message
485  *      number needing to be copied (pulled). It chases after w_remote_GP.put.
486  *      Any messages lying between w_local_GP.get and next_msg_to_pull have
487  *      been copied and are ready to be delivered. ]
488  *
489  *  E - Messages that have been copied and delivered, but have not yet been
490  *      acknowledged by the recipient as having been received.
491  *
492  *  F - Messages that have been acknowledged, but XPC has not yet notified the
493  *      sender that the message was received by its intended recipient.
494  *      This is also an area that needs to be prepared for the allocating of
495  *      new messages, by the clearing of the message flags of the acknowledged
496  *      messages.
497  */
498
499 struct xpc_channel_sn2 {
500         struct xpc_openclose_args *local_openclose_args; /* args passed on */
501                                              /* opening or closing of channel */
502
503         void *local_msgqueue_base;      /* base address of kmalloc'd space */
504         struct xpc_msg_sn2 *local_msgqueue;     /* local message queue */
505         void *remote_msgqueue_base;     /* base address of kmalloc'd space */
506         struct xpc_msg_sn2 *remote_msgqueue; /* cached copy of remote */
507                                            /* partition's local message queue */
508         unsigned long remote_msgqueue_pa; /* phys addr of remote partition's */
509                                           /* local message queue */
510
511         struct xpc_notify_sn2 *notify_queue;/* notify queue for messages sent */
512
513         /* various flavors of local and remote Get/Put values */
514
515         struct xpc_gp_sn2 *local_GP;    /* local Get/Put values */
516         struct xpc_gp_sn2 remote_GP;    /* remote Get/Put values */
517         struct xpc_gp_sn2 w_local_GP;   /* working local Get/Put values */
518         struct xpc_gp_sn2 w_remote_GP;  /* working remote Get/Put values */
519         s64 next_msg_to_pull;   /* Put value of next msg to pull */
520
521         struct mutex msg_to_pull_mutex; /* next msg to pull serialization */
522 };
523
524 struct xpc_channel_uv {
525         void *cached_notify_gru_mq_desc; /* remote partition's notify mq's */
526                                          /* gru mq descriptor */
527
528         struct xpc_send_msg_slot_uv *send_msg_slots;
529         void *recv_msg_slots;   /* each slot will hold a xpc_notify_mq_msg_uv */
530                                 /* structure plus the user's payload */
531
532         struct xpc_fifo_head_uv msg_slot_free_list;
533         struct xpc_fifo_head_uv recv_msg_list;  /* deliverable payloads */
534 };
535
536 struct xpc_channel {
537         short partid;           /* ID of remote partition connected */
538         spinlock_t lock;        /* lock for updating this structure */
539         unsigned int flags;     /* general flags */
540
541         enum xp_retval reason;  /* reason why channel is disconnect'g */
542         int reason_line;        /* line# disconnect initiated from */
543
544         u16 number;             /* channel # */
545
546         u16 entry_size;         /* sizeof each msg entry */
547         u16 local_nentries;     /* #of msg entries in local msg queue */
548         u16 remote_nentries;    /* #of msg entries in remote msg queue */
549
550         atomic_t references;    /* #of external references to queues */
551
552         atomic_t n_on_msg_allocate_wq;  /* #on msg allocation wait queue */
553         wait_queue_head_t msg_allocate_wq;      /* msg allocation wait queue */
554
555         u8 delayed_chctl_flags; /* chctl flags received, but delayed */
556                                 /* action until channel disconnected */
557
558         atomic_t n_to_notify;   /* #of msg senders to notify */
559
560         xpc_channel_func func;  /* user's channel function */
561         void *key;              /* pointer to user's key */
562
563         struct completion wdisconnect_wait;    /* wait for channel disconnect */
564
565         /* kthread management related fields */
566
567         atomic_t kthreads_assigned;     /* #of kthreads assigned to channel */
568         u32 kthreads_assigned_limit;    /* limit on #of kthreads assigned */
569         atomic_t kthreads_idle; /* #of kthreads idle waiting for work */
570         u32 kthreads_idle_limit;        /* limit on #of kthreads idle */
571         atomic_t kthreads_active;       /* #of kthreads actively working */
572
573         wait_queue_head_t idle_wq;      /* idle kthread wait queue */
574
575         union {
576                 struct xpc_channel_sn2 sn2;
577                 struct xpc_channel_uv uv;
578         } sn;
579
580 } ____cacheline_aligned;
581
582 /* struct xpc_channel flags */
583
584 #define XPC_C_WASCONNECTED      0x00000001      /* channel was connected */
585
586 #define XPC_C_ROPENREPLY        0x00000002      /* remote open channel reply */
587 #define XPC_C_OPENREPLY         0x00000004      /* local open channel reply */
588 #define XPC_C_ROPENREQUEST      0x00000008     /* remote open channel request */
589 #define XPC_C_OPENREQUEST       0x00000010      /* local open channel request */
590
591 #define XPC_C_SETUP             0x00000020 /* channel's msgqueues are alloc'd */
592 #define XPC_C_CONNECTEDCALLOUT  0x00000040     /* connected callout initiated */
593 #define XPC_C_CONNECTEDCALLOUT_MADE \
594                                 0x00000080     /* connected callout completed */
595 #define XPC_C_CONNECTED         0x00000100      /* local channel is connected */
596 #define XPC_C_CONNECTING        0x00000200      /* channel is being connected */
597
598 #define XPC_C_RCLOSEREPLY       0x00000400      /* remote close channel reply */
599 #define XPC_C_CLOSEREPLY        0x00000800      /* local close channel reply */
600 #define XPC_C_RCLOSEREQUEST     0x00001000    /* remote close channel request */
601 #define XPC_C_CLOSEREQUEST      0x00002000     /* local close channel request */
602
603 #define XPC_C_DISCONNECTED      0x00004000      /* channel is disconnected */
604 #define XPC_C_DISCONNECTING     0x00008000   /* channel is being disconnected */
605 #define XPC_C_DISCONNECTINGCALLOUT \
606                                 0x00010000 /* disconnecting callout initiated */
607 #define XPC_C_DISCONNECTINGCALLOUT_MADE \
608                                 0x00020000 /* disconnecting callout completed */
609 #define XPC_C_WDISCONNECT       0x00040000  /* waiting for channel disconnect */
610
611 /*
612  * The channel control flags (chctl) union consists of a 64-bit variable which
613  * is divided up into eight bytes, ordered from right to left. Byte zero
614  * pertains to channel 0, byte one to channel 1, and so on. Each channel's byte
615  * can have one or more of the chctl flags set in it.
616  */
617
618 union xpc_channel_ctl_flags {
619         u64 all_flags;
620         u8 flags[XPC_MAX_NCHANNELS];
621 };
622
623 /* chctl flags */
624 #define XPC_CHCTL_CLOSEREQUEST  0x01
625 #define XPC_CHCTL_CLOSEREPLY    0x02
626 #define XPC_CHCTL_OPENREQUEST   0x04
627 #define XPC_CHCTL_OPENREPLY     0x08
628 #define XPC_CHCTL_MSGREQUEST    0x10
629
630 #define XPC_OPENCLOSE_CHCTL_FLAGS \
631                         (XPC_CHCTL_CLOSEREQUEST | XPC_CHCTL_CLOSEREPLY | \
632                          XPC_CHCTL_OPENREQUEST | XPC_CHCTL_OPENREPLY)
633 #define XPC_MSG_CHCTL_FLAGS     XPC_CHCTL_MSGREQUEST
634
635 static inline int
636 xpc_any_openclose_chctl_flags_set(union xpc_channel_ctl_flags *chctl)
637 {
638         int ch_number;
639
640         for (ch_number = 0; ch_number < XPC_MAX_NCHANNELS; ch_number++) {
641                 if (chctl->flags[ch_number] & XPC_OPENCLOSE_CHCTL_FLAGS)
642                         return 1;
643         }
644         return 0;
645 }
646
647 static inline int
648 xpc_any_msg_chctl_flags_set(union xpc_channel_ctl_flags *chctl)
649 {
650         int ch_number;
651
652         for (ch_number = 0; ch_number < XPC_MAX_NCHANNELS; ch_number++) {
653                 if (chctl->flags[ch_number] & XPC_MSG_CHCTL_FLAGS)
654                         return 1;
655         }
656         return 0;
657 }
658
659 /*
660  * Manage channels on a partition basis. There is one of these structures
661  * for each partition (a partition will never utilize the structure that
662  * represents itself).
663  */
664
665 struct xpc_partition_sn2 {
666         unsigned long remote_amos_page_pa; /* paddr of partition's amos page */
667         int activate_IRQ_nasid; /* active partition's act/deact nasid */
668         int activate_IRQ_phys_cpuid;    /* active part's act/deact phys cpuid */
669
670         unsigned long remote_vars_pa;   /* phys addr of partition's vars */
671         unsigned long remote_vars_part_pa; /* paddr of partition's vars part */
672         u8 remote_vars_version; /* version# of partition's vars */
673
674         void *local_GPs_base;   /* base address of kmalloc'd space */
675         struct xpc_gp_sn2 *local_GPs;   /* local Get/Put values */
676         void *remote_GPs_base;  /* base address of kmalloc'd space */
677         struct xpc_gp_sn2 *remote_GPs;  /* copy of remote partition's local */
678                                         /* Get/Put values */
679         unsigned long remote_GPs_pa; /* phys addr of remote partition's local */
680                                      /* Get/Put values */
681
682         void *local_openclose_args_base;   /* base address of kmalloc'd space */
683         struct xpc_openclose_args *local_openclose_args;      /* local's args */
684         unsigned long remote_openclose_args_pa; /* phys addr of remote's args */
685
686         int notify_IRQ_nasid;   /* nasid of where to send notify IRQs */
687         int notify_IRQ_phys_cpuid;      /* CPUID of where to send notify IRQs */
688         char notify_IRQ_owner[8];       /* notify IRQ's owner's name */
689
690         struct amo *remote_chctl_amo_va; /* addr of remote chctl flags' amo */
691         struct amo *local_chctl_amo_va; /* address of chctl flags' amo */
692
693         struct timer_list dropped_notify_IRQ_timer;     /* dropped IRQ timer */
694 };
695
696 struct xpc_partition_uv {
697         unsigned long heartbeat_gpa; /* phys addr of partition's heartbeat */
698         struct xpc_heartbeat_uv cached_heartbeat; /* cached copy of */
699                                                   /* partition's heartbeat */
700         unsigned long activate_gru_mq_desc_gpa; /* phys addr of parititon's */
701                                                 /* activate mq's gru mq */
702                                                 /* descriptor */
703         void *cached_activate_gru_mq_desc; /* cached copy of partition's */
704                                            /* activate mq's gru mq descriptor */
705         struct mutex cached_activate_gru_mq_desc_mutex;
706         spinlock_t flags_lock;  /* protect updating of flags */
707         unsigned int flags;     /* general flags */
708         u8 remote_act_state;    /* remote partition's act_state */
709         u8 act_state_req;       /* act_state request from remote partition */
710         enum xp_retval reason;  /* reason for deactivate act_state request */
711 };
712
713 /* struct xpc_partition_uv flags */
714
715 #define XPC_P_CACHED_ACTIVATE_GRU_MQ_DESC_UV    0x00000001
716 #define XPC_P_ENGAGED_UV                        0x00000002
717
718 /* struct xpc_partition_uv act_state change requests */
719
720 #define XPC_P_ASR_ACTIVATE_UV           0x01
721 #define XPC_P_ASR_REACTIVATE_UV         0x02
722 #define XPC_P_ASR_DEACTIVATE_UV         0x03
723
724 struct xpc_partition {
725
726         /* XPC HB infrastructure */
727
728         u8 remote_rp_version;   /* version# of partition's rsvd pg */
729         unsigned long remote_rp_ts_jiffies; /* timestamp when rsvd pg setup */
730         unsigned long remote_rp_pa;     /* phys addr of partition's rsvd pg */
731         u64 last_heartbeat;     /* HB at last read */
732         u32 activate_IRQ_rcvd;  /* IRQs since activation */
733         spinlock_t act_lock;    /* protect updating of act_state */
734         u8 act_state;           /* from XPC HB viewpoint */
735         enum xp_retval reason;  /* reason partition is deactivating */
736         int reason_line;        /* line# deactivation initiated from */
737
738         unsigned long disengage_timeout;        /* timeout in jiffies */
739         struct timer_list disengage_timer;
740
741         /* XPC infrastructure referencing and teardown control */
742
743         u8 setup_state;         /* infrastructure setup state */
744         wait_queue_head_t teardown_wq;  /* kthread waiting to teardown infra */
745         atomic_t references;    /* #of references to infrastructure */
746
747         u8 nchannels;           /* #of defined channels supported */
748         atomic_t nchannels_active;  /* #of channels that are not DISCONNECTED */
749         atomic_t nchannels_engaged;  /* #of channels engaged with remote part */
750         struct xpc_channel *channels;   /* array of channel structures */
751
752         /* fields used for managing channel avialability and activity */
753
754         union xpc_channel_ctl_flags chctl; /* chctl flags yet to be processed */
755         spinlock_t chctl_lock;  /* chctl flags lock */
756
757         void *remote_openclose_args_base;  /* base address of kmalloc'd space */
758         struct xpc_openclose_args *remote_openclose_args; /* copy of remote's */
759                                                           /* args */
760
761         /* channel manager related fields */
762
763         atomic_t channel_mgr_requests;  /* #of requests to activate chan mgr */
764         wait_queue_head_t channel_mgr_wq;       /* channel mgr's wait queue */
765
766         union {
767                 struct xpc_partition_sn2 sn2;
768                 struct xpc_partition_uv uv;
769         } sn;
770
771 } ____cacheline_aligned;
772
773 /* struct xpc_partition act_state values (for XPC HB) */
774
775 #define XPC_P_AS_INACTIVE       0x00    /* partition is not active */
776 #define XPC_P_AS_ACTIVATION_REQ 0x01    /* created thread to activate */
777 #define XPC_P_AS_ACTIVATING     0x02    /* activation thread started */
778 #define XPC_P_AS_ACTIVE         0x03    /* xpc_partition_up() was called */
779 #define XPC_P_AS_DEACTIVATING   0x04    /* partition deactivation initiated */
780
781 #define XPC_DEACTIVATE_PARTITION(_p, _reason) \
782                         xpc_deactivate_partition(__LINE__, (_p), (_reason))
783
784 /* struct xpc_partition setup_state values */
785
786 #define XPC_P_SS_UNSET          0x00    /* infrastructure was never setup */
787 #define XPC_P_SS_SETUP          0x01    /* infrastructure is setup */
788 #define XPC_P_SS_WTEARDOWN      0x02    /* waiting to teardown infrastructure */
789 #define XPC_P_SS_TORNDOWN       0x03    /* infrastructure is torndown */
790
791 /*
792  * struct xpc_partition_sn2's dropped notify IRQ timer is set to wait the
793  * following interval #of seconds before checking for dropped notify IRQs.
794  * These can occur whenever an IRQ's associated amo write doesn't complete
795  * until after the IRQ was received.
796  */
797 #define XPC_DROPPED_NOTIFY_IRQ_WAIT_INTERVAL    (0.25 * HZ)
798
799 /* number of seconds to wait for other partitions to disengage */
800 #define XPC_DISENGAGE_DEFAULT_TIMELIMIT         90
801
802 /* interval in seconds to print 'waiting deactivation' messages */
803 #define XPC_DEACTIVATE_PRINTMSG_INTERVAL        10
804
805 #define XPC_PARTID(_p)  ((short)((_p) - &xpc_partitions[0]))
806
807 /* found in xp_main.c */
808 extern struct xpc_registration xpc_registrations[];
809
810 /* found in xpc_main.c */
811 extern struct device *xpc_part;
812 extern struct device *xpc_chan;
813 extern int xpc_disengage_timelimit;
814 extern int xpc_disengage_timedout;
815 extern int xpc_activate_IRQ_rcvd;
816 extern spinlock_t xpc_activate_IRQ_rcvd_lock;
817 extern wait_queue_head_t xpc_activate_IRQ_wq;
818 extern void *xpc_kzalloc_cacheline_aligned(size_t, gfp_t, void **);
819 extern void xpc_activate_partition(struct xpc_partition *);
820 extern void xpc_activate_kthreads(struct xpc_channel *, int);
821 extern void xpc_create_kthreads(struct xpc_channel *, int, int);
822 extern void xpc_disconnect_wait(int);
823 extern int (*xpc_setup_partitions_sn) (void);
824 extern void (*xpc_teardown_partitions_sn) (void);
825 extern enum xp_retval (*xpc_get_partition_rsvd_page_pa) (void *, u64 *,
826                                                          unsigned long *,
827                                                          size_t *);
828 extern int (*xpc_setup_rsvd_page_sn) (struct xpc_rsvd_page *);
829 extern void (*xpc_heartbeat_init) (void);
830 extern void (*xpc_heartbeat_exit) (void);
831 extern void (*xpc_increment_heartbeat) (void);
832 extern void (*xpc_offline_heartbeat) (void);
833 extern void (*xpc_online_heartbeat) (void);
834 extern enum xp_retval (*xpc_get_remote_heartbeat) (struct xpc_partition *);
835 extern void (*xpc_allow_hb) (short);
836 extern void (*xpc_disallow_hb) (short);
837 extern void (*xpc_disallow_all_hbs) (void);
838 extern enum xp_retval (*xpc_make_first_contact) (struct xpc_partition *);
839 extern u64 (*xpc_get_chctl_all_flags) (struct xpc_partition *);
840 extern enum xp_retval (*xpc_setup_msg_structures) (struct xpc_channel *);
841 extern void (*xpc_teardown_msg_structures) (struct xpc_channel *);
842 extern void (*xpc_notify_senders_of_disconnect) (struct xpc_channel *);
843 extern void (*xpc_process_msg_chctl_flags) (struct xpc_partition *, int);
844 extern int (*xpc_n_of_deliverable_payloads) (struct xpc_channel *);
845 extern void *(*xpc_get_deliverable_payload) (struct xpc_channel *);
846 extern void (*xpc_request_partition_activation) (struct xpc_rsvd_page *,
847                                                  unsigned long, int);
848 extern void (*xpc_request_partition_reactivation) (struct xpc_partition *);
849 extern void (*xpc_request_partition_deactivation) (struct xpc_partition *);
850 extern void (*xpc_cancel_partition_deactivation_request) (
851                                                         struct xpc_partition *);
852 extern void (*xpc_process_activate_IRQ_rcvd) (void);
853 extern enum xp_retval (*xpc_setup_ch_structures_sn) (struct xpc_partition *);
854 extern void (*xpc_teardown_ch_structures_sn) (struct xpc_partition *);
855
856 extern void (*xpc_indicate_partition_engaged) (struct xpc_partition *);
857 extern int (*xpc_partition_engaged) (short);
858 extern int (*xpc_any_partition_engaged) (void);
859 extern void (*xpc_indicate_partition_disengaged) (struct xpc_partition *);
860 extern void (*xpc_assume_partition_disengaged) (short);
861
862 extern void (*xpc_send_chctl_closerequest) (struct xpc_channel *,
863                                             unsigned long *);
864 extern void (*xpc_send_chctl_closereply) (struct xpc_channel *,
865                                           unsigned long *);
866 extern void (*xpc_send_chctl_openrequest) (struct xpc_channel *,
867                                            unsigned long *);
868 extern void (*xpc_send_chctl_openreply) (struct xpc_channel *, unsigned long *);
869
870 extern enum xp_retval (*xpc_save_remote_msgqueue_pa) (struct xpc_channel *,
871                                                       unsigned long);
872
873 extern enum xp_retval (*xpc_send_payload) (struct xpc_channel *, u32, void *,
874                                            u16, u8, xpc_notify_func, void *);
875 extern void (*xpc_received_payload) (struct xpc_channel *, void *);
876
877 /* found in xpc_sn2.c */
878 extern int xpc_init_sn2(void);
879 extern void xpc_exit_sn2(void);
880
881 /* found in xpc_uv.c */
882 extern int xpc_init_uv(void);
883 extern void xpc_exit_uv(void);
884
885 /* found in xpc_partition.c */
886 extern int xpc_exiting;
887 extern int xpc_nasid_mask_nlongs;
888 extern struct xpc_rsvd_page *xpc_rsvd_page;
889 extern unsigned long *xpc_mach_nasids;
890 extern struct xpc_partition *xpc_partitions;
891 extern void *xpc_kmalloc_cacheline_aligned(size_t, gfp_t, void **);
892 extern int xpc_setup_rsvd_page(void);
893 extern void xpc_teardown_rsvd_page(void);
894 extern int xpc_identify_activate_IRQ_sender(void);
895 extern int xpc_partition_disengaged(struct xpc_partition *);
896 extern enum xp_retval xpc_mark_partition_active(struct xpc_partition *);
897 extern void xpc_mark_partition_inactive(struct xpc_partition *);
898 extern void xpc_discovery(void);
899 extern enum xp_retval xpc_get_remote_rp(int, unsigned long *,
900                                         struct xpc_rsvd_page *,
901                                         unsigned long *);
902 extern void xpc_deactivate_partition(const int, struct xpc_partition *,
903                                      enum xp_retval);
904 extern enum xp_retval xpc_initiate_partid_to_nasids(short, void *);
905
906 /* found in xpc_channel.c */
907 extern void xpc_initiate_connect(int);
908 extern void xpc_initiate_disconnect(int);
909 extern enum xp_retval xpc_allocate_msg_wait(struct xpc_channel *);
910 extern enum xp_retval xpc_initiate_send(short, int, u32, void *, u16);
911 extern enum xp_retval xpc_initiate_send_notify(short, int, u32, void *, u16,
912                                                xpc_notify_func, void *);
913 extern void xpc_initiate_received(short, int, void *);
914 extern void xpc_process_sent_chctl_flags(struct xpc_partition *);
915 extern void xpc_connected_callout(struct xpc_channel *);
916 extern void xpc_deliver_payload(struct xpc_channel *);
917 extern void xpc_disconnect_channel(const int, struct xpc_channel *,
918                                    enum xp_retval, unsigned long *);
919 extern void xpc_disconnect_callout(struct xpc_channel *, enum xp_retval);
920 extern void xpc_partition_going_down(struct xpc_partition *, enum xp_retval);
921
922 static inline void
923 xpc_wakeup_channel_mgr(struct xpc_partition *part)
924 {
925         if (atomic_inc_return(&part->channel_mgr_requests) == 1)
926                 wake_up(&part->channel_mgr_wq);
927 }
928
929 /*
930  * These next two inlines are used to keep us from tearing down a channel's
931  * msg queues while a thread may be referencing them.
932  */
933 static inline void
934 xpc_msgqueue_ref(struct xpc_channel *ch)
935 {
936         atomic_inc(&ch->references);
937 }
938
939 static inline void
940 xpc_msgqueue_deref(struct xpc_channel *ch)
941 {
942         s32 refs = atomic_dec_return(&ch->references);
943
944         DBUG_ON(refs < 0);
945         if (refs == 0)
946                 xpc_wakeup_channel_mgr(&xpc_partitions[ch->partid]);
947 }
948
949 #define XPC_DISCONNECT_CHANNEL(_ch, _reason, _irqflgs) \
950                 xpc_disconnect_channel(__LINE__, _ch, _reason, _irqflgs)
951
952 /*
953  * These two inlines are used to keep us from tearing down a partition's
954  * setup infrastructure while a thread may be referencing it.
955  */
956 static inline void
957 xpc_part_deref(struct xpc_partition *part)
958 {
959         s32 refs = atomic_dec_return(&part->references);
960
961         DBUG_ON(refs < 0);
962         if (refs == 0 && part->setup_state == XPC_P_SS_WTEARDOWN)
963                 wake_up(&part->teardown_wq);
964 }
965
966 static inline int
967 xpc_part_ref(struct xpc_partition *part)
968 {
969         int setup;
970
971         atomic_inc(&part->references);
972         setup = (part->setup_state == XPC_P_SS_SETUP);
973         if (!setup)
974                 xpc_part_deref(part);
975
976         return setup;
977 }
978
979 /*
980  * The following macro is to be used for the setting of the reason and
981  * reason_line fields in both the struct xpc_channel and struct xpc_partition
982  * structures.
983  */
984 #define XPC_SET_REASON(_p, _reason, _line) \
985         { \
986                 (_p)->reason = _reason; \
987                 (_p)->reason_line = _line; \
988         }
989
990 #endif /* _DRIVERS_MISC_SGIXP_XPC_H */