Modules/UDI - NSR layer and fixes to enumeration
authorJohn Hodge <[email protected]>
Tue, 8 Oct 2013 15:10:48 +0000 (23:10 +0800)
committerJohn Hodge <[email protected]>
Tue, 8 Oct 2013 15:10:48 +0000 (23:10 +0800)
KernelLand/Modules/Interfaces/UDI/Makefile
KernelLand/Modules/Interfaces/UDI/channels.c
KernelLand/Modules/Interfaces/UDI/include/trans_nsr.h [new file with mode: 0644]
KernelLand/Modules/Interfaces/UDI/include/udi_internal.h
KernelLand/Modules/Interfaces/UDI/main.c
KernelLand/Modules/Interfaces/UDI/management_agent.c
KernelLand/Modules/Interfaces/UDI/trans/bus_pci.c
KernelLand/Modules/Interfaces/UDI/trans/nsr.c [new file with mode: 0644]
KernelLand/Modules/Interfaces/UDI/udi_lib/core/cb.c
KernelLand/Modules/Interfaces/UDI/udi_lib/core/meta_mgmt.c
KernelLand/Modules/Interfaces/UDI/udi_lib/udi_nic.c

index 4d90a1a..1f99c95 100644 (file)
@@ -11,7 +11,7 @@ LIB_OBJS += physio.o physio/meta_bus.o physio/pio.o physio/dma.o
 LIB_OBJS += scsi.o
 LIB_OBJS += udi_nic.o
 # - UDI->Acess Translation Layer
-TRANS_OBJS := bus_pci.o
+TRANS_OBJS := bus_pci.o nsr.o
 
 OBJ  = main.o channels.o deferred_calls.o management_agent.o
 OBJ += $(LIB_OBJS:%=udi_lib/%) $(TRANS_OBJS:%=trans/%)
index bb723a2..993308b 100644 (file)
@@ -103,7 +103,7 @@ int UDI_BindChannel(udi_channel_t channel, bool other_side, tUDI_DriverInstance
                return 1;
        }
 
-       tUDI_MetaLang *ops_ml = UDI_int_GetMetaLang(inst, ops->meta_idx);
+       tUDI_MetaLang *ops_ml = UDI_int_GetMetaLang(inst->Module, ops->meta_idx);
        if( ops_ml != ch->MetaLang ) {
                Log_Warning("UDI", "Attempt by %s to bind with mismatched channel '%s' op '%s' channel",
                        inst->Module, ops_ml->Name, ch->MetaLang->Name);
diff --git a/KernelLand/Modules/Interfaces/UDI/include/trans_nsr.h b/KernelLand/Modules/Interfaces/UDI/include/trans_nsr.h
new file mode 100644 (file)
index 0000000..dcfbec8
--- /dev/null
@@ -0,0 +1,16 @@
+/*
+ * Acess2 UDI Layer
+ * - By John Hodge (thePowersGang)
+ *
+ * trans_nsr.h
+ * - Acess IPStack to UDI Network Service Requester
+ */
+#ifndef _TRANS_NSR_H_
+#define _TRANS_NSR_H_
+
+extern const udi_init_t        acessnsr_init;
+extern const char      acessnsr_udiprops[];
+extern size_t  acessnsr_udiprops_size;
+
+#endif
+
index e07b8d4..7bebc2f 100644 (file)
@@ -107,7 +107,7 @@ struct sUDI_DriverModule
        tUDI_DriverModule       *Next;
        void    *Base;
 
-       udi_init_t      *InitInfo;
+       const udi_init_t        *InitInfo;
 
        // Counts of arrays in InitInfo
         int    nCBInit;
@@ -174,7 +174,7 @@ extern tUDI_MetaLang        cMetaLang_Management;
 
 // --- Index to pointer translation ---
 extern udi_ops_init_t  *UDI_int_GetOps(tUDI_DriverInstance *Inst, udi_index_t index);
-extern tUDI_MetaLang *UDI_int_GetMetaLang(tUDI_DriverInstance *Inst, udi_index_t meta_idx);
+extern tUDI_MetaLang *UDI_int_GetMetaLang(tUDI_DriverModule *Inst, udi_index_t meta_idx);
 
 // --- Channels ---
 extern udi_channel_t   UDI_CreateChannel_Blank(tUDI_MetaLang *metalang);
index bb24d19..fabdcbb 100644 (file)
 #include <udi_internal.h>
 #include <udi_internal_ma.h>
 #include <trans_pci.h>
+#include <trans_nsr.h>
 
 // === PROTOTYPES ===
  int   UDI_Install(char **Arguments);
  int   UDI_DetectDriver(void *Base);
  int   UDI_LoadDriver(void *Base);
-tUDI_DriverModule      *UDI_int_LoadDriver(void *LoadBase, udi_init_t *info, const char *udiprops, size_t udiprops_size);
+tUDI_DriverModule      *UDI_int_LoadDriver(void *LoadBase, const udi_init_t *info, const char *udiprops, size_t udiprops_size);
 const tUDI_MetaLang    *UDI_int_GetMetaLangByName(const char *Name);
 
 // === GLOBALS ===
@@ -40,6 +41,7 @@ int UDI_Install(char **Arguments)
        Proc_SpawnWorker(UDI_int_DeferredThread, NULL);
 
        UDI_int_LoadDriver(NULL, &pci_init, pci_udiprops, pci_udiprops_size);
+       UDI_int_LoadDriver(NULL, &acessnsr_init, acessnsr_udiprops, acessnsr_udiprops_size);
 
        return MODULE_ERR_OK;
 }
