1*4e1bc9a0SAchim Leubner /*******************************************************************************
2*4e1bc9a0SAchim Leubner *Copyright (c) 2014 PMC-Sierra, Inc. All rights reserved.
3*4e1bc9a0SAchim Leubner *
4*4e1bc9a0SAchim Leubner *Redistribution and use in source and binary forms, with or without modification, are permitted provided
5*4e1bc9a0SAchim Leubner *that the following conditions are met:
6*4e1bc9a0SAchim Leubner *1. Redistributions of source code must retain the above copyright notice, this list of conditions and the
7*4e1bc9a0SAchim Leubner *following disclaimer.
8*4e1bc9a0SAchim Leubner *2. Redistributions in binary form must reproduce the above copyright notice,
9*4e1bc9a0SAchim Leubner *this list of conditions and the following disclaimer in the documentation and/or other materials provided
10*4e1bc9a0SAchim Leubner *with the distribution.
11*4e1bc9a0SAchim Leubner *
12*4e1bc9a0SAchim Leubner *THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED
13*4e1bc9a0SAchim Leubner *WARRANTIES,INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
14*4e1bc9a0SAchim Leubner *FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
15*4e1bc9a0SAchim Leubner *FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
16*4e1bc9a0SAchim Leubner *NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
17*4e1bc9a0SAchim Leubner *BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
18*4e1bc9a0SAchim Leubner *LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
19*4e1bc9a0SAchim Leubner *SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE
20*4e1bc9a0SAchim Leubner
21*4e1bc9a0SAchim Leubner ********************************************************************************/
22*4e1bc9a0SAchim Leubner /*******************************************************************************/
23*4e1bc9a0SAchim Leubner /*! \file satimer.c
24*4e1bc9a0SAchim Leubner * \brief The file implements the timerTick function
25*4e1bc9a0SAchim Leubner *
26*4e1bc9a0SAchim Leubner */
27*4e1bc9a0SAchim Leubner /******************************************************************************/
28*4e1bc9a0SAchim Leubner #include <sys/cdefs.h>
29*4e1bc9a0SAchim Leubner #include <dev/pms/config.h>
30*4e1bc9a0SAchim Leubner
31*4e1bc9a0SAchim Leubner #include <dev/pms/RefTisa/sallsdk/spc/saglobal.h>
32*4e1bc9a0SAchim Leubner #ifdef SA_FW_TEST_BUNCH_STARTS
33*4e1bc9a0SAchim Leubner void mpiMsgProduceBunch( agsaLLRoot_t *saRoot);
34*4e1bc9a0SAchim Leubner #endif /* SA_FW_TEST_BUNCH_STARTS */
35*4e1bc9a0SAchim Leubner
36*4e1bc9a0SAchim Leubner #ifdef SA_ENABLE_TRACE_FUNCTIONS
37*4e1bc9a0SAchim Leubner #ifdef siTraceFileID
38*4e1bc9a0SAchim Leubner #undef siTraceFileID
39*4e1bc9a0SAchim Leubner #endif
40*4e1bc9a0SAchim Leubner #define siTraceFileID 'P'
41*4e1bc9a0SAchim Leubner #endif
42*4e1bc9a0SAchim Leubner
43*4e1bc9a0SAchim Leubner /******************************************************************************/
44*4e1bc9a0SAchim Leubner /*! \brief TimerTick
45*4e1bc9a0SAchim Leubner *
46*4e1bc9a0SAchim Leubner * TimerTick
47*4e1bc9a0SAchim Leubner *
48*4e1bc9a0SAchim Leubner * \param agRoot handles for this instance of SAS/SATA hardware
49*4e1bc9a0SAchim Leubner *
50*4e1bc9a0SAchim Leubner * \return -void-
51*4e1bc9a0SAchim Leubner */
52*4e1bc9a0SAchim Leubner /*******************************************************************************/
saTimerTick(agsaRoot_t * agRoot)53*4e1bc9a0SAchim Leubner GLOBAL void saTimerTick(
54*4e1bc9a0SAchim Leubner agsaRoot_t *agRoot
55*4e1bc9a0SAchim Leubner )
56*4e1bc9a0SAchim Leubner {
57*4e1bc9a0SAchim Leubner agsaLLRoot_t *saRoot = (agsaLLRoot_t *)(agRoot->sdkData);
58*4e1bc9a0SAchim Leubner agsaTimerDesc_t *pTimer;
59*4e1bc9a0SAchim Leubner bit32 Event;
60*4e1bc9a0SAchim Leubner void * pParm;
61*4e1bc9a0SAchim Leubner
62*4e1bc9a0SAchim Leubner if(agNULL == saRoot)
63*4e1bc9a0SAchim Leubner {
64*4e1bc9a0SAchim Leubner SA_DBG1(("saTimerTick:agNULL == saRoot \n"));
65*4e1bc9a0SAchim Leubner return;
66*4e1bc9a0SAchim Leubner }
67*4e1bc9a0SAchim Leubner
68*4e1bc9a0SAchim Leubner /* (1) Acquire timer list lock */
69*4e1bc9a0SAchim Leubner ossaSingleThreadedEnter(agRoot, LL_TIMER_LOCK);
70*4e1bc9a0SAchim Leubner
71*4e1bc9a0SAchim Leubner /* (2) Find the timers are timeout */
72*4e1bc9a0SAchim Leubner pTimer = (agsaTimerDesc_t *) saLlistGetHead(&(saRoot->validTimers));
73*4e1bc9a0SAchim Leubner while ( agNULL != pTimer )
74*4e1bc9a0SAchim Leubner {
75*4e1bc9a0SAchim Leubner /* (2.1) Find the first timer is timeout */
76*4e1bc9a0SAchim Leubner if ( pTimer->timeoutTick == saRoot->timeTick )
77*4e1bc9a0SAchim Leubner {
78*4e1bc9a0SAchim Leubner /* (2.1.1) remove the timer from valid timer list */
79*4e1bc9a0SAchim Leubner saLlistRemove(&(saRoot->validTimers), &(pTimer->linkNode));
80*4e1bc9a0SAchim Leubner /* (2.1.2) Invalid timer */
81*4e1bc9a0SAchim Leubner pTimer->valid = agFALSE;
82*4e1bc9a0SAchim Leubner /* (2.1.3) Get timer event and param */
83*4e1bc9a0SAchim Leubner Event = pTimer->Event;
84*4e1bc9a0SAchim Leubner pParm = pTimer->pParm;
85*4e1bc9a0SAchim Leubner /* (2.1.4) Release timer list lock */
86*4e1bc9a0SAchim Leubner ossaSingleThreadedLeave(agRoot, LL_TIMER_LOCK);
87*4e1bc9a0SAchim Leubner
88*4e1bc9a0SAchim Leubner /* (2.1.5) Timer Callback */
89*4e1bc9a0SAchim Leubner pTimer->pfnTimeout(agRoot, Event, pParm);
90*4e1bc9a0SAchim Leubner
91*4e1bc9a0SAchim Leubner /* (2.1.6) Acquire timer list lock again */
92*4e1bc9a0SAchim Leubner ossaSingleThreadedEnter(agRoot, LL_TIMER_LOCK);
93*4e1bc9a0SAchim Leubner /* (2.1.7) return the timer to free timer list */
94*4e1bc9a0SAchim Leubner saLlistAdd(&(saRoot->freeTimers), &(pTimer->linkNode));
95*4e1bc9a0SAchim Leubner }
96*4e1bc9a0SAchim Leubner /* (2.2) the first timer is not timeout */
97*4e1bc9a0SAchim Leubner else
98*4e1bc9a0SAchim Leubner {
99*4e1bc9a0SAchim Leubner break;
100*4e1bc9a0SAchim Leubner }
101*4e1bc9a0SAchim Leubner pTimer = (agsaTimerDesc_t *) saLlistGetHead(&(saRoot->validTimers));
102*4e1bc9a0SAchim Leubner }
103*4e1bc9a0SAchim Leubner
104*4e1bc9a0SAchim Leubner /* (3) increment timeTick */
105*4e1bc9a0SAchim Leubner saRoot->timeTick ++;
106*4e1bc9a0SAchim Leubner
107*4e1bc9a0SAchim Leubner if( saRoot->ResetFailed )
108*4e1bc9a0SAchim Leubner {
109*4e1bc9a0SAchim Leubner SA_DBG1(("saTimerTick: siChipResetV saRoot->ResetFailed\n"));
110*4e1bc9a0SAchim Leubner }
111*4e1bc9a0SAchim Leubner
112*4e1bc9a0SAchim Leubner #ifdef SA_FW_TEST_BUNCH_STARTS
113*4e1bc9a0SAchim Leubner if (saRoot->BunchStarts_Enable &&
114*4e1bc9a0SAchim Leubner saRoot->BunchStarts_Pending)
115*4e1bc9a0SAchim Leubner {
116*4e1bc9a0SAchim Leubner SA_DBG3(("saTimerTick: mpiMsgProduceBunch\n"));
117*4e1bc9a0SAchim Leubner mpiMsgProduceBunch( saRoot);
118*4e1bc9a0SAchim Leubner }
119*4e1bc9a0SAchim Leubner #endif /* SA_FW_TEST_BUNCH_STARTS */
120*4e1bc9a0SAchim Leubner
121*4e1bc9a0SAchim Leubner
122*4e1bc9a0SAchim Leubner #ifdef SA_FW_TEST_INTERRUPT_REASSERT
123*4e1bc9a0SAchim Leubner
124*4e1bc9a0SAchim Leubner if(1)
125*4e1bc9a0SAchim Leubner {
126*4e1bc9a0SAchim Leubner mpiOCQueue_t *circularQ;
127*4e1bc9a0SAchim Leubner int i;
128*4e1bc9a0SAchim Leubner SA_DBG4(("saTimerTick:SA_FW_TEST_INTERRUPT_REASSERT\n"));
129*4e1bc9a0SAchim Leubner for ( i = 0; i < saRoot->QueueConfig.numOutboundQueues; i++ )
130*4e1bc9a0SAchim Leubner {
131*4e1bc9a0SAchim Leubner circularQ = &saRoot->outboundQueue[i];
132*4e1bc9a0SAchim Leubner OSSA_READ_LE_32(circularQ->agRoot, &circularQ->producerIdx, circularQ->piPointer, 0);
133*4e1bc9a0SAchim Leubner if(circularQ->producerIdx != circularQ->consumerIdx)
134*4e1bc9a0SAchim Leubner {
135*4e1bc9a0SAchim Leubner if( saRoot->OldCi[i] == circularQ->consumerIdx && saRoot->OldPi[i] >= circularQ->producerIdx)
136*4e1bc9a0SAchim Leubner {
137*4e1bc9a0SAchim Leubner agsaEchoCmd_t payload;
138*4e1bc9a0SAchim Leubner payload.tag = 0xF0;
139*4e1bc9a0SAchim Leubner payload.payload[0]= 0x0;
140*4e1bc9a0SAchim Leubner if( ++saRoot->OldFlag[i] > 1 )
141*4e1bc9a0SAchim Leubner {
142*4e1bc9a0SAchim Leubner saRoot->CheckAll++;
143*4e1bc9a0SAchim Leubner }
144*4e1bc9a0SAchim Leubner SA_DBG1(("saTimerTick:Q %d (%d) PI 0x%03x CI 0x%03x (%d) CheckAll %d %d\n",i,
145*4e1bc9a0SAchim Leubner saRoot->OldFlag[i],
146*4e1bc9a0SAchim Leubner circularQ->producerIdx,
147*4e1bc9a0SAchim Leubner circularQ->consumerIdx,
148*4e1bc9a0SAchim Leubner (circularQ->producerIdx > circularQ->consumerIdx ? (circularQ->producerIdx - circularQ->consumerIdx) : (circularQ->numElements - circularQ->consumerIdx ) + circularQ->producerIdx),
149*4e1bc9a0SAchim Leubner saRoot->CheckAll,
150*4e1bc9a0SAchim Leubner saRoot->sysIntsActive ));
151*4e1bc9a0SAchim Leubner
152*4e1bc9a0SAchim Leubner if(smIS64bInt(agRoot))
153*4e1bc9a0SAchim Leubner {
154*4e1bc9a0SAchim Leubner SA_DBG1(("saTimerTick:CheckAll %d ODR 0x%08X%08X ODMR 0x%08X%08X our Int %x\n",
155*4e1bc9a0SAchim Leubner saRoot->CheckAll,
156*4e1bc9a0SAchim Leubner ossaHwRegReadExt(agRoot, 0, V_Outbound_Doorbell_Set_RegisterU),
157*4e1bc9a0SAchim Leubner ossaHwRegReadExt(agRoot, 0, V_Outbound_Doorbell_Set_Register),
158*4e1bc9a0SAchim Leubner ossaHwRegReadExt(agRoot, 0, V_Outbound_Doorbell_Mask_Set_RegisterU),
159*4e1bc9a0SAchim Leubner ossaHwRegReadExt(agRoot, 0, V_Outbound_Doorbell_Mask_Set_Register),
160*4e1bc9a0SAchim Leubner saRoot->OurInterrupt(agRoot,i)
161*4e1bc9a0SAchim Leubner ));
162*4e1bc9a0SAchim Leubner }
163*4e1bc9a0SAchim Leubner else
164*4e1bc9a0SAchim Leubner {
165*4e1bc9a0SAchim Leubner SA_DBG1(("saTimerTick:CheckAll %d ODR 0x%08X ODMR 0x%08X our Int %x\n",
166*4e1bc9a0SAchim Leubner saRoot->CheckAll,
167*4e1bc9a0SAchim Leubner siHalRegReadExt(agRoot, GEN_MSGU_ODR, V_Outbound_Doorbell_Set_Register),
168*4e1bc9a0SAchim Leubner siHalRegReadExt(agRoot, GEN_MSGU_ODMR, V_Outbound_Doorbell_Mask_Set_Register),
169*4e1bc9a0SAchim Leubner saRoot->OurInterrupt(agRoot,i)
170*4e1bc9a0SAchim Leubner ));
171*4e1bc9a0SAchim Leubner }
172*4e1bc9a0SAchim Leubner
173*4e1bc9a0SAchim Leubner
174*4e1bc9a0SAchim Leubner if( saRoot->CheckAll > 1)
175*4e1bc9a0SAchim Leubner {
176*4e1bc9a0SAchim Leubner saEchoCommand(agRoot,agNULL, ((i << 16) & 0xFFFF0000 ), (void *)&payload);
177*4e1bc9a0SAchim Leubner }
178*4e1bc9a0SAchim Leubner
179*4e1bc9a0SAchim Leubner }
180*4e1bc9a0SAchim Leubner else
181*4e1bc9a0SAchim Leubner {
182*4e1bc9a0SAchim Leubner saRoot->OldFlag[i] = 0;
183*4e1bc9a0SAchim Leubner }
184*4e1bc9a0SAchim Leubner
185*4e1bc9a0SAchim Leubner saRoot->OldPi[i] = circularQ->producerIdx;
186*4e1bc9a0SAchim Leubner saRoot->OldCi[i] = circularQ->consumerIdx;
187*4e1bc9a0SAchim Leubner
188*4e1bc9a0SAchim Leubner }
189*4e1bc9a0SAchim Leubner }
190*4e1bc9a0SAchim Leubner }
191*4e1bc9a0SAchim Leubner #endif /* SA_FW_TEST_INTERRUPT_REASSERT */
192*4e1bc9a0SAchim Leubner
193*4e1bc9a0SAchim Leubner /* (4) Release timer list lock */
194*4e1bc9a0SAchim Leubner ossaSingleThreadedLeave(agRoot, LL_TIMER_LOCK);
195*4e1bc9a0SAchim Leubner #ifdef SA_FW_TEST_INTERRUPT_REASSERT
196*4e1bc9a0SAchim Leubner if(saRoot->CheckAll )
197*4e1bc9a0SAchim Leubner {
198*4e1bc9a0SAchim Leubner int a;
199*4e1bc9a0SAchim Leubner for(a=0; a < 32; a++ )
200*4e1bc9a0SAchim Leubner {
201*4e1bc9a0SAchim Leubner if (saRoot->interruptVecIndexBitMap[a] & (1 << a))
202*4e1bc9a0SAchim Leubner {
203*4e1bc9a0SAchim Leubner SA_DBG1(("saTimerTick DI %d\n",a));
204*4e1bc9a0SAchim Leubner saSystemInterruptsEnable ( agRoot, a );
205*4e1bc9a0SAchim Leubner
206*4e1bc9a0SAchim Leubner }
207*4e1bc9a0SAchim Leubner }
208*4e1bc9a0SAchim Leubner }
209*4e1bc9a0SAchim Leubner #endif /* SA_FW_TEST_INTERRUPT_REASSERT */
210*4e1bc9a0SAchim Leubner }
211*4e1bc9a0SAchim Leubner
212*4e1bc9a0SAchim Leubner /******************************************************************************/
213*4e1bc9a0SAchim Leubner /*! \brief add a timer
214*4e1bc9a0SAchim Leubner *
215*4e1bc9a0SAchim Leubner * add a timer
216*4e1bc9a0SAchim Leubner *
217*4e1bc9a0SAchim Leubner * \param agRoot handles for this instance of SAS/SATA hardware
218*4e1bc9a0SAchim Leubner * \param pTimer the pointer to the timer being added
219*4e1bc9a0SAchim Leubner * \param timeout the timeout ticks from now
220*4e1bc9a0SAchim Leubner * \param pfnTimeout callback function when time is out
221*4e1bc9a0SAchim Leubner * \param Event the Event code passed to callback function
222*4e1bc9a0SAchim Leubner * \param pParm the pointer to parameter passed to callback function
223*4e1bc9a0SAchim Leubner *
224*4e1bc9a0SAchim Leubner * \return If the timer is added successfully
225*4e1bc9a0SAchim Leubner * - \e AGSA_RC_SUCCESS timer is added successfully
226*4e1bc9a0SAchim Leubner * - \e AGSA_RC_FAILURE cannot add new timer, run out of resource
227*4e1bc9a0SAchim Leubner */
228*4e1bc9a0SAchim Leubner /*******************************************************************************/
siTimerAdd(agsaRoot_t * agRoot,bit32 timeout,agsaCallback_t pfnTimeout,bit32 Event,void * pParm)229*4e1bc9a0SAchim Leubner GLOBAL agsaTimerDesc_t *siTimerAdd(
230*4e1bc9a0SAchim Leubner agsaRoot_t *agRoot,
231*4e1bc9a0SAchim Leubner bit32 timeout,
232*4e1bc9a0SAchim Leubner agsaCallback_t pfnTimeout,
233*4e1bc9a0SAchim Leubner bit32 Event,
234*4e1bc9a0SAchim Leubner void * pParm
235*4e1bc9a0SAchim Leubner )
236*4e1bc9a0SAchim Leubner {
237*4e1bc9a0SAchim Leubner agsaLLRoot_t *saRoot = (agsaLLRoot_t *)(agRoot->sdkData);
238*4e1bc9a0SAchim Leubner agsaTimerDesc_t *pTimer;
239*4e1bc9a0SAchim Leubner agsaTimerDesc_t *pValidTimer;
240*4e1bc9a0SAchim Leubner
241*4e1bc9a0SAchim Leubner smTraceFuncEnter(hpDBG_VERY_LOUD, "Ta");
242*4e1bc9a0SAchim Leubner /* (1) Acquire timer list lock */
243*4e1bc9a0SAchim Leubner ossaSingleThreadedEnter(agRoot, LL_TIMER_LOCK);
244*4e1bc9a0SAchim Leubner
245*4e1bc9a0SAchim Leubner /* (2) Get a free timer */
246*4e1bc9a0SAchim Leubner pTimer = (agsaTimerDesc_t *) saLlistGetHead(&(saRoot->freeTimers));
247*4e1bc9a0SAchim Leubner
248*4e1bc9a0SAchim Leubner /* (3) If the timer is availble */
249*4e1bc9a0SAchim Leubner if ( agNULL != pTimer )
250*4e1bc9a0SAchim Leubner {
251*4e1bc9a0SAchim Leubner saLlistRemove(&(saRoot->freeTimers), &(pTimer->linkNode));
252*4e1bc9a0SAchim Leubner
253*4e1bc9a0SAchim Leubner /* (3.1) Setup timer */
254*4e1bc9a0SAchim Leubner saLlinkInitialize(&(pTimer->linkNode));
255*4e1bc9a0SAchim Leubner /*--------------------------------------**
256*4e1bc9a0SAchim Leubner ** the timeout shall greater than 0 **
257*4e1bc9a0SAchim Leubner **--------------------------------------*/
258*4e1bc9a0SAchim Leubner if ( 0 == timeout )
259*4e1bc9a0SAchim Leubner {
260*4e1bc9a0SAchim Leubner timeout = timeout + 1;
261*4e1bc9a0SAchim Leubner }
262*4e1bc9a0SAchim Leubner pTimer->valid = agTRUE;
263*4e1bc9a0SAchim Leubner pTimer->timeoutTick = saRoot->timeTick + timeout;
264*4e1bc9a0SAchim Leubner pTimer->pfnTimeout = pfnTimeout;
265*4e1bc9a0SAchim Leubner pTimer->Event = Event;
266*4e1bc9a0SAchim Leubner pTimer->pParm = pParm;
267*4e1bc9a0SAchim Leubner
268*4e1bc9a0SAchim Leubner /* (3.2) Add timer the timer to valid timer list */
269*4e1bc9a0SAchim Leubner pValidTimer = (agsaTimerDesc_t *) saLlistGetHead(&(saRoot->validTimers));
270*4e1bc9a0SAchim Leubner /* (3.3) for each timer in the valid timer list */
271*4e1bc9a0SAchim Leubner while ( agNULL != pValidTimer )
272*4e1bc9a0SAchim Leubner {
273*4e1bc9a0SAchim Leubner /* (3.3.1) If the timeoutTick is not wrapped around */
274*4e1bc9a0SAchim Leubner if ( pTimer->timeoutTick > saRoot->timeTick )
275*4e1bc9a0SAchim Leubner {
276*4e1bc9a0SAchim Leubner /* (3.3.1.1) If validTimer wrapped around */
277*4e1bc9a0SAchim Leubner if ( pValidTimer->timeoutTick < saRoot->timeTick )
278*4e1bc9a0SAchim Leubner {
279*4e1bc9a0SAchim Leubner saLlistInsert(&(saRoot->validTimers), &(pValidTimer->linkNode), &(pTimer->linkNode));
280*4e1bc9a0SAchim Leubner break;
281*4e1bc9a0SAchim Leubner }
282*4e1bc9a0SAchim Leubner /* (3.3.1.2) If validTimer is not wrapped around */
283*4e1bc9a0SAchim Leubner else
284*4e1bc9a0SAchim Leubner {
285*4e1bc9a0SAchim Leubner if ( pValidTimer->timeoutTick > pTimer->timeoutTick )
286*4e1bc9a0SAchim Leubner {
287*4e1bc9a0SAchim Leubner saLlistInsert(&(saRoot->validTimers), &(pValidTimer->linkNode), &(pTimer->linkNode));
288*4e1bc9a0SAchim Leubner break;
289*4e1bc9a0SAchim Leubner }
290*4e1bc9a0SAchim Leubner }
291*4e1bc9a0SAchim Leubner }
292*4e1bc9a0SAchim Leubner /* (3.3.2) If the timeoutTick is wrapped around */
293*4e1bc9a0SAchim Leubner else
294*4e1bc9a0SAchim Leubner {
295*4e1bc9a0SAchim Leubner /* (3.3.2.1) If validTimer is wrapped around */
296*4e1bc9a0SAchim Leubner if ( pValidTimer->timeoutTick < saRoot->timeTick )
297*4e1bc9a0SAchim Leubner {
298*4e1bc9a0SAchim Leubner if ( pValidTimer->timeoutTick > pTimer->timeoutTick )
299*4e1bc9a0SAchim Leubner {
300*4e1bc9a0SAchim Leubner saLlistInsert(&(saRoot->validTimers), &(pValidTimer->linkNode), &(pTimer->linkNode));
301*4e1bc9a0SAchim Leubner break;
302*4e1bc9a0SAchim Leubner }
303*4e1bc9a0SAchim Leubner }
304*4e1bc9a0SAchim Leubner }
305*4e1bc9a0SAchim Leubner /* (3.3.3) Continue to the next valid timer */
306*4e1bc9a0SAchim Leubner pValidTimer = (agsaTimerDesc_t *) saLlistGetNext(&(saRoot->validTimers), &(pValidTimer->linkNode));
307*4e1bc9a0SAchim Leubner }
308*4e1bc9a0SAchim Leubner
309*4e1bc9a0SAchim Leubner /* (3.4) No timers in the validtimer list is greater than this timer */
310*4e1bc9a0SAchim Leubner if ( agNULL == pValidTimer )
311*4e1bc9a0SAchim Leubner {
312*4e1bc9a0SAchim Leubner saLlistAdd(&(saRoot->validTimers), &(pTimer->linkNode));
313*4e1bc9a0SAchim Leubner }
314*4e1bc9a0SAchim Leubner }
315*4e1bc9a0SAchim Leubner
316*4e1bc9a0SAchim Leubner /* (4) Release timer list lock */
317*4e1bc9a0SAchim Leubner ossaSingleThreadedLeave(agRoot, LL_TIMER_LOCK);
318*4e1bc9a0SAchim Leubner smTraceFuncExit(hpDBG_VERY_LOUD, 'a', "Ta");
319*4e1bc9a0SAchim Leubner
320*4e1bc9a0SAchim Leubner return pTimer;
321*4e1bc9a0SAchim Leubner }
322*4e1bc9a0SAchim Leubner
323*4e1bc9a0SAchim Leubner /******************************************************************************/
324*4e1bc9a0SAchim Leubner /*! \brief remove a valid timer
325*4e1bc9a0SAchim Leubner *
326*4e1bc9a0SAchim Leubner * remove a timer
327*4e1bc9a0SAchim Leubner *
328*4e1bc9a0SAchim Leubner * \param agRoot handles for this instance of SAS/SATA hardware
329*4e1bc9a0SAchim Leubner * \param pTimer the timer to be removed
330*4e1bc9a0SAchim Leubner *
331*4e1bc9a0SAchim Leubner * \return -void-
332*4e1bc9a0SAchim Leubner */
333*4e1bc9a0SAchim Leubner /*******************************************************************************/
siTimerRemove(agsaRoot_t * agRoot,agsaTimerDesc_t * pTimer)334*4e1bc9a0SAchim Leubner GLOBAL void siTimerRemove(
335*4e1bc9a0SAchim Leubner agsaRoot_t *agRoot,
336*4e1bc9a0SAchim Leubner agsaTimerDesc_t *pTimer
337*4e1bc9a0SAchim Leubner )
338*4e1bc9a0SAchim Leubner {
339*4e1bc9a0SAchim Leubner agsaLLRoot_t *saRoot = (agsaLLRoot_t *)(agRoot->sdkData);
340*4e1bc9a0SAchim Leubner
341*4e1bc9a0SAchim Leubner /* (1) Acquire timer list lock */
342*4e1bc9a0SAchim Leubner smTraceFuncEnter(hpDBG_VERY_LOUD,"Tb");
343*4e1bc9a0SAchim Leubner ossaSingleThreadedEnter(agRoot, LL_TIMER_LOCK);
344*4e1bc9a0SAchim Leubner
345*4e1bc9a0SAchim Leubner /* (2) If the timer is still valid */
346*4e1bc9a0SAchim Leubner if ( agTRUE == pTimer->valid )
347*4e1bc9a0SAchim Leubner {
348*4e1bc9a0SAchim Leubner /* (2.1) remove from the valid timer list */
349*4e1bc9a0SAchim Leubner saLlistRemove(&(saRoot->validTimers), &(pTimer->linkNode));
350*4e1bc9a0SAchim Leubner /* (2.2) Invalid the timer */
351*4e1bc9a0SAchim Leubner pTimer->valid = agFALSE;
352*4e1bc9a0SAchim Leubner /* (2.3) return the timer to the free timer list */
353*4e1bc9a0SAchim Leubner saLlistAdd(&(saRoot->freeTimers), &(pTimer->linkNode));
354*4e1bc9a0SAchim Leubner }
355*4e1bc9a0SAchim Leubner /* (3) Release timer list lock */
356*4e1bc9a0SAchim Leubner ossaSingleThreadedLeave(agRoot, LL_TIMER_LOCK);
357*4e1bc9a0SAchim Leubner smTraceFuncExit(hpDBG_VERY_LOUD, 'a', "Tb");
358*4e1bc9a0SAchim Leubner
359*4e1bc9a0SAchim Leubner return;
360*4e1bc9a0SAchim Leubner }
361*4e1bc9a0SAchim Leubner
362*4e1bc9a0SAchim Leubner /******************************************************************************/
363*4e1bc9a0SAchim Leubner /*! \brief remove all valid timer
364*4e1bc9a0SAchim Leubner *
365*4e1bc9a0SAchim Leubner * remove all timer
366*4e1bc9a0SAchim Leubner *
367*4e1bc9a0SAchim Leubner * \param agRoot handles for this instance of SAS/SATA hardware
368*4e1bc9a0SAchim Leubner *
369*4e1bc9a0SAchim Leubner * \return -void-
370*4e1bc9a0SAchim Leubner */
371*4e1bc9a0SAchim Leubner /*******************************************************************************/
siTimerRemoveAll(agsaRoot_t * agRoot)372*4e1bc9a0SAchim Leubner GLOBAL void siTimerRemoveAll(
373*4e1bc9a0SAchim Leubner agsaRoot_t *agRoot
374*4e1bc9a0SAchim Leubner )
375*4e1bc9a0SAchim Leubner {
376*4e1bc9a0SAchim Leubner agsaLLRoot_t *saRoot = (agsaLLRoot_t *)(agRoot->sdkData);
377*4e1bc9a0SAchim Leubner agsaTimerDesc_t *pTimer;
378*4e1bc9a0SAchim Leubner
379*4e1bc9a0SAchim Leubner smTraceFuncEnter(hpDBG_VERY_LOUD,"Tc");
380*4e1bc9a0SAchim Leubner
381*4e1bc9a0SAchim Leubner /* (1) Acquire timer list lock */
382*4e1bc9a0SAchim Leubner ossaSingleThreadedEnter(agRoot, LL_TIMER_LOCK);
383*4e1bc9a0SAchim Leubner
384*4e1bc9a0SAchim Leubner /* (2) Get a valid timer */
385*4e1bc9a0SAchim Leubner pTimer = (agsaTimerDesc_t *) saLlistGetHead(&(saRoot->validTimers));
386*4e1bc9a0SAchim Leubner
387*4e1bc9a0SAchim Leubner /* (3) If the timer is valid */
388*4e1bc9a0SAchim Leubner while ( agNULL != pTimer )
389*4e1bc9a0SAchim Leubner {
390*4e1bc9a0SAchim Leubner /* (3.1) remove from the valid timer list */
391*4e1bc9a0SAchim Leubner saLlistRemove(&(saRoot->validTimers), &(pTimer->linkNode));
392*4e1bc9a0SAchim Leubner
393*4e1bc9a0SAchim Leubner /* (3.2) Invalid timer */
394*4e1bc9a0SAchim Leubner pTimer->valid = agFALSE;
395*4e1bc9a0SAchim Leubner
396*4e1bc9a0SAchim Leubner /* (3.3) return the timer to the free timer list */
397*4e1bc9a0SAchim Leubner saLlistAdd(&(saRoot->freeTimers), &(pTimer->linkNode));
398*4e1bc9a0SAchim Leubner
399*4e1bc9a0SAchim Leubner /* (3.4) get next valid timer */
400*4e1bc9a0SAchim Leubner pTimer = (agsaTimerDesc_t *) saLlistGetHead(&(saRoot->validTimers));
401*4e1bc9a0SAchim Leubner }
402*4e1bc9a0SAchim Leubner
403*4e1bc9a0SAchim Leubner /* (4) Release timer list lock */
404*4e1bc9a0SAchim Leubner ossaSingleThreadedLeave(agRoot, LL_TIMER_LOCK);
405*4e1bc9a0SAchim Leubner
406*4e1bc9a0SAchim Leubner smTraceFuncExit(hpDBG_VERY_LOUD, 'a', "Tc");
407*4e1bc9a0SAchim Leubner
408*4e1bc9a0SAchim Leubner return;
409*4e1bc9a0SAchim Leubner }
410