UDI/ne2000 - Incomplete TX implementation
[tpg/acess2.git] / KernelLand / Modules / Interfaces / UDI / udi_lib / core / cb.c
1 /**
2  * \file cb.c
3  * \author John Hodge (thePowersGang)
4  * \brief Control block code
5  */
6 #define DEBUG   1
7 #include <udi.h>
8 #include <acess.h>
9 #include <udi_internal.h>
10 #include <udi_internal_ma.h>    // for cUDI_MgmtCbInitList
11
12 typedef struct sUDI_CBHeader
13 {
14         tUDI_MetaLang   *Metalang;
15         udi_index_t     MetaCBNum;
16         udi_cb_t        cb;
17 } tUDI_CBHeader;
18
19 // === CODE ===
20 tUDI_MetaLang *UDI_int_GetCbType(udi_cb_t *cb, udi_index_t *meta_cb_num)
21 {
22         tUDI_CBHeader   *hdr = (void*)cb - offsetof(tUDI_CBHeader, cb);
23         if(meta_cb_num)
24                 *meta_cb_num = hdr->MetaCBNum;
25         return hdr->Metalang;
26 }
27
28 udi_cb_t *udi_cb_alloc_internal_v(tUDI_MetaLang *Meta, udi_index_t MetaCBNum,
29         size_t inline_size, size_t scratch_size, udi_channel_t channel)
30 {
31         ASSERTC(MetaCBNum, <, Meta->nCbTypes);
32         size_t  base = Meta->CbTypes[MetaCBNum].Size;
33         ASSERTC(base, >=, sizeof(udi_cb_t));
34         base -= sizeof(udi_cb_t);
35         LOG("+ %i + %i + %i", base, inline_size, scratch_size);
36         tUDI_CBHeader   *cbhdr = NEW(tUDI_CBHeader, + base + inline_size + scratch_size);
37         cbhdr->Metalang = Meta;
38         cbhdr->MetaCBNum = MetaCBNum;
39         udi_cb_t *ret = &cbhdr->cb;
40         ret->channel = channel;
41         ret->scratch = (void*)(ret + 1) + base + inline_size;
42         return ret;
43 }
44 void *udi_cb_alloc_internal(tUDI_DriverInstance *Inst, udi_ubit8_t bind_cb_idx, udi_channel_t channel)
45 {
46         const udi_cb_init_t     *cb_init;
47         LOG("Inst=%p, bind_cb_idx=%i, channel=%p", Inst, bind_cb_idx, channel);
48         ASSERT(Inst);
49         ASSERT(Inst->Module);
50         ASSERT(Inst->Module->InitInfo);
51         ASSERT(Inst->Module->InitInfo->cb_init_list);
52         
53         for( cb_init = Inst->Module->InitInfo->cb_init_list; cb_init->cb_idx; cb_init ++ )
54         {
55                 if( cb_init->cb_idx == bind_cb_idx )
56                 {
57                         // TODO: Get base size using meta/cbnum
58                         tUDI_MetaLang *metalang = UDI_int_GetMetaLang(Inst->Module, cb_init->meta_idx);
59                         if( !metalang ) {
60                                 Log_Warning("UDI", "Metalang referenced in %s CB %i is invalid (%i)",
61                                         Inst->Module->ModuleName, bind_cb_idx, cb_init->meta_idx);
62                                 return NULL;
63                         }
64                         return udi_cb_alloc_internal_v(metalang, cb_init->meta_cb_num,
65                                 cb_init->inline_size, cb_init->scratch_requirement, channel);
66                         #if 0
67                         ASSERTC(cb_init->meta_cb_num, <, metalang->nCbTypes);
68                         size_t  base = metalang->CbTypes[cb_init->meta_cb_num].Size;
69                         ASSERTC(base, >=, sizeof(udi_cb_t));
70                         base -= sizeof(udi_cb_t);
71                         LOG("+ %i + %i + %i", base, cb_init->inline_size, cb_init->scratch_requirement);
72                         udi_cb_t *ret = NEW(udi_cb_t, + base
73                                 + cb_init->inline_size + cb_init->scratch_requirement);
74                         ret->channel = channel;
75                         ret->scratch = (void*)ret + sizeof(udi_cb_t) + base + cb_init->inline_size;
76                         return ret;
77                         #endif
78                 }
79         }
80         Log_Warning("UDI", "Cannot find CB init def %i for '%s'",
81                 bind_cb_idx, Inst->Module->ModuleName);
82         return NULL;
83 }
84
85 void udi_cb_alloc (
86         udi_cb_alloc_call_t     *callback,      //!< Function to be called when the CB is allocated
87         udi_cb_t        *gcb,   //!< Parent Control Block
88         udi_index_t     cb_idx,
89         udi_channel_t   default_channel
90         )
91 {
92         tUDI_DriverInstance *inst = UDI_int_ChannelGetInstance(gcb, false, NULL);
93         void *ret = udi_cb_alloc_internal(inst, cb_idx, default_channel);
94         callback(gcb, ret);
95 }
96
97 void udi_cb_alloc_dynamic(
98         udi_cb_alloc_call_t     *callback,
99         udi_cb_t        *gcb,
100         udi_index_t     cb_idx,
101         udi_channel_t   default_channel,
102         udi_size_t      inline_size,
103         udi_layout_t    *inline_layout
104         )
105 {
106         UNIMPLEMENTED();
107 }
108
109 void udi_cb_alloc_batch(
110         udi_cb_alloc_batch_call_t       *callback,      //!< 
111         udi_cb_t        *gcb,   //!< 
112         udi_index_t     cb_idx,
113         udi_index_t     count,
114         udi_boolean_t   with_buf,
115         udi_size_t      buf_size,
116         udi_buf_path_t  path_handle
117         )
118 {
119         UNIMPLEMENTED();
120 }
121
122 void udi_cb_free(udi_cb_t *cb)
123 {
124         tUDI_CBHeader   *hdr = (void*)cb - offsetof(tUDI_CBHeader, cb);
125         // TODO: Ensure that cb is inactive
126         free(hdr);
127 }
128
129 void udi_cancel(udi_cancel_call_t *callback, udi_cb_t *gcb)
130 {
131         UNIMPLEMENTED();
132 }
133
134 // === EXPORTS ===
135 EXPORT(udi_cb_alloc);
136 EXPORT(udi_cb_alloc_dynamic);
137 EXPORT(udi_cb_alloc_batch);
138 EXPORT(udi_cb_free);
139 EXPORT(udi_cancel);

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