@@ -318,7 +320,7 @@ const char *caUDI_UdipropsNames[] = {
 };
 #undef _defpropname
 
-tUDI_DriverModule *UDI_int_LoadDriver(void *LoadBase, udi_init_t *info, const char *udiprops, size_t udiprops_size)
+tUDI_DriverModule *UDI_int_LoadDriver(void *LoadBase, const udi_init_t *info, const char *udiprops, size_t udiprops_size)
 {
        //UDI_int_DumpInitInfo(info);
        
@@ -664,6 +666,10 @@ tUDI_DriverModule *UDI_int_LoadDriver(void *LoadBase, udi_init_t *info, const ch
                }
        }
        free(udipropsptrs);
+
+       for( int i = 0; i < driver_module->nDevices; i ++ )
+               driver_module->Devices[i]->Metalang = UDI_int_GetMetaLang(driver_module,
+                       driver_module->Devices[i]->MetaIdx);
        
        // Sort message list
        // TODO: Sort message list
@@ -767,15 +773,15 @@ udi_ops_init_t *UDI_int_GetOps(tUDI_DriverInstance *Inst, udi_index_t index)
        return ops;
 }
 
-tUDI_MetaLang *UDI_int_GetMetaLang(tUDI_DriverInstance *Inst, udi_index_t index)
+tUDI_MetaLang *UDI_int_GetMetaLang(tUDI_DriverModule *Module, udi_index_t index)
 {
        if( index == 0 )
                return &cMetaLang_Management;
-       ASSERT(Inst);
-       for( int i = 0; i < Inst->Module->nMetaLangs; i ++ )
+       ASSERT(Module);
+       for( int i = 0; i < Module->nMetaLangs; i ++ )
        {
-               if( Inst->Module->MetaLangs[i].meta_idx == index )
-                       return Inst->Module->MetaLangs[i].metalang;
+               if( Module->MetaLangs[i].meta_idx == index )
+                       return Module->MetaLangs[i].metalang;
        }
        return NULL;
 }
