Modules/UDI - Heaps of fixes and features
authorJohn Hodge <[email protected]>
Sat, 12 Oct 2013 13:50:27 +0000 (21:50 +0800)
committerJohn Hodge <[email protected]>
Sat, 12 Oct 2013 13:50:27 +0000 (21:50 +0800)
- Buffer read working
- Buffer write is simple insert-only atm
- Batch cb allocations implemented

13 files changed:
KernelLand/Modules/Interfaces/UDI/channels.c
KernelLand/Modules/Interfaces/UDI/deferred_calls.c
KernelLand/Modules/Interfaces/UDI/include/udi_internal.h
KernelLand/Modules/Interfaces/UDI/trans/bus_pci.c
KernelLand/Modules/Interfaces/UDI/trans/nsr.c
KernelLand/Modules/Interfaces/UDI/udi_lib/core/buf.c
KernelLand/Modules/Interfaces/UDI/udi_lib/core/cb.c
KernelLand/Modules/Interfaces/UDI/udi_lib/core/layout.c
KernelLand/Modules/Interfaces/UDI/udi_lib/core/mei.c
KernelLand/Modules/Interfaces/UDI/udi_lib/core/meta_mgmt.c
KernelLand/Modules/Interfaces/UDI/udi_lib/physio/meta_bus.c
KernelLand/Modules/Interfaces/UDI/udi_lib/physio/pio.c
KernelLand/Modules/Interfaces/UDI/udi_lib/udi_nic.c

index 993308b..b386507 100644 (file)
@@ -75,8 +75,6 @@ struct sUDI_ChannelSide *UDI_int_ChannelGetSide(udi_channel_t channel, bool othe
        if( other_side )
                side_idx = 1 - side_idx;        
 
-       LOG("side_idx = %i, other_side=%b", side_idx, other_side);
-
        return &ch->Side[side_idx];
 }
 
