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 *****************************************************************************/
95 osGLOBAL void
96 itdssGetResource(
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 *****************************************************************************/
244 osGLOBAL void
245 itdssGetOperatingOptionParams(
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 *****************************************************************************/
370 osGLOBAL bit32
371 itdssInit(
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 *****************************************************************************/
443 osGLOBAL void
444 itdssInitTimers(
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