IxNpeMhSolicitedCbMgr.c 9.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334
  1. /**
  2. * @file IxNpeMhSolicitedCbMgr.c
  3. *
  4. * @author Intel Corporation
  5. * @date 18 Jan 2002
  6. *
  7. * @brief This file contains the implementation of the private API for the
  8. * Solicited Callback Manager module.
  9. *
  10. *
  11. * @par
  12. * IXP400 SW Release version 2.0
  13. *
  14. * -- Copyright Notice --
  15. *
  16. * @par
  17. * Copyright 2001-2005, Intel Corporation.
  18. * All rights reserved.
  19. *
  20. * @par
  21. * SPDX-License-Identifier: BSD-3-Clause
  22. * @par
  23. * -- End of Copyright Notice --
  24. */
  25. #ifndef IXNPEMHCONFIG_P_H
  26. # define IXNPEMHSOLICITEDCBMGR_C
  27. #else
  28. # error "Error, IxNpeMhConfig_p.h should not be included before this definition."
  29. #endif
  30. /*
  31. * Put the system defined include files required.
  32. */
  33. /*
  34. * Put the user defined include files required.
  35. */
  36. #include "IxOsal.h"
  37. #include "IxNpeMhMacros_p.h"
  38. #include "IxNpeMhSolicitedCbMgr_p.h"
  39. #include "IxNpeMhConfig_p.h"
  40. /*
  41. * #defines and macros used in this file.
  42. */
  43. /*
  44. * Typedefs whose scope is limited to this file.
  45. */
  46. /**
  47. * @struct IxNpeMhSolicitedCallbackListEntry
  48. *
  49. * @brief This structure is used to store the information associated with
  50. * an entry in the callback list. This consists of the ID of the send
  51. * message (which indicates the ID of the corresponding response message)
  52. * and the callback function pointer itself.
  53. *
  54. */
  55. typedef struct IxNpeMhSolicitedCallbackListEntry
  56. {
  57. /** message ID */
  58. IxNpeMhMessageId messageId;
  59. /** callback function pointer */
  60. IxNpeMhCallback callback;
  61. /** pointer to next entry in the list */
  62. struct IxNpeMhSolicitedCallbackListEntry *next;
  63. } IxNpeMhSolicitedCallbackListEntry;
  64. /**
  65. * @struct IxNpeMhSolicitedCallbackList
  66. *
  67. * @brief This structure is used to maintain the list of response
  68. * callbacks. The number of entries in this list will be variable, and
  69. * they will be stored in a linked list fashion for ease of addition and
  70. * removal. The entries themselves are statically allocated, and are
  71. * organised into a "free" list and a "callback" list. Adding an entry
  72. * means taking an entry from the "free" list and adding it to the
  73. * "callback" list. Removing an entry means removing it from the
  74. * "callback" list and returning it to the "free" list.
  75. */
  76. typedef struct
  77. {
  78. /** pointer to the head of the free list */
  79. IxNpeMhSolicitedCallbackListEntry *freeHead;
  80. /** pointer to the head of the callback list */
  81. IxNpeMhSolicitedCallbackListEntry *callbackHead;
  82. /** pointer to the tail of the callback list */
  83. IxNpeMhSolicitedCallbackListEntry *callbackTail;
  84. /** array of entries - the first entry is used as a dummy entry to */
  85. /* avoid the scenario of having an empty list, hence '+ 1' */
  86. IxNpeMhSolicitedCallbackListEntry entries[IX_NPEMH_MAX_CALLBACKS + 1];
  87. } IxNpeMhSolicitedCallbackList;
  88. /**
  89. * @struct IxNpeMhSolicitedCbMgrStats
  90. *
  91. * @brief This structure is used to maintain statistics for the Solicited
  92. * Callback Manager module.
  93. */
  94. typedef struct
  95. {
  96. UINT32 saves; /**< callback list saves */
  97. UINT32 retrieves; /**< callback list retrieves */
  98. } IxNpeMhSolicitedCbMgrStats;
  99. /*
  100. * Variable declarations global to this file only. Externs are followed by
  101. * static variables.
  102. */
  103. PRIVATE IxNpeMhSolicitedCallbackList
  104. ixNpeMhSolicitedCbMgrCallbackLists[IX_NPEMH_NUM_NPES];
  105. PRIVATE IxNpeMhSolicitedCbMgrStats
  106. ixNpeMhSolicitedCbMgrStats[IX_NPEMH_NUM_NPES];
  107. /*
  108. * Extern function prototypes.
  109. */
  110. /*
  111. * Static function prototypes.
  112. */
  113. /*
  114. * Function definition: ixNpeMhSolicitedCbMgrInitialize
  115. */
  116. void ixNpeMhSolicitedCbMgrInitialize (void)
  117. {
  118. IxNpeMhNpeId npeId;
  119. UINT32 localIndex;
  120. IxNpeMhSolicitedCallbackList *list = NULL;
  121. IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Entering "
  122. "ixNpeMhSolicitedCbMgrInitialize\n");
  123. /* for each NPE ... */
  124. for (npeId = 0; npeId < IX_NPEMH_NUM_NPES; npeId++)
  125. {
  126. /* initialise a pointer to the list for convenience */
  127. list = &ixNpeMhSolicitedCbMgrCallbackLists[npeId];
  128. /* for each entry in the list, after the dummy entry ... */
  129. for (localIndex = 1; localIndex <= IX_NPEMH_MAX_CALLBACKS; localIndex++)
  130. {
  131. /* initialise the entry */
  132. list->entries[localIndex].messageId = 0x00;
  133. list->entries[localIndex].callback = NULL;
  134. /* if this entry is before the last entry */
  135. if (localIndex < IX_NPEMH_MAX_CALLBACKS)
  136. {
  137. /* chain this entry to the following entry */
  138. list->entries[localIndex].next = &(list->entries[localIndex + 1]);
  139. }
  140. else /* this entry is the last entry */
  141. {
  142. /* the last entry isn't chained to anything */
  143. list->entries[localIndex].next = NULL;
  144. }
  145. }
  146. /* set the free list pointer to point to the first real entry */
  147. /* (all real entries begin chained together on the free list) */
  148. list->freeHead = &(list->entries[1]);
  149. /* set the callback list pointers to point to the dummy entry */
  150. /* (the callback list is initially empty) */
  151. list->callbackHead = &(list->entries[0]);
  152. list->callbackTail = &(list->entries[0]);
  153. }
  154. IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Exiting "
  155. "ixNpeMhSolicitedCbMgrInitialize\n");
  156. }
  157. /*
  158. * Function definition: ixNpeMhSolicitedCbMgrCallbackSave
  159. */
  160. IX_STATUS ixNpeMhSolicitedCbMgrCallbackSave (
  161. IxNpeMhNpeId npeId,
  162. IxNpeMhMessageId solicitedMessageId,
  163. IxNpeMhCallback solicitedCallback)
  164. {
  165. IxNpeMhSolicitedCallbackList *list = NULL;
  166. IxNpeMhSolicitedCallbackListEntry *callbackEntry = NULL;
  167. IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Entering "
  168. "ixNpeMhSolicitedCbMgrCallbackSave\n");
  169. /* initialise a pointer to the list for convenience */
  170. list = &ixNpeMhSolicitedCbMgrCallbackLists[npeId];
  171. /* check to see if there are any entries in the free list */
  172. if (list->freeHead == NULL)
  173. {
  174. IX_NPEMH_ERROR_REPORT ("Solicited callback list is full\n");
  175. return IX_FAIL;
  176. }
  177. /* there is an entry in the free list we can use */
  178. /* update statistical info */
  179. ixNpeMhSolicitedCbMgrStats[npeId].saves++;
  180. /* remove a callback entry from the start of the free list */
  181. callbackEntry = list->freeHead;
  182. list->freeHead = callbackEntry->next;
  183. /* fill in the callback entry with the new data */
  184. callbackEntry->messageId = solicitedMessageId;
  185. callbackEntry->callback = solicitedCallback;
  186. /* the new callback entry will be added to the tail of the callback */
  187. /* list, so it isn't chained to anything */
  188. callbackEntry->next = NULL;
  189. /* chain new callback entry to the last entry of the callback list */
  190. list->callbackTail->next = callbackEntry;
  191. list->callbackTail = callbackEntry;
  192. IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Exiting "
  193. "ixNpeMhSolicitedCbMgrCallbackSave\n");
  194. return IX_SUCCESS;
  195. }
  196. /*
  197. * Function definition: ixNpeMhSolicitedCbMgrCallbackRetrieve
  198. */
  199. void ixNpeMhSolicitedCbMgrCallbackRetrieve (
  200. IxNpeMhNpeId npeId,
  201. IxNpeMhMessageId solicitedMessageId,
  202. IxNpeMhCallback *solicitedCallback)
  203. {
  204. IxNpeMhSolicitedCallbackList *list = NULL;
  205. IxNpeMhSolicitedCallbackListEntry *callbackEntry = NULL;
  206. IxNpeMhSolicitedCallbackListEntry *previousEntry = NULL;
  207. /* initialise a pointer to the list for convenience */
  208. list = &ixNpeMhSolicitedCbMgrCallbackLists[npeId];
  209. /* initialise the callback entry to the first entry of the callback */
  210. /* list - we must skip over the dummy entry, which is the previous */
  211. callbackEntry = list->callbackHead->next;
  212. previousEntry = list->callbackHead;
  213. /* traverse the callback list looking for an entry with a matching */
  214. /* message ID. note we also save the previous entry's pointer to */
  215. /* allow us to unchain the matching entry from the callback list */
  216. while ((callbackEntry != NULL) &&
  217. (callbackEntry->messageId != solicitedMessageId))
  218. {
  219. previousEntry = callbackEntry;
  220. callbackEntry = callbackEntry->next;
  221. }
  222. /* if we didn't find a matching callback entry */
  223. if (callbackEntry == NULL)
  224. {
  225. /* return a NULL callback in the outgoing parameter */
  226. *solicitedCallback = NULL;
  227. }
  228. else /* we found a matching callback entry */
  229. {
  230. /* update statistical info */
  231. ixNpeMhSolicitedCbMgrStats[npeId].retrieves++;
  232. /* return the callback in the outgoing parameter */
  233. *solicitedCallback = callbackEntry->callback;
  234. /* unchain callback entry by chaining previous entry to next */
  235. previousEntry->next = callbackEntry->next;
  236. /* if the callback entry is at the tail of the list */
  237. if (list->callbackTail == callbackEntry)
  238. {
  239. /* update the tail of the callback list */
  240. list->callbackTail = previousEntry;
  241. }
  242. /* re-initialise the callback entry */
  243. callbackEntry->messageId = 0x00;
  244. callbackEntry->callback = NULL;
  245. /* add the callback entry to the start of the free list */
  246. callbackEntry->next = list->freeHead;
  247. list->freeHead = callbackEntry;
  248. }
  249. }
  250. /*
  251. * Function definition: ixNpeMhSolicitedCbMgrShow
  252. */
  253. void ixNpeMhSolicitedCbMgrShow (
  254. IxNpeMhNpeId npeId)
  255. {
  256. /* show the solicited callback list save counter */
  257. IX_NPEMH_SHOW ("Solicited callback list saves",
  258. ixNpeMhSolicitedCbMgrStats[npeId].saves);
  259. /* show the solicited callback list retrieve counter */
  260. IX_NPEMH_SHOW ("Solicited callback list retrieves",
  261. ixNpeMhSolicitedCbMgrStats[npeId].retrieves);
  262. }
  263. /*
  264. * Function definition: ixNpeMhSolicitedCbMgrShowReset
  265. */
  266. void ixNpeMhSolicitedCbMgrShowReset (
  267. IxNpeMhNpeId npeId)
  268. {
  269. /* reset the solicited callback list save counter */
  270. ixNpeMhSolicitedCbMgrStats[npeId].saves = 0;
  271. /* reset the solicited callback list retrieve counter */
  272. ixNpeMhSolicitedCbMgrStats[npeId].retrieves = 0;
  273. }