Modules/UDI - PIO and better instance startup
[tpg/acess2.git] / KernelLand / Modules / Interfaces / UDI / udi_lib / core / imc.c
1 /**
2  * \file imc.c
3  * \author John Hodge (thePowersGang)
4  */
5 #define DEBUG   1
6 #include <udi.h>
7 #include <acess.h>
8 #include <udi_internal.h>
9 #include <udi_internal_ma.h>
10
11 // === EXPORTS ===
12 EXPORT(udi_channel_anchor);
13 EXPORT(udi_channel_spawn);
14 EXPORT(udi_channel_set_context);
15 EXPORT(udi_channel_op_abort);
16 EXPORT(udi_channel_close);
17 EXPORT(udi_channel_event_ind);
18 EXPORT(udi_channel_event_complete);
19
20 // === CODE ===
21 /**
22  */
23 void udi_channel_anchor(
24         udi_channel_anchor_call_t *callback, udi_cb_t *gcb,
25         udi_channel_t channel, udi_index_t ops_idx, void *channel_context
26         )
27 {
28         UNIMPLEMENTED();
29 }
30
31 /**
32  */
33 extern void udi_channel_spawn(
34         udi_channel_spawn_call_t *callback, udi_cb_t *gcb,
35         udi_channel_t channel, udi_index_t spawn_idx,
36         udi_index_t ops_idx, void *channel_context
37         )
38 {
39         LOG("gcb=%p,channel=%p", gcb, channel, spawn_idx, ops_idx, channel_context);
40         
41         // Search existing channel for a matching spawn_idx
42         udi_channel_t ret = UDI_CreateChannel_Linked(channel, spawn_idx);
43
44         // Bind local end of channel to ops_idx (with channel_context)
45         if( ops_idx != 0 )
46         {
47                 udi_index_t     region_idx;
48                 tUDI_DriverInstance     *inst = UDI_int_ChannelGetInstance(gcb, false, &region_idx);
49                 UDI_BindChannel(ret, false, inst, ops_idx, region_idx, channel_context, false,0);
50         }
51         else
52         {
53                 // leave unbound
54         }
55
56         callback(gcb, ret);
57 }
58
59 /**
60  * 
61  */
62 void udi_channel_set_context(
63         udi_channel_t target_channel, void *channel_context
64         )
65 {
66         LOG("target_channel=%p,channel_context=%p", target_channel, channel_context);
67         UDI_int_ChannelSetContext(target_channel, channel_context);
68 }
69
70 void udi_channel_op_abort(
71         udi_channel_t target_channel, udi_cb_t *orig_cb
72         )
73 {
74         udi_channel_event_cb_t cb;
75         cb.gcb.channel = target_channel;
76         cb.event = UDI_CHANNEL_CLOSED;
77         cb.params.orig_cb = orig_cb;
78         udi_channel_event_ind(&cb);
79 }
80
81 void udi_channel_close(udi_channel_t channel)
82 {
83         Warning("%s Unimplemented", __func__);
84 }
85
86 void udi_channel_event_ind(udi_channel_event_cb_t *cb)
87 {
88         LOG("cb=%p{...}", cb);
89         const struct {
90                 udi_channel_event_ind_op_t *channel_event_ind_op;
91         } *ops = UDI_int_ChannelPrepForCall( UDI_GCB(cb), NULL, 0 );
92         if(!ops) {
93                 Log_Warning("UDI", "udi_channel_event_ind on wrong channel type");
94                 return ;
95         }
96
97         // UDI_int_MakeDeferredCb( UDI_GCB(cb), ops->channel_event_ind_op );
98
99         UDI_int_ChannelReleaseFromCall( UDI_GCB(cb) );  
100         ops->channel_event_ind_op(cb);
101 }
102
103 void udi_channel_event_complete(udi_channel_event_cb_t *cb, udi_status_t status)
104 {
105         LOG("cb=%p,status=%i", cb, status);
106         UDI_MA_TransitionState( UDI_GCB(cb)->initiator_context, UDI_MASTATE_PARENTBIND, UDI_MASTATE_ENUMCHILDREN );
107         udi_cb_free( UDI_GCB(cb) );
108 }

UCC git Repository :: git.ucc.asn.au