tdint.c revision 285809
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 *
26 * This file contains interrupt related functions in the SAS/SATA TD layer
27 *
28 */
29#include <sys/cdefs.h>
30__FBSDID("$FreeBSD$");
31#include <dev/pms/config.h>
32
33#include <dev/pms/freebsd/driver/common/osenv.h>
34#include <dev/pms/freebsd/driver/common/ostypes.h>
35#include <dev/pms/freebsd/driver/common/osdebug.h>
36
37#include <dev/pms/RefTisa/sallsdk/api/sa.h>
38#include <dev/pms/RefTisa/sallsdk/api/saapi.h>
39#include <dev/pms/RefTisa/sallsdk/api/saosapi.h>
40
41#include <dev/pms/RefTisa/tisa/api/titypes.h>
42#include <dev/pms/RefTisa/tisa/api/ostiapi.h>
43#include <dev/pms/RefTisa/tisa/api/tiapi.h>
44#include <dev/pms/RefTisa/tisa/api/tiglobal.h>
45
46#ifdef FDS_SM
47#include <dev/pms/RefTisa/sat/api/sm.h>
48#include <dev/pms/RefTisa/sat/api/smapi.h>
49#include <dev/pms/RefTisa/sat/api/tdsmapi.h>
50#endif
51
52#ifdef FDS_DM
53#include <dev/pms/RefTisa/discovery/api/dm.h>
54#include <dev/pms/RefTisa/discovery/api/dmapi.h>
55#include <dev/pms/RefTisa/discovery/api/tddmapi.h>
56#endif
57
58#include <dev/pms/RefTisa/tisa/sassata/sas/common/tdtypes.h>
59#include <dev/pms/freebsd/driver/common/osstring.h>
60#include <dev/pms/RefTisa/tisa/sassata/common/tdutil.h>
61
62#ifdef INITIATOR_DRIVER
63#include <dev/pms/RefTisa/tisa/sassata/sas/ini/itdtypes.h>
64#include <dev/pms/RefTisa/tisa/sassata/sas/ini/itddefs.h>
65#include <dev/pms/RefTisa/tisa/sassata/sas/ini/itdglobl.h>
66#endif
67
68#ifdef TARGET_DRIVER
69#include <dev/pms/RefTisa/tisa/sassata/sas/tgt/ttdglobl.h>
70#include <dev/pms/RefTisa/tisa/sassata/sas/tgt/ttdxchg.h>
71#include <dev/pms/RefTisa/tisa/sassata/sas/tgt/ttdtypes.h>
72#endif
73
74#include <dev/pms/RefTisa/tisa/sassata/common/tdsatypes.h>
75#include <dev/pms/RefTisa/tisa/sassata/common/tdproto.h>
76
77/*****************************************************************************
78*! \biref  tiCOMInterruptHandler
79*
80*  Purpose: This function is called to service the hardware interrupt of the
81*           hardware.
82*
83*  \param tiRoot:   Pointer to initiator specific root data structure  for this
84*                   instance of the driver.
85*
86*  \param channelNum: The zero-base channel number of the controller.
87*                     0xFFFFFFFF indicates that the OS-App Specific layer does
88*                     not provide the channel number. The TD/LL Layer needs to
89*                     discover of any of its own channels that are causing the
90*                     interrupt.
91*
92*  \return None
93*
94*  \note - The only thing that this API will do is to acknowledge and mask
95*          the necessary hardware interrupt register. The actual processing
96*          of the interrupt handler is done in tiCOMDelayedInterruptHandler().
97*
98*****************************************************************************/
99FORCEINLINE bit32
100tiCOMInterruptHandler(
101                      tiRoot_t * tiRoot,
102                      bit32      channelNum)
103{
104  tdsaRoot_t      *tdsaRoot = (tdsaRoot_t *) tiRoot->tdData;
105  tdsaContext_t   *tdsaAllShared = (tdsaContext_t *)&(tdsaRoot->tdsaAllShared);
106  agsaRoot_t      *agRoot = &(tdsaAllShared->agRootNonInt);
107  bit32           interruptPending = agFALSE;
108
109  interruptPending = saInterruptHandler(agRoot, channelNum);
110
111  return interruptPending;
112
113} /* tiCOMInterruptHandler() */
114
115
116/*****************************************************************************
117*! \brief tiCOMDelayedInterruptHandler
118*
119*  Purpose: This function is called to process the task associated with the
120*           interrupt handler. The task that this handler needs to do includes:
121*           completion of I/O, login event, error event, etc
122*
123*  \param tiRoot:     Pointer to initiator specific root data structure for
124*                     this instance of the driver.
125*  \param channelNum: The zero-base channel number of the controller.
126*                     0xFFFFFFFF indicates that the OS-App Specific layer does
127*                     not provide the channel number. The TD/LL Layer needs to
128*                     discover of any of its own channels that are causing the
129*                     interrupt.
130*  \param count:      Count on how many items (such as IO completion) need to
131*                     be processed in this context.
132*  \param interruptContext: The thread/process context within which this
133*                           function is called.
134*
135*             tiInterruptContext:     this function is called within an
136*                                     interrupt context.
137*             tiNonInterruptContext:  this function is called outside an
138*                                     interrupt context.
139*  \return None
140*
141*****************************************************************************/
142FORCEINLINE
143bit32
144tiCOMDelayedInterruptHandler(
145                             tiRoot_t  *tiRoot,
146                             bit32     channelNum,
147                             bit32     count,
148                             bit32     context
149                             )
150{
151  tdsaRoot_t      *tdsaRoot = (tdsaRoot_t *) tiRoot->tdData;
152  tdsaContext_t   *tdsaAllShared = (tdsaContext_t *)&(tdsaRoot->tdsaAllShared);
153  agsaRoot_t      *agRoot = agNULL;
154  bit32            completed = 0;
155
156  TDSA_OUT_ENTER(tiRoot);
157
158  if(context == tiInterruptContext)
159  {
160    agRoot = &(tdsaAllShared->agRootInt);
161  }
162  else
163  {
164    agRoot = &(tdsaAllShared->agRootNonInt);
165  }
166
167  completed = saDelayedInterruptHandler(agRoot, channelNum, count);
168
169  if(completed == 0)
170  {
171    TI_DBG3(("tiCOMDelayedInterruptHandler: processedMsgCount zero\n"));
172  }
173
174
175  TDSA_OUT_LEAVE(tiRoot);
176
177  return(completed);
178} /* tiCOMDelayedInterruptHandler() */
179
180
181/*****************************************************************************
182*! \brief tiCOMSystemInterruptsActive
183*
184*  Purpose: This function is called to indicate whether interrupts are
185*           active or not from this point in time.
186*
187*  \param tiRoot:        Pointer to initiator specific root data structure for
188*                        this instance of the driver.
189*  \param sysIntsActive: Boolean value either true or false
190*
191*  \return None
192*
193*****************************************************************************/
194osGLOBAL void
195tiCOMSystemInterruptsActive(
196                            tiRoot_t * tiRoot,
197                            bit32 sysIntsActive
198                            )
199{
200
201  tdsaRoot_t     *tdsaRoot = (tdsaRoot_t *) tiRoot->tdData;
202  tdsaContext_t  *tdsaAllShared = (tdsaContext_t *)&(tdsaRoot->tdsaAllShared);
203  agsaRoot_t     *agRoot;
204  agRoot = &(tdsaAllShared->agRootNonInt);
205
206#ifdef SPC_POLLINGMODE
207  if(sysIntsActive)  return;
208#endif /* SPC_POLLINGMODE */
209
210  tdsaAllShared->flags.sysIntsActive = sysIntsActive;
211
212  TI_DBG6(("tiCOMSystemInterruptsActive: start\n"));
213  /* enable low level interrupts */
214  if(agRoot->sdkData != agNULL)
215  {
216    saSystemInterruptsActive(
217                             agRoot,
218                             (agBOOLEAN) tdsaAllShared->flags.sysIntsActive
219                             );
220  }
221
222  TI_DBG6(("tiCOMSystemInterruptsActive: end\n"));
223} /* tiCOMSystemInterruptsActive */
224
225
226osGLOBAL void
227tiComCountActiveIORequests(
228                            tiRoot_t * tiRoot
229                          )
230{
231  tdsaRoot_t     *tdsaRoot = (tdsaRoot_t *) tiRoot->tdData;
232  tdsaContext_t  *tdsaAllShared = (tdsaContext_t *)&(tdsaRoot->tdsaAllShared);
233  agsaRoot_t     *agRoot;
234  agRoot = &(tdsaAllShared->agRootNonInt);
235  saCountActiveIORequests(agRoot );
236}
237
238/*****************************************************************************
239*! \brief tiCOMInterruptEnable
240*
241*  Purpose: This function is called to enable an interrupts on the specified channel
242*           active or not from this point in time.
243*
244*  \param tiRoot:        Pointer to initiator specific root data structure for
245*                        this instance of the driver.
246*  \param : channelNum   vector number for MSIX  Zero for legacy interrupt
247*
248*  \return None
249*
250*****************************************************************************/
251osGLOBAL FORCEINLINE
252void
253tiCOMInterruptEnable(
254                      tiRoot_t * tiRoot,
255                      bit32      channelNum)
256{
257  tdsaRoot_t     *tdsaRoot = (tdsaRoot_t *) tiRoot->tdData;
258  tdsaContext_t  *tdsaAllShared = (tdsaContext_t *)&(tdsaRoot->tdsaAllShared);
259  agsaRoot_t     *agRoot;
260  agRoot = &(tdsaAllShared->agRootNonInt);
261
262  saSystemInterruptsEnable(agRoot, channelNum);
263}
264