1
2
3
4
5
6
7
8
9
10
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
24
25
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
32#define XPC_HB_DEFAULT_INTERVAL 5
33#define XPC_HB_CHECK_DEFAULT_INTERVAL 20
34
35
36#define XPC_HB_CHECK_THREAD_NAME "xpc_hb"
37#define XPC_HB_CHECK_CPU 0
38
39
40#define XPC_DISCOVERY_THREAD_NAME "xpc_discovery"
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86struct xpc_rsvd_page {
87 u64 SAL_signature;
88 u64 SAL_version;
89 short SAL_partid;
90 short max_npartitions;
91 u8 version;
92 u8 pad1[3];
93 union {
94 unsigned long vars_pa;
95 unsigned long activate_mq_gpa;
96 } sn;
97 unsigned long ts_jiffies;
98 u64 pad2[10];
99 u64 SAL_nasids_size;
100};
101
102#define XPC_RP_VERSION _XPC_VERSION(2, 0)
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118struct xpc_vars_sn2 {
119 u8 version;
120 u64 heartbeat;
121 DECLARE_BITMAP(heartbeating_to_mask, XP_MAX_NPARTITIONS_SN2);
122 u64 heartbeat_offline;
123 int activate_IRQ_nasid;
124 int activate_IRQ_phys_cpuid;
125 unsigned long vars_part_pa;
126 unsigned long amos_page_pa;
127 struct amo *amos_page;
128};
129
130#define XPC_V_VERSION _XPC_VERSION(3, 1)
131
132
133
134
135
136
137
138
139
140
141
142struct xpc_vars_part_sn2 {
143 u64 magic;
144
145 unsigned long openclose_args_pa;
146 unsigned long GPs_pa;
147
148 unsigned long chctl_amo_pa;
149
150 int notify_IRQ_nasid;
151 int notify_IRQ_phys_cpuid;
152
153 u8 nchannels;
154
155 u8 reserved[23];
156};
157
158
159
160
161
162
163
164
165
166
167#define XPC_VP_MAGIC1_SN2 0x0053524156435058L
168#define XPC_VP_MAGIC2_SN2 0x0073726176435058L
169
170
171
172#define XPC_RP_HEADER_SIZE L1_CACHE_ALIGN(sizeof(struct xpc_rsvd_page))
173#define XPC_RP_VARS_SIZE L1_CACHE_ALIGN(sizeof(struct xpc_vars_sn2))
174
175#define XPC_RP_PART_NASIDS(_rp) ((unsigned long *)((u8 *)(_rp) + \
176 XPC_RP_HEADER_SIZE))
177#define XPC_RP_MACH_NASIDS(_rp) (XPC_RP_PART_NASIDS(_rp) + \
178 xpc_nasid_mask_nlongs)
179#define XPC_RP_VARS(_rp) ((struct xpc_vars_sn2 *) \
180 (XPC_RP_MACH_NASIDS(_rp) + \
181 xpc_nasid_mask_nlongs))
182
183
184
185
186
187struct xpc_activate_mq_msghdr_uv {
188 short partid;
189 u8 act_state;
190 u8 type;
191 unsigned long rp_ts_jiffies;
192};
193
194
195#define XPC_ACTIVATE_MQ_MSG_SYNC_ACT_STATE_UV 0
196#define XPC_ACTIVATE_MQ_MSG_INC_HEARTBEAT_UV 1
197#define XPC_ACTIVATE_MQ_MSG_OFFLINE_HEARTBEAT_UV 2
198#define XPC_ACTIVATE_MQ_MSG_ONLINE_HEARTBEAT_UV 3
199
200#define XPC_ACTIVATE_MQ_MSG_ACTIVATE_REQ_UV 4
201#define XPC_ACTIVATE_MQ_MSG_DEACTIVATE_REQ_UV 5
202
203#define XPC_ACTIVATE_MQ_MSG_CHCTL_CLOSEREQUEST_UV 6
204#define XPC_ACTIVATE_MQ_MSG_CHCTL_CLOSEREPLY_UV 7
205#define XPC_ACTIVATE_MQ_MSG_CHCTL_OPENREQUEST_UV 8
206#define XPC_ACTIVATE_MQ_MSG_CHCTL_OPENREPLY_UV 9
207
208#define XPC_ACTIVATE_MQ_MSG_MARK_ENGAGED_UV 10
209#define XPC_ACTIVATE_MQ_MSG_MARK_DISENGAGED_UV 11
210
211struct xpc_activate_mq_msg_uv {
212 struct xpc_activate_mq_msghdr_uv hdr;
213};
214
215struct xpc_activate_mq_msg_heartbeat_req_uv {
216 struct xpc_activate_mq_msghdr_uv hdr;
217 u64 heartbeat;
218};
219
220struct xpc_activate_mq_msg_activate_req_uv {
221 struct xpc_activate_mq_msghdr_uv hdr;
222 unsigned long rp_gpa;
223 unsigned long activate_mq_gpa;
224};
225
226struct xpc_activate_mq_msg_deactivate_req_uv {
227 struct xpc_activate_mq_msghdr_uv hdr;
228 enum xp_retval reason;
229};
230
231struct xpc_activate_mq_msg_chctl_closerequest_uv {
232 struct xpc_activate_mq_msghdr_uv hdr;
233 short ch_number;
234 enum xp_retval reason;
235};
236
237struct xpc_activate_mq_msg_chctl_closereply_uv {
238 struct xpc_activate_mq_msghdr_uv hdr;
239 short ch_number;
240};
241
242struct xpc_activate_mq_msg_chctl_openrequest_uv {
243 struct xpc_activate_mq_msghdr_uv hdr;
244 short ch_number;
245 short entry_size;
246 short local_nentries;
247};
248
249struct xpc_activate_mq_msg_chctl_openreply_uv {
250 struct xpc_activate_mq_msghdr_uv hdr;
251 short ch_number;
252 short remote_nentries;
253 short local_nentries;
254 unsigned long local_notify_mq_gpa;
255};
256
257
258
259
260
261
262
263#define XPC_PACK_ARGS(_arg1, _arg2) \
264 ((((u64)_arg1) & 0xffffffff) | \
265 ((((u64)_arg2) & 0xffffffff) << 32))
266
267#define XPC_UNPACK_ARG1(_args) (((u64)_args) & 0xffffffff)
268#define XPC_UNPACK_ARG2(_args) ((((u64)_args) >> 32) & 0xffffffff)
269
270
271
272
273struct xpc_gp_sn2 {
274 s64 get;
275 s64 put;
276};
277
278#define XPC_GP_SIZE \
279 L1_CACHE_ALIGN(sizeof(struct xpc_gp_sn2) * XPC_MAX_NCHANNELS)
280
281
282
283
284
285struct xpc_openclose_args {
286 u16 reason;
287 u16 entry_size;
288 u16 remote_nentries;
289 u16 local_nentries;
290 unsigned long local_msgqueue_pa;
291};
292
293#define XPC_OPENCLOSE_ARGS_SIZE \
294 L1_CACHE_ALIGN(sizeof(struct xpc_openclose_args) * \
295 XPC_MAX_NCHANNELS)
296
297
298
299
300
301
302struct xpc_fifo_entry_uv {
303 struct xpc_fifo_entry_uv *next;
304};
305
306struct xpc_fifo_head_uv {
307 struct xpc_fifo_entry_uv *first;
308 struct xpc_fifo_entry_uv *last;
309 spinlock_t lock;
310 int n_entries;
311};
312
313
314
315
316
317
318
319
320
321
322
323struct xpc_msg_sn2 {
324 u8 flags;
325 u8 reserved[7];
326 s64 number;
327
328 u64 payload;
329};
330
331
332
333#define XPC_M_SN2_DONE 0x01
334#define XPC_M_SN2_READY 0x02
335#define XPC_M_SN2_INTERRUPT 0x04
336
337
338
339
340
341
342
343
344
345
346
347struct xpc_notify_mq_msghdr_uv {
348 union {
349 unsigned int gru_msg_hdr;
350 struct xpc_fifo_entry_uv next;
351 } u;
352 short partid;
353 u8 ch_number;
354 u8 size;
355 unsigned int msg_slot_number;
356};
357
358struct xpc_notify_mq_msg_uv {
359 struct xpc_notify_mq_msghdr_uv hdr;
360 unsigned long payload;
361};
362
363
364
365
366
367
368
369struct xpc_notify_sn2 {
370 u8 type;
371
372
373 xpc_notify_func func;
374 void *key;
375};
376
377
378
379#define XPC_N_CALL 0x01
380
381
382
383
384
385struct xpc_send_msg_slot_uv {
386 struct xpc_fifo_entry_uv next;
387 unsigned int msg_slot_number;
388 xpc_notify_func func;
389 void *key;
390};
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475struct xpc_channel_sn2 {
476 struct xpc_openclose_args *local_openclose_args;
477
478
479 void *local_msgqueue_base;
480 struct xpc_msg_sn2 *local_msgqueue;
481 void *remote_msgqueue_base;
482 struct xpc_msg_sn2 *remote_msgqueue;
483
484 unsigned long remote_msgqueue_pa;
485
486
487 struct xpc_notify_sn2 *notify_queue;
488
489
490
491 struct xpc_gp_sn2 *local_GP;
492 struct xpc_gp_sn2 remote_GP;
493 struct xpc_gp_sn2 w_local_GP;
494 struct xpc_gp_sn2 w_remote_GP;
495 s64 next_msg_to_pull;
496
497 struct mutex msg_to_pull_mutex;
498};
499
500struct xpc_channel_uv {
501 unsigned long remote_notify_mq_gpa;
502
503
504 struct xpc_send_msg_slot_uv *send_msg_slots;
505 void *recv_msg_slots;
506
507
508 struct xpc_fifo_head_uv msg_slot_free_list;
509 struct xpc_fifo_head_uv recv_msg_list;
510};
511
512struct xpc_channel {
513 short partid;
514 spinlock_t lock;
515 unsigned int flags;
516
517 enum xp_retval reason;
518 int reason_line;
519
520 u16 number;
521
522 u16 entry_size;
523 u16 local_nentries;
524 u16 remote_nentries;
525
526 atomic_t references;
527
528 atomic_t n_on_msg_allocate_wq;
529 wait_queue_head_t msg_allocate_wq;
530
531 u8 delayed_chctl_flags;
532
533
534 atomic_t n_to_notify;
535
536 xpc_channel_func func;
537 void *key;
538
539 struct completion wdisconnect_wait;
540
541
542
543 atomic_t kthreads_assigned;
544 u32 kthreads_assigned_limit;
545 atomic_t kthreads_idle;
546 u32 kthreads_idle_limit;
547 atomic_t kthreads_active;
548
549 wait_queue_head_t idle_wq;
550
551 union {
552 struct xpc_channel_sn2 sn2;
553 struct xpc_channel_uv uv;
554 } sn;
555
556} ____cacheline_aligned;
557
558
559
560#define XPC_C_WASCONNECTED 0x00000001
561
562#define XPC_C_ROPENREPLY 0x00000002
563#define XPC_C_OPENREPLY 0x00000004
564#define XPC_C_ROPENREQUEST 0x00000008
565#define XPC_C_OPENREQUEST 0x00000010
566
567#define XPC_C_SETUP 0x00000020
568#define XPC_C_CONNECTEDCALLOUT 0x00000040
569#define XPC_C_CONNECTEDCALLOUT_MADE \
570 0x00000080
571#define XPC_C_CONNECTED 0x00000100
572#define XPC_C_CONNECTING 0x00000200
573
574#define XPC_C_RCLOSEREPLY 0x00000400
575#define XPC_C_CLOSEREPLY 0x00000800
576#define XPC_C_RCLOSEREQUEST 0x00001000
577#define XPC_C_CLOSEREQUEST 0x00002000
578
579#define XPC_C_DISCONNECTED 0x00004000
580#define XPC_C_DISCONNECTING 0x00008000
581#define XPC_C_DISCONNECTINGCALLOUT \
582 0x00010000
583#define XPC_C_DISCONNECTINGCALLOUT_MADE \
584 0x00020000
585#define XPC_C_WDISCONNECT 0x00040000
586
587
588
589
590
591
592
593
594union xpc_channel_ctl_flags {
595 u64 all_flags;
596 u8 flags[XPC_MAX_NCHANNELS];
597};
598
599
600#define XPC_CHCTL_CLOSEREQUEST 0x01
601#define XPC_CHCTL_CLOSEREPLY 0x02
602#define XPC_CHCTL_OPENREQUEST 0x04
603#define XPC_CHCTL_OPENREPLY 0x08
604#define XPC_CHCTL_MSGREQUEST 0x10
605
606#define XPC_OPENCLOSE_CHCTL_FLAGS \
607 (XPC_CHCTL_CLOSEREQUEST | XPC_CHCTL_CLOSEREPLY | \
608 XPC_CHCTL_OPENREQUEST | XPC_CHCTL_OPENREPLY)
609#define XPC_MSG_CHCTL_FLAGS XPC_CHCTL_MSGREQUEST
610
611static inline int
612xpc_any_openclose_chctl_flags_set(union xpc_channel_ctl_flags *chctl)
613{
614 int ch_number;
615
616 for (ch_number = 0; ch_number < XPC_MAX_NCHANNELS; ch_number++) {
617 if (chctl->flags[ch_number] & XPC_OPENCLOSE_CHCTL_FLAGS)
618 return 1;
619 }
620 return 0;
621}
622
623static inline int
624xpc_any_msg_chctl_flags_set(union xpc_channel_ctl_flags *chctl)
625{
626 int ch_number;
627
628 for (ch_number = 0; ch_number < XPC_MAX_NCHANNELS; ch_number++) {
629 if (chctl->flags[ch_number] & XPC_MSG_CHCTL_FLAGS)
630 return 1;
631 }
632 return 0;
633}
634
635
636
637
638
639
640
641struct xpc_partition_sn2 {
642 unsigned long remote_amos_page_pa;
643 int activate_IRQ_nasid;
644 int activate_IRQ_phys_cpuid;
645
646 unsigned long remote_vars_pa;
647 unsigned long remote_vars_part_pa;
648 u8 remote_vars_version;
649
650 void *local_GPs_base;
651 struct xpc_gp_sn2 *local_GPs;
652 void *remote_GPs_base;
653 struct xpc_gp_sn2 *remote_GPs;
654
655 unsigned long remote_GPs_pa;
656
657
658 void *local_openclose_args_base;
659 struct xpc_openclose_args *local_openclose_args;
660 unsigned long remote_openclose_args_pa;
661
662 int notify_IRQ_nasid;
663 int notify_IRQ_phys_cpuid;
664 char notify_IRQ_owner[8];
665
666 struct amo *remote_chctl_amo_va;
667 struct amo *local_chctl_amo_va;
668
669 struct timer_list dropped_notify_IRQ_timer;
670};
671
672struct xpc_partition_uv {
673 unsigned long remote_activate_mq_gpa;
674
675 spinlock_t flags_lock;
676 unsigned int flags;
677 u8 remote_act_state;
678 u8 act_state_req;
679 enum xp_retval reason;
680 u64 heartbeat;
681};
682
683
684
685#define XPC_P_HEARTBEAT_OFFLINE_UV 0x00000001
686#define XPC_P_ENGAGED_UV 0x00000002
687
688
689
690#define XPC_P_ASR_ACTIVATE_UV 0x01
691#define XPC_P_ASR_REACTIVATE_UV 0x02
692#define XPC_P_ASR_DEACTIVATE_UV 0x03
693
694struct xpc_partition {
695
696
697
698 u8 remote_rp_version;
699 unsigned long remote_rp_ts_jiffies;
700 unsigned long remote_rp_pa;
701 u64 last_heartbeat;
702 u32 activate_IRQ_rcvd;
703 spinlock_t act_lock;
704 u8 act_state;
705 enum xp_retval reason;
706 int reason_line;
707
708 unsigned long disengage_timeout;
709 struct timer_list disengage_timer;
710
711
712
713 u8 setup_state;
714 wait_queue_head_t teardown_wq;
715 atomic_t references;
716
717 u8 nchannels;
718 atomic_t nchannels_active;
719 atomic_t nchannels_engaged;
720 struct xpc_channel *channels;
721
722
723
724 union xpc_channel_ctl_flags chctl;
725 spinlock_t chctl_lock;
726
727 void *remote_openclose_args_base;
728 struct xpc_openclose_args *remote_openclose_args;
729
730
731
732
733 atomic_t channel_mgr_requests;
734 wait_queue_head_t channel_mgr_wq;
735
736 union {
737 struct xpc_partition_sn2 sn2;
738 struct xpc_partition_uv uv;
739 } sn;
740
741} ____cacheline_aligned;
742
743
744
745#define XPC_P_AS_INACTIVE 0x00
746#define XPC_P_AS_ACTIVATION_REQ 0x01
747#define XPC_P_AS_ACTIVATING 0x02
748#define XPC_P_AS_ACTIVE 0x03
749#define XPC_P_AS_DEACTIVATING 0x04
750
751#define XPC_DEACTIVATE_PARTITION(_p, _reason) \
752 xpc_deactivate_partition(__LINE__, (_p), (_reason))
753
754
755
756#define XPC_P_SS_UNSET 0x00
757#define XPC_P_SS_SETUP 0x01
758#define XPC_P_SS_WTEARDOWN 0x02
759#define XPC_P_SS_TORNDOWN 0x03
760
761
762
763
764
765
766
767#define XPC_DROPPED_NOTIFY_IRQ_WAIT_INTERVAL (0.25 * HZ)
768
769
770#define XPC_DISENGAGE_DEFAULT_TIMELIMIT 90
771
772
773#define XPC_DEACTIVATE_PRINTMSG_INTERVAL 10
774
775#define XPC_PARTID(_p) ((short)((_p) - &xpc_partitions[0]))
776
777
778extern struct xpc_registration xpc_registrations[];
779
780
781extern struct device *xpc_part;
782extern struct device *xpc_chan;
783extern int xpc_disengage_timelimit;
784extern int xpc_disengage_timedout;
785extern int xpc_activate_IRQ_rcvd;
786extern spinlock_t xpc_activate_IRQ_rcvd_lock;
787extern wait_queue_head_t xpc_activate_IRQ_wq;
788extern void *xpc_heartbeating_to_mask;
789extern void *xpc_kzalloc_cacheline_aligned(size_t, gfp_t, void **);
790extern void xpc_activate_partition(struct xpc_partition *);
791extern void xpc_activate_kthreads(struct xpc_channel *, int);
792extern void xpc_create_kthreads(struct xpc_channel *, int, int);
793extern void xpc_disconnect_wait(int);
794extern int (*xpc_setup_partitions_sn) (void);
795extern enum xp_retval (*xpc_get_partition_rsvd_page_pa) (void *, u64 *,
796 unsigned long *,
797 size_t *);
798extern int (*xpc_setup_rsvd_page_sn) (struct xpc_rsvd_page *);
799extern void (*xpc_heartbeat_init) (void);
800extern void (*xpc_heartbeat_exit) (void);
801extern void (*xpc_increment_heartbeat) (void);
802extern void (*xpc_offline_heartbeat) (void);
803extern void (*xpc_online_heartbeat) (void);
804extern enum xp_retval (*xpc_get_remote_heartbeat) (struct xpc_partition *);
805extern enum xp_retval (*xpc_make_first_contact) (struct xpc_partition *);
806extern u64 (*xpc_get_chctl_all_flags) (struct xpc_partition *);
807extern enum xp_retval (*xpc_setup_msg_structures) (struct xpc_channel *);
808extern void (*xpc_teardown_msg_structures) (struct xpc_channel *);
809extern void (*xpc_notify_senders_of_disconnect) (struct xpc_channel *);
810extern void (*xpc_process_msg_chctl_flags) (struct xpc_partition *, int);
811extern int (*xpc_n_of_deliverable_payloads) (struct xpc_channel *);
812extern void *(*xpc_get_deliverable_payload) (struct xpc_channel *);
813extern void (*xpc_request_partition_activation) (struct xpc_rsvd_page *,
814 unsigned long, int);
815extern void (*xpc_request_partition_reactivation) (struct xpc_partition *);
816extern void (*xpc_request_partition_deactivation) (struct xpc_partition *);
817extern void (*xpc_cancel_partition_deactivation_request) (
818 struct xpc_partition *);
819extern void (*xpc_process_activate_IRQ_rcvd) (void);
820extern enum xp_retval (*xpc_setup_ch_structures_sn) (struct xpc_partition *);
821extern void (*xpc_teardown_ch_structures_sn) (struct xpc_partition *);
822
823extern void (*xpc_indicate_partition_engaged) (struct xpc_partition *);
824extern int (*xpc_partition_engaged) (short);
825extern int (*xpc_any_partition_engaged) (void);
826extern void (*xpc_indicate_partition_disengaged) (struct xpc_partition *);
827extern void (*xpc_assume_partition_disengaged) (short);
828
829extern void (*xpc_send_chctl_closerequest) (struct xpc_channel *,
830 unsigned long *);
831extern void (*xpc_send_chctl_closereply) (struct xpc_channel *,
832 unsigned long *);
833extern void (*xpc_send_chctl_openrequest) (struct xpc_channel *,
834 unsigned long *);
835extern void (*xpc_send_chctl_openreply) (struct xpc_channel *, unsigned long *);
836
837extern void (*xpc_save_remote_msgqueue_pa) (struct xpc_channel *,
838 unsigned long);
839
840extern enum xp_retval (*xpc_send_payload) (struct xpc_channel *, u32, void *,
841 u16, u8, xpc_notify_func, void *);
842extern void (*xpc_received_payload) (struct xpc_channel *, void *);
843
844
845extern int xpc_init_sn2(void);
846extern void xpc_exit_sn2(void);
847
848
849extern int xpc_init_uv(void);
850extern void xpc_exit_uv(void);
851
852
853extern int xpc_exiting;
854extern int xpc_nasid_mask_nlongs;
855extern struct xpc_rsvd_page *xpc_rsvd_page;
856extern unsigned long *xpc_mach_nasids;
857extern struct xpc_partition *xpc_partitions;
858extern void *xpc_kmalloc_cacheline_aligned(size_t, gfp_t, void **);
859extern int xpc_setup_rsvd_page(void);
860extern void xpc_teardown_rsvd_page(void);
861extern int xpc_identify_activate_IRQ_sender(void);
862extern int xpc_partition_disengaged(struct xpc_partition *);
863extern enum xp_retval xpc_mark_partition_active(struct xpc_partition *);
864extern void xpc_mark_partition_inactive(struct xpc_partition *);
865extern void xpc_discovery(void);
866extern enum xp_retval xpc_get_remote_rp(int, unsigned long *,
867 struct xpc_rsvd_page *,
868 unsigned long *);
869extern void xpc_deactivate_partition(const int, struct xpc_partition *,
870 enum xp_retval);
871extern enum xp_retval xpc_initiate_partid_to_nasids(short, void *);
872
873
874extern void xpc_initiate_connect(int);
875extern void xpc_initiate_disconnect(int);
876extern enum xp_retval xpc_allocate_msg_wait(struct xpc_channel *);
877extern enum xp_retval xpc_initiate_send(short, int, u32, void *, u16);
878extern enum xp_retval xpc_initiate_send_notify(short, int, u32, void *, u16,
879 xpc_notify_func, void *);
880extern void xpc_initiate_received(short, int, void *);
881extern void xpc_process_sent_chctl_flags(struct xpc_partition *);
882extern void xpc_connected_callout(struct xpc_channel *);
883extern void xpc_deliver_payload(struct xpc_channel *);
884extern void xpc_disconnect_channel(const int, struct xpc_channel *,
885 enum xp_retval, unsigned long *);
886extern void xpc_disconnect_callout(struct xpc_channel *, enum xp_retval);
887extern void xpc_partition_going_down(struct xpc_partition *, enum xp_retval);
888
889static inline int
890xpc_hb_allowed(short partid, void *heartbeating_to_mask)
891{
892 return test_bit(partid, heartbeating_to_mask);
893}
894
895static inline int
896xpc_any_hbs_allowed(void)
897{
898 DBUG_ON(xpc_heartbeating_to_mask == NULL);
899 return !bitmap_empty(xpc_heartbeating_to_mask, xp_max_npartitions);
900}
901
902static inline void
903xpc_allow_hb(short partid)
904{
905 DBUG_ON(xpc_heartbeating_to_mask == NULL);
906 set_bit(partid, xpc_heartbeating_to_mask);
907}
908
909static inline void
910xpc_disallow_hb(short partid)
911{
912 DBUG_ON(xpc_heartbeating_to_mask == NULL);
913 clear_bit(partid, xpc_heartbeating_to_mask);
914}
915
916static inline void
917xpc_disallow_all_hbs(void)
918{
919 DBUG_ON(xpc_heartbeating_to_mask == NULL);
920 bitmap_zero(xpc_heartbeating_to_mask, xp_max_npartitions);
921}
922
923static inline void
924xpc_wakeup_channel_mgr(struct xpc_partition *part)
925{
926 if (atomic_inc_return(&part->channel_mgr_requests) == 1)
927 wake_up(&part->channel_mgr_wq);
928}
929
930
931
932
933
934static inline void
935xpc_msgqueue_ref(struct xpc_channel *ch)
936{
937 atomic_inc(&ch->references);
938}
939
940static inline void
941xpc_msgqueue_deref(struct xpc_channel *ch)
942{
943 s32 refs = atomic_dec_return(&ch->references);
944
945 DBUG_ON(refs < 0);
946 if (refs == 0)
947 xpc_wakeup_channel_mgr(&xpc_partitions[ch->partid]);
948}
949
950#define XPC_DISCONNECT_CHANNEL(_ch, _reason, _irqflgs) \
951 xpc_disconnect_channel(__LINE__, _ch, _reason, _irqflgs)
952
953
954
955
956
957static inline void
958xpc_part_deref(struct xpc_partition *part)
959{
960 s32 refs = atomic_dec_return(&part->references);
961
962 DBUG_ON(refs < 0);
963 if (refs == 0 && part->setup_state == XPC_P_SS_WTEARDOWN)
964 wake_up(&part->teardown_wq);
965}
966
967static inline int
968xpc_part_ref(struct xpc_partition *part)
969{
970 int setup;
971
972 atomic_inc(&part->references);
973 setup = (part->setup_state == XPC_P_SS_SETUP);
974 if (!setup)
975 xpc_part_deref(part);
976
977 return setup;
978}
979
980
981
982
983
984
985#define XPC_SET_REASON(_p, _reason, _line) \
986 { \
987 (_p)->reason = _reason; \
988 (_p)->reason_line = _line; \
989 }
990
991#endif
992