/** * @file IxNpeMhSolicitedCbMgr.c * * @author Intel Corporation * @date 18 Jan 2002 * * @brief This file contains the implementation of the private API for the * Solicited Callback Manager module. * * * @par * IXP400 SW Release version 2.0 * * -- Copyright Notice -- * * @par * Copyright 2001-2005, Intel Corporation. * All rights reserved. * * @par * SPDX-License-Identifier: BSD-3-Clause * @par * -- End of Copyright Notice -- */ #ifndef IXNPEMHCONFIG_P_H # define IXNPEMHSOLICITEDCBMGR_C #else # error "Error, IxNpeMhConfig_p.h should not be included before this definition." #endif /* * Put the system defined include files required. */ /* * Put the user defined include files required. */ #include "IxOsal.h" #include "IxNpeMhMacros_p.h" #include "IxNpeMhSolicitedCbMgr_p.h" #include "IxNpeMhConfig_p.h" /* * #defines and macros used in this file. */ /* * Typedefs whose scope is limited to this file. */ /** * @struct IxNpeMhSolicitedCallbackListEntry * * @brief This structure is used to store the information associated with * an entry in the callback list. This consists of the ID of the send * message (which indicates the ID of the corresponding response message) * and the callback function pointer itself. * */ typedef struct IxNpeMhSolicitedCallbackListEntry { /** message ID */ IxNpeMhMessageId messageId; /** callback function pointer */ IxNpeMhCallback callback; /** pointer to next entry in the list */ struct IxNpeMhSolicitedCallbackListEntry *next; } IxNpeMhSolicitedCallbackListEntry; /** * @struct IxNpeMhSolicitedCallbackList * * @brief This structure is used to maintain the list of response * callbacks. The number of entries in this list will be variable, and * they will be stored in a linked list fashion for ease of addition and * removal. The entries themselves are statically allocated, and are * organised into a "free" list and a "callback" list. Adding an entry * means taking an entry from the "free" list and adding it to the * "callback" list. Removing an entry means removing it from the * "callback" list and returning it to the "free" list. */ typedef struct { /** pointer to the head of the free list */ IxNpeMhSolicitedCallbackListEntry *freeHead; /** pointer to the head of the callback list */ IxNpeMhSolicitedCallbackListEntry *callbackHead; /** pointer to the tail of the callback list */ IxNpeMhSolicitedCallbackListEntry *callbackTail; /** array of entries - the first entry is used as a dummy entry to */ /* avoid the scenario of having an empty list, hence '+ 1' */ IxNpeMhSolicitedCallbackListEntry entries[IX_NPEMH_MAX_CALLBACKS + 1]; } IxNpeMhSolicitedCallbackList; /** * @struct IxNpeMhSolicitedCbMgrStats * * @brief This structure is used to maintain statistics for the Solicited * Callback Manager module. */ typedef struct { UINT32 saves; /**< callback list saves */ UINT32 retrieves; /**< callback list retrieves */ } IxNpeMhSolicitedCbMgrStats; /* * Variable declarations global to this file only. Externs are followed by * static variables. */ PRIVATE IxNpeMhSolicitedCallbackList ixNpeMhSolicitedCbMgrCallbackLists[IX_NPEMH_NUM_NPES]; PRIVATE IxNpeMhSolicitedCbMgrStats ixNpeMhSolicitedCbMgrStats[IX_NPEMH_NUM_NPES]; /* * Extern function prototypes. */ /* * Static function prototypes. */ /* * Function definition: ixNpeMhSolicitedCbMgrInitialize */ 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"); } /* * Function definition: ixNpeMhSolicitedCbMgrCallbackSave */ 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: ixNpeMhSolicitedCbMgrCallbackRetrieve */ void ixNpeMhSolicitedCbMgrCallbackRetrieve ( IxNpeMhNpeId npeId, IxNpeMhMessageId solicitedMessageId, IxNpeMhCallback *solicitedCallback) { IxNpeMhSolicitedCallbackList *list = NULL; IxNpeMhSolicitedCallbackListEntry *callbackEntry = NULL; IxNpeMhSolicitedCallbackListEntry *previousEntry = NULL; /* initialise a pointer to the list for convenience */ list = &ixNpeMhSolicitedCbMgrCallbackLists[npeId]; /* initialise the callback entry to the first entry of the callback */ /* list - we must skip over the dummy entry, which is the previous */ callbackEntry = list->callbackHead->next; previousEntry = list->callbackHead; /* traverse the callback list looking for an entry with a matching */ /* message ID. note we also save the previous entry's pointer to */ /* allow us to unchain the matching entry from the callback list */ while ((callbackEntry != NULL) && (callbackEntry->messageId != solicitedMessageId)) { previousEntry = callbackEntry; callbackEntry = callbackEntry->next; } /* if we didn't find a matching callback entry */ if (callbackEntry == NULL) { /* return a NULL callback in the outgoing parameter */ *solicitedCallback = NULL; } else /* we found a matching callback entry */ { /* update statistical info */ ixNpeMhSolicitedCbMgrStats[npeId].retrieves++; /* return the callback in the outgoing parameter */ *solicitedCallback = callbackEntry->callback; /* unchain callback entry by chaining previous entry to next */ previousEntry->next = callbackEntry->next; /* if the callback entry is at the tail of the list */ if (list->callbackTail == callbackEntry) { /* update the tail of the callback list */ list->callbackTail = previousEntry; } /* re-initialise the callback entry */ callbackEntry->messageId = 0x00; callbackEntry->callback = NULL; /* add the callback entry to the start of the free list */ callbackEntry->next = list->freeHead; list->freeHead = callbackEntry; } } /* * Function definition: ixNpeMhSolicitedCbMgrShow */ void ixNpeMhSolicitedCbMgrShow ( IxNpeMhNpeId npeId) { /* show the solicited callback list save counter */ IX_NPEMH_SHOW ("Solicited callback list saves", ixNpeMhSolicitedCbMgrStats[npeId].saves); /* show the solicited callback list retrieve counter */ IX_NPEMH_SHOW ("Solicited callback list retrieves", ixNpeMhSolicitedCbMgrStats[npeId].retrieves); } /* * Function definition: ixNpeMhSolicitedCbMgrShowReset */ void ixNpeMhSolicitedCbMgrShowReset ( IxNpeMhNpeId npeId) { /* reset the solicited callback list save counter */ ixNpeMhSolicitedCbMgrStats[npeId].saves = 0; /* reset the solicited callback list retrieve counter */ ixNpeMhSolicitedCbMgrStats[npeId].retrieves = 0; }