@@ -112,6 +110,7 @@ int UDI_BindChannel(udi_channel_t channel, bool other_side, tUDI_DriverInstance
 
        if( context ) {
                // Use provided context pointer
+               LOG("context = provided %p", context);
        }
        else if( ops->chan_context_size )
        {
@@ -119,16 +118,18 @@ int UDI_BindChannel(udi_channel_t channel, bool other_side, tUDI_DriverInstance
                        ASSERTCR( ops->chan_context_size, >=, sizeof(udi_child_chan_context_t), 4 );
                else
                        ASSERTCR( ops->chan_context_size, >=, sizeof(udi_chan_context_t), 4 );
-               context = malloc( ops->chan_context_size );
+               context = calloc( 1, ops->chan_context_size );
                ((udi_chan_context_t*)context)->rdata = rgn->InitContext;
                if( is_child_bind )
                        ((udi_child_chan_context_t*)context)->child_ID = child_ID;
+               LOG("context = allocated %p", context);
                
                // TODO: The driver may change the channel context, but this must be freed by the environment
                UDI_int_ChannelGetSide(channel, other_side)->AllocatedContext = context;
        }
        else {
                context = rgn->InitContext;
+               LOG("context = region %p", context);
        }
        
        UDI_BindChannel_Raw(channel, other_side, inst, region, ops->meta_ops_num, context, ops->ops_vector);
index aec1fcb..49738bb 100644 (file)
@@ -44,6 +44,8 @@ void UDI_int_DeferredThread(void *unused)
 
 void UDI_int_AddDeferred(tUDI_DeferredCall *Call)
 {
+       LOG("Added deferred %p{um=%p,cb=%p,handler=%p}",
+               Call, Call->Unmarshal, Call->cb, Call->Handler);
        Workqueue_AddWork(&gUDI_DeferredWorkQueue, Call);
 }
 
index ff7f278..83093f9 100644 (file)
@@ -71,7 +71,7 @@ struct sUDI_PropRegion
 struct sUDI_MetaLang
 {
        const char *Name;
-       //void  *MeiInfo;
+       const void      *MeiInfo;
         int    nCbTypes;
        struct {
                udi_size_t      Size;
@@ -216,7 +216,11 @@ extern tUDI_MetaLang       *UDI_int_GetCbType(udi_cb_t *gcb, udi_index_t *meta_cb_num)
 extern udi_instance_attr_type_t udi_instance_attr_get_internal(udi_cb_t *gcb, const char *attr_name, udi_ubit32_t child_ID, void *attr_value, udi_size_t attr_length, udi_size_t *actual_length);
 
 // --- Layout ---
+extern size_t  _udi_marshal_step(void *buf, size_t cur_ofs, udi_layout_t **layoutp, va_list *values);
 extern size_t  _udi_marshal_values(void *buf, udi_layout_t *layout, va_list values);
 
+// --- Buffers ---
+extern udi_buf_t       *_udi_buf_allocate(const void *data, udi_size_t length, udi_buf_path_t path_handle);
+
 #endif
 
index e5d3bf4..2d7459a 100644 (file)
@@ -66,10 +66,11 @@ typedef struct
 
         int    interrupt_handle;
 
-       udi_pio_handle_t        intr_preprocessing;     
+       udi_pio_handle_t        intr_preprocessing;
        udi_intr_event_cb_t     *event_cbs[PCI_MAX_EVENT_CBS];
-        int    event_cb_wr_ofs;
-        int    event_cb_rd_ofs;
+       udi_index_t     event_cb_wr_ofs;
+       udi_index_t     event_cb_rd_ofs;
+        int    bIntrEnabled;
 } pci_child_chan_context_t;
 
 // === PROTOTYPES ===
@@ -87,6 +88,7 @@ void  pci_intr_detach_req(udi_intr_detach_cb_t *cb);
 
 void   pci_intr_ch_event_ind(udi_channel_event_cb_t *cb);
 void   pci_intr_event_rdy(udi_intr_event_cb_t *cb);
+void   pci_intr_event_rdy__irqs_enabled(udi_cb_t *gcb, udi_buf_t *newbuf, udi_status_t status, udi_ubit16_t result);
 void   pci_intr_handler(int irq, void *void_context);
 void   pci_intr_handle__trans_done(udi_cb_t *gcb, udi_buf_t *new_buf, udi_status_t status, udi_ubit16_t result);
 
@@ -218,7 +220,7 @@ void pci_intr_attach_req__channel_spawned(udi_cb_t *gcb, udi_channel_t new_chann
        
        context->interrupt_handle = IRQ_AddHandler(
                PCI_GetIRQ(context->child_chan_context.child_ID),
-               pci_intr_handler, new_channel);
+               pci_intr_handler, context);
 
        udi_intr_attach_ack(cb, UDI_OK);
 }
@@ -234,6 +236,11 @@ void pci_intr_ch_event_ind(udi_channel_event_cb_t *cb)
 void pci_intr_event_rdy(udi_intr_event_cb_t *cb)
 {
        pci_child_chan_context_t        *context = UDI_GCB(cb)->context;
+
+       ASSERTC(context->event_cb_rd_ofs, <, PCI_MAX_EVENT_CBS);
+       ASSERTC(context->event_cb_wr_ofs, <, PCI_MAX_EVENT_CBS);
+
+       LOG("Rd %i, Wr %i [WR %p]", context->event_cb_rd_ofs, context->event_cb_wr_ofs, cb);
        if( context->event_cbs[context->event_cb_wr_ofs] )
        {
                // oops, overrun.
@@ -242,22 +249,40 @@ void pci_intr_event_rdy(udi_intr_event_cb_t *cb)
        context->event_cbs[context->event_cb_wr_ofs++] = cb;
        if( context->event_cb_wr_ofs == PCI_MAX_EVENT_CBS )
                context->event_cb_wr_ofs = 0;
+       
+       // TODO: Fire once >= min_event_pend CBs are recieved
+       if( !context->bIntrEnabled )
+       {
+               context->bIntrEnabled = 1;
+               udi_pio_trans(pci_intr_event_rdy__irqs_enabled, NULL, context->intr_preprocessing, 0, NULL, NULL);
+       }
+}
+void pci_intr_event_rdy__irqs_enabled(udi_cb_t *gcb, udi_buf_t *newbuf, udi_status_t status, udi_ubit16_t result)
+{
+       // nothing
 }
 
 void pci_intr_handler(int irq, void *void_context)
 {
        pci_child_chan_context_t *context = void_context;
 
+       LOG("irq=%i, context=%p", irq, context);
+
        if( context->event_cb_rd_ofs == context->event_cb_wr_ofs ) {
                // Dropped
                return ;
        }
 
+       ASSERTC(context->event_cb_rd_ofs, <, PCI_MAX_EVENT_CBS);
+       ASSERTC(context->event_cb_wr_ofs, <, PCI_MAX_EVENT_CBS);
+
        udi_intr_event_cb_t *cb = context->event_cbs[context->event_cb_rd_ofs];
+       LOG("Rd %i, Wr %i [RD %p]", context->event_cb_rd_ofs, context->event_cb_wr_ofs, cb);
        context->event_cbs[context->event_cb_rd_ofs] = NULL;
        context->event_cb_rd_ofs ++;
        if( context->event_cb_rd_ofs == PCI_MAX_EVENT_CBS )
                context->event_cb_rd_ofs = 0;
+       ASSERT(cb);
        
        if( UDI_HANDLE_IS_NULL(context->intr_preprocessing, udi_pio_handle_t) )
        {
@@ -303,12 +328,12 @@ udi_status_t pci_pio_do_io(uint32_t child_ID, udi_ubit32_t regset_idx, udi_ubit3
                        bar &= ~3;
                        #define _IO(fc, type) do {\
                                if( isOutput ) { \
-                                       LOG("out"#fc"(0x%x, 0x%x)",bar+ofs,*(type*)data);\
+                                       /*LOG("out"#fc"(0x%x, 0x%x)",bar+ofs,*(type*)data);*/\
                                        out##fc(bar+ofs, *(type*)data); \
                                } \
                                else { \
                                        *(type*)data = in##fc(bar+ofs); \
-                                       LOG("in"#fc"(0x%x) = 0x%x",bar+ofs,*(type*)data);\
+                                       /*LOG("in"#fc"(0x%x) = 0x%x",bar+ofs,*(type*)data);*/\
                                }\
                                } while(0)
                        switch(len)
index 879d0bd..e6a3930 100644 (file)
@@ -27,7 +27,8 @@ enum {
 enum {
        ACESSNSR_CB_CTRL = 1,
        ACESSNSR_CB_RX,
-       ACESSNSR_CB_TX
+       ACESSNSR_CB_TX,
+       ACESSNSR_CB_STD,
 };
 
 // === TYPES ===
@@ -43,10 +44,7 @@ typedef struct
 {
        udi_init_context_t      init_context;   
        udi_cb_t        *active_cb;
-
-       udi_index_t     init_idx;
-       udi_buf_t       *rx_buffers[NUM_RX_BUFFERS];
-       udi_nic_rx_cb_t *rx_cbs[NUM_RX_BUFFERS];
+       udi_channel_t   saved_active_channel;
 
        tWorkqueue      RXQueue;
 
@@ -70,9 +68,9 @@ void acessnsr_ctrl_channel_event_ind(udi_channel_event_cb_t *cb);
 void acessnsr_ctrl_ch_ev_ind__rx_channel_spawned(udi_cb_t *gcb, udi_channel_t channel);
 void acessnsr_ctrl_ch_ev_ind__tx_channel_spawned(udi_cb_t *gcb, udi_channel_t channel);
 void acessnsr_ctrl_bind_ack(udi_nic_bind_cb_t *cb, udi_status_t status);
-void acessnsr_ctrl_bind_ack__rx_buf_allocated(udi_cb_t *gcb, udi_buf_t *new_buf);
-void acessnsr_ctrl_bind_ack__rx_cb_allocated(udi_cb_t *gcb, udi_cb_t *new_cb);
-void acessnsr_ctrl_bind_ack__tx_cb_allocated(udi_cb_t *gcb, udi_cb_t *new_cb);
+void acessnsr_ctrl_bind_ack__rx_cbs_allocated(udi_cb_t *gcb, udi_cb_t *first_new_cb);
+void acessnsr_ctrl_bind_ack__tx_cbs_allocated(udi_cb_t *gcb, udi_cb_t *first_new_cb);
+void acessnsr_ctrl_bind_ack__std_cb_allocated(udi_cb_t *gcb, udi_cb_t *new_cb);
 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);
@@ -162,81 +160,66 @@ void acessnsr_ctrl_bind_ack(udi_nic_bind_cb_t *cb, udi_status_t status)
                break;
        }
 
+       // - Register with IPStack
        if(cb->capabilities & UDI_NIC_CAP_TX_IP_CKSUM)
                rdata->AdapterType.Flags |= ADAPTERFLAG_OFFLOAD_IP4;
        if(cb->capabilities & UDI_NIC_CAP_TX_TCP_CKSUM)
                rdata->AdapterType.Flags |= ADAPTERFLAG_OFFLOAD_TCP;
        if(cb->capabilities & UDI_NIC_CAP_TX_UDP_CKSUM)
                rdata->AdapterType.Flags |= ADAPTERFLAG_OFFLOAD_UDP;
-       
        rdata->AdapterType.Name = "udi";
        rdata->AdapterType.SendPacket = acessnsr_SendPacket;
        rdata->AdapterType.WaitForPacket = acessnsr_WaitForPacket;
-
        rdata->ipstack_handle = IPStack_Adapter_Add(&rdata->AdapterType, rdata, cb->mac_addr);
 
        // Allocate RX CBs and buffers
-       rdata->init_idx = -1;
-       acessnsr_ctrl_bind_ack__rx_buf_allocated(rdata->active_cb, NULL);
+       // EVIL: Save and change channel of event CB
+       rdata->saved_active_channel = rdata->active_cb->channel;
+       rdata->active_cb->channel = rdata->rx_channel;
+       udi_cb_alloc_batch( acessnsr_ctrl_bind_ack__rx_cbs_allocated, rdata->active_cb,
+               ACESSNSR_CB_RX, NUM_RX_BUFFERS, TRUE, 0, NULL);
        // V V V V
 }
-void acessnsr_ctrl_bind_ack__rx_buf_allocated(udi_cb_t *gcb, udi_buf_t *new_buf)
+void acessnsr_ctrl_bind_ack__rx_cbs_allocated(udi_cb_t *gcb, udi_cb_t *first_new_cb)
 {
        acessnsr_rdata_t *rdata = gcb->context;
-       if( rdata->init_idx != (udi_index_t)-1 )
-       {
-               rdata->rx_buffers[rdata->init_idx] = new_buf;
-       }
-       rdata->init_idx ++;
-       if( rdata->init_idx < NUM_RX_BUFFERS )
-       {
-               UDI_BUF_ALLOC(acessnsr_ctrl_bind_ack__rx_buf_allocated, gcb, NULL, 0, NULL);
-               // A A A A
-               return ;
-       }
+       // Send of the entire list
+       ASSERT(first_new_cb);
+       udi_nd_rx_rdy( UDI_MCB(first_new_cb, udi_nic_rx_cb_t) );
        
-       rdata->init_idx = -1;
-       acessnsr_ctrl_bind_ack__rx_cb_allocated(gcb, NULL);
+       // Allocate batch (no buffers)
+       gcb->channel = rdata->tx_channel;
+       udi_cb_alloc_batch( acessnsr_ctrl_bind_ack__tx_cbs_allocated, gcb,
+               ACESSNSR_CB_TX, NUM_TX_DESCS, FALSE, 0, NULL);
+       // V V V V
 }
-void acessnsr_ctrl_bind_ack__rx_cb_allocated(udi_cb_t *gcb, udi_cb_t *new_cb)
+void acessnsr_ctrl_bind_ack__tx_cbs_allocated(udi_cb_t *gcb, udi_cb_t *first_new_cb)
 {
        acessnsr_rdata_t *rdata = gcb->context;
-       if( rdata->init_idx != (udi_index_t)-1 )
-       {
-               udi_nic_rx_cb_t *cb = UDI_MCB(new_cb, udi_nic_rx_cb_t);
-               rdata->rx_cbs[rdata->init_idx] = cb;
-               cb->rx_buf = rdata->rx_buffers[rdata->init_idx];
-               udi_nd_rx_rdy(cb);
-       }
-       rdata->init_idx ++;
-       if( rdata->init_idx < NUM_RX_BUFFERS )
+       ASSERT(first_new_cb);
+       
        {
-               udi_cb_alloc(acessnsr_ctrl_bind_ack__rx_cb_allocated, gcb, ACESSNSR_CB_RX, rdata->rx_channel);
-               // A A A A
-               return ;
+               udi_nic_tx_cb_t *cb, *next_cb;
+               cb = UDI_MCB(first_new_cb, udi_nic_tx_cb_t);
+               ASSERT(cb);
+               do {
+                       next_cb = cb->chain;
+                       cb->chain = NULL;
+                       Workqueue_AddWork( &rdata->TXWorkQueue, cb );
+               } while(next_cb);
        }
-       rdata->init_idx = -1;
-       acessnsr_ctrl_bind_ack__tx_cb_allocated(gcb, NULL);
+       
+       // Allocate standard control CB (for enable/disable)
+       udi_cb_alloc(acessnsr_ctrl_bind_ack__std_cb_allocated, gcb,
+               ACESSNSR_CB_STD, rdata->saved_active_channel);
        // V V V V
 }
-void acessnsr_ctrl_bind_ack__tx_cb_allocated(udi_cb_t *gcb, udi_cb_t *new_cb)
+void acessnsr_ctrl_bind_ack__std_cb_allocated(udi_cb_t *gcb, udi_cb_t *new_cb)
 {
-       acessnsr_rdata_t *rdata = gcb->context;
-       if( rdata->init_idx != (udi_index_t)-1 )
-       {
-               //udi_assert(new_cb);
-               ASSERT(new_cb);
-               Workqueue_AddWork( &rdata->TXWorkQueue,  UDI_MCB(new_cb, udi_nic_tx_cb_t) );
-       }
-       rdata->init_idx ++;
-       if( rdata->init_idx < NUM_TX_DESCS )
-       {
-               udi_cb_alloc(acessnsr_ctrl_bind_ack__tx_cb_allocated, gcb, ACESSNSR_CB_TX, rdata->tx_channel);
-               // A A A A
-               return ;
-       }
-       udi_channel_event_complete( UDI_MCB(rdata->active_cb,udi_channel_event_cb_t), UDI_OK );
-       // = = = =
+       // Final Operations:
+       // - Enable card (RX won't happen until this is called)
+       udi_nd_enable_req( UDI_MCB(new_cb, udi_nic_cb_t) );
+       // Continued in acessnsr_ctrl_enable_ack
 }
 void acessnsr_ctrl_unbind_ack(udi_nic_cb_t *cb, udi_status_t status)
 {
@@ -244,7 +227,12 @@ 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)
 {
-       UNIMPLEMENTED();
+       udi_cb_t        *gcb = UDI_GCB(cb);
+       acessnsr_rdata_t *rdata = gcb->context;
+       
+       rdata->active_cb->channel = rdata->saved_active_channel;
+       udi_channel_event_complete( UDI_MCB(rdata->active_cb,udi_channel_event_cb_t), UDI_OK );
+       // = = = =
 }
 void acessnsr_ctrl_disable_ack(udi_nic_cb_t *cb, udi_status_t status)
 {
@@ -303,11 +291,13 @@ void acessnsr_rx_exp_ind(udi_nic_rx_cb_t *cb)
 int acessnsr_SendPacket(void *Card, tIPStackBuffer *Buffer)
 {
        acessnsr_rdata_t *rdata = Card;
+       LOG("Card=%p,Buffer=%p", Card, Buffer);
        udi_nic_tx_cb_t *cb = Workqueue_GetWork(&rdata->TXWorkQueue);
        ASSERT(cb);
        acessnsr_txdesc_t *tx = UDI_GCB(cb)->scratch;
        ASSERT(tx);
-       
+
+       LOG("Mutex acquire #1 %p", cb);
        Mutex_Acquire(&tx->CompleteMutex);
        tx->IPBuffer = Buffer;
        tx->BufIdx = -1;
@@ -318,7 +308,8 @@ int acessnsr_SendPacket(void *Card, tIPStackBuffer *Buffer)
        Mutex_Release(&tx->CompleteMutex);
        // TODO: TX status
        
-       Workqueue_AddWork(&rdata->TXWorkQueue, tx);
+       LOG("Release %p", cb);  
+       Workqueue_AddWork(&rdata->TXWorkQueue, cb);
        return 0;
 }
 void acessnsr_SendPacket__buf_write_complete(udi_cb_t *gcb, udi_buf_t *buf)
@@ -332,6 +323,7 @@ void acessnsr_SendPacket__buf_write_complete(udi_cb_t *gcb, udi_buf_t *buf)
        const void      *bufptr;
        if( (tx->BufIdx = IPStack_Buffer_GetBuffer(tx->IPBuffer, tx->BufIdx, &buflen, &bufptr )) != -1 )
        {
+               Debug_HexDump("NSR", bufptr, buflen);
                udi_buf_write(acessnsr_SendPacket__buf_write_complete, gcb,
                        bufptr, buflen, cb->tx_buf, (cb->tx_buf ? cb->tx_buf->buf_size : 0), 0, NULL);
                // A A A A
@@ -421,6 +413,7 @@ udi_cb_init_t       acessnsr_cb_init_list[] = {
        {ACESSNSR_CB_CTRL, ACESSNSR_META_NIC, UDI_NIC_BIND_CB_NUM, 0, 0,NULL},
        {ACESSNSR_CB_RX, ACESSNSR_META_NIC, UDI_NIC_RX_CB_NUM, 0, 0,NULL},
        {ACESSNSR_CB_TX, ACESSNSR_META_NIC, UDI_NIC_TX_CB_NUM, sizeof(acessnsr_txdesc_t), 0,NULL},
+       {ACESSNSR_CB_STD, ACESSNSR_META_NIC, UDI_NIC_TX_CB_NUM, 0, 0,NULL},
        {0}
 };
 const udi_init_t       acessnsr_init = {
index a9df466..1dda055 100644 (file)
@@ -4,6 +4,7 @@
  * 
  * Buffer Manipulation
  */
+#define DEBUG  0
 #include <acess.h>
 #include <udi.h>
 #include <udi_internal.h>
@@ -18,9 +19,10 @@ typedef struct sUDI_BufTag
 typedef struct sUDI_BufSect
 {
        struct sUDI_BufSect     *Next;
-       size_t  Offset;
+       size_t  RelOfs;
        size_t  Length;
        size_t  Space;
+       void    *Data;
        // data
 } tUDI_BufSect;
 
@@ -47,12 +49,45 @@ void udi_buf_copy(
        udi_buf_t       *dst_buf,
        udi_size_t      dst_off,
        udi_size_t      dst_len,
-       udi_buf_path_t path_handle
+       udi_buf_path_t  path_handle
        )
 {
        UNIMPLEMENTED();
 }
 
+tUDI_BufSect *UDI_int_BufAddSect(size_t data_len, size_t relofs, tUDI_BufSect **prevptr, const void *data,
+       udi_buf_path_t path_handle
+       )
+{
+       const int       space_atom = 1<<7;
+       size_t  space = (data_len + space_atom-1) & ~(space_atom-1);
+       tUDI_BufSect    *newsect = NEW(tUDI_BufSect, + space);
+       newsect->RelOfs = relofs;
+       newsect->Length = data_len;
+       newsect->Space = space_atom;
+       newsect->Data = newsect+1;
+       memcpy(newsect->Data, data, data_len);
+       
+       newsect->Next = *prevptr;
+       *prevptr = newsect;
+       LOG("@0x%x : %p <= %p+%i", relofs, newsect->Data, data, data_len);
+       
+       return newsect;
+}
+
+udi_buf_t *_udi_buf_allocate(const void *data, udi_size_t length, udi_buf_path_t path_handle)
+{
+       tUDI_BufInt *buf = NEW(tUDI_BufInt,);
+       udi_buf_t *ret = &buf->buf;
+
+       if( data ) {
+               UDI_int_BufAddSect(length, 0, &buf->Sections, data, path_handle);
+       }
+       ret->buf_size = length;
+
+       return ret;
+}
+
 /**
  * \brief Write to a buffer
  * \param callback     Function to call once the write has completed
@@ -61,7 +96,7 @@ void udi_buf_copy(
  * \param src_len      Length of source data
  * \param dst_buf      Destination buffer
  * \param dst_off      Destination offset in the buffer
- * \param dst_len      Length of destination area
+ * \param dst_len      Length of area to be replaced
  * \param path_handle  ???
  */
 void udi_buf_write(
@@ -78,14 +113,52 @@ void udi_buf_write(
        tUDI_BufInt     *dst = (void*)dst_buf;
        if( !dst ) {
                dst = NEW(tUDI_BufInt,);
+               dst_buf = &dst->buf;
        }
-       
+
+       tUDI_BufSect    **prevptr = &dst->Sections;
+       tUDI_BufSect    *sect = dst->Sections;
+       for( ; sect; prevptr = &sect->Next, sect = sect->Next )
+       {
+               if(sect->RelOfs >= dst_off)
+                       break;
+               if(sect->RelOfs + sect->Length > dst_off)
+                       break ;
+               dst_off -= sect->RelOfs + sect->Length;
+       }
+
+       // Find dst_off segment (or create one if src_len>0)
+       // Copy in src data
+       // or (if src_len==0) delete dst_len bytes      
        if( dst_len == 0 )
        {
                // Insert / Initialise
                if( src_len > 0 )
                {
-                       Log_Warning("UDI", "TODO: udi_buf_write - insert");
+                       if( !sect || sect->RelOfs > dst_off ) {
+                               // Simple: Just add a new section
+                               UDI_int_BufAddSect(src_len, dst_off, prevptr, src_mem, path_handle);
+                               dst_buf->buf_size += src_len;
+                       }
+                       else if( sect->RelOfs + sect->Length == dst_off ) {
+                               // End of block inserts
+                               size_t  avail = sect->Space - sect->Length;
+                               if( avail ) {
+                                       size_t  bytes = MIN(avail, src_len);
+                                       memcpy(sect->Data + sect->Length, src_mem, bytes);
+                                       src_mem += bytes;
+                                       src_len -= bytes;
+                               }
+                               if( src_len ) {
+                                       // New block(s)
+                                       UDI_int_BufAddSect(src_len, 0, prevptr, src_mem, path_handle);
+                               }
+                               dst_buf->buf_size += src_len;
+                       }
+                       else {
+                               // Complex: Need to handle mid-section inserts
+                               Log_Warning("UDI", "TODO: udi_buf_write - mid-section inserts");
+                       }
                }
                // no-op
                else
@@ -94,15 +167,15 @@ void udi_buf_write(
        }
        else
        {
-               // Overwrite
-               if( src_len > 0 )
+               // Delete
+               if( src_len == 0 )
                {
-                       Log_Warning("UDI", "TODO: udi_buf_write - overwrite");
+                       Log_Warning("UDI", "TODO: udi_buf_write - delete");
                }
-               // Delete
+               // Overwrite
                else
                {
-                       Log_Warning("UDI", "TODO: udi_buf_write - delete");
+                       Log_Warning("UDI", "TODO: udi_buf_write - overwrite");
                }
        }
        
@@ -115,7 +188,48 @@ void udi_buf_read(
        udi_size_t      src_len,
        void    *dst_mem )
 {
-       UNIMPLEMENTED();
+       ENTER("psrc_buf isrc_off isrc_len pdst_mem",
+               src_buf, src_off, src_len, dst_mem);
+       tUDI_BufInt     *src = (void*)src_buf;
+       
+       tUDI_BufSect    *sect = src->Sections;
+       while( src_len )
+       {
+               for( ; sect; sect = sect->Next )
+               {
+                       LOG("%x <= %x <= +%x", sect->RelOfs, src_off, sect->Length);
+                       if(sect->RelOfs >= src_off)
+                               break;
+                       if(sect->RelOfs + sect->Length > src_off)
+                               break;
+                       src_off -= sect->RelOfs + sect->Length;
+               }
+               if( !sect ) {
+                       LOG("no section");
+                       break;
+               }
+               if( src_off < sect->RelOfs ) {
+                       size_t  undef_len = MIN(src_len, sect->RelOfs - src_off);
+                       LOG("%i undef", undef_len);
+                       memset(dst_mem, 0xFF, undef_len);
+                       dst_mem += undef_len;
+                       src_len -= undef_len;
+                       src_off += undef_len;
+               }
+               if( src_len == 0 )
+                       break;
+               ASSERTC(src_off, >=, sect->RelOfs);
+               size_t  ofs = src_off - sect->RelOfs;
+               size_t  len = MIN(src_len, sect->Length - ofs);
+               LOG("%i data from %p + %i", len, sect->Data, ofs);
+               memcpy(dst_mem, sect->Data+ofs, len);
+               dst_mem += len;
+               src_len -= len;
+       
+               src_off -= sect->RelOfs + sect->Length;
+               sect = sect->Next;
+       }
+       LEAVE('-');
 }
 
 void udi_buf_free(udi_buf_t *buf)
index c939934..2e0dbfc 100644 (file)
@@ -32,14 +32,14 @@ udi_cb_t *udi_cb_alloc_internal_v(tUDI_MetaLang *Meta, udi_index_t MetaCBNum,
        size_t  base = Meta->CbTypes[MetaCBNum].Size;
        ASSERTC(base, >=, sizeof(udi_cb_t));
        base -= sizeof(udi_cb_t);
-       LOG("(%s) udi_cb_t + %i + %i + %i",
-               Meta->Name, base, inline_size, scratch_size);
        tUDI_CBHeader   *cbhdr = NEW(tUDI_CBHeader, + base + inline_size + scratch_size);
        cbhdr->Metalang = Meta;
        cbhdr->MetaCBNum = MetaCBNum;
        udi_cb_t *ret = &cbhdr->cb;
        ret->channel = channel;
        ret->scratch = (void*)(ret + 1) + base + inline_size;
+       LOG("(%s) udi_cb_t + %i + %i + %i = %p",
+               Meta->Name, base, inline_size, scratch_size, ret);
        return ret;
 }
 void *udi_cb_alloc_internal(tUDI_DriverInstance *Inst, udi_ubit8_t bind_cb_idx, udi_channel_t channel)
@@ -106,7 +106,99 @@ void udi_cb_alloc_batch(
        udi_buf_path_t  path_handle
        )
 {
-       UNIMPLEMENTED();
+       tUDI_DriverInstance *inst = UDI_int_ChannelGetInstance(gcb, false, NULL);
+       udi_cb_init_t   *cb_init;
+       for( cb_init = inst->Module->InitInfo->cb_init_list; cb_init->cb_idx; cb_init ++ )
+       {
+               if( cb_init->cb_idx == cb_idx )
+                       break;
+       }
+       if( cb_init->cb_idx == 0 ) {
+               callback(gcb, NULL);
+               return ;
+       }
+       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, cb_idx, cb_init->meta_idx);
+               callback(gcb, NULL);
+               return ;
+       }
+
+       if( cb_init->meta_cb_num >= metalang->nCbTypes ) {      
+               Log_Warning("UDI", "Metalang CB referenced in %s CB %i is invalid (%s %i>=%i)",
+                       inst->Module->ModuleName, cb_idx,
+                       metalang->Name, cb_init->meta_cb_num, metalang->nCbTypes);
+               callback(gcb, NULL);
+               return ;
+       }       
+
+       // Get chain offset and buffer offset
+       size_t  buf_ofs = 0;    // TODO: Multiple buffers are to be supported
+       size_t  chain_ofs = 0;
+       {
+               udi_layout_t    *layout = metalang->CbTypes[cb_init->meta_cb_num].Layout;
+               if( !layout ) {
+                       Log_Warning("UDI", "Metalang CB %s:%i does not define a layout. Bulk alloc impossible",
+                               metalang->Name, cb_init->meta_cb_num);
+                       callback(gcb, NULL);
+                       return ;
+               }
+               
+               size_t  cur_ofs = sizeof(udi_cb_t);
+               while( *layout != UDI_DL_END )
+               {
+                       if( *layout == UDI_DL_BUF ) {
+                               if( buf_ofs ) {
+                                       Log_Notice("UDI", "TODO Multiple buffers in cb_alloc_batch (%s:%i)",
+                                               metalang->Name, cb_init->meta_cb_num);
+                               }
+                               buf_ofs = cur_ofs;
+                       }
+                       else if( *layout == UDI_DL_CB ) {
+                               if( chain_ofs ) {
+                                       Log_Warning("UDI", "Cb %s:%i has multiple DL_CB entries",
+                                               metalang->Name, cb_init->meta_cb_num);
+                               }
+                               chain_ofs = cur_ofs;
+                       }
+                       else {
+                               // No-op        
+                       }
+                       
+                       cur_ofs += _udi_marshal_step(NULL, 0, &layout, NULL);
+                       layout ++;
+               }
+       }
+
+       // Use initiator context if there's no chain
+       if( !chain_ofs ) {
+               chain_ofs = offsetof(udi_cb_t, initiator_context);
+               LOG("chain_ofs = %i (initiator_context)", chain_ofs);
+       }
+       else {
+               LOG("chain_ofs = %i", chain_ofs);
+       }
+
+       udi_cb_t *first_cb = NULL, *cur_cb;
+       udi_cb_t **prevptr = &first_cb;
+       for( int i = 0; i < count; i ++ )
+       {
+               cur_cb = udi_cb_alloc_internal_v(metalang, cb_init->meta_cb_num,
+                       cb_init->inline_size, cb_init->scratch_requirement, gcb->channel);
+
+               // Allocate buffer
+               if( with_buf && buf_ofs ) {
+                       *(void**)((char*)cur_cb + buf_ofs) =_udi_buf_allocate(NULL, buf_size, path_handle);
+               }
+
+               LOG("*%p = %p", prevptr, cur_cb);
+               *prevptr = cur_cb;
+               prevptr = (void*)cur_cb + chain_ofs;
+       }
+       *prevptr = NULL;
+       
+       callback(gcb, first_cb);
 }
 
 void udi_cb_free(udi_cb_t *cb)
index 97db27c..2df3178 100644 (file)
 #define _PUT(type,vtype) do{\
        ofs = alignto(ofs,type); \
        if(buf){\
-               *(type*)(buf+ofs) = va_arg(values,vtype);\
+               *(type*)(buf+ofs) = va_arg(*values,vtype);\
                LOG(#type" %p %x", buf+ofs, *(type*)(buf+ofs));\
        }\
-       else    va_arg(values,vtype); \
+       else if(values) \
+               va_arg(*values,vtype); \
        ofs += sizeof(type); \
 }while(0)
 
+size_t _udi_marshal_step(void *buf, size_t cur_ofs, udi_layout_t **layoutp, va_list *values)
+{
+       size_t  ofs = cur_ofs;
+       udi_layout_t    *layout = *layoutp;
+       switch(*layout++)
+       {
+       case UDI_DL_UBIT8_T:    _PUT(udi_ubit8_t, UDI_VA_UBIT8_T);      break;
+       case UDI_DL_SBIT8_T:    _PUT(udi_sbit8_t, UDI_VA_SBIT8_T);      break;
+       case UDI_DL_UBIT16_T:   _PUT(udi_ubit16_t, UDI_VA_UBIT16_T);    break;
+       case UDI_DL_SBIT16_T:   _PUT(udi_sbit16_t, UDI_VA_SBIT16_T);    break;
+       case UDI_DL_UBIT32_T:   _PUT(udi_ubit32_t, UDI_VA_UBIT32_T);    break;
+       case UDI_DL_SBIT32_T:   _PUT(udi_sbit32_t, UDI_VA_SBIT16_T);    break;
+       case UDI_DL_BOOLEAN_T:  _PUT(udi_boolean_t, UDI_VA_BOOLEAN_T);  break;
+       case UDI_DL_STATUS_T:   _PUT(udi_status_t, UDI_VA_STATUS_T);    break;
+       
+       case UDI_DL_INDEX_T:    _PUT(udi_index_t, UDI_VA_INDEX_T);      break;
+       
+       case UDI_DL_CHANNEL_T:  _PUT(udi_channel_t, UDI_VA_CHANNEL_T);  break;
+       case UDI_DL_ORIGIN_T:   _PUT(udi_origin_t, UDI_VA_ORIGIN_T);    break;
+
+       case UDI_DL_BUF:
+               _PUT(udi_buf_t*,UDI_VA_POINTER);
+               layout += 3;
+               break;
+       case UDI_DL_CB:
+               _PUT(udi_cb_t*,UDI_VA_POINTER);
+               break;
+
+       default:
+               Log_Error("UDI", "_udi_marshal_values - Unknown layout code %i", layout[-1]);
+               return 0;
+       }
+       *layoutp = layout;
+       return ofs;
+}
+
 size_t _udi_marshal_values(void *buf, udi_layout_t *layout, va_list values)
 {
        size_t  ofs = 0;
        while( *layout != UDI_DL_END )
        {
-               switch(*layout++)
-               {
-               case UDI_DL_UBIT8_T:    _PUT(udi_ubit8_t, UDI_VA_UBIT8_T);      break;
-               case UDI_DL_SBIT8_T:    _PUT(udi_sbit8_t, UDI_VA_SBIT8_T);      break;
-               case UDI_DL_UBIT16_T:   _PUT(udi_ubit16_t, UDI_VA_UBIT16_T);    break;
-               case UDI_DL_SBIT16_T:   _PUT(udi_sbit16_t, UDI_VA_SBIT16_T);    break;
-               case UDI_DL_UBIT32_T:   _PUT(udi_ubit32_t, UDI_VA_UBIT32_T);    break;
-               case UDI_DL_SBIT32_T:   _PUT(udi_sbit32_t, UDI_VA_SBIT16_T);    break;
-               case UDI_DL_BOOLEAN_T:  _PUT(udi_boolean_t, UDI_VA_BOOLEAN_T);  break;
-               case UDI_DL_STATUS_T:   _PUT(udi_status_t, UDI_VA_STATUS_T);    break;
-               
-               case UDI_DL_INDEX_T:    _PUT(udi_index_t, UDI_VA_INDEX_T);      break;
-               
-               case UDI_DL_CHANNEL_T:  _PUT(udi_channel_t, UDI_VA_CHANNEL_T);  break;
-               case UDI_DL_ORIGIN_T:   _PUT(udi_origin_t, UDI_VA_ORIGIN_T);    break;
-               
-               default:
-                       Log_Error("UDI", "_udi_marshal_values - Unknown layout code %i", layout[-1]);
-                       return -1;
-               }
+               ofs = _udi_marshal_step(buf, ofs, &layout, &values);
+               if( ofs == 0 )
+                       return 0;
        }
        return ofs;
 }
index e0caec7..338898c 100644 (file)
@@ -20,13 +20,14 @@ void _udi_mei_call_unmarshal(tUDI_DeferredCall *DCall)
 {
        tUDI_MeiCall    *Call = (void*)DCall;
        const udi_mei_op_template_t     *mei_op = Call->mei_op;
+       LOG("%s backend", mei_op->op_name);
        mei_op->backend_stub(Call->DCall.Handler, Call->DCall.cb, Call+1);
 }
 
 void udi_mei_call(udi_cb_t *gcb, udi_mei_init_t *meta_info, udi_index_t meta_ops_num, udi_index_t vec_idx, ...)
 {
-       ENTER("pgcb pmeta_info imeta_ops_num ivec_idx",
-               gcb, meta_info, meta_ops_num, vec_idx);
+//     ENTER("pgcb pmeta_info imeta_ops_num ivec_idx",
+//             gcb, meta_info, meta_ops_num, vec_idx);
        const udi_mei_op_template_t     *mei_op;
 
        {
@@ -40,27 +41,32 @@ void udi_mei_call(udi_cb_t *gcb, udi_mei_init_t *meta_info, udi_index_t meta_ops
                mei_op = &ops->op_template_list[vec_idx-1];
        }
        
-       LOG("%s", mei_op->op_name);
-
        // Check CB type
        udi_index_t     cb_type;
        tUDI_MetaLang   *metalang = UDI_int_GetCbType(gcb, &cb_type);
-       //if( metalang->MeiInfo != meta_info )
-       //      return ;
-       if( mei_op->meta_cb_num != cb_type ) {
-               LEAVE('-');
+       if( meta_info != metalang->MeiInfo && mei_op->meta_cb_num != cb_type ) {
+               Log_Warning("UDI", "%s meta cb mismatch want %p:%i got %p:%i",
+                       mei_op->op_name,
+                       meta_info, mei_op->meta_cb_num,
+                       metalang->MeiInfo, cb_type
+                       );
+               ASSERTC(meta_info, ==, metalang->MeiInfo);
+               ASSERTC(mei_op->meta_cb_num, ==, cb_type);
+//             LEAVE('-');
                return ;
        }
-       // Check call type
-       udi_op_t        *const*ops = UDI_int_ChannelPrepForCall(gcb, metalang, meta_ops_num);
-       udi_op_t        *op = ops[vec_idx];
        
-       // Start va_args
        // Determine if indirect call is needed
        // > check stack depth?
        // > Direction?
         int indirect_call = (mei_op->op_category == UDI_MEI_OPCAT_REQ)
                || (mei_op->op_category == UDI_MEI_OPCAT_IND);
+       
+       LOG("%s %sdirect", mei_op->op_name, (indirect_call ? "in" : ""));
+       
+       // Check call type
+       udi_op_t        *const*ops = UDI_int_ChannelPrepForCall(gcb, metalang, meta_ops_num);
+       udi_op_t        *op = ops[vec_idx];
        if( indirect_call )
        {
                va_list args;
@@ -87,6 +93,6 @@ void udi_mei_call(udi_cb_t *gcb, udi_mei_init_t *meta_info, udi_index_t meta_ops
                mei_op->direct_stub( op, gcb, args );
                va_end(args);
        }
-       LEAVE('-');
+//     LEAVE('-');
 }
 
index 865ace4..1c13b31 100644 (file)
@@ -22,7 +22,7 @@ EXPORT(udi_final_cleanup_ack);
 
 tUDI_MetaLang  cMetaLang_Management = {
        "udi_mgmt",
-       
+       NULL,
        3,
        {
                {sizeof(udi_enumerate_cb_t), NULL},
index af5b88f..5fe1cb9 100644 (file)
@@ -202,6 +202,10 @@ udi_layout_t       udi_meta_info__bridge__intr_event_cb[] = {
        UDI_DL_END
 };
 
+udi_layout_t   _BUS_BIND_cb_layout[] = {
+       UDI_DL_END
+};
+
 #if USE_MEI
 udi_layout_t   _noargs_marshal[] = {
        UDI_DL_END
@@ -267,6 +271,11 @@ udi_mei_init_t     udi_meta_info__bridge = {
 #endif
 tUDI_MetaLang  cMetaLang_BusBridge = {
        "udi_bridge",
+       #if USE_MEI
+       &udi_meta_info__bridge,
+       #else
+       NULL,
+       #endif
        // CB Types
        5,
        {
index 8297eab..4d05e45 100644 (file)
@@ -2,7 +2,7 @@
  * \file udi_lib/physio/pio.c
  * \author John Hodge (thePowersGang)
  */
-#define DEBUG  0
+#define DEBUG  1
 #include <udi.h>
 #include <udi_physio.h>
 #include <acess.h>
@@ -294,13 +294,16 @@ static inline int _read_mem(udi_cb_t *gcb, udi_buf_t *buf, void *mem_ptr,
        case UDI_PIO_SCRATCH:
                ASSERTCR( (ofs & (size-1)), ==, 0, 1);
                memcpy(val, gcb->scratch + ofs, size);
+               //LOG("scr %p+%i => %i %x,...", gcb->scratch, ofs, size, val->words[0]);
                break;
        case UDI_PIO_BUF:
                udi_buf_read(buf, ofs, size, val);
+               //LOG("buf %p+%i => %i %x,...", buf, ofs, size, val->words[0]);
                break;
        case UDI_PIO_MEM:
                ASSERTCR( (ofs & (size-1)), ==, 0, 1 );
                memcpy(val, mem_ptr + ofs, size);
+               //LOG("mem %p+%i => %i %x,...", mem_ptr, ofs, size, val->words[0]);
                break;
        }
        return 0;
index f2b6b4d..5dfd7d5 100644 (file)
@@ -37,85 +37,69 @@ EXPORT(udi_nsr_rx_ind);
 EXPORT(udi_nsr_exp_rx_ind);
 EXPORT(udi_nd_rx_rdy);
 
-// === 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 ---
+// ND - Network Device
 UDI_MEI_STUBS(udi_nd_bind_req, udi_nic_bind_cb_t,
-       2,
-       (tx_chan_index,  rx_chan_index),
-       (udi_index_t,    udi_index_t),
-       (UDI_VA_INDEX_T, UDI_VA_INDEX_T),
+       2, (tx_chan_index, rx_chan_index), (udi_index_t, udi_index_t), (UDI_VA_INDEX_T, UDI_VA_INDEX_T),
        UDI_ND_CTRL_OPS_NUM, 1)
 udi_layout_t   _udi_nd_bind_req_marshal_layout[] = { UDI_DL_INDEX_T, UDI_DL_INDEX_T, UDI_DL_END };
+
+UDI_MEI_STUBS(udi_nd_unbind_req, udi_nic_cb_t,
+       0, (), (), (),
+       UDI_ND_CTRL_OPS_NUM, 2)
+udi_layout_t   _udi_nd_unbind_req_marshal_layout[] = { UDI_DL_END };
+
+UDI_MEI_STUBS(udi_nd_enable_req, udi_nic_cb_t,
+       0, (), (), (),
+       UDI_ND_CTRL_OPS_NUM, 3)
+udi_layout_t   _udi_nd_enable_req_marshal_layout[] = { UDI_DL_END };
+
+UDI_MEI_STUBS(udi_nd_disable_req, udi_nic_cb_t,
+       0, (), (), (),
+       UDI_ND_CTRL_OPS_NUM, 4)
+udi_layout_t   _udi_nd_disable_req_marshal_layout[] = { UDI_DL_END };
+
+UDI_MEI_STUBS(udi_nd_ctrl_req, udi_nic_ctrl_cb_t,
+       0, (), (), (),
+       UDI_ND_CTRL_OPS_NUM, 5)
+udi_layout_t   _udi_nd_ctrl_req_marshal_layout[] = { UDI_DL_END };
+
+UDI_MEI_STUBS(udi_nd_info_req, udi_nic_info_cb_t,
+       1, (reset_statistics), (udi_boolean_t), (UDI_VA_BOOLEAN_T),
+       UDI_ND_CTRL_OPS_NUM, 6)
+udi_layout_t   _udi_nd_info_req_marshal_layout[] = { UDI_DL_BOOLEAN_T, UDI_DL_END };
+
+// NSR - Network Service Requester
 UDI_MEI_STUBS(udi_nsr_bind_ack, udi_nic_bind_cb_t,
        1, (status), (udi_status_t), (UDI_VA_STATUS_T),
        UDI_NSR_CTRL_OPS_NUM, 1)
 udi_layout_t   _udi_nsr_bind_ack_marshal_layout[] = { UDI_DL_STATUS_T, UDI_DL_END };
 
-void udi_nd_unbind_req(udi_nic_cb_t *cb)
-{
-       UNIMPLEMENTED();
-}
-
-void udi_nsr_unbind_ack(udi_nic_cb_t *cb, udi_status_t status)
-{
-       UNIMPLEMENTED();
-}
-
-void udi_nd_enable_req(udi_nic_cb_t *cb)
-{
-       UNIMPLEMENTED();
-}
-
-void udi_nsr_enable_ack(udi_nic_cb_t *cb, udi_status_t status)
-{
-       UNIMPLEMENTED();
-}
-
-void udi_nd_disable_req(udi_nic_cb_t *cb)
-{
-       UNIMPLEMENTED();
-}
-
-void udi_nd_ctrl_req(udi_nic_ctrl_cb_t *cb)
-{
-       UNIMPLEMENTED();
-}
-
-void udi_nsr_ctrl_ack(udi_nic_ctrl_cb_t *cb, udi_status_t status)
-{
-       UNIMPLEMENTED();
-}
-
-void udi_nsr_status_ind(udi_nic_status_cb_t *cb)
-{
-       UNIMPLEMENTED();
-}
-
-void udi_nd_info_req(udi_nic_info_cb_t *cb, udi_boolean_t reset_statistics)
-{
-       UNIMPLEMENTED();
-}
-
-void udi_nsr_info_ack(udi_nic_info_cb_t *cb)
-{
-       UNIMPLEMENTED();
-}
+UDI_MEI_STUBS(udi_nsr_unbind_ack, udi_nic_cb_t,
+       1, (status), (udi_status_t), (UDI_VA_STATUS_T),
+       UDI_NSR_CTRL_OPS_NUM, 2)
+udi_layout_t   _udi_nsr_unbind_ack_marshal_layout[] = { UDI_DL_STATUS_T, UDI_DL_END };
+
+UDI_MEI_STUBS(udi_nsr_enable_ack, udi_nic_cb_t,
+       1, (status), (udi_status_t), (UDI_VA_STATUS_T),
+       UDI_NSR_CTRL_OPS_NUM, 3)
+udi_layout_t   _udi_nsr_enable_ack_marshal_layout[] = { UDI_DL_STATUS_T, UDI_DL_END };
+
+UDI_MEI_STUBS(udi_nsr_ctrl_ack, udi_nic_ctrl_cb_t,
+       1, (status), (udi_status_t), (UDI_VA_STATUS_T),
+       UDI_NSR_CTRL_OPS_NUM, 4)
+udi_layout_t   _udi_nsr_ctrl_ack_marshal_layout[] = { UDI_DL_STATUS_T, UDI_DL_END };
+
+UDI_MEI_STUBS(udi_nsr_status_ind, udi_nic_status_cb_t,
+       0, (), (), (),
+       UDI_NSR_CTRL_OPS_NUM, 5)
+udi_layout_t   _udi_nsr_status_ind_marshal_layout[] = { UDI_DL_END };
+
+UDI_MEI_STUBS(udi_nsr_info_ack, udi_nic_info_cb_t,
+       0, (), (), (),
+       UDI_NSR_CTRL_OPS_NUM, 6)
+udi_layout_t   _udi_nsr_info_ack_marshal_layout[] = { UDI_DL_END };
 
 // --- TX ---
 UDI_MEI_STUBS(udi_nsr_tx_rdy,  udi_nic_tx_cb_t, 0, (), (), (), UDI_NSR_TX_OPS_NUM, 1);
@@ -139,6 +123,11 @@ udi_layout_t       _udi_nd_rx_rdy_marshal_layout[] = { UDI_DL_END };
                UDI_##rsp_ops##_OPS_NUM,rsp_idx,UDI_##err_ops##_OPS_NUM,err_idx, \
                name##_direct, name##_backend, _##cbtype##_cb_layout, _##name##_marshal_layout }
 
+// 1: UDI_NIC_STD_CB_NUM
+udi_layout_t   _NIC_STD_cb_layout[] = {
+       UDI_DL_END
+};
+// 2: UDI_NIC_BIND_CB_NUM
 udi_layout_t   _NIC_BIND_cb_layout[] = {
        UDI_DL_UBIT8_T, // media_type
        UDI_DL_UBIT32_T,        // min_pdu_size
@@ -154,6 +143,38 @@ udi_layout_t       _NIC_BIND_cb_layout[] = {
                UDI_DL_END,
        UDI_DL_END
 };
+// 3: UDI_NIC_CTRL_CB_NUM
+udi_layout_t   _NIC_CTRL_cb_layout[] = {
+       UDI_DL_UBIT8_T, // command
+       UDI_DL_UBIT32_T,        // indicator
+       UDI_DL_BUF, 0,0,0,      // data_buf
+       UDI_DL_END
+       
+};
+// 4: UDI_NIC_STATUS_CB_NUM
+udi_layout_t   _NIC_STATUS_cb_layout[] = {
+       UDI_DL_UBIT8_T,
+       UDI_DL_END
+};
+// 5: UDI_NIC_INFO_CB_NUM
+udi_layout_t   _NIC_INFO_cb_layout[] = {
+       UDI_DL_BOOLEAN_T,       // interface_is_active
+       UDI_DL_BOOLEAN_T,       // link_is_active
+       UDI_DL_BOOLEAN_T,       // is_full_duplex
+       UDI_DL_UBIT32_T,        // link_mbps
+       UDI_DL_UBIT32_T,        // link_bps
+       UDI_DL_UBIT32_T,        // tx_packets
+       UDI_DL_UBIT32_T,        // rx_packets
+       UDI_DL_UBIT32_T,        // tx_errors
+       UDI_DL_UBIT32_T,        // rx_errors
+       UDI_DL_UBIT32_T,        // tx_discards
+       UDI_DL_UBIT32_T,        // rx_discards
+       UDI_DL_UBIT32_T,        // tx_underrun
+       UDI_DL_UBIT32_T,        // rx_underrun
+       UDI_DL_UBIT32_T,        // collisions
+       UDI_DL_END
+};
+// 6: UDI_NIC_RX_CB_NUM
 udi_layout_t   _NIC_RX_cb_layout[] = {
        UDI_DL_CB,      // chain
        UDI_DL_BUF, 0, 0, 0,    // rx_buf
@@ -162,6 +183,7 @@ udi_layout_t        _NIC_RX_cb_layout[] = {
        UDI_DL_UBIT8_T, // rx_valid
        UDI_DL_END
 };
+// 7: UDI_NIC_TX_CB_NUM
 udi_layout_t   _NIC_TX_cb_layout[] = {
        UDI_DL_CB,      // chain
        UDI_DL_BUF, 0, 0, 0,    // tx_buf
@@ -171,10 +193,20 @@ udi_layout_t      _NIC_TX_cb_layout[] = {
 
 udi_mei_op_template_t  udi_mei_info__nic__nd_ctrl_ops[] = {
        MEI_OPINFO(udi_nd_bind_req, REQ, 0, NIC_BIND, NSR_CTRL,1, ,0),
+       MEI_OPINFO(udi_nd_unbind_req, REQ, 0, NIC_STD, NSR_CTRL,2, ,0),
+       MEI_OPINFO(udi_nd_enable_req, REQ, 0, NIC_STD, NSR_CTRL,3, ,0),
+       MEI_OPINFO(udi_nd_disable_req, REQ, 0, NIC_STD, ,0, ,0),
+       MEI_OPINFO(udi_nd_ctrl_req, REQ, 0, NIC_CTRL, NSR_CTRL,4, ,0),
+       MEI_OPINFO(udi_nd_info_req, REQ, 0, NIC_INFO, NSR_CTRL,5, ,0),
        {0} 
 };
 udi_mei_op_template_t  udi_mei_info__nic__nsr_ctrl_ops[] = {
        MEI_OPINFO(udi_nsr_bind_ack, ACK, 0, NIC_BIND, ,0, ,0),
+       MEI_OPINFO(udi_nsr_unbind_ack, ACK, 0, NIC_STD, ,0, ,0),
+       MEI_OPINFO(udi_nsr_enable_ack, ACK, 0, NIC_STD, ,0, ,0),
+       MEI_OPINFO(udi_nsr_ctrl_ack, ACK, 0, NIC_CTRL, ,0, ,0),
+       MEI_OPINFO(udi_nsr_info_ack, ACK, 0, NIC_INFO, ,0, ,0),
+       MEI_OPINFO(udi_nsr_status_ind, IND, 0, NIC_INFO, ,0, ,0),
        {0}
 };
 udi_mei_op_template_t  udi_mei_info__nic__nd_tx_ops[] = {
@@ -209,3 +241,19 @@ udi_mei_init_t     udi_mei_info__nic = {
        udi_mei_info__nic_ops,
        NULL
 };
+
+tUDI_MetaLang  cMetaLang_NIC = {
+       "udi_nic",
+       &udi_mei_info__nic,
+       8,
+       {
+               {0},
+               {sizeof(udi_nic_cb_t), _NIC_STD_cb_layout},
+               {sizeof(udi_nic_bind_cb_t), _NIC_BIND_cb_layout},
+               {sizeof(udi_nic_ctrl_cb_t), _NIC_CTRL_cb_layout},
+               {sizeof(udi_nic_status_cb_t), _NIC_STATUS_cb_layout},
+               {sizeof(udi_nic_info_cb_t), _NIC_INFO_cb_layout},
+               {sizeof(udi_nic_tx_cb_t), _NIC_TX_cb_layout},
+               {sizeof(udi_nic_rx_cb_t), _NIC_RX_cb_layout},
+       }
+};

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