Modules/UDI - Buffer delete, chained CB support
[tpg/acess2.git] / KernelLand / Modules / Interfaces / UDI / udi_lib / core / meta_mgmt.c
1 /**
2  * \file meta_mgmt.c
3  * \author John Hodge (thePowersGang)
4  */
5 #define DEBUG   0
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_usage_ind);
13 EXPORT(udi_static_usage);
14 EXPORT(udi_usage_res);
15 EXPORT(udi_enumerate_req);
16 EXPORT(udi_enumerate_no_children);
17 EXPORT(udi_enumerate_ack);
18 EXPORT(udi_devmgmt_req);
19 EXPORT(udi_devmgmt_ack);
20 EXPORT(udi_final_cleanup_req);
21 EXPORT(udi_final_cleanup_ack);
22
23 tUDI_MetaLang   cMetaLang_Management = {
24         "udi_mgmt",
25         NULL,
26         3,
27         {
28                 {sizeof(udi_enumerate_cb_t),     0, NULL},
29                 {sizeof(udi_usage_cb_t),         0, NULL},
30                 {sizeof(udi_channel_event_cb_t), 0, NULL},
31         }
32 };
33
34 // === CODE ===
35 void udi_usage_ind(udi_usage_cb_t *cb, udi_ubit8_t resource_level)
36 {
37         LOG("cb=%p{...}, resource_level=%i", cb, resource_level);
38         const udi_mgmt_ops_t *ops = UDI_int_ChannelPrepForCall( UDI_GCB(cb), &cMetaLang_Management, 0 );
39         if(!ops) {
40                 Log_Warning("UDI", "%s on wrong channel type", __func__);
41                 return ;
42         }
43
44         // Non-deferred because it's usually called with a stack allocated cb   
45         UDI_int_ChannelReleaseFromCall( UDI_GCB(cb) );
46         ops->usage_ind_op(cb, resource_level);
47 }
48
49 void udi_static_usage(udi_usage_cb_t *cb, udi_ubit8_t resource_level)
50 {
51         cb->trace_mask = 0;
52         udi_usage_res(cb);
53 }
54
55 void udi_usage_res(udi_usage_cb_t *cb)
56 {
57         // TODO: Update trace mask from cb
58         LOG("cb=%p{cb->trace_mask=%x}", cb, cb->trace_mask);
59         UDI_MA_TransitionState(UDI_GCB(cb)->initiator_context, UDI_MASTATE_USAGEIND, UDI_MASTATE_SECBIND);
60         udi_cb_free( UDI_GCB(cb) );
61 }
62
63 void udi_enumerate_req(udi_enumerate_cb_t *cb, udi_ubit8_t enumeration_level)
64 {
65         LOG("cb=%p{...}, enumeration_level=%i", cb, enumeration_level);
66         const udi_mgmt_ops_t *ops = UDI_int_ChannelPrepForCall( UDI_GCB(cb), &cMetaLang_Management, 0 );
67         if(!ops) {
68                 Log_Warning("UDI", "%s on wrong channel type", __func__);
69                 return ;
70         }
71         
72         UDI_int_MakeDeferredCbU8( UDI_GCB(cb), (udi_op_t*)ops->enumerate_req_op, enumeration_level );
73 }
74
75 void udi_enumerate_no_children(udi_enumerate_cb_t *cb, udi_ubit8_t enumeration_level)
76 {
77         udi_enumerate_ack(cb, UDI_ENUMERATE_LEAF, 0);
78 }
79
80 void udi_enumerate_ack(udi_enumerate_cb_t *cb, udi_ubit8_t enumeration_result, udi_index_t ops_idx)
81 {
82         UDI_int_ChannelFlip( UDI_GCB(cb) );
83         LOG("cb=%p, enumeration_result=%i, ops_idx=%i", cb, enumeration_result, ops_idx);
84         switch( enumeration_result )
85         {
86         case UDI_ENUMERATE_OK:
87                 #if DEBUG && 0
88                 for( int i = 0; i < cb->attr_valid_length; i ++ )
89                 {
90                         udi_instance_attr_list_t        *at = &cb->attr_list[i];
91                         switch(at->attr_type)
92                         {
93                         case UDI_ATTR_STRING:
94                                 LOG("[%i] %s String '%.*s'", i, at->attr_name,
95                                         at->attr_length, at->attr_value);
96                                 break;
97                         case UDI_ATTR_UBIT32:
98                                 LOG("[%i] %s UBit32 0x%08x", i, at->attr_name,
99                                         UDI_ATTR32_GET(at->attr_value));
100                                 break;
101                         default:
102                                 LOG("[%i] %s %i", i, at->attr_name,
103                                         at->attr_type);
104                                 break;
105                         }
106                 }
107                 #endif
108                 // Returned a device
109                 UDI_MA_AddChild(cb, ops_idx);
110                 udi_enumerate_req(cb, UDI_ENUMERATE_NEXT);
111                 return ;
112         case UDI_ENUMERATE_LEAF:
113         case UDI_ENUMERATE_DONE:
114                 // All done. Chain terminates
115                 UDI_MA_TransitionState(UDI_GCB(cb)->initiator_context,
116                         UDI_MASTATE_ENUMCHILDREN, UDI_MASTATE_ACTIVE);
117                 udi_cb_free( UDI_GCB(cb) );
118                 return ;
119         default:
120                 Log_Notice("UDI", "Unknown enumeration_result %i", enumeration_result);
121                 return ;
122         }
123 }
124
125 void udi_devmgmt_req(udi_mgmt_cb_t *cb, udi_ubit8_t mgmt_op, udi_ubit8_t parent_ID )
126 {       
127         ENTER("pcb imgmt_op iparent_ID", cb, mgmt_op, parent_ID);
128         LEAVE('-');
129 }
130
131 void udi_devmgmt_ack(udi_mgmt_cb_t *cb, udi_ubit8_t flags, udi_status_t status)
132 {
133         ENTER("pcb xflags istatus", cb, flags, status);
134         LEAVE('-');
135 }
136
137 void udi_final_cleanup_req(udi_mgmt_cb_t *cb)
138 {
139         ENTER("pcb", cb);
140         LEAVE('-');
141 }
142
143 void udi_final_cleanup_ack(udi_mgmt_cb_t *cb)
144 {
145         ENTER("pcb", cb);
146         LEAVE('-');
147 }
148

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