blob: c539d090715eb6c4abbff031d24f6f6c938572ee [file] [log] [blame]
Wolfgang Denk4646d2a2006-05-30 15:56:48 +02001/**
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
Wolfgang Denkc57eadc2013-07-28 22:12:47 +020021 * SPDX-License-Identifier: BSD-3-Clause
Wolfgang Denk4646d2a2006-05-30 15:56:48 +020022 * @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/*
32 * Put the system defined include files required.
33 */
34
35
36/*
37 * Put the user defined include files required.
38 */
39
40#include "IxOsal.h"
41
42#include "IxNpeMhMacros_p.h"
43#include "IxNpeMhSolicitedCbMgr_p.h"
44#include "IxNpeMhConfig_p.h"
45/*
46 * #defines and macros used in this file.
47 */
48
49/*
50 * Typedefs whose scope is limited to this file.
51 */
52
53/**
54 * @struct IxNpeMhSolicitedCallbackListEntry
55 *
56 * @brief This structure is used to store the information associated with
57 * an entry in the callback list. This consists of the ID of the send
58 * message (which indicates the ID of the corresponding response message)
59 * and the callback function pointer itself.
60 *
61 */
62
63typedef struct IxNpeMhSolicitedCallbackListEntry
64{
65 /** message ID */
66 IxNpeMhMessageId messageId;
67
68 /** callback function pointer */
69 IxNpeMhCallback callback;
70
71 /** pointer to next entry in the list */
72 struct IxNpeMhSolicitedCallbackListEntry *next;
73} IxNpeMhSolicitedCallbackListEntry;
74
75/**
76 * @struct IxNpeMhSolicitedCallbackList
77 *
78 * @brief This structure is used to maintain the list of response
79 * callbacks. The number of entries in this list will be variable, and
80 * they will be stored in a linked list fashion for ease of addition and
81 * removal. The entries themselves are statically allocated, and are
82 * organised into a "free" list and a "callback" list. Adding an entry
83 * means taking an entry from the "free" list and adding it to the
84 * "callback" list. Removing an entry means removing it from the
85 * "callback" list and returning it to the "free" list.
86 */
87
88typedef struct
89{
90 /** pointer to the head of the free list */
91 IxNpeMhSolicitedCallbackListEntry *freeHead;
92
93 /** pointer to the head of the callback list */
94 IxNpeMhSolicitedCallbackListEntry *callbackHead;
95
96 /** pointer to the tail of the callback list */
97 IxNpeMhSolicitedCallbackListEntry *callbackTail;
98
99 /** array of entries - the first entry is used as a dummy entry to */
100 /* avoid the scenario of having an empty list, hence '+ 1' */
101 IxNpeMhSolicitedCallbackListEntry entries[IX_NPEMH_MAX_CALLBACKS + 1];
102} IxNpeMhSolicitedCallbackList;
103
104/**
105 * @struct IxNpeMhSolicitedCbMgrStats
106 *
107 * @brief This structure is used to maintain statistics for the Solicited
108 * Callback Manager module.
109 */
110
111typedef struct
112{
113 UINT32 saves; /**< callback list saves */
114 UINT32 retrieves; /**< callback list retrieves */
115} IxNpeMhSolicitedCbMgrStats;
116
117/*
118 * Variable declarations global to this file only. Externs are followed by
119 * static variables.
120 */
121
122PRIVATE IxNpeMhSolicitedCallbackList
123ixNpeMhSolicitedCbMgrCallbackLists[IX_NPEMH_NUM_NPES];
124
125PRIVATE IxNpeMhSolicitedCbMgrStats
126ixNpeMhSolicitedCbMgrStats[IX_NPEMH_NUM_NPES];
127
128/*
129 * Extern function prototypes.
130 */
131
132/*
133 * Static function prototypes.
134 */
135
136/*
137 * Function definition: ixNpeMhSolicitedCbMgrInitialize
138 */
139
140void ixNpeMhSolicitedCbMgrInitialize (void)
141{
142 IxNpeMhNpeId npeId;
143 UINT32 localIndex;
144 IxNpeMhSolicitedCallbackList *list = NULL;
145
146 IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Entering "
147 "ixNpeMhSolicitedCbMgrInitialize\n");
148
149 /* for each NPE ... */
150 for (npeId = 0; npeId < IX_NPEMH_NUM_NPES; npeId++)
151 {
152 /* initialise a pointer to the list for convenience */
153 list = &ixNpeMhSolicitedCbMgrCallbackLists[npeId];
154
155 /* for each entry in the list, after the dummy entry ... */
156 for (localIndex = 1; localIndex <= IX_NPEMH_MAX_CALLBACKS; localIndex++)
157 {
158 /* initialise the entry */
159 list->entries[localIndex].messageId = 0x00;
160 list->entries[localIndex].callback = NULL;
161
162 /* if this entry is before the last entry */
163 if (localIndex < IX_NPEMH_MAX_CALLBACKS)
164 {
165 /* chain this entry to the following entry */
166 list->entries[localIndex].next = &(list->entries[localIndex + 1]);
167 }
168 else /* this entry is the last entry */
169 {
170 /* the last entry isn't chained to anything */
171 list->entries[localIndex].next = NULL;
172 }
173 }
174
175 /* set the free list pointer to point to the first real entry */
176 /* (all real entries begin chained together on the free list) */
177 list->freeHead = &(list->entries[1]);
178
179 /* set the callback list pointers to point to the dummy entry */
180 /* (the callback list is initially empty) */
181 list->callbackHead = &(list->entries[0]);
182 list->callbackTail = &(list->entries[0]);
183 }
184
185 IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Exiting "
186 "ixNpeMhSolicitedCbMgrInitialize\n");
187}
188
189/*
190 * Function definition: ixNpeMhSolicitedCbMgrCallbackSave
191 */
192
193IX_STATUS ixNpeMhSolicitedCbMgrCallbackSave (
194 IxNpeMhNpeId npeId,
195 IxNpeMhMessageId solicitedMessageId,
196 IxNpeMhCallback solicitedCallback)
197{
198 IxNpeMhSolicitedCallbackList *list = NULL;
199 IxNpeMhSolicitedCallbackListEntry *callbackEntry = NULL;
200
201 IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Entering "
202 "ixNpeMhSolicitedCbMgrCallbackSave\n");
203
204 /* initialise a pointer to the list for convenience */
205 list = &ixNpeMhSolicitedCbMgrCallbackLists[npeId];
206
207 /* check to see if there are any entries in the free list */
208 if (list->freeHead == NULL)
209 {
210 IX_NPEMH_ERROR_REPORT ("Solicited callback list is full\n");
211 return IX_FAIL;
212 }
213
214 /* there is an entry in the free list we can use */
215
216 /* update statistical info */
217 ixNpeMhSolicitedCbMgrStats[npeId].saves++;
218
219 /* remove a callback entry from the start of the free list */
220 callbackEntry = list->freeHead;
221 list->freeHead = callbackEntry->next;
222
223 /* fill in the callback entry with the new data */
224 callbackEntry->messageId = solicitedMessageId;
225 callbackEntry->callback = solicitedCallback;
226
227 /* the new callback entry will be added to the tail of the callback */
228 /* list, so it isn't chained to anything */
229 callbackEntry->next = NULL;
230
231 /* chain new callback entry to the last entry of the callback list */
232 list->callbackTail->next = callbackEntry;
233 list->callbackTail = callbackEntry;
234
235 IX_NPEMH_TRACE0 (IX_NPEMH_FN_ENTRY_EXIT, "Exiting "
236 "ixNpeMhSolicitedCbMgrCallbackSave\n");
237
238 return IX_SUCCESS;
239}
240
241/*
242 * Function definition: ixNpeMhSolicitedCbMgrCallbackRetrieve
243 */
244
245void ixNpeMhSolicitedCbMgrCallbackRetrieve (
246 IxNpeMhNpeId npeId,
247 IxNpeMhMessageId solicitedMessageId,
248 IxNpeMhCallback *solicitedCallback)
249{
250 IxNpeMhSolicitedCallbackList *list = NULL;
251 IxNpeMhSolicitedCallbackListEntry *callbackEntry = NULL;
252 IxNpeMhSolicitedCallbackListEntry *previousEntry = NULL;
253
254 /* initialise a pointer to the list for convenience */
255 list = &ixNpeMhSolicitedCbMgrCallbackLists[npeId];
256
257 /* initialise the callback entry to the first entry of the callback */
258 /* list - we must skip over the dummy entry, which is the previous */
259 callbackEntry = list->callbackHead->next;
260 previousEntry = list->callbackHead;
261
262 /* traverse the callback list looking for an entry with a matching */
263 /* message ID. note we also save the previous entry's pointer to */
264 /* allow us to unchain the matching entry from the callback list */
265 while ((callbackEntry != NULL) &&
266 (callbackEntry->messageId != solicitedMessageId))
267 {
268 previousEntry = callbackEntry;
269 callbackEntry = callbackEntry->next;
270 }
271
272 /* if we didn't find a matching callback entry */
273 if (callbackEntry == NULL)
274 {
275 /* return a NULL callback in the outgoing parameter */
276 *solicitedCallback = NULL;
277 }
278 else /* we found a matching callback entry */
279 {
280 /* update statistical info */
281 ixNpeMhSolicitedCbMgrStats[npeId].retrieves++;
282
283 /* return the callback in the outgoing parameter */
284 *solicitedCallback = callbackEntry->callback;
285
286 /* unchain callback entry by chaining previous entry to next */
287 previousEntry->next = callbackEntry->next;
288
289 /* if the callback entry is at the tail of the list */
290 if (list->callbackTail == callbackEntry)
291 {
292 /* update the tail of the callback list */
293 list->callbackTail = previousEntry;
294 }
295
296 /* re-initialise the callback entry */
297 callbackEntry->messageId = 0x00;
298 callbackEntry->callback = NULL;
299
300 /* add the callback entry to the start of the free list */
301 callbackEntry->next = list->freeHead;
302 list->freeHead = callbackEntry;
303 }
304}
305
306/*
307 * Function definition: ixNpeMhSolicitedCbMgrShow
308 */
309
310void ixNpeMhSolicitedCbMgrShow (
311 IxNpeMhNpeId npeId)
312{
313 /* show the solicited callback list save counter */
314 IX_NPEMH_SHOW ("Solicited callback list saves",
315 ixNpeMhSolicitedCbMgrStats[npeId].saves);
316
317 /* show the solicited callback list retrieve counter */
318 IX_NPEMH_SHOW ("Solicited callback list retrieves",
319 ixNpeMhSolicitedCbMgrStats[npeId].retrieves);
320}
321
322/*
323 * Function definition: ixNpeMhSolicitedCbMgrShowReset
324 */
325
326void ixNpeMhSolicitedCbMgrShowReset (
327 IxNpeMhNpeId npeId)
328{
329 /* reset the solicited callback list save counter */
330 ixNpeMhSolicitedCbMgrStats[npeId].saves = 0;
331
332 /* reset the solicited callback list retrieve counter */
333 ixNpeMhSolicitedCbMgrStats[npeId].retrieves = 0;
334}