@@ -784,8 +790,10 @@ const tUDI_MetaLang *UDI_int_GetMetaLangByName(const char *Name)
 {
        //extern tUDI_MetaLang  cMetaLang_Management;
        extern tUDI_MetaLang    cMetaLang_BusBridge;
+       extern tUDI_MetaLang    cMetaLang_NIC;
        const tUDI_MetaLang     *langs[] = {
                &cMetaLang_BusBridge,
+               &cMetaLang_NIC,
                NULL
        };
        for( int i = 0; langs[i]; i ++ )
index 512fda3..536c28f 100644 (file)
@@ -49,9 +49,11 @@ tUDI_DriverInstance *UDI_MA_CreateInstance(tUDI_DriverModule *DriverModule,
 //     UDI_BindChannel_Raw(inst->ManagementChannel, false,
 //             NULL, 1, inst, &cUDI_MgmtOpsList);      // TODO: ops list for management agent?
 
-       for( int i = 0; i < DriverModule->nRegions; i ++ )
-               Log("Rgn %i: %p", i, inst->Regions[i]);
+//     for( int i = 0; i < DriverModule->nRegions; i ++ )
+//             Log("Rgn %i: %p", i, inst->Regions[i]);
 
+       LOG("Inst %s %p MA state =%i",
+               inst->Module->ModuleName, inst, UDI_MASTATE_USAGEIND);
        inst->CurState = UDI_MASTATE_USAGEIND;
        // Next State: _SECBIND
 
@@ -132,7 +134,7 @@ int UDI_MA_CheckDeviceMatch(int nDevAttr, udi_instance_attr_list_t *DevAttrs,
                else
                {
                        // Attribute desired is missing, error?
-                       //LOG("attr '%s' missing", dev_attr->attr_name);
+                       LOG("attr '%s' missing", dev_attr->attr_name);
                }
        }
        //LOG("n_matches = %i", n_matches);
@@ -184,13 +186,16 @@ void UDI_MA_AddChild(udi_enumerate_cb_t *cb, udi_index_t ops_idx)
        inst->FirstChild = child;
        
        // and search for a handler
-       tUDI_MetaLang   *metalang = UDI_int_GetMetaLang(inst, child->Ops->meta_idx);
+       tUDI_MetaLang   *metalang = UDI_int_GetMetaLang(inst->Module, child->Ops->meta_idx);
         int    best_level = 0;
        tUDI_DriverModule *best_module = NULL;
        for( tUDI_DriverModule *module = gpUDI_LoadedModules; module; module = module->Next )
        {
                for( int i = 0; i < module->nDevices; i ++ )
                {
+                       //LOG("%s:%i %p ?== %p",
+                       //      module->ModuleName, i,
+                       //      module->Devices[i]->Metalang, metalang);
                        if( module->Devices[i]->Metalang != metalang )
                                continue ;
                        
@@ -223,6 +228,7 @@ void UDI_MA_BindParents(tUDI_DriverModule *Module)
                        {
                                if( child->BoundInstance )
                                        continue ;
+                               // TODO: Check metalangs
                                // Check for match
                                int level = UDI_MA_CheckDeviceMatch(
                                        Module->Devices[i]->nAttribs, Module->Devices[i]->Attribs,
@@ -244,6 +250,9 @@ void UDI_MA_TransitionState(tUDI_DriverInstance *Inst, enum eUDI_MAState Src, en
        if( Inst->CurState != Src )
                return ;
        
+       LOG("Inst %s %p MA state %i->%i",
+               Inst->Module->ModuleName, Inst, Src, Dst);
+       
        switch(Dst)
        {
        case UDI_MASTATE_USAGEIND:
@@ -270,7 +279,7 @@ void UDI_MA_TransitionState(tUDI_DriverInstance *Inst, enum eUDI_MAState Src, en
                        
                        // Bind to parent
                        tUDI_BindOps    *parent = &Module->Parents[0];
-                       udi_channel_t channel = UDI_CreateChannel_Blank(UDI_int_GetMetaLang(Inst, parent->meta_idx));
+                       udi_channel_t channel = UDI_CreateChannel_Blank(UDI_int_GetMetaLang(Inst->Module, parent->meta_idx));
                        
                        UDI_BindChannel(channel,true,  Inst, parent->ops_idx, parent->region_idx, NULL,false,0);
                        UDI_BindChannel(channel,false,
index e51db75..daf07f2 100644 (file)
@@ -285,8 +285,8 @@ void pci_intr_handle__trans_done(udi_cb_t *gcb, udi_buf_t *new_buf, udi_status_t
 udi_status_t pci_pio_do_io(uint32_t child_ID, udi_ubit32_t regset_idx, udi_ubit32_t ofs, udi_ubit8_t len,
        void *data, bool isOutput)
 {
-       LOG("child_ID=%i, regset_idx=%i,ofs=0x%x,len=%i,data=%p,isOutput=%b",
-               child_ID, regset_idx, ofs, len, data, isOutput);
+//     LOG("child_ID=%i, regset_idx=%i,ofs=0x%x,len=%i,data=%p,isOutput=%b",
+//             child_ID, regset_idx, ofs, len, data, isOutput);
        tPCIDev pciid = child_ID;
        // TODO: Cache child mappings   
 
diff --git a/KernelLand/Modules/Interfaces/UDI/trans/nsr.c b/KernelLand/Modules/Interfaces/UDI/trans/nsr.c
new file mode 100644 (file)
index 0000000..a613571
--- /dev/null
@@ -0,0 +1,199 @@
+/*
+ * Acess2 UDI Layer
+ * - By John Hodge (thePowersGang)
+ *
+ * trans/nsr.c
+ * - "Network Service Requester" (UDI->IP Translation)
+ */
+#define DEBUG  1
+#include <udi.h>
+#include <udi_nic.h>
+#include <acess.h>
+#include <trans_nsr.h>
+#include <IPStack/include/adapters_api.h>
+
+enum {
+       ACESSNSR_OPS_CTRL = 1,
+       ACESSNSR_OPS_TX,
+       ACESSNSR_OPS_RX,
+};
+enum {
+       ACESSNSR_META_NIC = 1
+};
+enum {
+       ACESSNSR_CB_CTRL = 1
+};
+
+// === TYPES ===
+typedef struct
+{
+       udi_init_context_t      init_context;
+} acessnsr_rdata_t;
+
+// === PROTOTYPES ===
+// --- Management metalang
+void acessnsr_usage_ind(udi_usage_cb_t *cb, udi_ubit8_t resource_level);
+void acessnsr_devmgmt_req(udi_mgmt_cb_t *cb, udi_ubit8_t mgmt_op, udi_ubit8_t parent_ID);
+void acessnsr_final_cleanup_req(udi_mgmt_cb_t *cb);
+// --- NSR Control
+void acessnsr_ctrl_channel_event_ind(udi_channel_event_cb_t *cb);
+void acessnsr_ctrl_bind_ack(udi_nic_bind_cb_t *cb, udi_status_t status);
+void acessnsr_ctrl_unbind_ack(udi_nic_cb_t *cb, udi_status_t status);
+void acessnsr_ctrl_enable_ack(udi_nic_cb_t *cb, udi_status_t status);
+void acessnsr_ctrl_disable_ack(udi_nic_cb_t *cb, udi_status_t status);
+void acessnsr_ctrl_ctrl_ack(udi_nic_ctrl_cb_t *cb, udi_status_t status);
+void acessnsr_ctrl_status_ind(udi_nic_status_cb_t *cb);
+void acessnsr_ctrl_info_ack(udi_nic_info_cb_t *cb);
+// --- NSR TX
+void acessnsr_tx_channel_event_ind(udi_channel_event_cb_t *cb);
+void acessnsr_tx_rdy(udi_nic_tx_cb_t *cb);
+// --- NSR RX
+void acessnsr_rx_channel_event_ind(udi_channel_event_cb_t *cb);
+void acessnsr_rx_ind(udi_nic_rx_cb_t *cb);
+void acessnsr_rx_exp_ind(udi_nic_rx_cb_t *cb);
+
+// === CODE ===
+// --- Management metalang
+void acessnsr_usage_ind(udi_usage_cb_t *cb, udi_ubit8_t resource_level)
+{
+}
+void acessnsr_devmgmt_req(udi_mgmt_cb_t *cb, udi_ubit8_t mgmt_op, udi_ubit8_t parent_ID)
+{
+}
+void acessnsr_final_cleanup_req(udi_mgmt_cb_t *cb)
+{
+}
+// --- NSR Control
+void acessnsr_ctrl_channel_event_ind(udi_channel_event_cb_t *cb)
+{
+       //acessnsr_rdata_t *rdata = UDI_GCB(cb)->context;
+       switch(cb->event)
+       {
+       
+       }
+}
+void acessnsr_ctrl_bind_ack(udi_nic_bind_cb_t *cb, udi_status_t status)
+{
+}
+void acessnsr_ctrl_unbind_ack(udi_nic_cb_t *cb, udi_status_t status)
+{
+}
+void acessnsr_ctrl_enable_ack(udi_nic_cb_t *cb, udi_status_t status)
+{
+}
+void acessnsr_ctrl_disable_ack(udi_nic_cb_t *cb, udi_status_t status)
+{
+}
+void acessnsr_ctrl_ctrl_ack(udi_nic_ctrl_cb_t *cb, udi_status_t status)
+{
+}
+void acessnsr_ctrl_status_ind(udi_nic_status_cb_t *cb)
+{
+}
+void acessnsr_ctrl_info_ack(udi_nic_info_cb_t *cb)
+{
+}
+// --- NSR TX
+void acessnsr_tx_channel_event_ind(udi_channel_event_cb_t *cb)
+{
+}
+void acessnsr_tx_rdy(udi_nic_tx_cb_t *cb)
+{
+}
+// --- NSR RX
+void acessnsr_rx_channel_event_ind(udi_channel_event_cb_t *cb)
+{
+}
+void acessnsr_rx_ind(udi_nic_rx_cb_t *cb)
+{
+}
+void acessnsr_rx_exp_ind(udi_nic_rx_cb_t *cb)
+{
+}
+
+// === UDI Bindings ===
+udi_mgmt_ops_t acessnsr_mgmt_ops = {
+       acessnsr_usage_ind,
+       udi_enumerate_no_children,
+       acessnsr_devmgmt_req,
+       acessnsr_final_cleanup_req
+};
+udi_ubit8_t    acessnsr_mgmt_ops_flags[4] = {0,0,0,0};
+
+udi_primary_init_t     acessnsr_pri_init = {
+       .mgmt_ops = &acessnsr_mgmt_ops,
+       .mgmt_op_flags = acessnsr_mgmt_ops_flags,
+       .mgmt_scratch_requirement = 0,
+       .enumeration_attr_list_length = 4,
+       .rdata_size = sizeof(acessnsr_rdata_t),
+       .child_data_size = 0,
+       .per_parent_paths = 0
+};
+
+udi_nsr_ctrl_ops_t     acessnsr_ctrl_ops = {
+       acessnsr_ctrl_channel_event_ind,
+       acessnsr_ctrl_bind_ack,
+       acessnsr_ctrl_unbind_ack,
+       acessnsr_ctrl_enable_ack,
+       acessnsr_ctrl_ctrl_ack,
+       acessnsr_ctrl_info_ack,
+       acessnsr_ctrl_status_ind
+};
+udi_ubit8_t    acessnsr_ctrl_op_flags[7] = {0};
+
+udi_nsr_tx_ops_t       acessnsr_tx_ops = {
+       acessnsr_tx_channel_event_ind,
+       acessnsr_tx_rdy
+};
+udi_ubit8_t    acessnsr_tx_ops_flags[2] = {0};
+
+udi_nsr_rx_ops_t       acessnsr_rx_ops = {
+       acessnsr_rx_channel_event_ind,
+       acessnsr_rx_ind,
+       acessnsr_rx_exp_ind
+};
+udi_ubit8_t    acessnsr_rx_ops_flags[3] = {0};
+
+udi_ops_init_t acessnsr_ops_list[] = {
+       {
+               ACESSNSR_OPS_CTRL, ACESSNSR_META_NIC, UDI_NSR_CTRL_OPS_NUM,
+               0, (udi_ops_vector_t*)&acessnsr_ctrl_ops, acessnsr_ctrl_op_flags
+       },
+       {
+               ACESSNSR_OPS_TX, ACESSNSR_META_NIC, UDI_NSR_TX_OPS_NUM,
+               0, (udi_ops_vector_t*)&acessnsr_tx_ops, acessnsr_tx_ops_flags
+       },
+       {
+               ACESSNSR_OPS_RX, ACESSNSR_META_NIC, UDI_NSR_RX_OPS_NUM,
+               0, (udi_ops_vector_t*)&acessnsr_rx_ops, acessnsr_rx_ops_flags
+       },
+       {0}
+};
+udi_cb_init_t  acessnsr_cb_init_list[] = {
+       {ACESSNSR_CB_CTRL, ACESSNSR_META_NIC, UDI_NIC_BIND_CB_NUM, 0, 0,NULL},
+       {0}
+};
+const udi_init_t       acessnsr_init = {
+       .primary_init_info = &acessnsr_pri_init,
+       .ops_init_list = acessnsr_ops_list,
+       .cb_init_list = acessnsr_cb_init_list,
+};
+const char     acessnsr_udiprops[] = 
+       "properties_version 0x101\0"
+       "message 1 Acess2 Kernel\0"
+       "message 2 John Hodge ([email protected])\0"
+       "message 3 Acess2 NSR\0"
+       "supplier 1\0"
+       "contact 2\0"
+       "name 3\0"
+       "module acess_nsr\0"
+       "shortname acessnsr\0"
+       "requires udi 0x101\0"
+       "requires udi_nic 0x101\0"
+       "meta 1 udi_nic\0"
+       "message 101 Ethernet Adapter\0"
+       "device 101 1 if_media string eth\0"
+       "parent_bind_ops 1 0 1 1\0"
+       "\0";
+size_t acessnsr_udiprops_size = sizeof(acessnsr_udiprops);
+
index ae8c155..14bcd32 100644 (file)
@@ -37,7 +37,7 @@ void *udi_cb_alloc_internal(tUDI_DriverInstance *Inst, udi_ubit8_t bind_cb_idx,
                if( cb_init->cb_idx == bind_cb_idx )
                {
                        // TODO: Get base size using meta/cbnum
-                       tUDI_MetaLang *metalang = UDI_int_GetMetaLang(Inst, cb_init->meta_idx);
+                       tUDI_MetaLang *metalang = UDI_int_GetMetaLang(Inst->Module, cb_init->meta_idx);
                        if( !metalang ) {
                                Log_Warning("UDI", "Metalang referenced in %s CB %i is invalid (%i)",
                                        Inst->Module->ModuleName, bind_cb_idx, cb_init->meta_idx);
@@ -103,7 +103,8 @@ void udi_cb_alloc_batch(
 
 void udi_cb_free(udi_cb_t *cb)
 {
-       UNIMPLEMENTED();
+       // TODO: Ensure that cb is inactive
+       free(cb);
 }
 
 void udi_cancel(udi_cancel_call_t *callback, udi_cb_t *gcb)
index ab8f68a..865ace4 100644 (file)
@@ -91,13 +91,16 @@ void udi_enumerate_ack(udi_enumerate_cb_t *cb, udi_ubit8_t enumeration_result, u
                        switch(at->attr_type)
                        {
                        case UDI_ATTR_STRING:
-                               LOG("[%i] String '%.*s'", i, at->attr_length, at->attr_value);
+                               LOG("[%i] %s String '%.*s'", i, at->attr_name,
+                                       at->attr_length, at->attr_value);
                                break;
                        case UDI_ATTR_UBIT32:
-                               LOG("[%i] UBit32 0x%08x", i, UDI_ATTR32_GET(at->attr_value));
+                               LOG("[%i] %s UBit32 0x%08x", i, at->attr_name,
+                                       UDI_ATTR32_GET(at->attr_value));
                                break;
                        default:
-                               LOG("[%i] %i", i, at->attr_type);
+                               LOG("[%i] %s %i", i, at->attr_name,
+                                       at->attr_type);
                                break;
                        }
                }
index 6bf636b..00790f0 100644 (file)
@@ -2,9 +2,10 @@
  * \file physio.c
  * \author John Hodge (thePowersGang)
  */
-#include <acess.h>
 #include <udi.h>
 #include <udi_nic.h>
+#include <acess.h>     // for EXPORT
+#include <udi_internal.h>
 
 // === EXPORTS ===
 EXPORT(udi_nd_bind_req);
@@ -28,6 +29,29 @@ EXPORT(udi_nsr_rx_ind);
 EXPORT(udi_nsr_exp_rx_ind);
 EXPORT(udi_nd_rx_rdy);
 
+#define UDI_NIC_STD_CB_NUM     1
+#define UDI_NIC_BIND_CB_NUM    2
+#define UDI_NIC_CTRL_CB_NUM    3
+#define UDI_NIC_STATUS_CB_NUM  4
+#define UDI_NIC_INFO_CB_NUM    5
+#define UDI_NIC_TX_CB_NUM      6
+#define UDI_NIC_RX_CB_NUM      7
+// === GLOBALS ===
+tUDI_MetaLang  cMetaLang_NIC = {
+       "udi_nic",
+       8,
+       {
+               {0},
+               {sizeof(udi_nic_cb_t), NULL},
+               {sizeof(udi_nic_bind_cb_t), NULL},
+               {sizeof(udi_nic_ctrl_cb_t), NULL},
+               {sizeof(udi_nic_status_cb_t), NULL},
+               {sizeof(udi_nic_info_cb_t), NULL},
+               {sizeof(udi_nic_tx_cb_t), NULL},
+               {sizeof(udi_nic_rx_cb_t), NULL},
+       }
+};
+
 // === CODE ===
 // --- Control Ops ---
 void udi_nd_bind_req(udi_nic_bind_cb_t *cb, udi_index_t tx_chan_index, udi_index_t rx_chan_index)

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