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 unsigned long ts_jiffies;
94 union {
95 struct {
96 unsigned long vars_pa;
97 } sn2;
98 struct {
99 unsigned long heartbeat_gpa;
100 unsigned long activate_gru_mq_desc_gpa;
101 } uv;
102 } sn;
103 u64 pad2[9];
104 u64 SAL_nasids_size;
105};
106
107#define XPC_RP_VERSION _XPC_VERSION(3, 0)
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123struct xpc_vars_sn2 {
124 u8 version;
125 u64 heartbeat;
126 DECLARE_BITMAP(heartbeating_to_mask, XP_MAX_NPARTITIONS_SN2);
127 u64 heartbeat_offline;
128 int activate_IRQ_nasid;
129 int activate_IRQ_phys_cpuid;
130 unsigned long vars_part_pa;
131 unsigned long amos_page_pa;
132 struct amo *amos_page;
133};
134
135#define XPC_V_VERSION _XPC_VERSION(3, 1)
136
137
138
139
140
141
142
143
144
145
146
147struct xpc_vars_part_sn2 {
148 u64 magic;
149
150 unsigned long openclose_args_pa;
151 unsigned long GPs_pa;
152
153 unsigned long chctl_amo_pa;
154
155 int notify_IRQ_nasid;
156 int notify_IRQ_phys_cpuid;
157
158 u8 nchannels;
159
160 u8 reserved[23];
161};
162
163
164
165
166
167
168
169
170
171
172#define XPC_VP_MAGIC1_SN2 0x0053524156435058L
173#define XPC_VP_MAGIC2_SN2 0x0073726176435058L
174
175
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
191
192
193
194struct xpc_heartbeat_uv {
195 unsigned long value;
196 unsigned long offline;
197};
198
199
200
201
202struct xpc_gru_mq_uv {
203 void *address;
204 unsigned int order;
205 int irq;
206 int mmr_blade;
207 unsigned long mmr_offset;
208 unsigned long mmr_value;
209 int watchlist_num;
210 void *gru_mq_desc;
211};
212
213
214
215
216
217struct xpc_activate_mq_msghdr_uv {
218 unsigned int gru_msg_hdr;
219 short partid;
220 u8 act_state;
221 u8 type;
222 unsigned long rp_ts_jiffies;
223};
224
225
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#define XPC_ACTIVATE_MQ_MSG_CHCTL_OPENCOMPLETE_UV 7
236
237#define XPC_ACTIVATE_MQ_MSG_MARK_ENGAGED_UV 8
238#define XPC_ACTIVATE_MQ_MSG_MARK_DISENGAGED_UV 9
239
240struct xpc_activate_mq_msg_uv {
241 struct xpc_activate_mq_msghdr_uv hdr;
242};
243
244struct xpc_activate_mq_msg_activate_req_uv {
245 struct xpc_activate_mq_msghdr_uv hdr;
246 unsigned long rp_gpa;
247 unsigned long heartbeat_gpa;
248 unsigned long activate_gru_mq_desc_gpa;
249};
250
251struct xpc_activate_mq_msg_deactivate_req_uv {
252 struct xpc_activate_mq_msghdr_uv hdr;
253 enum xp_retval reason;
254};
255
256struct xpc_activate_mq_msg_chctl_closerequest_uv {
257 struct xpc_activate_mq_msghdr_uv hdr;
258 short ch_number;
259 enum xp_retval reason;
260};
261
262struct xpc_activate_mq_msg_chctl_closereply_uv {
263 struct xpc_activate_mq_msghdr_uv hdr;
264 short ch_number;
265};
266
267struct xpc_activate_mq_msg_chctl_openrequest_uv {
268 struct xpc_activate_mq_msghdr_uv hdr;
269 short ch_number;
270 short entry_size;
271 short local_nentries;
272};
273
274struct xpc_activate_mq_msg_chctl_openreply_uv {
275 struct xpc_activate_mq_msghdr_uv hdr;
276 short ch_number;
277 short remote_nentries;
278 short local_nentries;
279 unsigned long notify_gru_mq_desc_gpa;
280};
281
282struct xpc_activate_mq_msg_chctl_opencomplete_uv {
283 struct xpc_activate_mq_msghdr_uv hdr;
284 short ch_number;
285};
286
287
288
289
290
291
292
293#define XPC_PACK_ARGS(_arg1, _arg2) \
294 ((((u64)_arg1) & 0xffffffff) | \
295 ((((u64)_arg2) & 0xffffffff) << 32))
296
297#define XPC_UNPACK_ARG1(_args) (((u64)_args) & 0xffffffff)
298#define XPC_UNPACK_ARG2(_args) ((((u64)_args) >> 32) & 0xffffffff)
299
300
301
302
303struct xpc_gp_sn2 {
304 s64 get;
305 s64 put;
306};
307
308#define XPC_GP_SIZE \
309 L1_CACHE_ALIGN(sizeof(struct xpc_gp_sn2) * XPC_MAX_NCHANNELS)
310
311
312
313
314
315struct xpc_openclose_args {
316 u16 reason;
317 u16 entry_size;
318 u16 remote_nentries;
319 u16 local_nentries;
320 unsigned long local_msgqueue_pa;
321};
322
323#define XPC_OPENCLOSE_ARGS_SIZE \
324 L1_CACHE_ALIGN(sizeof(struct xpc_openclose_args) * \
325 XPC_MAX_NCHANNELS)
326
327
328
329
330
331
332struct xpc_fifo_entry_uv {
333 struct xpc_fifo_entry_uv *next;
334};
335
336struct xpc_fifo_head_uv {
337 struct xpc_fifo_entry_uv *first;
338 struct xpc_fifo_entry_uv *last;
339 spinlock_t lock;
340 int n_entries;
341};
342
343
344
345
346
347
348
349
350
351
352
353struct xpc_msg_sn2 {
354 u8 flags;
355 u8 reserved[7];
356 s64 number;
357
358 u64 payload;
359};
360
361
362
363#define XPC_M_SN2_DONE 0x01
364#define XPC_M_SN2_READY 0x02
365#define XPC_M_SN2_INTERRUPT 0x04
366
367
368
369
370
371
372
373
374
375
376
377struct xpc_notify_mq_msghdr_uv {
378 union {
379 unsigned int gru_msg_hdr;
380 struct xpc_fifo_entry_uv next;
381 } u;
382 short partid;
383 u8 ch_number;
384 u8 size;
385 unsigned int msg_slot_number;
386};
387
388struct xpc_notify_mq_msg_uv {
389 struct xpc_notify_mq_msghdr_uv hdr;
390 unsigned long payload;
391};
392
393
394
395
396
397
398
399struct xpc_notify_sn2 {
400 u8 type;
401
402
403 xpc_notify_func func;
404 void *key;
405};
406
407
408
409#define XPC_N_CALL 0x01
410
411
412
413
414
415struct xpc_send_msg_slot_uv {
416 struct xpc_fifo_entry_uv next;
417 unsigned int msg_slot_number;
418 xpc_notify_func func;
419 void *key;
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
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505struct xpc_channel_sn2 {
506 struct xpc_openclose_args *local_openclose_args;
507
508
509 void *local_msgqueue_base;
510 struct xpc_msg_sn2 *local_msgqueue;
511 void *remote_msgqueue_base;
512 struct xpc_msg_sn2 *remote_msgqueue;
513
514 unsigned long remote_msgqueue_pa;
515
516
517 struct xpc_notify_sn2 *notify_queue;
518
519
520
521 struct xpc_gp_sn2 *local_GP;
522 struct xpc_gp_sn2 remote_GP;
523 struct xpc_gp_sn2 w_local_GP;
524 struct xpc_gp_sn2 w_remote_GP;
525 s64 next_msg_to_pull;
526
527 struct mutex msg_to_pull_mutex;
528};
529
530struct xpc_channel_uv {
531 void *cached_notify_gru_mq_desc;
532
533
534 struct xpc_send_msg_slot_uv *send_msg_slots;
535 void *recv_msg_slots;
536
537
538 struct xpc_fifo_head_uv msg_slot_free_list;
539 struct xpc_fifo_head_uv recv_msg_list;
540};
541
542struct xpc_channel {
543 short partid;
544 spinlock_t lock;
545 unsigned int flags;
546
547 enum xp_retval reason;
548 int reason_line;
549
550 u16 number;
551
552 u16 entry_size;
553 u16 local_nentries;
554 u16 remote_nentries;
555
556 atomic_t references;
557
558 atomic_t n_on_msg_allocate_wq;
559 wait_queue_head_t msg_allocate_wq;
560
561 u8 delayed_chctl_flags;
562
563
564 atomic_t n_to_notify;
565
566 xpc_channel_func func;
567 void *key;
568
569 struct completion wdisconnect_wait;
570
571
572
573 atomic_t kthreads_assigned;
574 u32 kthreads_assigned_limit;
575 atomic_t kthreads_idle;
576 u32 kthreads_idle_limit;
577 atomic_t kthreads_active;
578
579 wait_queue_head_t idle_wq;
580
581 union {
582 struct xpc_channel_sn2 sn2;
583 struct xpc_channel_uv uv;
584 } sn;
585
586} ____cacheline_aligned;
587
588
589
590#define XPC_C_WASCONNECTED 0x00000001
591
592#define XPC_C_ROPENCOMPLETE 0x00000002
593#define XPC_C_OPENCOMPLETE 0x00000004
594#define XPC_C_ROPENREPLY 0x00000008
595#define XPC_C_OPENREPLY 0x00000010
596#define XPC_C_ROPENREQUEST 0x00000020
597#define XPC_C_OPENREQUEST 0x00000040
598
599#define XPC_C_SETUP 0x00000080
600#define XPC_C_CONNECTEDCALLOUT 0x00000100
601#define XPC_C_CONNECTEDCALLOUT_MADE \
602 0x00000200
603#define XPC_C_CONNECTED 0x00000400
604#define XPC_C_CONNECTING 0x00000800
605
606#define XPC_C_RCLOSEREPLY 0x00001000
607#define XPC_C_CLOSEREPLY 0x00002000
608#define XPC_C_RCLOSEREQUEST 0x00004000
609#define XPC_C_CLOSEREQUEST 0x00008000
610
611#define XPC_C_DISCONNECTED 0x00010000
612#define XPC_C_DISCONNECTING 0x00020000
613#define XPC_C_DISCONNECTINGCALLOUT \
614 0x00040000
615#define XPC_C_DISCONNECTINGCALLOUT_MADE \
616 0x00080000
617#define XPC_C_WDISCONNECT 0x00100000
618
619
620
621
622
623
624
625
626union xpc_channel_ctl_flags {
627 u64 all_flags;
628 u8 flags[XPC_MAX_NCHANNELS];
629};
630
631
632#define XPC_CHCTL_CLOSEREQUEST 0x01
633#define XPC_CHCTL_CLOSEREPLY 0x02
634#define XPC_CHCTL_OPENREQUEST 0x04
635#define XPC_CHCTL_OPENREPLY 0x08
636#define XPC_CHCTL_OPENCOMPLETE 0x10
637#define XPC_CHCTL_MSGREQUEST 0x20
638
639#define XPC_OPENCLOSE_CHCTL_FLAGS \
640 (XPC_CHCTL_CLOSEREQUEST | XPC_CHCTL_CLOSEREPLY | \
641 XPC_CHCTL_OPENREQUEST | XPC_CHCTL_OPENREPLY | \
642 XPC_CHCTL_OPENCOMPLETE)
643#define XPC_MSG_CHCTL_FLAGS XPC_CHCTL_MSGREQUEST
644
645static inline int
646xpc_any_openclose_chctl_flags_set(union xpc_channel_ctl_flags *chctl)
647{
648 int ch_number;
649
650 for (ch_number = 0; ch_number < XPC_MAX_NCHANNELS; ch_number++) {
651 if (chctl->flags[ch_number] & XPC_OPENCLOSE_CHCTL_FLAGS)
652 return 1;
653 }
654 return 0;
655}
656
657static inline int
658xpc_any_msg_chctl_flags_set(union xpc_channel_ctl_flags *chctl)
659{
660 int ch_number;
661
662 for (ch_number = 0; ch_number < XPC_MAX_NCHANNELS; ch_number++) {
663 if (chctl->flags[ch_number] & XPC_MSG_CHCTL_FLAGS)
664 return 1;
665 }
666 return 0;
667}
668
669
670
671
672
673
674
675struct xpc_partition_sn2 {
676 unsigned long remote_amos_page_pa;
677 int activate_IRQ_nasid;
678 int activate_IRQ_phys_cpuid;
679
680 unsigned long remote_vars_pa;
681 unsigned long remote_vars_part_pa;
682 u8 remote_vars_version;
683
684 void *local_GPs_base;
685 struct xpc_gp_sn2 *local_GPs;
686 void *remote_GPs_base;
687 struct xpc_gp_sn2 *remote_GPs;
688
689 unsigned long remote_GPs_pa;
690
691
692 void *local_openclose_args_base;
693 struct xpc_openclose_args *local_openclose_args;
694 unsigned long remote_openclose_args_pa;
695
696 int notify_IRQ_nasid;
697 int notify_IRQ_phys_cpuid;
698 char notify_IRQ_owner[8];
699
700 struct amo *remote_chctl_amo_va;
701 struct amo *local_chctl_amo_va;
702
703 struct timer_list dropped_notify_IRQ_timer;
704};
705
706struct xpc_partition_uv {
707 unsigned long heartbeat_gpa;
708 struct xpc_heartbeat_uv cached_heartbeat;
709
710 unsigned long activate_gru_mq_desc_gpa;
711
712
713 void *cached_activate_gru_mq_desc;
714
715 struct mutex cached_activate_gru_mq_desc_mutex;
716 spinlock_t flags_lock;
717 unsigned int flags;
718 u8 remote_act_state;
719 u8 act_state_req;
720 enum xp_retval reason;
721};
722
723
724
725#define XPC_P_CACHED_ACTIVATE_GRU_MQ_DESC_UV 0x00000001
726#define XPC_P_ENGAGED_UV 0x00000002
727
728
729
730#define XPC_P_ASR_ACTIVATE_UV 0x01
731#define XPC_P_ASR_REACTIVATE_UV 0x02
732#define XPC_P_ASR_DEACTIVATE_UV 0x03
733
734struct xpc_partition {
735
736
737
738 u8 remote_rp_version;
739 unsigned long remote_rp_ts_jiffies;
740 unsigned long remote_rp_pa;
741 u64 last_heartbeat;
742 u32 activate_IRQ_rcvd;
743 spinlock_t act_lock;
744 u8 act_state;
745 enum xp_retval reason;
746 int reason_line;
747
748 unsigned long disengage_timeout;
749 struct timer_list disengage_timer;
750
751
752
753 u8 setup_state;
754 wait_queue_head_t teardown_wq;
755 atomic_t references;
756
757 u8 nchannels;
758 atomic_t nchannels_active;
759 atomic_t nchannels_engaged;
760 struct xpc_channel *channels;
761
762
763
764 union xpc_channel_ctl_flags chctl;
765 spinlock_t chctl_lock;
766
767 void *remote_openclose_args_base;
768 struct xpc_openclose_args *remote_openclose_args;
769
770
771
772
773 atomic_t channel_mgr_requests;
774 wait_queue_head_t channel_mgr_wq;
775
776 union {
777 struct xpc_partition_sn2 sn2;
778 struct xpc_partition_uv uv;
779 } sn;
780
781} ____cacheline_aligned;
782
783struct xpc_arch_operations {
784 int (*setup_partitions) (void);
785 void (*teardown_partitions) (void);
786 void (*process_activate_IRQ_rcvd) (void);
787 enum xp_retval (*get_partition_rsvd_page_pa)
788 (void *, u64 *, unsigned long *, size_t *);
789 int (*setup_rsvd_page) (struct xpc_rsvd_page *);
790
791 void (*allow_hb) (short);
792 void (*disallow_hb) (short);
793 void (*disallow_all_hbs) (void);
794 void (*increment_heartbeat) (void);
795 void (*offline_heartbeat) (void);
796 void (*online_heartbeat) (void);
797 void (*heartbeat_init) (void);
798 void (*heartbeat_exit) (void);
799 enum xp_retval (*get_remote_heartbeat) (struct xpc_partition *);
800
801 void (*request_partition_activation) (struct xpc_rsvd_page *,
802 unsigned long, int);
803 void (*request_partition_reactivation) (struct xpc_partition *);
804 void (*request_partition_deactivation) (struct xpc_partition *);
805 void (*cancel_partition_deactivation_request) (struct xpc_partition *);
806 enum xp_retval (*setup_ch_structures) (struct xpc_partition *);
807 void (*teardown_ch_structures) (struct xpc_partition *);
808
809 enum xp_retval (*make_first_contact) (struct xpc_partition *);
810
811 u64 (*get_chctl_all_flags) (struct xpc_partition *);
812 void (*send_chctl_closerequest) (struct xpc_channel *, unsigned long *);
813 void (*send_chctl_closereply) (struct xpc_channel *, unsigned long *);
814 void (*send_chctl_openrequest) (struct xpc_channel *, unsigned long *);
815 void (*send_chctl_openreply) (struct xpc_channel *, unsigned long *);
816 void (*send_chctl_opencomplete) (struct xpc_channel *, unsigned long *);
817 void (*process_msg_chctl_flags) (struct xpc_partition *, int);
818
819 enum xp_retval (*save_remote_msgqueue_pa) (struct xpc_channel *,
820 unsigned long);
821
822 enum xp_retval (*setup_msg_structures) (struct xpc_channel *);
823 void (*teardown_msg_structures) (struct xpc_channel *);
824
825 void (*indicate_partition_engaged) (struct xpc_partition *);
826 void (*indicate_partition_disengaged) (struct xpc_partition *);
827 void (*assume_partition_disengaged) (short);
828 int (*partition_engaged) (short);
829 int (*any_partition_engaged) (void);
830
831 int (*n_of_deliverable_payloads) (struct xpc_channel *);
832 enum xp_retval (*send_payload) (struct xpc_channel *, u32, void *,
833 u16, u8, xpc_notify_func, void *);
834 void *(*get_deliverable_payload) (struct xpc_channel *);
835 void (*received_payload) (struct xpc_channel *, void *);
836 void (*notify_senders_of_disconnect) (struct xpc_channel *);
837};
838
839
840
841#define XPC_P_AS_INACTIVE 0x00
842#define XPC_P_AS_ACTIVATION_REQ 0x01
843#define XPC_P_AS_ACTIVATING 0x02
844#define XPC_P_AS_ACTIVE 0x03
845#define XPC_P_AS_DEACTIVATING 0x04
846
847#define XPC_DEACTIVATE_PARTITION(_p, _reason) \
848 xpc_deactivate_partition(__LINE__, (_p), (_reason))
849
850
851
852#define XPC_P_SS_UNSET 0x00
853#define XPC_P_SS_SETUP 0x01
854#define XPC_P_SS_WTEARDOWN 0x02
855#define XPC_P_SS_TORNDOWN 0x03
856
857
858
859
860
861
862
863#define XPC_DROPPED_NOTIFY_IRQ_WAIT_INTERVAL (0.25 * HZ)
864
865
866#define XPC_DISENGAGE_DEFAULT_TIMELIMIT 90
867
868
869#define XPC_DEACTIVATE_PRINTMSG_INTERVAL 10
870
871#define XPC_PARTID(_p) ((short)((_p) - &xpc_partitions[0]))
872
873
874extern struct xpc_registration xpc_registrations[];
875
876
877extern struct device *xpc_part;
878extern struct device *xpc_chan;
879extern struct xpc_arch_operations xpc_arch_ops;
880extern int xpc_disengage_timelimit;
881extern int xpc_disengage_timedout;
882extern int xpc_activate_IRQ_rcvd;
883extern spinlock_t xpc_activate_IRQ_rcvd_lock;
884extern wait_queue_head_t xpc_activate_IRQ_wq;
885extern void *xpc_kzalloc_cacheline_aligned(size_t, gfp_t, void **);
886extern void xpc_activate_partition(struct xpc_partition *);
887extern void xpc_activate_kthreads(struct xpc_channel *, int);
888extern void xpc_create_kthreads(struct xpc_channel *, int, int);
889extern void xpc_disconnect_wait(int);
890
891
892extern int xpc_init_sn2(void);
893extern void xpc_exit_sn2(void);
894
895
896extern int xpc_init_uv(void);
897extern void xpc_exit_uv(void);
898
899
900extern int xpc_exiting;
901extern int xpc_nasid_mask_nlongs;
902extern struct xpc_rsvd_page *xpc_rsvd_page;
903extern unsigned long *xpc_mach_nasids;
904extern struct xpc_partition *xpc_partitions;
905extern void *xpc_kmalloc_cacheline_aligned(size_t, gfp_t, void **);
906extern int xpc_setup_rsvd_page(void);
907extern void xpc_teardown_rsvd_page(void);
908extern int xpc_identify_activate_IRQ_sender(void);
909extern int xpc_partition_disengaged(struct xpc_partition *);
910extern enum xp_retval xpc_mark_partition_active(struct xpc_partition *);
911extern void xpc_mark_partition_inactive(struct xpc_partition *);
912extern void xpc_discovery(void);
913extern enum xp_retval xpc_get_remote_rp(int, unsigned long *,
914 struct xpc_rsvd_page *,
915 unsigned long *);
916extern void xpc_deactivate_partition(const int, struct xpc_partition *,
917 enum xp_retval);
918extern enum xp_retval xpc_initiate_partid_to_nasids(short, void *);
919
920
921extern void xpc_initiate_connect(int);
922extern void xpc_initiate_disconnect(int);
923extern enum xp_retval xpc_allocate_msg_wait(struct xpc_channel *);
924extern enum xp_retval xpc_initiate_send(short, int, u32, void *, u16);
925extern enum xp_retval xpc_initiate_send_notify(short, int, u32, void *, u16,
926 xpc_notify_func, void *);
927extern void xpc_initiate_received(short, int, void *);
928extern void xpc_process_sent_chctl_flags(struct xpc_partition *);
929extern void xpc_connected_callout(struct xpc_channel *);
930extern void xpc_deliver_payload(struct xpc_channel *);
931extern void xpc_disconnect_channel(const int, struct xpc_channel *,
932 enum xp_retval, unsigned long *);
933extern void xpc_disconnect_callout(struct xpc_channel *, enum xp_retval);
934extern void xpc_partition_going_down(struct xpc_partition *, enum xp_retval);
935
936static inline void
937xpc_wakeup_channel_mgr(struct xpc_partition *part)
938{
939 if (atomic_inc_return(&part->channel_mgr_requests) == 1)
940 wake_up(&part->channel_mgr_wq);
941}
942
943
944
945
946
947static inline void
948xpc_msgqueue_ref(struct xpc_channel *ch)
949{
950 atomic_inc(&ch->references);
951}
952
953static inline void
954xpc_msgqueue_deref(struct xpc_channel *ch)
955{
956 s32 refs = atomic_dec_return(&ch->references);
957
958 DBUG_ON(refs < 0);
959 if (refs == 0)
960 xpc_wakeup_channel_mgr(&xpc_partitions[ch->partid]);
961}
962
963#define XPC_DISCONNECT_CHANNEL(_ch, _reason, _irqflgs) \
964 xpc_disconnect_channel(__LINE__, _ch, _reason, _irqflgs)
965
966
967
968
969
970static inline void
971xpc_part_deref(struct xpc_partition *part)
972{
973 s32 refs = atomic_dec_return(&part->references);
974
975 DBUG_ON(refs < 0);
976 if (refs == 0 && part->setup_state == XPC_P_SS_WTEARDOWN)
977 wake_up(&part->teardown_wq);
978}
979
980static inline int
981xpc_part_ref(struct xpc_partition *part)
982{
983 int setup;
984
985 atomic_inc(&part->references);
986 setup = (part->setup_state == XPC_P_SS_SETUP);
987 if (!setup)
988 xpc_part_deref(part);
989
990 return setup;
991}
992
993
994
995
996
997
998#define XPC_SET_REASON(_p, _reason, _line) \
999 { \
1000 (_p)->reason = _reason; \
1001 (_p)->reason_line = _line; \
1002 }
1003
1004#endif
1005