3 * - By John Hodge (thePowersGang)
5 * udi_lib/physio/meta_bus.c
6 * - Bus Bridge Metalanguage
10 #include <udi_physio.h>
12 #include <udi_internal.h>
16 #define udi_mei_info udi_meta_info__bridge
18 extern tUDI_MetaLang cMetaLang_BusBridge;
19 extern udi_mei_init_t udi_meta_info__bridge;
22 EXPORT(udi_bus_bind_req);
23 EXPORT(udi_bus_bind_ack);
24 EXPORT(udi_bus_unbind_req);
25 EXPORT(udi_bus_unbind_ack);
26 EXPORT(udi_intr_attach_req);
27 EXPORT(udi_intr_attach_ack);
28 EXPORT(udi_intr_attach_ack_unused);
29 EXPORT(udi_intr_detach_req);
30 EXPORT(udi_intr_detach_ack);
31 EXPORT(udi_intr_detach_ack_unused);
32 EXPORT(udi_intr_event_ind);
33 EXPORT(udi_intr_event_rdy);
35 #define PREP_OPS(type,ml,num) const type *ops = UDI_int_ChannelPrepForCall(UDI_GCB(cb), ml, num); \
36 if(!ops) { Log_Warning("UDI", "%s on wrong channel type", __func__); return ; }
38 #define PREP_OPS_DEVICE const udi_bus_device_ops_t *ops = UDI_int_ChannelPrepForCall( UDI_GCB(cb), &cMetaLang_BusBridge, UDI_BUS_DEVICE_OPS_NUM ); \
39 if(!ops) { Log_Warning("UDI", "%s on wrong channel type", __func__); return ; }
43 void udi_bus_unbind_req(udi_bus_bind_cb_t *cb)
47 void udi_bus_unbind_ack(udi_bus_bind_cb_t *cb)
52 void udi_bus_bind_req(udi_bus_bind_cb_t *cb)
54 LOG("cb=%p{...}", cb);
55 PREP_OPS(udi_bus_bridge_ops_t, &cMetaLang_BusBridge, UDI_BUS_BRIDGE_OPS_NUM)
57 UDI_int_MakeDeferredCb( UDI_GCB(cb), (udi_op_t*)ops->bus_bind_req_op );
60 struct marshalled_bus_bind_ack
62 tUDI_DeferredCall Call;
63 udi_dma_constraints_t dma_constraints;
64 udi_ubit8_t preferred_endianness;
68 static void _unmarshal_bus_bind_ack(tUDI_DeferredCall *Call)
71 struct marshalled_bus_bind_ack *info = (void*)Call;
72 UDI_int_ChannelReleaseFromCall( Call->cb );
73 ((udi_bus_bind_ack_op_t*)Call->Handler)(
74 UDI_MCB(Call->cb, udi_bus_bind_cb_t),
75 info->dma_constraints,
76 info->preferred_endianness,
81 void udi_bus_bind_ack(
82 udi_bus_bind_cb_t *cb,
83 udi_dma_constraints_t dma_constraints,
84 udi_ubit8_t preferred_endianness,
88 LOG("cb=%p{...}, dma_constraints=%p, preferred_endianness=%i,status=%i",
89 cb, dma_constraints, preferred_endianness, status);
90 PREP_OPS(udi_bus_device_ops_t, &cMetaLang_BusBridge, UDI_BUS_DEVICE_OPS_NUM)
92 struct marshalled_bus_bind_ack *call = NEW(struct marshalled_bus_bind_ack,);
93 call->Call.Unmarshal = _unmarshal_bus_bind_ack;
94 call->Call.cb = UDI_GCB(cb);
95 call->Call.Handler = (udi_op_t*)ops->bus_bind_ack_op;
96 call->dma_constraints = dma_constraints;
97 call->preferred_endianness = preferred_endianness;
98 call->status = status;
99 UDI_int_AddDeferred(&call->Call);
102 void udi_intr_attach_req(udi_intr_attach_cb_t *cb)
105 PREP_OPS(udi_bus_bridge_ops_t, &cMetaLang_BusBridge, UDI_BUS_BRIDGE_OPS_NUM)
106 UDI_int_MakeDeferredCb( UDI_GCB(cb), (udi_op_t*)ops->intr_attach_req_op );
108 void udi_intr_attach_ack(udi_intr_attach_cb_t *cb, udi_status_t status)
110 LOG("cb=%p,status=%i", cb, status);
111 PREP_OPS(udi_bus_device_ops_t, &cMetaLang_BusBridge, UDI_BUS_DEVICE_OPS_NUM)
112 UDI_int_MakeDeferredCbS( UDI_GCB(cb), (udi_op_t*)ops->intr_attach_ack_op, status );
115 void udi_intr_detach_req(udi_intr_detach_cb_t *cb)
118 PREP_OPS(udi_bus_bridge_ops_t, &cMetaLang_BusBridge, UDI_BUS_BRIDGE_OPS_NUM)
119 UDI_int_MakeDeferredCb( UDI_GCB(cb), (udi_op_t*)ops->intr_detach_req_op );
121 void udi_intr_detach_ack(udi_intr_detach_cb_t *cb)
124 PREP_OPS(udi_bus_device_ops_t, &cMetaLang_BusBridge, UDI_BUS_DEVICE_OPS_NUM)
125 UDI_int_MakeDeferredCb( UDI_GCB(cb), (udi_op_t*)ops->intr_detach_ack_op );
129 void udi_intr_event_ind(udi_intr_event_cb_t *cb, udi_ubit8_t flags)
131 LOG("cb=%p,flags=0x%x", cb, flags);
132 PREP_OPS(udi_intr_handler_ops_t, &cMetaLang_BusBridge, UDI_BUS_INTR_HANDLER_OPS_NUM)
133 UDI_int_MakeDeferredCbU8( UDI_GCB(cb), (udi_op_t*)ops->intr_event_ind_op, flags );
136 void udi_intr_event_rdy(udi_intr_event_cb_t *cb)
139 PREP_OPS(udi_intr_dispatcher_ops_t, &cMetaLang_BusBridge, UDI_BUS_INTR_DISPATCH_OPS_NUM)
140 UDI_int_MakeDeferredCb( UDI_GCB(cb), (udi_op_t*)ops->intr_event_rdy_op );
143 void udi_intr_attach_ack_unused(udi_intr_attach_cb_t *intr_attach_cb, udi_status_t status)
145 Log_Error("UDI", "Driver %s caused %s to be called",
146 UDI_int_ChannelGetInstance(UDI_GCB(intr_attach_cb), false, NULL)->Module->ModuleName,
149 void udi_intr_detach_ack_unused(udi_intr_detach_cb_t *intr_detach_cb)
151 Log_Error("UDI", "Driver %s caused %s to be called",
152 UDI_int_ChannelGetInstance(UDI_GCB(intr_detach_cb), false, NULL)->Module->ModuleName,
157 UDI_MEI_STUBS(udi_bus_bind_ack, udi_bus_bind_cb_t, 3,
158 (dma_constraints, preferred_endianness, status ),
159 (udi_dma_constraints_t, udi_ubit8_t, udi_status_t),
160 (UDI_VA_POINTER, UDI_VA_UBIT8_T, UDI_VA_STATUS_T),
161 UDI_BUS_DEVICE_OPS_NUM, 1)
162 UDI_MEI_STUBS(udi_bus_unbind_ack, udi_bus_bind_cb_t, 0,
164 UDI_BUS_DEVICE_OPS_NUM, 2)
165 UDI_MEI_STUBS(udi_intr_attach_ack, udi_intr_attach_cb_t, 1,
166 (status), (udi_status_t), (UDI_VA_STATUS_T),
167 UDI_BUS_DEVICE_OPS_NUM, 3)
168 UDI_MEI_STUBS(udi_intr_detach_ack, udi_intr_detach_cb_t, 0,
170 UDI_BUS_DEVICE_OPS_NUM, 4)
172 UDI_MEI_STUBS(udi_bus_bind_req, udi_bus_bind_cb_t, 0,
174 UDI_BUS_BRIDGE_OPS_NUM, 1)
175 UDI_MEI_STUBS(udi_bus_unbind_req, udi_bus_bind_cb_t, 0,
177 UDI_BUS_BRIDGE_OPS_NUM, 2)
178 UDI_MEI_STUBS(udi_intr_attach_req, udi_intr_attach_cb_t, 0,
180 UDI_BUS_BRIDGE_OPS_NUM, 3)
181 UDI_MEI_STUBS(udi_intr_detach_req, udi_intr_detach_cb_t, 0,
183 UDI_BUS_BRIDGE_OPS_NUM, 4)
188 udi_layout_t udi_meta_info__bridge__bus_bind_cb[] = {
191 udi_layout_t udi_meta_info__bridge__intr_attach_cb[] = {
197 udi_layout_t udi_meta_info__bridge__intr_detach_cb[] = {
201 udi_layout_t udi_meta_info__bridge__intr_event_cb[] = {
205 udi_layout_t _BUS_BIND_cb_layout[] = {
210 udi_layout_t _noargs_marshal[] = {
213 udi_layout_t _bus_bind_ack_marshal[] = {
214 UDI_DL_DMA_CONSTRAINTS_T,
219 udi_layout_t _udi_intr_attach_ack_marshal[] = {
224 #define UDI__OPS_NUM 0
225 #define MEI_OPINFO(name,cat,flags,cbtype,rsp_ops,rsp_idx,err_ops,err_idx) \
226 {#name, UDI_MEI_OPCAT_##cat,flags,UDI_##cbtype##_CB_NUM, \
227 UDI_##rsp_ops##_OPS_NUM,rsp_idx,UDI_##err_ops##_OPS_NUM,err_idx, \
228 name##_direct, name##_backend, _##cbtype##_cb_layout, _##name##_marshal_layout }
230 udi_mei_op_template_t udi_meta_info__bridge__bus_ops[] = {
231 #define _udi_bus_bind_req_marshal_layout _noargs_marshal
232 MEI_OPINFO(udi_bus_bind_req, REQ, 0, BUS_BIND, BUS_DEVICE,1, ,0),
233 // {"udi_bus_bind_req", UDI_MEI_OPCAT_REQ, 0, UDI_BUS_BIND_CB_NUM, UDI_BUS_DEVICE_OPS_NUM,1, 0,0,
234 // udi_bus_bind_req_direct, udi_bus_bind_req_backend, udi_meta_info__bridge__bus_bind_cb,
236 {"udi_bus_unbind_req", UDI_MEI_OPCAT_REQ, 0, UDI_BUS_BIND_CB_NUM, UDI_BUS_DEVICE_OPS_NUM,2, 0,0,
237 udi_bus_unbind_req_direct, udi_bus_unbind_req_backend, udi_meta_info__bridge__bus_bind_cb,
239 {"udi_intr_attach_req", UDI_MEI_OPCAT_REQ, 0, UDI_BUS_INTR_ATTACH_CB_NUM, UDI_BUS_DEVICE_OPS_NUM,3, 0,0,
240 udi_intr_attach_req_direct, udi_intr_attach_req_backend, udi_meta_info__bridge__intr_attach_cb,
242 {"udi_intr_detach_req", UDI_MEI_OPCAT_REQ, 0, UDI_BUS_INTR_DETACH_CB_NUM, UDI_BUS_DEVICE_OPS_NUM,4, 0,0,
243 udi_intr_detach_req_direct, udi_intr_detach_req_backend, udi_meta_info__bridge__intr_detach_cb,
247 udi_mei_op_template_t udi_meta_info__bridge__device_ops[] = {
248 {"udi_bus_bind_ack", UDI_MEI_OPCAT_ACK, 0, UDI_BUS_BIND_CB_NUM, 0,0, 0,0,
249 udi_bus_bind_ack_direct, udi_bus_bind_ack_backend, udi_meta_info__bridge__bus_bind_cb,
250 _bus_bind_ack_marshal},
251 {"udi_bus_unbind_ack", UDI_MEI_OPCAT_ACK, 0, UDI_BUS_BIND_CB_NUM, 0,0, 0,0,
252 udi_bus_unbind_ack_direct, udi_bus_unbind_ack_backend, udi_meta_info__bridge__bus_bind_cb,
254 {"udi_intr_attach_ack", UDI_MEI_OPCAT_ACK, 0, UDI_BUS_INTR_ATTACH_CB_NUM, 0,0, 0,0,
255 udi_intr_attach_ack_direct, udi_intr_attach_ack_backend, udi_meta_info__bridge__intr_attach_cb,
256 _udi_intr_attach_ack_marshal},
257 {"udi_intr_detach_ack", UDI_MEI_OPCAT_ACK, 0, UDI_BUS_INTR_DETACH_CB_NUM, 0,0, 0,0,
258 udi_intr_detach_ack_direct, udi_intr_detach_ack_backend, udi_meta_info__bridge__intr_detach_cb,
262 udi_mei_ops_vec_template_t udi_meta_info__bridge_ops[] = {
263 {UDI_BUS_BRIDGE_OPS_NUM, UDI_MEI_REL_EXTERNAL|UDI_MEI_REL_BIND, udi_meta_info__bridge__bus_ops},
264 {UDI_BUS_DEVICE_OPS_NUM, UDI_MEI_REL_EXTERNAL|UDI_MEI_REL_BIND, udi_meta_info__bridge__device_ops},
267 udi_mei_init_t udi_meta_info__bridge = {
268 udi_meta_info__bridge_ops,
272 tUDI_MetaLang cMetaLang_BusBridge = {
275 &udi_meta_info__bridge,
283 {sizeof(udi_bus_bind_cb_t), 0, udi_meta_info__bridge__bus_bind_cb},
284 {sizeof(udi_intr_attach_cb_t), 0, udi_meta_info__bridge__intr_attach_cb},
285 {sizeof(udi_intr_detach_cb_t), 0, udi_meta_info__bridge__intr_detach_cb},
286 {sizeof(udi_intr_event_cb_t), 0, NULL}