IX_STATUS ixNpeMhSendMessageSend ( IxNpeMhNpeId npeId, IxNpeMhMessage message, UINT32 maxSendRetries) { IX_STATUS status; IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Entering " "ixNpeMhSendMessageSend\n"); /* update statistical info */ ixNpeMhSendStats[npeId].sends++; /* check if the NPE's inFIFO is full - if so return an error */ if (ixNpeMhSendInFifoIsFull (npeId, maxSendRetries)) { IX_NPEMH_TRACE0 (IX_NPEMH_WARNING, "NPE's inFIFO is full\n"); return IX_FAIL; } /* write the message to the NPE's inFIFO */ status = ixNpeMhConfigInFifoWrite (npeId, message); IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Exiting " "ixNpeMhSendMessageSend\n"); return status; }
/* * Function definition: ixNpeMhUnsolicitedCbMgrCallbackSave */ void ixNpeMhUnsolicitedCbMgrUninitialize (void) { IxNpeMhNpeId npeId; IxNpeMhUnsolicitedCallbackTable *table; IxNpeMhMessageId messageId; IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Entering " "ixNpeMhUnsolicitedCbMgrUninitialize\n"); /* for each NPE ... */ for (npeId = 0; npeId < IX_NPEMH_NUM_NPES; npeId++) { /* initialise a pointer to the table for convenience */ table = &ixNpeMhUnsolicitedCallbackTables[npeId]; /* for each message ID ... */ for (messageId = IX_NPEMH_MIN_MESSAGE_ID; messageId <= IX_NPEMH_MAX_MESSAGE_ID; messageId++) { /* initialise the callback for this message ID to NULL */ table->entries[messageId] = NULL; } } IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Exiting " "ixNpeMhUnsolicitedCbMgrUninitialize\n"); }
void ixNpeMhSolicitedCbMgrInitialize (void) { IxNpeMhNpeId npeId; UINT32 localIndex; IxNpeMhSolicitedCallbackList *list = NULL; IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Entering " "ixNpeMhSolicitedCbMgrInitialize\n"); /* for each NPE ... */ for (npeId = 0; npeId < IX_NPEMH_NUM_NPES; npeId++) { /* initialise a pointer to the list for convenience */ list = &ixNpeMhSolicitedCbMgrCallbackLists[npeId]; /* for each entry in the list, after the dummy entry ... */ for (localIndex = 1; localIndex <= IX_NPEMH_MAX_CALLBACKS; localIndex++) { /* initialise the entry */ list->entries[localIndex].messageId = 0x00; list->entries[localIndex].callback = NULL; /* if this entry is before the last entry */ if (localIndex < IX_NPEMH_MAX_CALLBACKS) { /* chain this entry to the following entry */ list->entries[localIndex].next = &(list->entries[localIndex + 1]); } else /* this entry is the last entry */ { /* the last entry isn't chained to anything */ list->entries[localIndex].next = NULL; } } /* set the free list pointer to point to the first real entry */ /* (all real entries begin chained together on the free list) */ list->freeHead = &(list->entries[1]); /* set the callback list pointers to point to the dummy entry */ /* (the callback list is initially empty) */ list->callbackHead = &(list->entries[0]); list->callbackTail = &(list->entries[0]); } IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Exiting " "ixNpeMhSolicitedCbMgrInitialize\n"); }
IX_STATUS ixNpeMhSolicitedCbMgrCallbackSave ( IxNpeMhNpeId npeId, IxNpeMhMessageId solicitedMessageId, IxNpeMhCallback solicitedCallback) { IxNpeMhSolicitedCallbackList *list = NULL; IxNpeMhSolicitedCallbackListEntry *callbackEntry = NULL; IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Entering " "ixNpeMhSolicitedCbMgrCallbackSave\n"); /* initialise a pointer to the list for convenience */ list = &ixNpeMhSolicitedCbMgrCallbackLists[npeId]; /* check to see if there are any entries in the free list */ if (list->freeHead == NULL) { IX_NPEMH_ERROR_REPORT ("Solicited callback list is full\n"); return IX_FAIL; } /* there is an entry in the free list we can use */ /* update statistical info */ ixNpeMhSolicitedCbMgrStats[npeId].saves++; /* remove a callback entry from the start of the free list */ callbackEntry = list->freeHead; list->freeHead = callbackEntry->next; /* fill in the callback entry with the new data */ callbackEntry->messageId = solicitedMessageId; callbackEntry->callback = solicitedCallback; /* the new callback entry will be added to the tail of the callback */ /* list, so it isn't chained to anything */ callbackEntry->next = NULL; /* chain new callback entry to the last entry of the callback list */ list->callbackTail->next = callbackEntry; list->callbackTail = callbackEntry; IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Exiting " "ixNpeMhSolicitedCbMgrCallbackSave\n"); return IX_SUCCESS; }
/* * Function definition: ixNpeMhReceiveUninitialize */ void ixNpeMhReceiveUninitialize (void) { IxNpeMhNpeId npeId; IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Entering " "ixNpeMhReceiveUninitialize\n"); /* for each NPE ... */ for (npeId = 0; npeId < IX_NPEMH_NUM_NPES; npeId++) { /* unregister and set ISR to NULL */ ixNpeMhConfigIsrUnregister (npeId); } IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Exiting " "ixNpeMhReceiveUninitialize\n"); }
IX_STATUS ixNpeMhSendMessageWithResponseSend ( IxNpeMhNpeId npeId, IxNpeMhMessage message, IxNpeMhMessageId solicitedMessageId, IxNpeMhCallback solicitedCallback, UINT32 maxSendRetries) { IX_STATUS status = IX_SUCCESS; IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Entering " "ixNpeMhSendMessageWithResponseSend\n"); /* update statistical info */ ixNpeMhSendStats[npeId].sendWithResponses++; /* sr: this sleep will call the receive routine (no interrupts used!!!) */ ixOsalSleep (IX_NPEMH_INFIFO_RETRY_DELAY_US); /* check if the NPE's inFIFO is full - if so return an error */ if (ixNpeMhSendInFifoIsFull (npeId, maxSendRetries)) { IX_NPEMH_TRACE0 (IX_NPEMH_WARNING, "NPE's inFIFO is full\n"); return IX_FAIL; } /* save the solicited callback */ status = ixNpeMhSolicitedCbMgrCallbackSave ( npeId, solicitedMessageId, solicitedCallback); if (status != IX_SUCCESS) { IX_NPEMH_ERROR_REPORT ("Failed to save solicited callback\n"); /* update statistical info */ ixNpeMhSendStats[npeId].callbackFulls++; return status; } /* write the message to the NPE's inFIFO */ status = ixNpeMhConfigInFifoWrite (npeId, message); IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Exiting " "ixNpeMhSendMessageWithResponseSend\n"); return status; }
void ixNpeMhReceiveInitialize (void) { IxNpeMhNpeId npeId = 0; IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Entering " "ixNpeMhReceiveInitialize\n"); /* for each NPE ... */ for (npeId = 0; npeId < IX_NPEMH_NUM_NPES; npeId++) { /* register our internal ISR for the NPE to handle "outFIFO not */ /* empty" interrupts */ ixNpeMhConfigIsrRegister (npeId, ixNpeMhReceiveIsr); } IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Exiting " "ixNpeMhReceiveInitialize\n"); }
void ixNpeMhUnsolicitedCbMgrCallbackSave ( IxNpeMhNpeId npeId, IxNpeMhMessageId unsolicitedMessageId, IxNpeMhCallback unsolicitedCallback) { IxNpeMhUnsolicitedCallbackTable *table = NULL; /* initialise a pointer to the table for convenience */ table = &ixNpeMhUnsolicitedCallbackTables[npeId]; IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Entering " "ixNpeMhUnsolicitedCbMgrCallbackSave\n"); /* update statistical info */ ixNpeMhUnsolicitedCbMgrStats[npeId].saves++; /* check if there is a callback already registered for this NPE and */ /* message ID */ if (table->entries[unsolicitedMessageId] != NULL) { /* if we are overwriting an existing callback */ if (unsolicitedCallback != NULL) { IX_NPEMH_TRACE2 (IX_NPEMH_DEBUG, "Unsolicited callback " "overwriting existing callback for NPE ID %d " "message ID 0x%02X\n", npeId, unsolicitedMessageId); } else /* if we are clearing an existing callback */ { IX_NPEMH_TRACE2 (IX_NPEMH_DEBUG, "NULL unsolicited callback " "clearing existing callback for NPE ID %d " "message ID 0x%02X\n", npeId, unsolicitedMessageId); } /* update statistical info */ ixNpeMhUnsolicitedCbMgrStats[npeId].overwrites++; } /* save the callback into the table */ table->entries[unsolicitedMessageId] = unsolicitedCallback; IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Exiting " "ixNpeMhUnsolicitedCbMgrCallbackSave\n"); }
PRIVATE void ixNpeMhReceiveIsr (int npeId) { int lockKey; IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Entering " "ixNpeMhReceiveIsr\n"); lockKey = ixOsalIrqLock (); /* invoke the message receive routine to get messages from the NPE */ ixNpeMhReceiveMessagesReceive (npeId); /* update statistical info */ ixNpeMhReceiveStats[npeId].isrs++; ixOsalIrqUnlock (lockKey); IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Exiting " "ixNpeMhReceiveIsr\n"); }
IX_STATUS ixNpeMhReceiveMessagesReceive ( IxNpeMhNpeId npeId) { IxNpeMhMessage message = { { 0, 0 } }; IxNpeMhMessageId messageId = 0; IxNpeMhCallback callback = NULL; IX_STATUS status; IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Entering " "ixNpeMhReceiveMessagesReceive\n"); /* update statistical info */ ixNpeMhReceiveStats[npeId].receives++; /* while the NPE has messages in its outFIFO */ while (!ixNpeMhConfigOutFifoIsEmpty (npeId)) { /* read a message from the NPE's outFIFO */ status = ixNpeMhConfigOutFifoRead (npeId, &message); if (IX_SUCCESS != status) { return status; } /* get the ID of the message */ messageId = ixNpeMhConfigMessageIdGet (message); IX_NPEMH_TRACE2 (IX_NPEMH_DEBUG, "Received message from NPE %d with ID 0x%02X\n", npeId, messageId); /* update statistical info */ ixNpeMhReceiveStats[npeId].messages++; /* try to find a matching unsolicited callback for this message. */ /* we assume the message is unsolicited. only if there is no */ /* unsolicited callback for this message type do we assume the */ /* message is solicited. it is much faster to check for an */ /* unsolicited callback, so doing this check first should result */ /* in better performance. */ ixNpeMhUnsolicitedCbMgrCallbackRetrieve ( npeId, messageId, &callback); if (callback != NULL) { IX_NPEMH_TRACE0 (IX_NPEMH_DEBUG, "Found matching unsolicited callback\n"); /* update statistical info */ ixNpeMhReceiveStats[npeId].unsolicited++; } /* if no unsolicited callback was found try to find a matching */ /* solicited callback for this message */ if (callback == NULL) { ixNpeMhSolicitedCbMgrCallbackRetrieve ( npeId, messageId, &callback); if (callback != NULL) { IX_NPEMH_TRACE0 (IX_NPEMH_DEBUG, "Found matching solicited callback\n"); /* update statistical info */ ixNpeMhReceiveStats[npeId].solicited++; } } /* if a callback (either unsolicited or solicited) was found */ if (callback != NULL) { /* invoke the callback to pass the message back to the client */ callback (npeId, message); /* update statistical info */ ixNpeMhReceiveStats[npeId].callbacks++; } else /* no callback (neither unsolicited nor solicited) was found */ { IX_NPEMH_TRACE2 (IX_NPEMH_WARNING, "No matching callback for NPE %d" " and ID 0x%02X, discarding message\n", npeId, messageId); /* the message will be discarded. this is normal behaviour */ /* if the client passes a NULL solicited callback when */ /* sending a message. this indicates that the client is not */ /* interested in receiving the response. alternatively a */ /* NULL callback here may signify an unsolicited message */ /* with no appropriate registered callback. */ } } IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Exiting " "ixNpeMhReceiveMessagesReceive\n"); return IX_SUCCESS; }