3 * - By John Hodge (thePowersGang)
6 * - Metalanguage-to-Environment Interface
11 typedef const struct udi_mei_init_s udi_mei_init_t;
12 typedef const struct udi_mei_ops_vec_template_s udi_mei_ops_vec_template_t;
13 typedef const struct uid_mei_op_template_s udi_mei_op_template_t;
15 typedef udi_ubit8_t udi_mei_enumeration_rank_func_t(udi_ubit32_t attr_device_match, void **attr_value_list);
16 typedef void udi_mei_direct_stub_t(udi_op_t *op, udi_cb_t *gcb, va_list arglist);
17 typedef void udi_mei_backend_stub_t(udi_op_t *op, udi_cb_t *gcb, void *marshal_space);
21 udi_mei_ops_vec_template_t *ops_vec_template_list;
22 udi_mei_enumeration_rank_func_t *mei_enumeration_rank;
25 struct udi_mei_ops_vec_template_s
27 udi_index_t meta_ops_num;
28 udi_ubit8_t relationship;
29 const udi_mei_op_template_t *op_template_list;
31 // Flags for `relationship`
32 #define UDI_MEI_REL_INITIATOR (1U<<0)
33 #define UDI_MEI_REL_BIND (1U<<1)
34 #define UDI_MEI_REL_EXTERNAL (1U<<2)
35 #define UDI_MEI_REL_INTERNAL (1U<<3)
36 #define UDI_MEI_REL_SINGLE (1U<<4)
38 struct uid_mei_op_template_s
41 udi_ubit8_t op_category;
43 udi_index_t meta_cb_num;
44 udi_index_t completion_ops_num;
45 udi_index_t completion_vec_idx;
46 udi_index_t exception_ops_num;
47 udi_index_t exception_vec_idx;
48 udi_mei_direct_stub_t *direct_stub;
49 udi_mei_backend_stub_t *backend_stub;
50 udi_layout_t *visible_layout;
51 udi_layout_t *marshal_layout;
53 /* Values for op_category */
54 #define UDI_MEI_OPCAT_REQ 1
55 #define UDI_MEI_OPCAT_ACK 2
56 #define UDI_MEI_OPCAT_NAK 3
57 #define UDI_MEI_OPCAT_IND 4
58 #define UDI_MEI_OPCAT_RES 5
59 #define UDI_MEI_OPCAT_RDY 6
60 /* Values for op_flags */
61 #define UDI_MEI_OP_ABORTABLE (1U<<0)
62 #define UDI_MEI_OP_RECOVERABLE (1U<<1)
63 #define UDI_MEI_OP_STATE_CHANGE (1U<<2)
64 /* Maximum Sizes For Control Block Layouts */
65 #define UDI_MEI_MAX_VISIBLE_SIZE 2000
66 #define UDI_MEI_MAX_MARSHAL_SIZE 4000
69 extern void udi_mei_call(udi_cb_t *gcb, udi_mei_init_t *meta_info, udi_index_t meta_ops_num, udi_index_t vec_idx, ...);
71 #define _UDI_MEI_FIRST(lst, ...) lst
72 #define _UDI_MEI_OTHER(lst, ...) (__VA_ARGS__)
73 #define _UDI_MEI_VARG(type,name,vatype) \
74 type name = UDI_VA_ARG(arglist, type, vatype);
75 #define _UDI_MEI_VARGS0(argt,args,argva)
76 #define _UDI_MEI_VARGS1(argt,args,argva) \
77 _UDI_MEI_VARG(_UDI_MEI_FIRST argt, _UDI_MEI_FIRST args, _UDI_MEI_FIRST argva)
78 #define _UDI_MEI_VARGS2(argt,args,argva) \
79 _UDI_MEI_VARG(_UDI_MEI_FIRST argt, _UDI_MEI_FIRST args,_UDI_MEI_FIRST argva ) \
80 _UDI_MEI_VARGS1( _UDI_MEI_OTHER argt, _UDI_MEI_OTHER args, _UDI_MEI_OTHER argva )
81 #define _UDI_MEI_VARGS3(argt,args,argva) \
82 _UDI_MEI_VARG(_UDI_MEI_FIRST argt, _UDI_MEI_FIRST args, _UDI_MEI_FIRST argva) \
83 _UDI_MEI_VARGS2( _UDI_MEI_OTHER argt, _UDI_MEI_OTHER args, _UDI_MEI_OTHER argva )
85 #define _UDI_MEI_ARG_LIST0(t,a)
86 #define _UDI_MEI_ARG_LIST1(t,a) , _UDI_MEI_FIRST t _UDI_MEI_FIRST a
87 #define _UDI_MEI_ARG_LIST2(t,a) , _UDI_MEI_FIRST t _UDI_MEI_FIRST a \
88 _UDI_MEI_ARG_LIST1(_UDI_MEI_OTHER t, _UDI_MEI_OTHER a)
89 #define _UDI_MEI_ARG_LIST3(t,a) , _UDI_MEI_FIRST t _UDI_MEI_FIRST a \
90 _UDI_MEI_ARG_LIST2(_UDI_MEI_OTHER t, _UDI_MEI_OTHER a)
92 #define _UDI_MEI_MARG_LIST0(t,a)
93 #define _UDI_MEI_MARG_LIST1(t,a) _UDI_MEI_FIRST t _UDI_MEI_FIRST a;
94 #define _UDI_MEI_MARG_LIST2(t,a) _UDI_MEI_FIRST t _UDI_MEI_FIRST a; \
95 _UDI_MEI_MARG_LIST1(_UDI_MEI_OTHER t, _UDI_MEI_OTHER a)
96 #define _UDI_MEI_MARG_LIST3(t,a) _UDI_MEI_FIRST t _UDI_MEI_FIRST a; \
97 _UDI_MEI_MARG_LIST2(_UDI_MEI_OTHER t, _UDI_MEI_OTHER a)
99 #define _UDI_ARG_LIST_0()
100 #define _UDI_ARG_LIST_1(a) ,a
101 #define _UDI_ARG_LIST_2(a,b) ,a,b
102 #define _UDI_ARG_LIST_3(a,b,c) ,a,b,c
104 #define _UDI_MARG_LIST_0()
105 #define _UDI_MARG_LIST_1(a) ,m->a
106 #define _UDI_MARG_LIST_2(a,b) ,m->a,m->b
107 #define _UDI_MARG_LIST_3(a,b,c) ,m->a,m->b,m->c
109 #define _UDI_MEI_NZ_0(...)
110 #define _UDI_MEI_NZ_1(...) __VA_ARGS__
111 #define _UDI_MEI_NZ_2(...) __VA_ARGS__
112 #define _UDI_MEI_NZ_3(...) __VA_ARGS__
114 #define UDI_MEI_STUBS(op_name, cb_type, argc, args, arg_types, arg_va_list, meta_ops_num, vec_idx) \
115 void op_name(cb_type *cb _UDI_MEI_ARG_LIST##argc(arg_types, args) ) {\
116 udi_mei_call(UDI_GCB(cb), &udi_mei_info, meta_ops_num, vec_idx _UDI_ARG_LIST_##argc args);\
118 void op_name##_direct(udi_op_t *op, udi_cb_t *gcb, va_list arglist) {\
119 _UDI_MEI_VARGS##argc(arg_types, args, arg_va_list)\
120 (*(op_name##_op_t*)op)(UDI_MCB(gcb, cb_type) _UDI_ARG_LIST_##argc args);\
122 void op_name##_backend(udi_op_t *op, udi_cb_t *gcb, void *marshal_space) {\
123 _UDI_MEI_NZ_##argc( struct { _UDI_MEI_MARG_LIST##argc(arg_types, args) } __attribute__((packed)) *m = marshal_space; )\
124 (*(op_name##_op_t*)op)(UDI_MCB(gcb, cb_type) _UDI_MARG_LIST_##argc args);\