IxNpeMhSolicitedCbMgr.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358
  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. * Redistribution and use in source and binary forms, with or without
  22. * modification, are permitted provided that the following conditions
  23. * are met:
  24. * 1. Redistributions of source code must retain the above copyright
  25. * notice, this list of conditions and the following disclaimer.
  26. * 2. Redistributions in binary form must reproduce the above copyright
  27. * notice, this list of conditions and the following disclaimer in the
  28. * documentation and/or other materials provided with the distribution.
  29. * 3. Neither the name of the Intel Corporation nor the names of its contributors
  30. * may be used to endorse or promote products derived from this software
  31. * without specific prior written permission.
  32. *
  33. * @par
  34. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
  35. * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  36. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  37. * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
  38. * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  39. * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  40. * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  41. * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  42. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  43. * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  44. * SUCH DAMAGE.
  45. *
  46. * @par
  47. * -- End of Copyright Notice --
  48. */
  49. #ifndef IXNPEMHCONFIG_P_H
  50. # define IXNPEMHSOLICITEDCBMGR_C
  51. #else
  52. # error "Error, IxNpeMhConfig_p.h should not be included before this definition."
  53. #endif
  54. /*
  55. * Put the system defined include files required.
  56. */
  57. /*
  58. * Put the user defined include files required.
  59. */
  60. #include "IxOsal.h"
  61. #include "IxNpeMhMacros_p.h"
  62. #include "IxNpeMhSolicitedCbMgr_p.h"
  63. #include "IxNpeMhConfig_p.h"
  64. /*
  65. * #defines and macros used in this file.
  66. */
  67. /*
  68. * Typedefs whose scope is limited to this file.
  69. */
  70. /**
  71. * @struct IxNpeMhSolicitedCallbackListEntry
  72. *
  73. * @brief This structure is used to store the information associated with
  74. * an entry in the callback list. This consists of the ID of the send
  75. * message (which indicates the ID of the corresponding response message)
  76. * and the callback function pointer itself.
  77. *
  78. */
  79. typedef struct IxNpeMhSolicitedCallbackListEntry
  80. {
  81. /** message ID */
  82. IxNpeMhMessageId messageId;
  83. /** callback function pointer */
  84. IxNpeMhCallback callback;
  85. /** pointer to next entry in the list */
  86. struct IxNpeMhSolicitedCallbackListEntry *next;
  87. } IxNpeMhSolicitedCallbackListEntry;
  88. /**
  89. * @struct IxNpeMhSolicitedCallbackList
  90. *
  91. * @brief This structure is used to maintain the list of response
  92. * callbacks. The number of entries in this list will be variable, and
  93. * they will be stored in a linked list fashion for ease of addition and
  94. * removal. The entries themselves are statically allocated, and are
  95. * organised into a "free" list and a "callback" list. Adding an entry
  96. * means taking an entry from the "free" list and adding it to the
  97. * "callback" list. Removing an entry means removing it from the
  98. * "callback" list and returning it to the "free" list.
  99. */
  100. typedef struct
  101. {
  102. /** pointer to the head of the free list */
  103. IxNpeMhSolicitedCallbackListEntry *freeHead;
  104. /** pointer to the head of the callback list */
  105. IxNpeMhSolicitedCallbackListEntry *callbackHead;
  106. /** pointer to the tail of the callback list */
  107. IxNpeMhSolicitedCallbackListEntry *callbackTail;
  108. /** array of entries - the first entry is used as a dummy entry to */
  109. /* avoid the scenario of having an empty list, hence '+ 1' */
  110. IxNpeMhSolicitedCallbackListEntry entries[IX_NPEMH_MAX_CALLBACKS + 1];
  111. } IxNpeMhSolicitedCallbackList;
  112. /**
  113. * @struct IxNpeMhSolicitedCbMgrStats
  114. *
  115. * @brief This structure is used to maintain statistics for the Solicited
  116. * Callback Manager module.
  117. */
  118. typedef struct
  119. {
  120. UINT32 saves; /**< callback list saves */
  121. UINT32 retrieves; /**< callback list retrieves */
  122. } IxNpeMhSolicitedCbMgrStats;
  123. /*
  124. * Variable declarations global to this file only. Externs are followed by
  125. * static variables.
  126. */
  127. PRIVATE IxNpeMhSolicitedCallbackList
  128. ixNpeMhSolicitedCbMgrCallbackLists[IX_NPEMH_NUM_NPES];
  129. PRIVATE IxNpeMhSolicitedCbMgrStats
  130. ixNpeMhSolicitedCbMgrStats[IX_NPEMH_NUM_NPES];
  131. /*
  132. * Extern function prototypes.
  133. */
  134. /*
  135. * Static function prototypes.
  136. */
  137. /*
  138. * Function definition: ixNpeMhSolicitedCbMgrInitialize
  139. */
  140. void ixNpeMhSolicitedCbMgrInitialize (void)
  141. {
  142. IxNpeMhNpeId npeId;
  143. UINT32 localIndex;
  144. IxNpeMhSolicitedCallbackList *list = NULL;
  145. IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Entering "
  146. "ixNpeMhSolicitedCbMgrInitialize\n");
  147. /* for each NPE ... */
  148. for (npeId = 0; npeId < IX_NPEMH_NUM_NPES; npeId++)
  149. {
  150. /* initialise a pointer to the list for convenience */
  151. list = &ixNpeMhSolicitedCbMgrCallbackLists[npeId];
  152. /* for each entry in the list, after the dummy entry ... */
  153. for (localIndex = 1; localIndex <= IX_NPEMH_MAX_CALLBACKS; localIndex++)
  154. {
  155. /* initialise the entry */
  156. list->entries[localIndex].messageId = 0x00;
  157. list->entries[localIndex].callback = NULL;
  158. /* if this entry is before the last entry */
  159. if (localIndex < IX_NPEMH_MAX_CALLBACKS)
  160. {
  161. /* chain this entry to the following entry */
  162. list->entries[localIndex].next = &(list->entries[localIndex + 1]);
  163. }
  164. else /* this entry is the last entry */
  165. {
  166. /* the last entry isn't chained to anything */
  167. list->entries[localIndex].next = NULL;
  168. }
  169. }
  170. /* set the free list pointer to point to the first real entry */
  171. /* (all real entries begin chained together on the free list) */
  172. list->freeHead = &(list->entries[1]);
  173. /* set the callback list pointers to point to the dummy entry */
  174. /* (the callback list is initially empty) */
  175. list->callbackHead = &(list->entries[0]);
  176. list->callbackTail = &(list->entries[0]);
  177. }
  178. IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Exiting "
  179. "ixNpeMhSolicitedCbMgrInitialize\n");
  180. }
  181. /*
  182. * Function definition: ixNpeMhSolicitedCbMgrCallbackSave
  183. */
  184. IX_STATUS ixNpeMhSolicitedCbMgrCallbackSave (
  185. IxNpeMhNpeId npeId,
  186. IxNpeMhMessageId solicitedMessageId,
  187. IxNpeMhCallback solicitedCallback)
  188. {
  189. IxNpeMhSolicitedCallbackList *list = NULL;
  190. IxNpeMhSolicitedCallbackListEntry *callbackEntry = NULL;
  191. IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Entering "
  192. "ixNpeMhSolicitedCbMgrCallbackSave\n");
  193. /* initialise a pointer to the list for convenience */
  194. list = &ixNpeMhSolicitedCbMgrCallbackLists[npeId];
  195. /* check to see if there are any entries in the free list */
  196. if (list->freeHead == NULL)
  197. {
  198. IX_NPEMH_ERROR_REPORT ("Solicited callback list is full\n");
  199. return IX_FAIL;
  200. }
  201. /* there is an entry in the free list we can use */
  202. /* update statistical info */
  203. ixNpeMhSolicitedCbMgrStats[npeId].saves++;
  204. /* remove a callback entry from the start of the free list */
  205. callbackEntry = list->freeHead;
  206. list->freeHead = callbackEntry->next;
  207. /* fill in the callback entry with the new data */
  208. callbackEntry->messageId = solicitedMessageId;
  209. callbackEntry->callback = solicitedCallback;
  210. /* the new callback entry will be added to the tail of the callback */
  211. /* list, so it isn't chained to anything */
  212. callbackEntry->next = NULL;
  213. /* chain new callback entry to the last entry of the callback list */
  214. list->callbackTail->next = callbackEntry;
  215. list->callbackTail = callbackEntry;
  216. IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Exiting "
  217. "ixNpeMhSolicitedCbMgrCallbackSave\n");
  218. return IX_SUCCESS;
  219. }
  220. /*
  221. * Function definition: ixNpeMhSolicitedCbMgrCallbackRetrieve
  222. */
  223. void ixNpeMhSolicitedCbMgrCallbackRetrieve (
  224. IxNpeMhNpeId npeId,
  225. IxNpeMhMessageId solicitedMessageId,
  226. IxNpeMhCallback *solicitedCallback)
  227. {
  228. IxNpeMhSolicitedCallbackList *list = NULL;
  229. IxNpeMhSolicitedCallbackListEntry *callbackEntry = NULL;
  230. IxNpeMhSolicitedCallbackListEntry *previousEntry = NULL;
  231. /* initialise a pointer to the list for convenience */
  232. list = &ixNpeMhSolicitedCbMgrCallbackLists[npeId];
  233. /* initialise the callback entry to the first entry of the callback */
  234. /* list - we must skip over the dummy entry, which is the previous */
  235. callbackEntry = list->callbackHead->next;
  236. previousEntry = list->callbackHead;
  237. /* traverse the callback list looking for an entry with a matching */
  238. /* message ID. note we also save the previous entry's pointer to */
  239. /* allow us to unchain the matching entry from the callback list */
  240. while ((callbackEntry != NULL) &&
  241. (callbackEntry->messageId != solicitedMessageId))
  242. {
  243. previousEntry = callbackEntry;
  244. callbackEntry = callbackEntry->next;
  245. }
  246. /* if we didn't find a matching callback entry */
  247. if (callbackEntry == NULL)
  248. {
  249. /* return a NULL callback in the outgoing parameter */
  250. *solicitedCallback = NULL;
  251. }
  252. else /* we found a matching callback entry */
  253. {
  254. /* update statistical info */
  255. ixNpeMhSolicitedCbMgrStats[npeId].retrieves++;
  256. /* return the callback in the outgoing parameter */
  257. *solicitedCallback = callbackEntry->callback;
  258. /* unchain callback entry by chaining previous entry to next */
  259. previousEntry->next = callbackEntry->next;
  260. /* if the callback entry is at the tail of the list */
  261. if (list->callbackTail == callbackEntry)
  262. {
  263. /* update the tail of the callback list */
  264. list->callbackTail = previousEntry;
  265. }
  266. /* re-initialise the callback entry */
  267. callbackEntry->messageId = 0x00;
  268. callbackEntry->callback = NULL;
  269. /* add the callback entry to the start of the free list */
  270. callbackEntry->next = list->freeHead;
  271. list->freeHead = callbackEntry;
  272. }
  273. }
  274. /*
  275. * Function definition: ixNpeMhSolicitedCbMgrShow
  276. */
  277. void ixNpeMhSolicitedCbMgrShow (
  278. IxNpeMhNpeId npeId)
  279. {
  280. /* show the solicited callback list save counter */
  281. IX_NPEMH_SHOW ("Solicited callback list saves",
  282. ixNpeMhSolicitedCbMgrStats[npeId].saves);
  283. /* show the solicited callback list retrieve counter */
  284. IX_NPEMH_SHOW ("Solicited callback list retrieves",
  285. ixNpeMhSolicitedCbMgrStats[npeId].retrieves);
  286. }
  287. /*
  288. * Function definition: ixNpeMhSolicitedCbMgrShowReset
  289. */
  290. void ixNpeMhSolicitedCbMgrShowReset (
  291. IxNpeMhNpeId npeId)
  292. {
  293. /* reset the solicited callback list save counter */
  294. ixNpeMhSolicitedCbMgrStats[npeId].saves = 0;
  295. /* reset the solicited callback list retrieve counter */
  296. ixNpeMhSolicitedCbMgrStats[npeId].retrieves = 0;
  297. }