1181074Sdas/*******************************************************************************
2181074Sdas*Copyright (c) 2014 PMC-Sierra, Inc.  All rights reserved.
3181074Sdas*
4181074Sdas*Redistribution and use in source and binary forms, with or without modification, are permitted provided
5181074Sdas*that the following conditions are met:
6181074Sdas*1. Redistributions of source code must retain the above copyright notice, this list of conditions and the
7181074Sdas*following disclaimer.
8181074Sdas*2. Redistributions in binary form must reproduce the above copyright notice,
9181074Sdas*this list of conditions and the following disclaimer in the documentation and/or other materials provided
10181074Sdas*with the distribution.
11181074Sdas*
12181074Sdas*THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED
13181074Sdas*WARRANTIES,INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
14181074Sdas*FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
15181074Sdas*FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
16181074Sdas*NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
17181074Sdas*BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
18181074Sdas*LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
19181074Sdas*SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE
20181074Sdas
21181074Sdas********************************************************************************/
22181074Sdas/*******************************************************************************/
23181074Sdas/** \file
24181074Sdas *
25181074Sdas *
26181074Sdas * This file contains interrupt related functions in the SAS/SATA TD layer
27181074Sdas *
28181074Sdas */
29181074Sdas#include <sys/cdefs.h>
30181074Sdas__FBSDID("$FreeBSD$");
31181074Sdas#include <dev/pms/config.h>
32181074Sdas
33181074Sdas#include <dev/pms/freebsd/driver/common/osenv.h>
34181074Sdas#include <dev/pms/freebsd/driver/common/ostypes.h>
35181074Sdas#include <dev/pms/freebsd/driver/common/osdebug.h>
36181074Sdas
37181074Sdas#include <dev/pms/RefTisa/sallsdk/api/sa.h>
38181074Sdas#include <dev/pms/RefTisa/sallsdk/api/saapi.h>
39181074Sdas#include <dev/pms/RefTisa/sallsdk/api/saosapi.h>
40181074Sdas
41181074Sdas#include <dev/pms/RefTisa/tisa/api/titypes.h>
42181074Sdas#include <dev/pms/RefTisa/tisa/api/ostiapi.h>
43181074Sdas#include <dev/pms/RefTisa/tisa/api/tiapi.h>
44181074Sdas#include <dev/pms/RefTisa/tisa/api/tiglobal.h>
45181074Sdas
46181074Sdas#ifdef FDS_SM
47181074Sdas#include <dev/pms/RefTisa/sat/api/sm.h>
48181074Sdas#include <dev/pms/RefTisa/sat/api/smapi.h>
49181074Sdas#include <dev/pms/RefTisa/sat/api/tdsmapi.h>
50181074Sdas#endif
51181074Sdas
52181074Sdas#ifdef FDS_DM
53181074Sdas#include <dev/pms/RefTisa/discovery/api/dm.h>
54181074Sdas#include <dev/pms/RefTisa/discovery/api/dmapi.h>
55181074Sdas#include <dev/pms/RefTisa/discovery/api/tddmapi.h>
56181074Sdas#endif
57181074Sdas
58181074Sdas#include <dev/pms/RefTisa/tisa/sassata/sas/common/tdtypes.h>
59181074Sdas#include <dev/pms/freebsd/driver/common/osstring.h>
60181074Sdas#include <dev/pms/RefTisa/tisa/sassata/common/tdutil.h>
61181074Sdas
62181074Sdas#ifdef INITIATOR_DRIVER
63181074Sdas#include <dev/pms/RefTisa/tisa/sassata/sas/ini/itdtypes.h>
64181074Sdas#include <dev/pms/RefTisa/tisa/sassata/sas/ini/itddefs.h>
65181074Sdas#include <dev/pms/RefTisa/tisa/sassata/sas/ini/itdglobl.h>
66181074Sdas#endif
67181074Sdas
68181074Sdas#ifdef TARGET_DRIVER
69181074Sdas#include <dev/pms/RefTisa/tisa/sassata/sas/tgt/ttdglobl.h>
70181074Sdas#include <dev/pms/RefTisa/tisa/sassata/sas/tgt/ttdxchg.h>
71181074Sdas#include <dev/pms/RefTisa/tisa/sassata/sas/tgt/ttdtypes.h>
72181074Sdas#endif
73181074Sdas
74181074Sdas#include <dev/pms/RefTisa/tisa/sassata/common/tdsatypes.h>
75181074Sdas#include <dev/pms/RefTisa/tisa/sassata/common/tdproto.h>
76181074Sdas
77181074Sdas/*****************************************************************************
78181074Sdas*! \biref  tiCOMInterruptHandler
79181074Sdas*
80181074Sdas*  Purpose: This function is called to service the hardware interrupt of the
81181074Sdas*           hardware.
82181074Sdas*
83181074Sdas*  \param tiRoot:   Pointer to initiator specific root data structure  for this
84181074Sdas*                   instance of the driver.
85181074Sdas*
86181074Sdas*  \param channelNum: The zero-base channel number of the controller.
87181074Sdas*                     0xFFFFFFFF indicates that the OS-App Specific layer does
88181074Sdas*                     not provide the channel number. The TD/LL Layer needs to
89181074Sdas*                     discover of any of its own channels that are causing the
90181074Sdas*                     interrupt.
91181074Sdas*
92181074Sdas*  \return None
93181074Sdas*
94181074Sdas*  \note - The only thing that this API will do is to acknowledge and mask
95181074Sdas*          the necessary hardware interrupt register. The actual processing
96181074Sdas*          of the interrupt handler is done in tiCOMDelayedInterruptHandler().
97181074Sdas*
98181074Sdas*****************************************************************************/
99181074SdasFORCEINLINE bit32
100181074SdastiCOMInterruptHandler(
101181074Sdas                      tiRoot_t * tiRoot,
102181074Sdas                      bit32      channelNum)
103181074Sdas{
104181074Sdas  tdsaRoot_t      *tdsaRoot = (tdsaRoot_t *) tiRoot->tdData;
105181074Sdas  tdsaContext_t   *tdsaAllShared = (tdsaContext_t *)&(tdsaRoot->tdsaAllShared);
106181074Sdas  agsaRoot_t      *agRoot = &(tdsaAllShared->agRootNonInt);
107181074Sdas  bit32           interruptPending = agFALSE;
108181074Sdas
109181074Sdas  interruptPending = saInterruptHandler(agRoot, channelNum);
110181074Sdas
111181074Sdas  return interruptPending;
112181074Sdas
113181074Sdas} /* 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