From: John Hodge Date: Sat, 12 Oct 2013 13:50:27 +0000 (+0800) Subject: Modules/UDI - Heaps of fixes and features X-Git-Tag: rel0.15~112 X-Git-Url: https://git.ucc.asn.au/?a=commitdiff_plain;h=948e0dcc41c180071b4534a2c4ec680306414af0;p=tpg%2Facess2.git Modules/UDI - Heaps of fixes and features - Buffer read working - Buffer write is simple insert-only atm - Batch cb allocations implemented --- diff --git a/KernelLand/Modules/Interfaces/UDI/channels.c b/KernelLand/Modules/Interfaces/UDI/channels.c index 993308b6..b3865077 100644 --- a/KernelLand/Modules/Interfaces/UDI/channels.c +++ b/KernelLand/Modules/Interfaces/UDI/channels.c @@ -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); diff --git a/KernelLand/Modules/Interfaces/UDI/deferred_calls.c b/KernelLand/Modules/Interfaces/UDI/deferred_calls.c index aec1fcb5..49738bb4 100644 --- a/KernelLand/Modules/Interfaces/UDI/deferred_calls.c +++ b/KernelLand/Modules/Interfaces/UDI/deferred_calls.c @@ -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); } diff --git a/KernelLand/Modules/Interfaces/UDI/include/udi_internal.h b/KernelLand/Modules/Interfaces/UDI/include/udi_internal.h index ff7f2786..83093f9f 100644 --- a/KernelLand/Modules/Interfaces/UDI/include/udi_internal.h +++ b/KernelLand/Modules/Interfaces/UDI/include/udi_internal.h @@ -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 diff --git a/KernelLand/Modules/Interfaces/UDI/trans/bus_pci.c b/KernelLand/Modules/Interfaces/UDI/trans/bus_pci.c index e5d3bf45..2d7459a8 100644 --- a/KernelLand/Modules/Interfaces/UDI/trans/bus_pci.c +++ b/KernelLand/Modules/Interfaces/UDI/trans/bus_pci.c @@ -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) diff --git a/KernelLand/Modules/Interfaces/UDI/trans/nsr.c b/KernelLand/Modules/Interfaces/UDI/trans/nsr.c index 879d0bdc..e6a39308 100644 --- a/KernelLand/Modules/Interfaces/UDI/trans/nsr.c +++ b/KernelLand/Modules/Interfaces/UDI/trans/nsr.c @@ -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 = { diff --git a/KernelLand/Modules/Interfaces/UDI/udi_lib/core/buf.c b/KernelLand/Modules/Interfaces/UDI/udi_lib/core/buf.c index a9df466b..1dda0552 100644 --- a/KernelLand/Modules/Interfaces/UDI/udi_lib/core/buf.c +++ b/KernelLand/Modules/Interfaces/UDI/udi_lib/core/buf.c @@ -4,6 +4,7 @@ * * Buffer Manipulation */ +#define DEBUG 0 #include #include #include @@ -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 = §->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) diff --git a/KernelLand/Modules/Interfaces/UDI/udi_lib/core/cb.c b/KernelLand/Modules/Interfaces/UDI/udi_lib/core/cb.c index c9399348..2e0dbfcc 100644 --- a/KernelLand/Modules/Interfaces/UDI/udi_lib/core/cb.c +++ b/KernelLand/Modules/Interfaces/UDI/udi_lib/core/cb.c @@ -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) diff --git a/KernelLand/Modules/Interfaces/UDI/udi_lib/core/layout.c b/KernelLand/Modules/Interfaces/UDI/udi_lib/core/layout.c index 97db27c8..2df3178e 100644 --- a/KernelLand/Modules/Interfaces/UDI/udi_lib/core/layout.c +++ b/KernelLand/Modules/Interfaces/UDI/udi_lib/core/layout.c @@ -16,38 +16,58 @@ #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; } diff --git a/KernelLand/Modules/Interfaces/UDI/udi_lib/core/mei.c b/KernelLand/Modules/Interfaces/UDI/udi_lib/core/mei.c index e0caec7e..338898cf 100644 --- a/KernelLand/Modules/Interfaces/UDI/udi_lib/core/mei.c +++ b/KernelLand/Modules/Interfaces/UDI/udi_lib/core/mei.c @@ -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('-'); } diff --git a/KernelLand/Modules/Interfaces/UDI/udi_lib/core/meta_mgmt.c b/KernelLand/Modules/Interfaces/UDI/udi_lib/core/meta_mgmt.c index 865ace44..1c13b310 100644 --- a/KernelLand/Modules/Interfaces/UDI/udi_lib/core/meta_mgmt.c +++ b/KernelLand/Modules/Interfaces/UDI/udi_lib/core/meta_mgmt.c @@ -22,7 +22,7 @@ EXPORT(udi_final_cleanup_ack); tUDI_MetaLang cMetaLang_Management = { "udi_mgmt", - + NULL, 3, { {sizeof(udi_enumerate_cb_t), NULL}, diff --git a/KernelLand/Modules/Interfaces/UDI/udi_lib/physio/meta_bus.c b/KernelLand/Modules/Interfaces/UDI/udi_lib/physio/meta_bus.c index af5b88f0..5fe1cb98 100644 --- a/KernelLand/Modules/Interfaces/UDI/udi_lib/physio/meta_bus.c +++ b/KernelLand/Modules/Interfaces/UDI/udi_lib/physio/meta_bus.c @@ -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, { diff --git a/KernelLand/Modules/Interfaces/UDI/udi_lib/physio/pio.c b/KernelLand/Modules/Interfaces/UDI/udi_lib/physio/pio.c index 8297eab9..4d05e45a 100644 --- a/KernelLand/Modules/Interfaces/UDI/udi_lib/physio/pio.c +++ b/KernelLand/Modules/Interfaces/UDI/udi_lib/physio/pio.c @@ -2,7 +2,7 @@ * \file udi_lib/physio/pio.c * \author John Hodge (thePowersGang) */ -#define DEBUG 0 +#define DEBUG 1 #include #include #include @@ -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; diff --git a/KernelLand/Modules/Interfaces/UDI/udi_lib/udi_nic.c b/KernelLand/Modules/Interfaces/UDI/udi_lib/udi_nic.c index f2b6b4d8..5dfd7d50 100644 --- a/KernelLand/Modules/Interfaces/UDI/udi_lib/udi_nic.c +++ b/KernelLand/Modules/Interfaces/UDI/udi_lib/udi_nic.c @@ -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}, + } +};