xref: /freebsd/sys/dev/pms/RefTisa/tisa/sassata/common/tdint.c (revision e8d8bef961a50d4dc22501cde4fb9fb0be1b2532)
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 *****************************************************************************/
99 FORCEINLINE bit32
100 tiCOMInterruptHandler(
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 *****************************************************************************/
142 FORCEINLINE
143 bit32
144 tiCOMDelayedInterruptHandler(
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 *****************************************************************************/
194 osGLOBAL void
195 tiCOMSystemInterruptsActive(
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 
226 osGLOBAL void
227 tiComCountActiveIORequests(
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 *****************************************************************************/
251 osGLOBAL FORCEINLINE
252 void
253 tiCOMInterruptEnable(
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