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/*******************************************************************************/
23/** \file
24 *
25 * This file contains timer functions in TD layer
26 *
27 */
28#include <sys/cdefs.h>
29__FBSDID("$FreeBSD$");
30#include <dev/pms/config.h>
31
32#include <dev/pms/freebsd/driver/common/osenv.h>
33#include <dev/pms/freebsd/driver/common/ostypes.h>
34#include <dev/pms/freebsd/driver/common/osdebug.h>
35
36#include <dev/pms/RefTisa/sallsdk/api/sa.h>
37#include <dev/pms/RefTisa/sallsdk/api/saapi.h>
38#include <dev/pms/RefTisa/sallsdk/api/saosapi.h>
39
40#include <dev/pms/RefTisa/tisa/api/titypes.h>
41#include <dev/pms/RefTisa/tisa/api/ostiapi.h>
42#include <dev/pms/RefTisa/tisa/api/tiapi.h>
43#include <dev/pms/RefTisa/tisa/api/tiglobal.h>
44
45#ifdef FDS_SM
46#include <dev/pms/RefTisa/sat/api/sm.h>
47#include <dev/pms/RefTisa/sat/api/smapi.h>
48#include <dev/pms/RefTisa/sat/api/tdsmapi.h>
49#endif
50
51#ifdef FDS_DM
52#include <dev/pms/RefTisa/discovery/api/dm.h>
53#include <dev/pms/RefTisa/discovery/api/dmapi.h>
54#include <dev/pms/RefTisa/discovery/api/tddmapi.h>
55#endif
56
57#include <dev/pms/RefTisa/tisa/sassata/sas/common/tdtypes.h>
58#include <dev/pms/freebsd/driver/common/osstring.h>
59#include <dev/pms/RefTisa/tisa/sassata/common/tdutil.h>
60
61#ifdef INITIATOR_DRIVER
62#include <dev/pms/RefTisa/tisa/sassata/sas/ini/itdtypes.h>
63#include <dev/pms/RefTisa/tisa/sassata/sas/ini/itddefs.h>
64#include <dev/pms/RefTisa/tisa/sassata/sas/ini/itdglobl.h>
65#endif
66
67#ifdef TARGET_DRIVER
68#include <dev/pms/RefTisa/tisa/sassata/sas/tgt/ttdglobl.h>
69#include <dev/pms/RefTisa/tisa/sassata/sas/tgt/ttdxchg.h>
70#include <dev/pms/RefTisa/tisa/sassata/sas/tgt/ttdtypes.h>
71#endif
72
73#include <dev/pms/RefTisa/tisa/sassata/common/tdsatypes.h>
74#include <dev/pms/RefTisa/tisa/sassata/common/tdproto.h>
75
76/*****************************************************************************
77*! \brief  tiCOMTimerTick
78*
79*  Purpose: This function is called to every usecsPerTick interval
80*
81*  \param tiRoot:   Pointer to initiator specific root data structure  for this
82*                   instance of the driver.
83*
84*  \return:         None
85*
86*
87*****************************************************************************/
88osGLOBAL void
89tiCOMTimerTick (
90                tiRoot_t * tiRoot
91                )
92{
93  tdsaRoot_t *tdsaRoot = (tdsaRoot_t *)(tiRoot->tdData);
94  agsaRoot_t *agRoot = &tdsaRoot->tdsaAllShared.agRootNonInt;
95#ifdef FDS_DM
96  dmRoot_t   *dmRoot = &tdsaRoot->tdsaAllShared.dmRoot;
97#endif
98
99#ifdef FDS_SM_NOT_YET
100  smRoot_t   *smRoot = &tdsaRoot->tdsaAllShared.smRoot;
101#endif
102  /* checking the lower layer */
103  saTimerTick(agRoot);
104
105#ifdef FDS_DM
106  /* checking the DM */
107  dmTimerTick(dmRoot);
108#endif
109
110#ifdef FDS_SM_NOT_YET
111  /* checking the SM */
112  smTimerTick(smRoot);
113#endif
114
115  /*
116    timers for discovery
117    checking tdsaRoot_t timers
118  */
119
120  tdsaProcessTimers(tiRoot);
121
122}
123
124/*****************************************************************************
125*! \brief  tdsaInitTimerRequest
126*
127*  Purpose: This function initiallizes timer request
128*
129*  \param tiRoot:       Pointer to initiator specific root data structure
130*                       for this instance of the driver.
131*  \param timerrequest  Pointer to timer request
132*
133*  \return:             None
134*
135*
136*****************************************************************************/
137osGLOBAL void
138tdsaInitTimerRequest(
139                     tiRoot_t                *tiRoot,
140                     tdsaTimerRequest_t      *timerRequest
141                     )
142{
143  timerRequest->timeout       = 0;
144  timerRequest->timerCBFunc   = agNULL;
145  timerRequest->timerData1     = agNULL;
146  timerRequest->timerData2     = agNULL;
147  timerRequest->timerData3     = agNULL;
148  TDLIST_INIT_ELEMENT((&timerRequest->timerLink));
149}
150
151/*****************************************************************************
152*! \brief  tdsaSetTimerRequest
153*
154*  Purpose: This function sets timer request
155*
156*  \param tiRoot:       Pointer to initiator specific root data structure
157*                       for this instance of the driver.
158*  \param timerrequest  Pointer to timer request
159*  \param timeout       timeout value
160*  \param CBFunc        timer CB function
161*  \param timerData1     Data associated with the timer
162*  \param timerData2     Data associated with the timer
163*  \param timerData3     Data associated with the timer
164*
165*  \return:             None
166*
167*
168*****************************************************************************/
169osGLOBAL void
170tdsaSetTimerRequest(
171                  tiRoot_t            *tiRoot,
172                  tdsaTimerRequest_t  *timerRequest,
173                  bit32               timeout,
174                  tdsaTimerCBFunc_t   CBFunc,
175                  void                *timerData1,
176                  void                *timerData2,
177                  void                *timerData3
178                  )
179{
180  timerRequest->timeout     = timeout;
181  timerRequest->timerCBFunc = CBFunc;
182  timerRequest->timerData1   = timerData1;
183  timerRequest->timerData2   = timerData2;
184  timerRequest->timerData3   = timerData3;
185}
186
187/*****************************************************************************
188*! \brief  tdsaAddTimer
189*
190*  Purpose: This function adds timer request to timer list
191*
192*  \param tiRoot:       Pointer to initiator specific root data structure
193*                       for this instance of the driver.
194*  \param timerListHdr  Pointer to the timer list
195*  \param timerrequest  Pointer to timer request
196*
197*  \return:             None
198*
199*
200*****************************************************************************/
201osGLOBAL void
202tdsaAddTimer(
203             tiRoot_t            *tiRoot,
204             tdList_t            *timerListHdr,
205             tdsaTimerRequest_t  *timerRequest
206            )
207{
208  tdsaSingleThreadedEnter(tiRoot, TD_TIMER_LOCK);
209  TDLIST_ENQUEUE_AT_TAIL(&(timerRequest->timerLink), timerListHdr);
210  timerRequest->timerRunning = agTRUE;
211  tdsaSingleThreadedLeave(tiRoot, TD_TIMER_LOCK);
212}
213
214/*****************************************************************************
215*! \brief  tdsaKillTimer
216*
217*  Purpose: This function kills timer request.
218*
219*  \param tiRoot:       Pointer to initiator specific root data structure
220*                       for this instance of the driver.
221*  \param timerrequest  Pointer to timer request
222*
223*  \return:             None
224*
225*
226*****************************************************************************/
227osGLOBAL void
228tdsaKillTimer(
229              tiRoot_t            *tiRoot,
230              tdsaTimerRequest_t  *timerRequest
231              )
232{
233  tdsaSingleThreadedEnter(tiRoot, TD_TIMER_LOCK);
234  timerRequest->timerRunning = agFALSE;
235  TDLIST_DEQUEUE_THIS(&(timerRequest->timerLink));
236  tdsaSingleThreadedLeave(tiRoot, TD_TIMER_LOCK);
237}
238
239/*****************************************************************************
240*! \brief  tdsaProcessTimers
241*
242*  Purpose: This function processes timer request.
243*
244*  \param tiRoot:       Pointer to initiator specific root data structure
245*                       for this instance of the driver.
246*
247*  \return:             None
248*
249*
250*****************************************************************************/
251osGLOBAL void
252tdsaProcessTimers(
253                  tiRoot_t *tiRoot
254                  )
255{
256  tdsaRoot_t     *tdsaRoot = (tdsaRoot_t *)(tiRoot->tdData);
257  tdsaContext_t  *tdsaAllShared = (tdsaContext_t *)&tdsaRoot->tdsaAllShared;
258  tdsaTimerRequest_t *timerRequest_to_process = agNULL;
259  tdList_t *timerlist_to_process, *nexttimerlist = agNULL;
260
261
262  timerlist_to_process = &tdsaAllShared->timerlist;
263
264  timerlist_to_process = timerlist_to_process->flink;
265
266  while ((timerlist_to_process != agNULL) && (timerlist_to_process != &tdsaAllShared->timerlist))
267  {
268    nexttimerlist = timerlist_to_process->flink;
269
270    tdsaSingleThreadedEnter(tiRoot, TD_TIMER_LOCK);
271    timerRequest_to_process = TDLIST_OBJECT_BASE(tdsaTimerRequest_t, timerLink, timerlist_to_process);
272    tdsaSingleThreadedLeave(tiRoot, TD_TIMER_LOCK);
273
274    if (timerRequest_to_process == agNULL)
275    {
276      TI_DBG1(("tdsaProcessTimers: timerRequest_to_process is NULL! Error!!!\n"));
277      return;
278    }
279
280    timerRequest_to_process->timeout--;
281
282    if (timerRequest_to_process->timeout == 0)
283    {
284      tdsaSingleThreadedEnter(tiRoot, TD_TIMER_LOCK);
285      if (timerRequest_to_process->timerRunning == agTRUE)
286      {
287        timerRequest_to_process->timerRunning = agFALSE;
288        TDLIST_DEQUEUE_THIS(timerlist_to_process);
289      }
290      tdsaSingleThreadedLeave(tiRoot, TD_TIMER_LOCK);
291      /* calling call back function */
292      (timerRequest_to_process->timerCBFunc)(tiRoot,
293                                             timerRequest_to_process->timerData1,
294                                             timerRequest_to_process->timerData2,
295                                             timerRequest_to_process->timerData3
296                                             );
297    }
298    timerlist_to_process = nexttimerlist;
299  }
300  return;
301}
302
303