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