FreeBSD kernel pms device code
satimer.c
Go to the documentation of this file.
1/*******************************************************************************
2*Copyright (c) 2014 PMC-Sierra, Inc. All rights reserved.
3*
4*Redistribution and use in source and binary forms, with or without modification, are permitted provided
5*that the following conditions are met:
6*1. Redistributions of source code must retain the above copyright notice, this list of conditions and the
7*following disclaimer.
8*2. Redistributions in binary form must reproduce the above copyright notice,
9*this list of conditions and the following disclaimer in the documentation and/or other materials provided
10*with the distribution.
11*
12*THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED
13*WARRANTIES,INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
14*FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
15*FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
16*NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
17*BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
18*LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
19*SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE
20
21********************************************************************************/
22/*******************************************************************************/
27/******************************************************************************/
28#include <sys/cdefs.h>
29__FBSDID("$FreeBSD$");
30#include <dev/pms/config.h>
31
33#ifdef SA_FW_TEST_BUNCH_STARTS
34void mpiMsgProduceBunch( agsaLLRoot_t *saRoot);
35#endif /* SA_FW_TEST_BUNCH_STARTS */
36
37#ifdef SA_ENABLE_TRACE_FUNCTIONS
38#ifdef siTraceFileID
39#undef siTraceFileID
40#endif
41#define siTraceFileID 'P'
42#endif
43
44/******************************************************************************/
53/*******************************************************************************/
55 agsaRoot_t *agRoot
56 )
57{
58 agsaLLRoot_t *saRoot = (agsaLLRoot_t *)(agRoot->sdkData);
59 agsaTimerDesc_t *pTimer;
60 bit32 Event;
61 void * pParm;
62
63 if(agNULL == saRoot)
64 {
65 SA_DBG1(("saTimerTick:agNULL == saRoot \n"));
66 return;
67 }
68
69 /* (1) Acquire timer list lock */
71
72 /* (2) Find the timers are timeout */
73 pTimer = (agsaTimerDesc_t *) saLlistGetHead(&(saRoot->validTimers));
74 while ( agNULL != pTimer )
75 {
76 /* (2.1) Find the first timer is timeout */
77 if ( pTimer->timeoutTick == saRoot->timeTick )
78 {
79 /* (2.1.1) remove the timer from valid timer list */
80 saLlistRemove(&(saRoot->validTimers), &(pTimer->linkNode));
81 /* (2.1.2) Invalid timer */
82 pTimer->valid = agFALSE;
83 /* (2.1.3) Get timer event and param */
84 Event = pTimer->Event;
85 pParm = pTimer->pParm;
86 /* (2.1.4) Release timer list lock */
88
89 /* (2.1.5) Timer Callback */
90 pTimer->pfnTimeout(agRoot, Event, pParm);
91
92 /* (2.1.6) Acquire timer list lock again */
94 /* (2.1.7) return the timer to free timer list */
95 saLlistAdd(&(saRoot->freeTimers), &(pTimer->linkNode));
96 }
97 /* (2.2) the first timer is not timeout */
98 else
99 {
100 break;
101 }
102 pTimer = (agsaTimerDesc_t *) saLlistGetHead(&(saRoot->validTimers));
103 }
104
105 /* (3) increment timeTick */
106 saRoot->timeTick ++;
107
108 if( saRoot->ResetFailed )
109 {
110 SA_DBG1(("saTimerTick: siChipResetV saRoot->ResetFailed\n"));
111 }
112
113#ifdef SA_FW_TEST_BUNCH_STARTS
114 if (saRoot->BunchStarts_Enable &&
115 saRoot->BunchStarts_Pending)
116 {
117 SA_DBG3(("saTimerTick: mpiMsgProduceBunch\n"));
118 mpiMsgProduceBunch( saRoot);
119 }
120#endif /* SA_FW_TEST_BUNCH_STARTS */
121
122
123#ifdef SA_FW_TEST_INTERRUPT_REASSERT
124
125 if(1)
126 {
127 mpiOCQueue_t *circularQ;
128 int i;
129 SA_DBG4(("saTimerTick:SA_FW_TEST_INTERRUPT_REASSERT\n"));
130 for ( i = 0; i < saRoot->QueueConfig.numOutboundQueues; i++ )
131 {
132 circularQ = &saRoot->outboundQueue[i];
133 OSSA_READ_LE_32(circularQ->agRoot, &circularQ->producerIdx, circularQ->piPointer, 0);
134 if(circularQ->producerIdx != circularQ->consumerIdx)
135 {
136 if( saRoot->OldCi[i] == circularQ->consumerIdx && saRoot->OldPi[i] >= circularQ->producerIdx)
137 {
138 agsaEchoCmd_t payload;
139 payload.tag = 0xF0;
140 payload.payload[0]= 0x0;
141 if( ++saRoot->OldFlag[i] > 1 )
142 {
143 saRoot->CheckAll++;
144 }
145 SA_DBG1(("saTimerTick:Q %d (%d) PI 0x%03x CI 0x%03x (%d) CheckAll %d %d\n",i,
146 saRoot->OldFlag[i],
147 circularQ->producerIdx,
148 circularQ->consumerIdx,
149 (circularQ->producerIdx > circularQ->consumerIdx ? (circularQ->producerIdx - circularQ->consumerIdx) : (circularQ->numElements - circularQ->consumerIdx ) + circularQ->producerIdx),
150 saRoot->CheckAll,
151 saRoot->sysIntsActive ));
152
153 if(smIS64bInt(agRoot))
154 {
155 SA_DBG1(("saTimerTick:CheckAll %d ODR 0x%08X%08X ODMR 0x%08X%08X our Int %x\n",
156 saRoot->CheckAll,
161 saRoot->OurInterrupt(agRoot,i)
162 ));
163 }
164 else
165 {
166 SA_DBG1(("saTimerTick:CheckAll %d ODR 0x%08X ODMR 0x%08X our Int %x\n",
167 saRoot->CheckAll,
170 saRoot->OurInterrupt(agRoot,i)
171 ));
172 }
173
174
175 if( saRoot->CheckAll > 1)
176 {
177 saEchoCommand(agRoot,agNULL, ((i << 16) & 0xFFFF0000 ), (void *)&payload);
178 }
179
180 }
181 else
182 {
183 saRoot->OldFlag[i] = 0;
184 }
185
186 saRoot->OldPi[i] = circularQ->producerIdx;
187 saRoot->OldCi[i] = circularQ->consumerIdx;
188
189 }
190 }
191 }
192#endif /* SA_FW_TEST_INTERRUPT_REASSERT */
193
194 /* (4) Release timer list lock */
196#ifdef SA_FW_TEST_INTERRUPT_REASSERT
197 if(saRoot->CheckAll )
198 {
199 int a;
200 for(a=0; a < 32; a++ )
201 {
202 if (saRoot->interruptVecIndexBitMap[a] & (1 << a))
203 {
204 SA_DBG1(("saTimerTick DI %d\n",a));
205 saSystemInterruptsEnable ( agRoot, a );
206
207 }
208 }
209 }
210#endif /* SA_FW_TEST_INTERRUPT_REASSERT */
211}
212
213/******************************************************************************/
229/*******************************************************************************/
231 agsaRoot_t *agRoot,
232 bit32 timeout,
233 agsaCallback_t pfnTimeout,
234 bit32 Event,
235 void * pParm
236 )
237{
238 agsaLLRoot_t *saRoot = (agsaLLRoot_t *)(agRoot->sdkData);
239 agsaTimerDesc_t *pTimer;
240 agsaTimerDesc_t *pValidTimer;
241
243 /* (1) Acquire timer list lock */
245
246 /* (2) Get a free timer */
247 pTimer = (agsaTimerDesc_t *) saLlistGetHead(&(saRoot->freeTimers));
248
249 /* (3) If the timer is availble */
250 if ( agNULL != pTimer )
251 {
252 saLlistRemove(&(saRoot->freeTimers), &(pTimer->linkNode));
253
254 /* (3.1) Setup timer */
255 saLlinkInitialize(&(pTimer->linkNode));
256 /*--------------------------------------**
257 ** the timeout shall greater than 0 **
258 **--------------------------------------*/
259 if ( 0 == timeout )
260 {
261 timeout = timeout + 1;
262 }
263 pTimer->valid = agTRUE;
264 pTimer->timeoutTick = saRoot->timeTick + timeout;
265 pTimer->pfnTimeout = pfnTimeout;
266 pTimer->Event = Event;
267 pTimer->pParm = pParm;
268
269 /* (3.2) Add timer the timer to valid timer list */
270 pValidTimer = (agsaTimerDesc_t *) saLlistGetHead(&(saRoot->validTimers));
271 /* (3.3) for each timer in the valid timer list */
272 while ( agNULL != pValidTimer )
273 {
274 /* (3.3.1) If the timeoutTick is not wrapped around */
275 if ( pTimer->timeoutTick > saRoot->timeTick )
276 {
277 /* (3.3.1.1) If validTimer wrapped around */
278 if ( pValidTimer->timeoutTick < saRoot->timeTick )
279 {
280 saLlistInsert(&(saRoot->validTimers), &(pValidTimer->linkNode), &(pTimer->linkNode));
281 break;
282 }
283 /* (3.3.1.2) If validTimer is not wrapped around */
284 else
285 {
286 if ( pValidTimer->timeoutTick > pTimer->timeoutTick )
287 {
288 saLlistInsert(&(saRoot->validTimers), &(pValidTimer->linkNode), &(pTimer->linkNode));
289 break;
290 }
291 }
292 }
293 /* (3.3.2) If the timeoutTick is wrapped around */
294 else
295 {
296 /* (3.3.2.1) If validTimer is wrapped around */
297 if ( pValidTimer->timeoutTick < saRoot->timeTick )
298 {
299 if ( pValidTimer->timeoutTick > pTimer->timeoutTick )
300 {
301 saLlistInsert(&(saRoot->validTimers), &(pValidTimer->linkNode), &(pTimer->linkNode));
302 break;
303 }
304 }
305 }
306 /* (3.3.3) Continue to the next valid timer */
307 pValidTimer = (agsaTimerDesc_t *) saLlistGetNext(&(saRoot->validTimers), &(pValidTimer->linkNode));
308 }
309
310 /* (3.4) No timers in the validtimer list is greater than this timer */
311 if ( agNULL == pValidTimer )
312 {
313 saLlistAdd(&(saRoot->validTimers), &(pTimer->linkNode));
314 }
315 }
316
317 /* (4) Release timer list lock */
320
321 return pTimer;
322}
323
324/******************************************************************************/
334/*******************************************************************************/
336 agsaRoot_t *agRoot,
337 agsaTimerDesc_t *pTimer
338 )
339{
340 agsaLLRoot_t *saRoot = (agsaLLRoot_t *)(agRoot->sdkData);
341
342 /* (1) Acquire timer list lock */
345
346 /* (2) If the timer is still valid */
347 if ( agTRUE == pTimer->valid )
348 {
349 /* (2.1) remove from the valid timer list */
350 saLlistRemove(&(saRoot->validTimers), &(pTimer->linkNode));
351 /* (2.2) Invalid the timer */
352 pTimer->valid = agFALSE;
353 /* (2.3) return the timer to the free timer list */
354 saLlistAdd(&(saRoot->freeTimers), &(pTimer->linkNode));
355 }
356 /* (3) Release timer list lock */
359
360 return;
361}
362
363/******************************************************************************/
372/*******************************************************************************/
374 agsaRoot_t *agRoot
375 )
376{
377 agsaLLRoot_t *saRoot = (agsaLLRoot_t *)(agRoot->sdkData);
378 agsaTimerDesc_t *pTimer;
379
381
382 /* (1) Acquire timer list lock */
384
385 /* (2) Get a valid timer */
386 pTimer = (agsaTimerDesc_t *) saLlistGetHead(&(saRoot->validTimers));
387
388 /* (3) If the timer is valid */
389 while ( agNULL != pTimer )
390 {
391 /* (3.1) remove from the valid timer list */
392 saLlistRemove(&(saRoot->validTimers), &(pTimer->linkNode));
393
394 /* (3.2) Invalid timer */
395 pTimer->valid = agFALSE;
396
397 /* (3.3) return the timer to the free timer list */
398 saLlistAdd(&(saRoot->freeTimers), &(pTimer->linkNode));
399
400 /* (3.4) get next valid timer */
401 pTimer = (agsaTimerDesc_t *) saLlistGetHead(&(saRoot->validTimers));
402 }
403
404 /* (4) Release timer list lock */
406
408
409 return;
410}
#define smTraceFuncEnter(L, I)
Definition: mpidebug.h:238
#define smTraceFuncExit(L, S, I)
Definition: mpidebug.h:239
#define hpDBG_VERY_LOUD
Definition: mpidebug.h:100
#define agNULL
Definition: ostypes.h:151
#define GLOBAL
Definition: ostypes.h:131
unsigned int bit32
Definition: ostypes.h:99
#define agFALSE
Definition: ostypes.h:150
#define agTRUE
Definition: ostypes.h:149
GLOBAL bit32 saEchoCommand(agsaRoot_t *agRoot, agsaContext_t *agContext, bit32 queueNum, void *echoPayload)
SAS/SATA LL API ECHO Command.
Definition: sampicmd.c:57
GLOBAL FORCEINLINE void saSystemInterruptsEnable(agsaRoot_t *agRoot, bit32 interruptVectorIndex)
Function to enable a single interrupt vector.
Definition: saint.c:1121
#define LL_TIMER_LOCK
Definition: sadefs.h:129
This file defines global types.
GLOBAL bit32 siHalRegReadExt(agsaRoot_t *agRoot, bit32 generic, bit32 regOffset)
Definition: sahw.c:2818
#define V_Outbound_Doorbell_Mask_Set_RegisterU
Definition: sahwreg.h:99
#define V_Outbound_Doorbell_Set_Register
Definition: sahwreg.h:94
#define V_Outbound_Doorbell_Set_RegisterU
Definition: sahwreg.h:95
@ GEN_MSGU_ODR
Definition: sahwreg.h:689
@ GEN_MSGU_ODMR
Definition: sahwreg.h:699
#define V_Outbound_Doorbell_Mask_Set_Register
Definition: sahwreg.h:98
#define saLlistGetNext(pList, pLink)
saLlistGetNext macro
Definition: sallist.h:395
#define saLlistAdd(pList, pLink)
saLlistAdd macro
Definition: sallist.h:176
#define saLlinkInitialize(pLink)
saLlinkInitialize macro
Definition: sallist.h:136
#define saLlistRemove(pList, pLink)
saLlistRemove macro
Definition: sallist.h:268
#define saLlistInsert(pList, pLink, pNew)
saLlistInsert macro
Definition: sallist.h:226
#define saLlistGetHead(pList)
saLlistGetHead macro
Definition: sallist.h:305
#define SA_DBG4(format)
Definition: samacro.h:203
#define smIS64bInt(agr)
Definition: samacro.h:173
#define SA_DBG1(format)
Definition: samacro.h:200
#define SA_DBG3(format)
Definition: samacro.h:202
GLOBAL FORCEINLINE void ossaSingleThreadedEnter(agsaRoot_t *agRoot, bit32 syncLockId)
ossaSingleThreadedEnter
Definition: ossacmnapi.c:3786
GLOBAL FORCEINLINE bit32 ossaHwRegReadExt(agsaRoot_t *agRoot, bit32 busBaseNumber, bit32 regOffset)
Definition: ossacmnapi.c:3603
GLOBAL FORCEINLINE void ossaSingleThreadedLeave(agsaRoot_t *agRoot, bit32 syncLockId)
ossaSingleThreadedLeave
Definition: ossacmnapi.c:3827
GLOBAL void siTimerRemoveAll(agsaRoot_t *agRoot)
remove all valid timer
Definition: satimer.c:373
__FBSDID("$FreeBSD$")
GLOBAL agsaTimerDesc_t * siTimerAdd(agsaRoot_t *agRoot, bit32 timeout, agsaCallback_t pfnTimeout, bit32 Event, void *pParm)
add a timer
Definition: satimer.c:230
GLOBAL void saTimerTick(agsaRoot_t *agRoot)
TimerTick.
Definition: satimer.c:54
GLOBAL void siTimerRemove(agsaRoot_t *agRoot, agsaTimerDesc_t *pTimer)
remove a valid timer
Definition: satimer.c:335
bit32(* agsaCallback_t)(agsaRoot_t *agRoot, bit32 Event, void *Parm)
the callback function of an timer
Definition: satypes.h:39
data structure stores OS specific and LL specific context
Definition: sa.h:1658
void * sdkData
Definition: sa.h:1660
the data structure of Echo Command
Definition: sampidefs.h:192
bit32 payload[14]
Definition: sampidefs.h:194
the LLRoot
Definition: satypes.h:209
SALINK_LIST freeTimers
Definition: satypes.h:218
bit32 timeTick
Definition: satypes.h:234
SALINK_LIST validTimers
Definition: satypes.h:219
bit8 sysIntsActive
Definition: satypes.h:229
bit32 interruptVecIndexBitMap[MAX_NUM_VECTOR]
Definition: satypes.h:238
bit32 ResetFailed
Definition: satypes.h:302
InterruptOurs_t OurInterrupt
Definition: satypes.h:269
mpiOCQueue_t outboundQueue[AGSA_MAX_OUTBOUND_Q]
Definition: satypes.h:258
agsaQueueConfig_t QueueConfig
Definition: satypes.h:253
bit16 numOutboundQueues
Definition: sa.h:2429
the data structure of a timer
Definition: satypes.h:49
bit32 Event
Definition: satypes.h:54
SALINK linkNode
Definition: satypes.h:50
bit32 timeoutTick
Definition: satypes.h:52
agsaCallback_t pfnTimeout
Definition: satypes.h:53
void * pParm
Definition: satypes.h:55
bit32 valid
Definition: satypes.h:51
void * piPointer
Definition: mpi.h:160
bit32 consumerIdx
Definition: mpi.h:163
agsaRoot_t * agRoot
Definition: mpi.h:165
bit32 numElements
Definition: mpi.h:153
bit32 producerIdx
Definition: mpi.h:162