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