0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013 #ifndef _DRIVERS_MISC_SGIXP_XPC_H
0014 #define _DRIVERS_MISC_SGIXP_XPC_H
0015
0016 #include <linux/wait.h>
0017 #include <linux/completion.h>
0018 #include <linux/timer.h>
0019 #include <linux/sched.h>
0020 #include "xp.h"
0021
0022
0023
0024
0025
0026
0027 #define _XPC_VERSION(_maj, _min) (((_maj) << 4) | ((_min) & 0xf))
0028 #define XPC_VERSION_MAJOR(_v) ((_v) >> 4)
0029 #define XPC_VERSION_MINOR(_v) ((_v) & 0xf)
0030
0031
0032 #define XPC_HB_DEFAULT_INTERVAL 5
0033 #define XPC_HB_CHECK_DEFAULT_INTERVAL 20
0034
0035
0036 #define XPC_HB_CHECK_THREAD_NAME "xpc_hb"
0037 #define XPC_HB_CHECK_CPU 0
0038
0039
0040 #define XPC_DISCOVERY_THREAD_NAME "xpc_discovery"
0041
0042
0043
0044
0045
0046
0047
0048
0049
0050
0051
0052
0053
0054
0055
0056
0057
0058
0059
0060
0061
0062
0063
0064
0065
0066
0067
0068
0069
0070
0071
0072
0073
0074
0075
0076
0077
0078
0079
0080
0081
0082 struct xpc_rsvd_page {
0083 u64 SAL_signature;
0084 u64 SAL_version;
0085 short SAL_partid;
0086 short max_npartitions;
0087 u8 version;
0088 u8 pad1[3];
0089 unsigned long ts_jiffies;
0090 union {
0091 struct {
0092 unsigned long heartbeat_gpa;
0093 unsigned long activate_gru_mq_desc_gpa;
0094 } uv;
0095 } sn;
0096 u64 pad2[9];
0097 u64 SAL_nasids_size;
0098 };
0099
0100 #define XPC_RP_VERSION _XPC_VERSION(3, 0)
0101
0102
0103
0104 #define XPC_RP_HEADER_SIZE L1_CACHE_ALIGN(sizeof(struct xpc_rsvd_page))
0105
0106 #define XPC_RP_PART_NASIDS(_rp) ((unsigned long *)((u8 *)(_rp) + \
0107 XPC_RP_HEADER_SIZE))
0108 #define XPC_RP_MACH_NASIDS(_rp) (XPC_RP_PART_NASIDS(_rp) + \
0109 xpc_nasid_mask_nlongs)
0110
0111
0112
0113
0114
0115
0116
0117 struct xpc_heartbeat_uv {
0118 unsigned long value;
0119 unsigned long offline;
0120 };
0121
0122
0123
0124
0125 struct xpc_gru_mq_uv {
0126 void *address;
0127 unsigned int order;
0128 int irq;
0129 int mmr_blade;
0130 unsigned long mmr_offset;
0131 unsigned long mmr_value;
0132 int watchlist_num;
0133 void *gru_mq_desc;
0134 };
0135
0136
0137
0138
0139
0140 struct xpc_activate_mq_msghdr_uv {
0141 unsigned int gru_msg_hdr;
0142 short partid;
0143 u8 act_state;
0144 u8 type;
0145 unsigned long rp_ts_jiffies;
0146 };
0147
0148
0149 #define XPC_ACTIVATE_MQ_MSG_SYNC_ACT_STATE_UV 0
0150
0151 #define XPC_ACTIVATE_MQ_MSG_ACTIVATE_REQ_UV 1
0152 #define XPC_ACTIVATE_MQ_MSG_DEACTIVATE_REQ_UV 2
0153
0154 #define XPC_ACTIVATE_MQ_MSG_CHCTL_CLOSEREQUEST_UV 3
0155 #define XPC_ACTIVATE_MQ_MSG_CHCTL_CLOSEREPLY_UV 4
0156 #define XPC_ACTIVATE_MQ_MSG_CHCTL_OPENREQUEST_UV 5
0157 #define XPC_ACTIVATE_MQ_MSG_CHCTL_OPENREPLY_UV 6
0158 #define XPC_ACTIVATE_MQ_MSG_CHCTL_OPENCOMPLETE_UV 7
0159
0160 #define XPC_ACTIVATE_MQ_MSG_MARK_ENGAGED_UV 8
0161 #define XPC_ACTIVATE_MQ_MSG_MARK_DISENGAGED_UV 9
0162
0163 struct xpc_activate_mq_msg_uv {
0164 struct xpc_activate_mq_msghdr_uv hdr;
0165 };
0166
0167 struct xpc_activate_mq_msg_activate_req_uv {
0168 struct xpc_activate_mq_msghdr_uv hdr;
0169 unsigned long rp_gpa;
0170 unsigned long heartbeat_gpa;
0171 unsigned long activate_gru_mq_desc_gpa;
0172 };
0173
0174 struct xpc_activate_mq_msg_deactivate_req_uv {
0175 struct xpc_activate_mq_msghdr_uv hdr;
0176 enum xp_retval reason;
0177 };
0178
0179 struct xpc_activate_mq_msg_chctl_closerequest_uv {
0180 struct xpc_activate_mq_msghdr_uv hdr;
0181 short ch_number;
0182 enum xp_retval reason;
0183 };
0184
0185 struct xpc_activate_mq_msg_chctl_closereply_uv {
0186 struct xpc_activate_mq_msghdr_uv hdr;
0187 short ch_number;
0188 };
0189
0190 struct xpc_activate_mq_msg_chctl_openrequest_uv {
0191 struct xpc_activate_mq_msghdr_uv hdr;
0192 short ch_number;
0193 short entry_size;
0194 short local_nentries;
0195 };
0196
0197 struct xpc_activate_mq_msg_chctl_openreply_uv {
0198 struct xpc_activate_mq_msghdr_uv hdr;
0199 short ch_number;
0200 short remote_nentries;
0201 short local_nentries;
0202 unsigned long notify_gru_mq_desc_gpa;
0203 };
0204
0205 struct xpc_activate_mq_msg_chctl_opencomplete_uv {
0206 struct xpc_activate_mq_msghdr_uv hdr;
0207 short ch_number;
0208 };
0209
0210
0211
0212
0213
0214
0215
0216 #define XPC_PACK_ARGS(_arg1, _arg2) \
0217 ((((u64)_arg1) & 0xffffffff) | \
0218 ((((u64)_arg2) & 0xffffffff) << 32))
0219
0220 #define XPC_UNPACK_ARG1(_args) (((u64)_args) & 0xffffffff)
0221 #define XPC_UNPACK_ARG2(_args) ((((u64)_args) >> 32) & 0xffffffff)
0222
0223
0224
0225
0226
0227 struct xpc_openclose_args {
0228 u16 reason;
0229 u16 entry_size;
0230 u16 remote_nentries;
0231 u16 local_nentries;
0232 unsigned long local_msgqueue_pa;
0233 };
0234
0235 #define XPC_OPENCLOSE_ARGS_SIZE \
0236 L1_CACHE_ALIGN(sizeof(struct xpc_openclose_args) * \
0237 XPC_MAX_NCHANNELS)
0238
0239
0240
0241
0242
0243
0244 struct xpc_fifo_entry_uv {
0245 struct xpc_fifo_entry_uv *next;
0246 };
0247
0248 struct xpc_fifo_head_uv {
0249 struct xpc_fifo_entry_uv *first;
0250 struct xpc_fifo_entry_uv *last;
0251 spinlock_t lock;
0252 int n_entries;
0253 };
0254
0255
0256
0257
0258
0259
0260
0261
0262
0263
0264
0265 struct xpc_notify_mq_msghdr_uv {
0266 union {
0267 unsigned int gru_msg_hdr;
0268 struct xpc_fifo_entry_uv next;
0269 } u;
0270 short partid;
0271 u8 ch_number;
0272 u8 size;
0273 unsigned int msg_slot_number;
0274 };
0275
0276 struct xpc_notify_mq_msg_uv {
0277 struct xpc_notify_mq_msghdr_uv hdr;
0278 unsigned long payload;
0279 };
0280
0281
0282
0283 #define XPC_N_CALL 0x01
0284
0285
0286
0287
0288
0289 struct xpc_send_msg_slot_uv {
0290 struct xpc_fifo_entry_uv next;
0291 unsigned int msg_slot_number;
0292 xpc_notify_func func;
0293 void *key;
0294 };
0295
0296
0297
0298
0299
0300
0301
0302
0303
0304
0305
0306
0307
0308 struct xpc_channel_uv {
0309 void *cached_notify_gru_mq_desc;
0310
0311
0312 struct xpc_send_msg_slot_uv *send_msg_slots;
0313 void *recv_msg_slots;
0314
0315
0316 struct xpc_fifo_head_uv msg_slot_free_list;
0317 struct xpc_fifo_head_uv recv_msg_list;
0318 };
0319
0320 struct xpc_channel {
0321 short partid;
0322 spinlock_t lock;
0323 unsigned int flags;
0324
0325 enum xp_retval reason;
0326 int reason_line;
0327
0328 u16 number;
0329
0330 u16 entry_size;
0331 u16 local_nentries;
0332 u16 remote_nentries;
0333
0334 atomic_t references;
0335
0336 atomic_t n_on_msg_allocate_wq;
0337 wait_queue_head_t msg_allocate_wq;
0338
0339 u8 delayed_chctl_flags;
0340
0341
0342 atomic_t n_to_notify;
0343
0344 xpc_channel_func func;
0345 void *key;
0346
0347 struct completion wdisconnect_wait;
0348
0349
0350
0351 atomic_t kthreads_assigned;
0352 u32 kthreads_assigned_limit;
0353 atomic_t kthreads_idle;
0354 u32 kthreads_idle_limit;
0355 atomic_t kthreads_active;
0356
0357 wait_queue_head_t idle_wq;
0358
0359 union {
0360 struct xpc_channel_uv uv;
0361 } sn;
0362
0363 } ____cacheline_aligned;
0364
0365
0366
0367 #define XPC_C_WASCONNECTED 0x00000001
0368
0369 #define XPC_C_ROPENCOMPLETE 0x00000002
0370 #define XPC_C_OPENCOMPLETE 0x00000004
0371 #define XPC_C_ROPENREPLY 0x00000008
0372 #define XPC_C_OPENREPLY 0x00000010
0373 #define XPC_C_ROPENREQUEST 0x00000020
0374 #define XPC_C_OPENREQUEST 0x00000040
0375
0376 #define XPC_C_SETUP 0x00000080
0377 #define XPC_C_CONNECTEDCALLOUT 0x00000100
0378 #define XPC_C_CONNECTEDCALLOUT_MADE \
0379 0x00000200
0380 #define XPC_C_CONNECTED 0x00000400
0381 #define XPC_C_CONNECTING 0x00000800
0382
0383 #define XPC_C_RCLOSEREPLY 0x00001000
0384 #define XPC_C_CLOSEREPLY 0x00002000
0385 #define XPC_C_RCLOSEREQUEST 0x00004000
0386 #define XPC_C_CLOSEREQUEST 0x00008000
0387
0388 #define XPC_C_DISCONNECTED 0x00010000
0389 #define XPC_C_DISCONNECTING 0x00020000
0390 #define XPC_C_DISCONNECTINGCALLOUT \
0391 0x00040000
0392 #define XPC_C_DISCONNECTINGCALLOUT_MADE \
0393 0x00080000
0394 #define XPC_C_WDISCONNECT 0x00100000
0395
0396
0397
0398
0399
0400
0401
0402
0403 union xpc_channel_ctl_flags {
0404 u64 all_flags;
0405 u8 flags[XPC_MAX_NCHANNELS];
0406 };
0407
0408
0409 #define XPC_CHCTL_CLOSEREQUEST 0x01
0410 #define XPC_CHCTL_CLOSEREPLY 0x02
0411 #define XPC_CHCTL_OPENREQUEST 0x04
0412 #define XPC_CHCTL_OPENREPLY 0x08
0413 #define XPC_CHCTL_OPENCOMPLETE 0x10
0414 #define XPC_CHCTL_MSGREQUEST 0x20
0415
0416 #define XPC_OPENCLOSE_CHCTL_FLAGS \
0417 (XPC_CHCTL_CLOSEREQUEST | XPC_CHCTL_CLOSEREPLY | \
0418 XPC_CHCTL_OPENREQUEST | XPC_CHCTL_OPENREPLY | \
0419 XPC_CHCTL_OPENCOMPLETE)
0420 #define XPC_MSG_CHCTL_FLAGS XPC_CHCTL_MSGREQUEST
0421
0422 static inline int
0423 xpc_any_openclose_chctl_flags_set(union xpc_channel_ctl_flags *chctl)
0424 {
0425 int ch_number;
0426
0427 for (ch_number = 0; ch_number < XPC_MAX_NCHANNELS; ch_number++) {
0428 if (chctl->flags[ch_number] & XPC_OPENCLOSE_CHCTL_FLAGS)
0429 return 1;
0430 }
0431 return 0;
0432 }
0433
0434 static inline int
0435 xpc_any_msg_chctl_flags_set(union xpc_channel_ctl_flags *chctl)
0436 {
0437 int ch_number;
0438
0439 for (ch_number = 0; ch_number < XPC_MAX_NCHANNELS; ch_number++) {
0440 if (chctl->flags[ch_number] & XPC_MSG_CHCTL_FLAGS)
0441 return 1;
0442 }
0443 return 0;
0444 }
0445
0446 struct xpc_partition_uv {
0447 unsigned long heartbeat_gpa;
0448 struct xpc_heartbeat_uv cached_heartbeat;
0449
0450 unsigned long activate_gru_mq_desc_gpa;
0451
0452
0453 void *cached_activate_gru_mq_desc;
0454
0455 struct mutex cached_activate_gru_mq_desc_mutex;
0456 spinlock_t flags_lock;
0457 unsigned int flags;
0458 u8 remote_act_state;
0459 u8 act_state_req;
0460 enum xp_retval reason;
0461 };
0462
0463
0464
0465 #define XPC_P_CACHED_ACTIVATE_GRU_MQ_DESC_UV 0x00000001
0466 #define XPC_P_ENGAGED_UV 0x00000002
0467
0468
0469
0470 #define XPC_P_ASR_ACTIVATE_UV 0x01
0471 #define XPC_P_ASR_REACTIVATE_UV 0x02
0472 #define XPC_P_ASR_DEACTIVATE_UV 0x03
0473
0474 struct xpc_partition {
0475
0476
0477
0478 u8 remote_rp_version;
0479 unsigned long remote_rp_ts_jiffies;
0480 unsigned long remote_rp_pa;
0481 u64 last_heartbeat;
0482 u32 activate_IRQ_rcvd;
0483 spinlock_t act_lock;
0484 u8 act_state;
0485 enum xp_retval reason;
0486 int reason_line;
0487
0488 unsigned long disengage_timeout;
0489 struct timer_list disengage_timer;
0490
0491
0492
0493 u8 setup_state;
0494 wait_queue_head_t teardown_wq;
0495 atomic_t references;
0496
0497 u8 nchannels;
0498 atomic_t nchannels_active;
0499 atomic_t nchannels_engaged;
0500 struct xpc_channel *channels;
0501
0502
0503
0504 union xpc_channel_ctl_flags chctl;
0505 spinlock_t chctl_lock;
0506
0507 void *remote_openclose_args_base;
0508 struct xpc_openclose_args *remote_openclose_args;
0509
0510
0511
0512
0513 atomic_t channel_mgr_requests;
0514 wait_queue_head_t channel_mgr_wq;
0515
0516 union {
0517 struct xpc_partition_uv uv;
0518 } sn;
0519
0520 } ____cacheline_aligned;
0521
0522 struct xpc_arch_operations {
0523 int (*setup_partitions) (void);
0524 void (*teardown_partitions) (void);
0525 void (*process_activate_IRQ_rcvd) (void);
0526 enum xp_retval (*get_partition_rsvd_page_pa)
0527 (void *, u64 *, unsigned long *, size_t *);
0528 int (*setup_rsvd_page) (struct xpc_rsvd_page *);
0529
0530 void (*allow_hb) (short);
0531 void (*disallow_hb) (short);
0532 void (*disallow_all_hbs) (void);
0533 void (*increment_heartbeat) (void);
0534 void (*offline_heartbeat) (void);
0535 void (*online_heartbeat) (void);
0536 void (*heartbeat_init) (void);
0537 void (*heartbeat_exit) (void);
0538 enum xp_retval (*get_remote_heartbeat) (struct xpc_partition *);
0539
0540 void (*request_partition_activation) (struct xpc_rsvd_page *,
0541 unsigned long, int);
0542 void (*request_partition_reactivation) (struct xpc_partition *);
0543 void (*request_partition_deactivation) (struct xpc_partition *);
0544 void (*cancel_partition_deactivation_request) (struct xpc_partition *);
0545 enum xp_retval (*setup_ch_structures) (struct xpc_partition *);
0546 void (*teardown_ch_structures) (struct xpc_partition *);
0547
0548 enum xp_retval (*make_first_contact) (struct xpc_partition *);
0549
0550 u64 (*get_chctl_all_flags) (struct xpc_partition *);
0551 void (*send_chctl_closerequest) (struct xpc_channel *, unsigned long *);
0552 void (*send_chctl_closereply) (struct xpc_channel *, unsigned long *);
0553 void (*send_chctl_openrequest) (struct xpc_channel *, unsigned long *);
0554 void (*send_chctl_openreply) (struct xpc_channel *, unsigned long *);
0555 void (*send_chctl_opencomplete) (struct xpc_channel *, unsigned long *);
0556 void (*process_msg_chctl_flags) (struct xpc_partition *, int);
0557
0558 enum xp_retval (*save_remote_msgqueue_pa) (struct xpc_channel *,
0559 unsigned long);
0560
0561 enum xp_retval (*setup_msg_structures) (struct xpc_channel *);
0562 void (*teardown_msg_structures) (struct xpc_channel *);
0563
0564 void (*indicate_partition_engaged) (struct xpc_partition *);
0565 void (*indicate_partition_disengaged) (struct xpc_partition *);
0566 void (*assume_partition_disengaged) (short);
0567 int (*partition_engaged) (short);
0568 int (*any_partition_engaged) (void);
0569
0570 int (*n_of_deliverable_payloads) (struct xpc_channel *);
0571 enum xp_retval (*send_payload) (struct xpc_channel *, u32, void *,
0572 u16, u8, xpc_notify_func, void *);
0573 void *(*get_deliverable_payload) (struct xpc_channel *);
0574 void (*received_payload) (struct xpc_channel *, void *);
0575 void (*notify_senders_of_disconnect) (struct xpc_channel *);
0576 };
0577
0578
0579
0580 #define XPC_P_AS_INACTIVE 0x00
0581 #define XPC_P_AS_ACTIVATION_REQ 0x01
0582 #define XPC_P_AS_ACTIVATING 0x02
0583 #define XPC_P_AS_ACTIVE 0x03
0584 #define XPC_P_AS_DEACTIVATING 0x04
0585
0586 #define XPC_DEACTIVATE_PARTITION(_p, _reason) \
0587 xpc_deactivate_partition(__LINE__, (_p), (_reason))
0588
0589
0590
0591 #define XPC_P_SS_UNSET 0x00
0592 #define XPC_P_SS_SETUP 0x01
0593 #define XPC_P_SS_WTEARDOWN 0x02
0594 #define XPC_P_SS_TORNDOWN 0x03
0595
0596
0597 #define XPC_DISENGAGE_DEFAULT_TIMELIMIT 90
0598
0599
0600 #define XPC_DEACTIVATE_PRINTMSG_INTERVAL 10
0601
0602 #define XPC_PARTID(_p) ((short)((_p) - &xpc_partitions[0]))
0603
0604
0605 extern struct xpc_registration xpc_registrations[];
0606
0607
0608 extern struct device *xpc_part;
0609 extern struct device *xpc_chan;
0610 extern struct xpc_arch_operations xpc_arch_ops;
0611 extern int xpc_disengage_timelimit;
0612 extern int xpc_disengage_timedout;
0613 extern int xpc_activate_IRQ_rcvd;
0614 extern spinlock_t xpc_activate_IRQ_rcvd_lock;
0615 extern wait_queue_head_t xpc_activate_IRQ_wq;
0616 extern void *xpc_kzalloc_cacheline_aligned(size_t, gfp_t, void **);
0617 extern void xpc_activate_partition(struct xpc_partition *);
0618 extern void xpc_activate_kthreads(struct xpc_channel *, int);
0619 extern void xpc_create_kthreads(struct xpc_channel *, int, int);
0620 extern void xpc_disconnect_wait(int);
0621
0622
0623 extern int xpc_init_uv(void);
0624 extern void xpc_exit_uv(void);
0625
0626
0627 extern int xpc_exiting;
0628 extern int xpc_nasid_mask_nlongs;
0629 extern struct xpc_rsvd_page *xpc_rsvd_page;
0630 extern unsigned long *xpc_mach_nasids;
0631 extern struct xpc_partition *xpc_partitions;
0632 extern void *xpc_kmalloc_cacheline_aligned(size_t, gfp_t, void **);
0633 extern int xpc_setup_rsvd_page(void);
0634 extern void xpc_teardown_rsvd_page(void);
0635 extern int xpc_identify_activate_IRQ_sender(void);
0636 extern int xpc_partition_disengaged(struct xpc_partition *);
0637 extern int xpc_partition_disengaged_from_timer(struct xpc_partition *part);
0638 extern enum xp_retval xpc_mark_partition_active(struct xpc_partition *);
0639 extern void xpc_mark_partition_inactive(struct xpc_partition *);
0640 extern void xpc_discovery(void);
0641 extern enum xp_retval xpc_get_remote_rp(int, unsigned long *,
0642 struct xpc_rsvd_page *,
0643 unsigned long *);
0644 extern void xpc_deactivate_partition(const int, struct xpc_partition *,
0645 enum xp_retval);
0646 extern enum xp_retval xpc_initiate_partid_to_nasids(short, void *);
0647
0648
0649 extern void xpc_initiate_connect(int);
0650 extern void xpc_initiate_disconnect(int);
0651 extern enum xp_retval xpc_allocate_msg_wait(struct xpc_channel *);
0652 extern enum xp_retval xpc_initiate_send(short, int, u32, void *, u16);
0653 extern enum xp_retval xpc_initiate_send_notify(short, int, u32, void *, u16,
0654 xpc_notify_func, void *);
0655 extern void xpc_initiate_received(short, int, void *);
0656 extern void xpc_process_sent_chctl_flags(struct xpc_partition *);
0657 extern void xpc_connected_callout(struct xpc_channel *);
0658 extern void xpc_deliver_payload(struct xpc_channel *);
0659 extern void xpc_disconnect_channel(const int, struct xpc_channel *,
0660 enum xp_retval, unsigned long *);
0661 extern void xpc_disconnect_callout(struct xpc_channel *, enum xp_retval);
0662 extern void xpc_partition_going_down(struct xpc_partition *, enum xp_retval);
0663
0664 static inline void
0665 xpc_wakeup_channel_mgr(struct xpc_partition *part)
0666 {
0667 if (atomic_inc_return(&part->channel_mgr_requests) == 1)
0668 wake_up(&part->channel_mgr_wq);
0669 }
0670
0671
0672
0673
0674
0675 static inline void
0676 xpc_msgqueue_ref(struct xpc_channel *ch)
0677 {
0678 atomic_inc(&ch->references);
0679 }
0680
0681 static inline void
0682 xpc_msgqueue_deref(struct xpc_channel *ch)
0683 {
0684 s32 refs = atomic_dec_return(&ch->references);
0685
0686 DBUG_ON(refs < 0);
0687 if (refs == 0)
0688 xpc_wakeup_channel_mgr(&xpc_partitions[ch->partid]);
0689 }
0690
0691 #define XPC_DISCONNECT_CHANNEL(_ch, _reason, _irqflgs) \
0692 xpc_disconnect_channel(__LINE__, _ch, _reason, _irqflgs)
0693
0694
0695
0696
0697
0698 static inline void
0699 xpc_part_deref(struct xpc_partition *part)
0700 {
0701 s32 refs = atomic_dec_return(&part->references);
0702
0703 DBUG_ON(refs < 0);
0704 if (refs == 0 && part->setup_state == XPC_P_SS_WTEARDOWN)
0705 wake_up(&part->teardown_wq);
0706 }
0707
0708 static inline int
0709 xpc_part_ref(struct xpc_partition *part)
0710 {
0711 int setup;
0712
0713 atomic_inc(&part->references);
0714 setup = (part->setup_state == XPC_P_SS_SETUP);
0715 if (!setup)
0716 xpc_part_deref(part);
0717
0718 return setup;
0719 }
0720
0721
0722
0723
0724
0725
0726 #define XPC_SET_REASON(_p, _reason, _line) \
0727 { \
0728 (_p)->reason = _reason; \
0729 (_p)->reason_line = _line; \
0730 }
0731
0732 #endif