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 *****************************************************************************/
94 osGLOBAL void
95 itdssGetResource(
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 *****************************************************************************/
243 osGLOBAL void
244 itdssGetOperatingOptionParams(
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 *****************************************************************************/
369 osGLOBAL bit32
370 itdssInit(
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 *****************************************************************************/
442 osGLOBAL void
443 itdssInitTimers(
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