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 initiator initialization functions
27 *
28 */
29#include <sys/cdefs.h>
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 itdssGetResource
78*
79*  Purpose:  This function is called to determine the Transport
80*            Dependent Layer internal resource requirement for the initiator
81*            side.
82*
83*  /param   tiRoot:            Pointer to driver/port instance.
84*  /param   initiatorResource: Pointer to initiator functionality memory and
85*                              option requirement.
86*
87*  /return: None
88*
89*  /note - This function only return the memory requirement in the tiMem_t
90*          structure in initiatorResource. It does not allocated memory, so the
91*          address fields in tiMem_t are not used.
92*
93*****************************************************************************/
94osGLOBAL void
95itdssGetResource(
96                 tiRoot_t * tiRoot,
97                 tiInitiatorResource_t * initiatorResource
98                 )
99{
100  itdssOperatingOption_t    OperatingOption;
101  tiInitiatorMem_t          *iniMem;
102  bit32 i;
103
104  iniMem                  = &initiatorResource->initiatorMem;
105  iniMem->count           = 1;          /* Only 1 memory descriptors are used */
106
107  TI_DBG6(("itdssGetResource: start\n"));
108
109  /*  other than [0], nothing is used
110   *  tdCachedMem[0]: cached mem for initiator TD Layer main functionality :
111   *                  itdssIni_t
112   *  tdCachedMem[1-5]: is availalbe
113  */
114
115  /*
116   * Get default parameters from the OS Specific area
117   * and reads parameters from the configuration file
118   */
119  itdssGetOperatingOptionParams(tiRoot, &OperatingOption);
120
121  /*
122   * Cached mem for initiator Transport Dependent Layer main functionality
123   */
124
125  iniMem->tdCachedMem[0].singleElementLength  = sizeof(itdsaIni_t);
126  iniMem->tdCachedMem[0].numElements          = 1;
127  iniMem->tdCachedMem[0].totalLength          =
128    iniMem->tdCachedMem[0].singleElementLength *
129    iniMem->tdCachedMem[0].numElements;
130  iniMem->tdCachedMem[0].alignment            = sizeof (void *); /* 4 bytes */
131  iniMem->tdCachedMem[0].type                 = TI_CACHED_MEM;
132  iniMem->tdCachedMem[0].reserved             = 0;
133  iniMem->tdCachedMem[0].virtPtr               = agNULL;
134  iniMem->tdCachedMem[0].osHandle              = agNULL;
135  iniMem->tdCachedMem[0].physAddrUpper         = 0;
136  iniMem->tdCachedMem[0].physAddrLower         = 0;
137
138
139  /*
140   * Not used mem structure. Initialize them.
141   */
142  for (i = iniMem->count; i < 6; i++)
143  {
144    iniMem->tdCachedMem[i].singleElementLength  = 0;
145    iniMem->tdCachedMem[i].numElements          = 0;
146    iniMem->tdCachedMem[i].totalLength          = 0;
147    iniMem->tdCachedMem[i].alignment            = 0;
148    iniMem->tdCachedMem[i].type                 = TI_CACHED_MEM;
149    iniMem->tdCachedMem[i].reserved             = 0;
150
151    iniMem->tdCachedMem[i].virtPtr               = agNULL;
152    iniMem->tdCachedMem[i].osHandle              = agNULL;
153    iniMem->tdCachedMem[i].physAddrUpper         = 0;
154    iniMem->tdCachedMem[i].physAddrLower         = 0;
155
156  }
157
158  /*
159   * Operating option of TISA
160   * fills in tiInitiatorOption
161   */
162  initiatorResource->initiatorOption.usecsPerTick       = OperatingOption.UsecsPerTick;  /* default value 1 sec*/
163
164  initiatorResource->initiatorOption.pageSize           = 0;
165
166  /* initialization */
167  initiatorResource->initiatorOption.dynamicDmaMem.numElements          = 0;
168  initiatorResource->initiatorOption.dynamicDmaMem.singleElementLength  = 0;
169  initiatorResource->initiatorOption.dynamicDmaMem.totalLength          = 0;
170  initiatorResource->initiatorOption.dynamicDmaMem.alignment            = 0;
171
172  /* initialization */
173  initiatorResource->initiatorOption.dynamicCachedMem.numElements         = 0;
174  initiatorResource->initiatorOption.dynamicCachedMem.singleElementLength = 0;
175  initiatorResource->initiatorOption.dynamicCachedMem.totalLength         = 0;
176  initiatorResource->initiatorOption.dynamicCachedMem.alignment           = 0;
177
178
179  /* This is not used in OS like Linux which supports dynamic memeory allocation
180     In short, this is for Windows, which does not support dynamic memory allocation */
181  /* ostiallocmemory(..... ,agFALSE) is supported by the following code eg) sat.c
182     The memory is DMA capable(uncached)
183   */
184#ifdef CCBUILD_EncryptionDriver
185  /* extend the DMA memory for supporting two encryption DEK tables */
186  initiatorResource->initiatorOption.dynamicDmaMem.numElements          = 128 + DEK_MAX_TABLE_ENTRIES / 2;
187#else
188  initiatorResource->initiatorOption.dynamicDmaMem.numElements          = 128;
189#endif
190  /* worked
191     initiatorResource->initiatorOption.dynamicDmaMem.singleElementLength  = sizeof(tdIORequestBody_t);
192  */
193  initiatorResource->initiatorOption.dynamicDmaMem.singleElementLength  = 512;
194  initiatorResource->initiatorOption.dynamicDmaMem.totalLength          =
195    initiatorResource->initiatorOption.dynamicDmaMem.numElements *
196    initiatorResource->initiatorOption.dynamicDmaMem.singleElementLength;
197  initiatorResource->initiatorOption.dynamicDmaMem.alignment            = sizeof(void *);
198
199
200  /* This is not used in OS like Linux which supports dynamic memeory allocation
201     In short, this is for Windows, which does not support dynamic memory allocation */
202  /* ostiallocmemory(..... ,agTRUE) is supported by the following code eg) sat.c
203     The memory is DMA incapable(cached)
204   */
205  initiatorResource->initiatorOption.dynamicCachedMem.numElements = 1024 + 256;
206  /* worked
207  initiatorResource->initiatorOption.dynamicCachedMem.singleElementLength = sizeof(tdIORequestBody_t);
208  initiatorResource->initiatorOption.dynamicCachedMem.singleElementLength = sizeof(tdssSMPRequestBody_t);
209  */
210  initiatorResource->initiatorOption.dynamicCachedMem.singleElementLength = 512;
211  initiatorResource->initiatorOption.dynamicCachedMem.totalLength         =
212        initiatorResource->initiatorOption.dynamicCachedMem.numElements *
213        initiatorResource->initiatorOption.dynamicCachedMem.singleElementLength;
214  initiatorResource->initiatorOption.dynamicCachedMem.alignment           = sizeof(void *);
215
216  /*
217   * set the I/O request body size
218   */
219  initiatorResource->initiatorOption.ioRequestBodySize  = sizeof(tdIORequestBody_t);
220  TI_DBG6(("itdssGetResource: sizeof(tdssSMPRequestBody_t) %d\n", (int)sizeof(tdssSMPRequestBody_t)));
221  TI_DBG6(("itdssGetResource: end\n"));
222
223  return;
224}
225
226
227/*****************************************************************************
228*! \brief  itdssGetOperatingOptionParams
229*
230*  Purpose: This function is called to get default parameters from the
231*           OS Specific area. This function is called in the context of
232*           tiCOMGetResource() and tiCOMInit().
233*
234*
235*  \param  tiRoot:   Pointer to initiator driver/port instance.
236*  \param  option:   Pointer to the Transport Dependent options.
237*
238*  \return: None
239*
240*  \note -
241*
242*****************************************************************************/
243osGLOBAL void
244itdssGetOperatingOptionParams(
245                      tiRoot_t                *tiRoot,
246                      itdssOperatingOption_t  *OperatingOption
247                      )
248{
249  char    *key = agNULL;
250  char    *subkey1 = agNULL;
251  char    *subkey2 = agNULL;
252  char    *buffer;
253  bit32   buffLen;
254  bit32   lenRecv = 0;
255  char    *pLastUsedChar = agNULL;
256  char    tmpBuffer[DEFAULT_KEY_BUFFER_SIZE];
257  char    globalStr[]     = "Global";
258  char    iniParmsStr[]   = "InitiatorParms";
259
260  TI_DBG6(("itdssGetOperatingOptionParams: start\n"));
261
262  /*
263     first set the values to Default values
264     Then, overwrite them using ostiGetTransportParam()
265  */
266
267
268  /* to remove compiler warnings */
269  pLastUsedChar   = pLastUsedChar;
270  lenRecv         = lenRecv;
271  subkey2         = subkey2;
272  subkey1         = subkey1;
273  key             = key;
274  buffer          = &tmpBuffer[0];
275  buffLen         = sizeof (tmpBuffer);
276
277  osti_memset(buffer, 0, buffLen);
278
279
280
281  /* default values */
282  OperatingOption->MaxTargets = DEFAULT_MAX_DEV; /* DEFAULT_MAX_TARGETS; */ /* 256 */
283  OperatingOption->UsecsPerTick = DEFAULT_INI_TIMER_TICK; /* 1 sec */
284
285  osti_memset(buffer, 0, buffLen);
286  lenRecv = 0;
287
288  /* defaults are overwritten in the following */
289  /* Get MaxTargets */
290  if ((ostiGetTransportParam(
291                             tiRoot,
292                             globalStr,
293                             iniParmsStr,
294                             agNULL,
295                             agNULL,
296                             agNULL,
297                             agNULL,
298                             "MaxTargets",
299                             buffer,
300                             buffLen,
301                             &lenRecv
302                             ) == tiSuccess) && (lenRecv != 0))
303  {
304    if (osti_strncmp(buffer, "0x", 2) == 0)
305    {
306      OperatingOption->MaxTargets = osti_strtoul (buffer, &pLastUsedChar, 0);
307    }
308    else
309    {
310      OperatingOption->MaxTargets = osti_strtoul (buffer, &pLastUsedChar, 10);
311    }
312    TI_DBG2(("itdssGetOperatingOptionParams: MaxTargets  %d\n",  OperatingOption->MaxTargets ));
313  }
314
315#ifdef REMOVED
316  /* get UsecsPerTick */
317  if ((ostiGetTransportParam(
318                             tiRoot,
319                             globalStr,
320                             iniParmsStr,
321                             agNULL,
322                             agNULL,
323                             agNULL,
324                             agNULL,
325                             "UsecsPerTick",
326                             buffer,
327                             buffLen,
328                             &lenRecv
329                             ) == tiSuccess) && (lenRecv != 0))
330  {
331    if (osti_strncmp(buffer, "0x", 2) == 0)
332    {
333      OperatingOption->UsecsPerTick = osti_strtoul (buffer, &pLastUsedChar, 0);
334    }
335    else
336    {
337      OperatingOption->UsecsPerTick = osti_strtoul (buffer, &pLastUsedChar, 10);
338    }
339  }
340  osti_memset(buffer, 0, buffLen);
341  lenRecv = 0;
342#endif
343
344  return;
345}
346
347
348/*****************************************************************************
349*! \brief  itdssInit
350*
351*  Purpose: This function is called to initialize the initiator specific
352*           Transport Dependent Layer.
353*           This function is not directly called by OS Specific module,
354*           as it is internally called by tiCOMInit().
355*
356*  /param tiRoot:            Pointer to driver/port instance.
357*  /param initiatorResource: Pointer to initiator functionality memory
358*                            and option requirement.
359*  /param tdSharedMem:       Pointer to cached memory required by the
360*                            target/initiator shared functionality.
361*
362*  /return:
363*   tiSuccess   OK
364*   others      not OK
365*
366*  /note -
367*
368*****************************************************************************/
369osGLOBAL bit32
370itdssInit(
371          tiRoot_t              *tiRoot,
372          tiInitiatorResource_t *initiatorResource,
373          tiTdSharedMem_t       *tdSharedMem
374          )
375{
376  tiInitiatorMem_t          *iniMem;
377  itdsaIni_t                *Initiator;
378  itdssOperatingOption_t    *OperatingOption;
379  tdsaRoot_t                *tdsaRoot;
380
381  TI_DBG6(("itdssInit: start\n"));
382  iniMem = &initiatorResource->initiatorMem;
383  tdsaRoot = (tdsaRoot_t *)tiRoot->tdData;
384  /*
385   * Cached mem for initiator Transport Dependent Layer main functionality
386   */
387  Initiator = iniMem->tdCachedMem[0].virtPtr;
388
389  /*
390   * Get default parameters from the OS Specific area
391   */
392  OperatingOption = &Initiator->OperatingOption;
393
394  /*
395   * Get default parameters from the OS Specific area
396   * and reads parameters from the configuration file
397   */
398
399  itdssGetOperatingOptionParams(tiRoot, OperatingOption);
400  /*
401   * Update TD operating options with OS-layer-saved value
402   * Only UsecsPerTick is updated
403   */
404  OperatingOption->UsecsPerTick =
405    initiatorResource->initiatorOption.usecsPerTick;
406
407  Initiator->NumIOsActive             = 0;
408
409  /*
410   *  tdCachedMem[0]: cached mem for initiator TD Layer main functionality :
411   *                   itdssIni_t
412   *  tdCachedMem[1-5]: not in use
413  */
414
415  /* initialize the timerlist */
416  itdssInitTimers(tiRoot);
417
418
419  /* Initialize the tdsaAllShared, tdssSASShared pointers */
420
421  Initiator->tdsaAllShared = &(tdsaRoot->tdsaAllShared);
422
423  TI_DBG6(("itdssInit: end\n"));
424  return (tiSuccess);
425
426}
427
428/*****************************************************************************
429*! \brief
430*  itdssInitTimers
431*
432*  Purpose: This function is called to initialize the timers
433*           for initiator
434*
435*  \param   tiRoot: pointer to the driver instance
436*
437*  \return: None
438*
439*  \note -
440*
441*****************************************************************************/
442osGLOBAL void
443itdssInitTimers(
444                tiRoot_t *tiRoot
445                )
446{
447  tdsaRoot_t     *tdsaRoot = (tdsaRoot_t *)(tiRoot->tdData);
448  tdsaContext_t  *tdsaAllShared = (tdsaContext_t *)&tdsaRoot->tdsaAllShared;
449  itdsaIni_t     *Initiator = (itdsaIni_t *)tdsaAllShared->itdsaIni;
450
451  /* initialize the timerlist */
452  TDLIST_INIT_HDR(&(Initiator->timerlist));
453
454  return;
455}
456