xref: /freebsd/sys/dev/pms/RefTisa/sallsdk/spc/satimer.c (revision 685dc743dc3b5645e34836464128e1c0558b404b)
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