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#include <sys/cdefs.h>
23#include <dev/pms/config.h>
24
25#include <dev/pms/freebsd/driver/common/osenv.h>
26#include <dev/pms/freebsd/driver/common/ostypes.h>
27#include <dev/pms/freebsd/driver/common/osdebug.h>
28
29#include <dev/pms/RefTisa/tisa/api/titypes.h>
30
31#include <dev/pms/RefTisa/sallsdk/api/sa.h>
32#include <dev/pms/RefTisa/sallsdk/api/saapi.h>
33#include <dev/pms/RefTisa/sallsdk/api/saosapi.h>
34
35#include <dev/pms/RefTisa/sat/api/sm.h>
36#include <dev/pms/RefTisa/sat/api/smapi.h>
37#include <dev/pms/RefTisa/sat/api/tdsmapi.h>
38
39#include <dev/pms/RefTisa/sat/src/smdefs.h>
40#include <dev/pms/RefTisa/sat/src/smproto.h>
41#include <dev/pms/RefTisa/sat/src/smtypes.h>
42
43#ifdef SM_DEBUG
44bit32 gSMDebugLevel = 1;
45#endif
46smRoot_t *gsmRoot = agNULL;
47
48/* start smapi defined APIS */
49osGLOBAL void
50smGetRequirements(
51                  smRoot_t 	  		*smRoot,
52                  smSwConfig_t			*swConfig,
53                  smMemoryRequirement_t		*memoryRequirement,
54                  bit32                         *usecsPerTick,
55                  bit32				*maxNumLocks
56                 )
57{
58  bit32               memoryReqCount = 0;
59  bit32               i;
60  bit32               max_dev = SM_MAX_DEV;
61  char                *buffer;
62  bit32               buffLen;
63  bit32               lenRecv = 0;
64  static char         tmpBuffer[DEFAULT_KEY_BUFFER_SIZE];
65  char                *pLastUsedChar = agNULL;
66  char                globalStr[]     = "Global";
67  char                iniParmsStr[]   = "InitiatorParms";
68  SM_DBG2(("smGetRequirements: start\n"));
69
70  /* sanity check */
71  SM_ASSERT((agNULL != swConfig), "");
72  SM_ASSERT((agNULL != memoryRequirement), "");
73  SM_ASSERT((agNULL != usecsPerTick), "");
74  SM_ASSERT((agNULL != maxNumLocks), "");
75
76  /* memory requirement for smRoot, CACHE memory */
77  memoryRequirement->smMemory[SM_ROOT_MEM_INDEX].singleElementLength = sizeof(smIntRoot_t);
78  memoryRequirement->smMemory[SM_ROOT_MEM_INDEX].numElements = 1;
79  memoryRequirement->smMemory[SM_ROOT_MEM_INDEX].totalLength =
80      (memoryRequirement->smMemory[SM_ROOT_MEM_INDEX].singleElementLength) * (memoryRequirement->smMemory[SM_ROOT_MEM_INDEX].numElements);
81  memoryRequirement->smMemory[SM_ROOT_MEM_INDEX].alignment = 4;
82  memoryRequirement->smMemory[SM_ROOT_MEM_INDEX].type = SM_CACHED_MEM;
83  memoryReqCount++;
84
85  /* reading the configurable parameter of MaxTargets */
86  buffer = tmpBuffer;
87  buffLen = sizeof(tmpBuffer);
88  sm_memset(buffer, 0, buffLen);
89  lenRecv = 0;
90  if ((tdsmGetTransportParam(
91                             smRoot,
92                             globalStr,
93                             iniParmsStr,
94                             agNULL,
95                             agNULL,
96                             agNULL,
97                             agNULL,
98                             "MaxTargets",
99                             buffer,
100                             buffLen,
101                             &lenRecv
102                             ) == SM_RC_SUCCESS) && (lenRecv != 0))
103  {
104    if (osti_strncmp(buffer, "0x", 2) == 0)
105    {
106      max_dev = osti_strtoul (buffer, &pLastUsedChar, 0);
107    }
108    else
109    {
110      max_dev = osti_strtoul (buffer, &pLastUsedChar, 10);
111    }
112  }
113  SM_DBG3(("smGetRequirements: max_expander %d\n", max_dev));
114  /* memory requirement for Device Links, CACHE memory */
115  memoryRequirement->smMemory[SM_DEVICE_MEM_INDEX].singleElementLength = sizeof(smDeviceData_t);
116  memoryRequirement->smMemory[SM_DEVICE_MEM_INDEX].numElements = max_dev;
117  memoryRequirement->smMemory[SM_DEVICE_MEM_INDEX].totalLength =
118      (memoryRequirement->smMemory[SM_DEVICE_MEM_INDEX].singleElementLength) * (memoryRequirement->smMemory[SM_DEVICE_MEM_INDEX].numElements);
119  memoryRequirement->smMemory[SM_DEVICE_MEM_INDEX].alignment = 4;
120  memoryRequirement->smMemory[SM_DEVICE_MEM_INDEX].type = SM_CACHED_MEM;
121  memoryReqCount++;
122
123  /* memory requirement for IO inks, CACHE memory */
124  memoryRequirement->smMemory[SM_IO_MEM_INDEX].singleElementLength = sizeof(smIORequestBody_t);
125  memoryRequirement->smMemory[SM_IO_MEM_INDEX].numElements = SM_MAX_IO;
126  memoryRequirement->smMemory[SM_IO_MEM_INDEX].totalLength =
127      (memoryRequirement->smMemory[SM_IO_MEM_INDEX].singleElementLength) * (memoryRequirement->smMemory[SM_IO_MEM_INDEX].numElements);
128  memoryRequirement->smMemory[SM_IO_MEM_INDEX].alignment = 4;
129  memoryRequirement->smMemory[SM_IO_MEM_INDEX].type = SM_CACHED_MEM;
130  memoryReqCount++;
131
132  /* for debugging */
133  for (i=0;i< memoryReqCount;i++)
134  {
135    SM_DBG3(("smGetRequirements: index %d numElements %d totalLength %d singleElementLength %d alignment %d\n", i
136    , memoryRequirement->smMemory[i].numElements, memoryRequirement->smMemory[i].totalLength,
137    memoryRequirement->smMemory[i].singleElementLength,memoryRequirement->smMemory[i].alignment ));
138  }
139  /* set up memory requirement count */
140  memoryRequirement->count = memoryReqCount;
141
142  /* requirement for locks */
143  *maxNumLocks = SM_MAX_LOCKS;
144
145  /* setup the time tick */
146  *usecsPerTick = SM_USECS_PER_TICK;
147
148  /* set up the number of active IOs */
149  swConfig->maxActiveIOs = SM_MAX_IO;
150
151  /* set up the number of device handles */
152  swConfig->numDevHandles = SM_MAX_DEV;
153
154
155  return;
156}
157
158osGLOBAL bit32
159smInitialize(
160             smRoot_t				*smRoot,
161             agsaRoot_t                         *agRoot,
162             smMemoryRequirement_t		*memoryAllocated,
163             smSwConfig_t			*swConfig,
164             bit32				usecsPerTick
165            )
166{
167  smIntRoot_t               *smIntRoot;
168  smDeviceData_t            *smDevice;
169  smIORequestBody_t         *smIORequest;
170  smIntContext_t            *smAllShared;
171  bit32                     i;
172  bit32                     max_dev = SM_MAX_DEV;
173  char                      *buffer;
174  bit32                     buffLen;
175  bit32                     lenRecv = 0;
176  static char               tmpBuffer[DEFAULT_KEY_BUFFER_SIZE];
177  char                      *pLastUsedChar = agNULL;
178  char                      globalStr[]     = "Global";
179  char                      iniParmsStr[]   = "InitiatorParms";
180
181  SM_DBG2(("smInitialize: start\n"));
182
183  /* sanity check */
184  SM_ASSERT((agNULL != smRoot), "");
185  SM_ASSERT((agNULL != agRoot), "");
186  SM_ASSERT((agNULL != memoryAllocated), "");
187  SM_ASSERT((agNULL != swConfig), "");
188  SM_ASSERT((SM_ROOT_MEM_INDEX < memoryAllocated->count), "");
189  SM_ASSERT((SM_DEVICE_MEM_INDEX < memoryAllocated->count), "");
190  SM_ASSERT((SM_IO_MEM_INDEX < memoryAllocated->count), "");
191
192  /* Check the memory allocated */
193  for ( i = 0; i < memoryAllocated->count; i ++ )
194  {
195    /* If memory allocatation failed  */
196    if (memoryAllocated->smMemory[i].singleElementLength &&
197        memoryAllocated->smMemory[i].numElements)
198    {
199      if ( (0 != memoryAllocated->smMemory[i].numElements)
200          && (0 == memoryAllocated->smMemory[i].totalLength) )
201      {
202        /* return failure */
203        SM_DBG1(("smInitialize: Memory[%d]  singleElementLength = 0x%x  numElements = 0x%x NOT allocated!!!\n",
204          i,
205          memoryAllocated->smMemory[i].singleElementLength,
206          memoryAllocated->smMemory[i].numElements));
207        return SM_RC_FAILURE;
208      }
209    }
210  }
211
212  /* for debugging */
213  for ( i = 0; i < memoryAllocated->count; i ++ )
214  {
215    SM_DBG3(("smInitialize: index %d virtPtr %p osHandle%p\n",i, memoryAllocated->smMemory[i].virtPtr, memoryAllocated->smMemory[i].osHandle));
216    SM_DBG3(("smInitialize: index %d phyAddrUpper 0x%x phyAddrLower 0x%x totalLength %d numElements %d\n", i,
217    memoryAllocated->smMemory[i].physAddrUpper,
218    memoryAllocated->smMemory[i].physAddrLower,
219    memoryAllocated->smMemory[i].totalLength,
220    memoryAllocated->smMemory[i].numElements));
221    SM_DBG3(("smInitialize: index %d singleElementLength 0x%x alignment 0x%x type %d reserved %d\n", i,
222    memoryAllocated->smMemory[i].singleElementLength,
223    memoryAllocated->smMemory[i].alignment,
224    memoryAllocated->smMemory[i].type,
225    memoryAllocated->smMemory[i].reserved));
226  }
227
228  /* SM's internal root */
229  smIntRoot  = (smIntRoot_t *) (memoryAllocated->smMemory[SM_ROOT_MEM_INDEX].virtPtr);
230  smRoot->smData = (void *) smIntRoot;
231
232  smAllShared = (smIntContext_t *)&(smIntRoot->smAllShared);
233  /**<  Initialize the TDM data part of the interrupt context */
234  smAllShared->smRootOsData.smRoot     = smRoot;
235  smAllShared->smRootOsData.smAllShared   = (void *) smAllShared;
236  gsmRoot = smRoot;
237  smAllShared->FCA = agTRUE;
238
239  /* Devices */
240  smDevice = (smDeviceData_t *) (memoryAllocated->smMemory[SM_DEVICE_MEM_INDEX].virtPtr);
241  smAllShared->DeviceMem = (smDeviceData_t *)smDevice;
242
243  /* IOs */
244  smIORequest = (smIORequestBody_t *) (memoryAllocated->smMemory[SM_IO_MEM_INDEX].virtPtr);
245  smAllShared->IOMem = (smIORequestBody_t *)smIORequest;
246
247  smAllShared->agRoot = agRoot;
248
249  smAllShared->usecsPerTick = usecsPerTick;
250
251  /**< initializes timers */
252  smInitTimers(smRoot);
253
254  /**< initializes devices */
255  buffer = tmpBuffer;
256  buffLen = sizeof(tmpBuffer);
257  sm_memset(buffer, 0, buffLen);
258  lenRecv = 0;
259  if ((tdsmGetTransportParam(
260                             smRoot,
261                             globalStr,
262                             iniParmsStr,
263                             agNULL,
264                             agNULL,
265                             agNULL,
266                             agNULL,
267                             "MaxTargets",
268                             buffer,
269                             buffLen,
270                             &lenRecv
271                             ) == SM_RC_SUCCESS) && (lenRecv != 0))
272  {
273    if (osti_strncmp(buffer, "0x", 2) == 0)
274    {
275      max_dev = osti_strtoul (buffer, &pLastUsedChar, 0);
276    }
277    else
278    {
279      max_dev = osti_strtoul (buffer, &pLastUsedChar, 10);
280    }
281   SM_DBG1(("smInitialize: MaxTargets %d\n", max_dev));
282 }
283
284  smDeviceDataInit(smRoot, max_dev);
285
286  /**< initializes IOs */
287  smIOInit(smRoot);
288
289#ifdef SM_DEBUG
290  gSMDebugLevel = swConfig->SMDebugLevel;
291#endif
292
293  return SM_RC_SUCCESS;
294}
295
296osGLOBAL void
297smInitTimers(
298             smRoot_t *smRoot
299            )
300{
301  smIntRoot_t               *smIntRoot    = (smIntRoot_t *)smRoot->smData;
302  smIntContext_t            *smAllShared = (smIntContext_t *)&smIntRoot->smAllShared;
303
304  SM_DBG2(("smInitTimers: start\n"));
305
306  /* initialize the timerlist */
307  SMLIST_INIT_HDR(&(smAllShared->timerlist));
308
309  return;
310}
311
312osGLOBAL void
313smDeviceDataReInit(
314                   smRoot_t		  *smRoot,
315                   smDeviceData_t         *oneDeviceData
316                  )
317{
318  int               j=0;
319  smSatInternalIo_t   *satIntIO;
320
321  SM_DBG2(("smDeviceDataReInit: start \n"));
322
323  if (oneDeviceData->satPendingIO != 0)
324  {
325    SM_DBG1(("smDeviceDataReInit: did %d\n", oneDeviceData->id));
326    SM_DBG1(("smDeviceDataReInit: satPendingIO %d satNCQMaxIO %d!!!\n", oneDeviceData->satPendingIO, oneDeviceData->satNCQMaxIO ));
327    SM_DBG1(("smDeviceDataReInit: satPendingNCQIO %d satPendingNONNCQIO %d!!!\n", oneDeviceData->satPendingNCQIO, oneDeviceData->satPendingNONNCQIO));
328  }
329
330//  oneDeviceData->smRoot = agNULL;
331  oneDeviceData->agDevHandle = agNULL;
332  oneDeviceData->valid = agFALSE;
333  oneDeviceData->SMAbortAll = agFALSE;
334  oneDeviceData->smDevHandle = agNULL;
335  oneDeviceData->directlyAttached = agFALSE;
336  oneDeviceData->agExpDevHandle = agNULL;
337  oneDeviceData->phyID = 0xFF;
338  oneDeviceData->SMNumOfFCA = 0;
339
340  /* default */
341  oneDeviceData->satDriveState = SAT_DEV_STATE_NORMAL;
342  oneDeviceData->satNCQMaxIO =SAT_NCQ_MAX;
343  oneDeviceData->satPendingIO = 0;
344  oneDeviceData->satPendingNCQIO = 0;
345  oneDeviceData->satPendingNONNCQIO = 0;
346  oneDeviceData->IDDeviceValid = agFALSE;
347  oneDeviceData->freeSATAFDMATagBitmap = 0;
348  oneDeviceData->NumOfFCA = 0;
349  oneDeviceData->NumOfIDRetries = 0;
350  oneDeviceData->ID_Retries = 0;
351  oneDeviceData->OSAbortAll = agFALSE;
352
353  sm_memset(oneDeviceData->satMaxLBA, 0, sizeof(oneDeviceData->satMaxLBA));
354  sm_memset(&(oneDeviceData->satIdentifyData), 0xFF, sizeof(agsaSATAIdentifyData_t));
355
356  oneDeviceData->satSaDeviceData = oneDeviceData;
357
358  satIntIO = (smSatInternalIo_t *)&(oneDeviceData->satIntIo[0]);
359  for (j = 0; j < SAT_MAX_INT_IO; j++)
360  {
361    SM_DBG2(("tdsaDeviceDataReInit: in loop of internal io free, id %d\n", satIntIO->id));
362    smsatFreeIntIoResource(smRoot, oneDeviceData, satIntIO);
363    satIntIO = satIntIO + 1;
364  }
365
366  return;
367}
368osGLOBAL void
369smDeviceDataInit(
370                 smRoot_t *smRoot,
371                 bit32    max_dev
372                )
373{
374  smIntRoot_t               *smIntRoot    = (smIntRoot_t *)smRoot->smData;
375  smIntContext_t            *smAllShared = (smIntContext_t *)&smIntRoot->smAllShared;
376  smDeviceData_t            *smDeviceData = (smDeviceData_t *)smAllShared->DeviceMem;
377  int                       i,j;
378  smSatInternalIo_t           *satIntIO;
379
380  SM_DBG2(("smDeviceDataInit: start \n"));
381
382  SMLIST_INIT_HDR(&(smAllShared->MainDeviceList));
383  SMLIST_INIT_HDR(&(smAllShared->FreeDeviceList));
384
385  for(i=0;i<(int)max_dev;i++)
386  {
387    SMLIST_INIT_ELEMENT(&(smDeviceData[i].FreeLink));
388    SMLIST_INIT_ELEMENT(&(smDeviceData[i].MainLink));
389    smDeviceData[i].id = i;
390    smDeviceData[i].smRoot = agNULL;
391    smDeviceData[i].agDevHandle = agNULL;
392    smDeviceData[i].valid = agFALSE;
393    smDeviceData[i].SMAbortAll = agFALSE;
394    smDeviceData[i].smDevHandle = agNULL;
395    smDeviceData[i].directlyAttached = agFALSE;
396    smDeviceData[i].agExpDevHandle = agNULL;
397    smDeviceData[i].phyID = 0xFF;
398    smDeviceData[i].SMNumOfFCA = 0;
399
400
401    SMLIST_INIT_HDR(&(smDeviceData[i].satIoLinkList));
402    SMLIST_INIT_HDR(&(smDeviceData[i].satFreeIntIoLinkList));
403    SMLIST_INIT_HDR(&(smDeviceData[i].satActiveIntIoLinkList));
404
405    /* default */
406    smDeviceData[i].satDriveState = SAT_DEV_STATE_NORMAL;
407    smDeviceData[i].satNCQMaxIO =SAT_NCQ_MAX;
408    smDeviceData[i].satPendingIO = 0;
409    smDeviceData[i].satPendingNCQIO = 0;
410    smDeviceData[i].satPendingNONNCQIO = 0;
411    smDeviceData[i].IDDeviceValid = agFALSE;
412    smDeviceData[i].freeSATAFDMATagBitmap = 0;
413    smDeviceData[i].NumOfFCA = 0;
414    smDeviceData[i].NumOfIDRetries = 0;
415    smDeviceData[i].ID_Retries = 0;
416    smDeviceData[i].OSAbortAll = agFALSE;
417    smInitTimerRequest(smRoot, &(smDeviceData[i].SATAIDDeviceTimer));
418
419    sm_memset(&(smDeviceData[i].satIdentifyData), 0xFF, sizeof(agsaSATAIdentifyData_t));
420    sm_memset(smDeviceData[i].satMaxLBA, 0, sizeof(smDeviceData[i].satMaxLBA));
421
422    smDeviceData[i].satSaDeviceData = &smDeviceData[i];
423
424#if 1
425    satIntIO = &smDeviceData[i].satIntIo[0];
426    for (j = 0; j < SAT_MAX_INT_IO; j++)
427    {
428      SMLIST_INIT_ELEMENT (&satIntIO->satIntIoLink);
429      SMLIST_ENQUEUE_AT_TAIL (&satIntIO->satIntIoLink,
430                              &smDeviceData[i].satFreeIntIoLinkList);
431      satIntIO->satOrgSmIORequest = agNULL;
432      satIntIO->id = j;
433      satIntIO = satIntIO + 1;
434    }
435#endif
436
437    /* some other variables */
438    SMLIST_ENQUEUE_AT_TAIL(&(smDeviceData[i].FreeLink), &(smAllShared->FreeDeviceList));
439  }
440
441  return;
442}
443
444osGLOBAL void
445smIOInit(
446         smRoot_t *smRoot
447        )
448{
449  smIntRoot_t               *smIntRoot    = (smIntRoot_t *)smRoot->smData;
450  smIntContext_t            *smAllShared = (smIntContext_t *)&smIntRoot->smAllShared;
451  smIORequestBody_t         *smIOCommand = (smIORequestBody_t *)smAllShared->IOMem;
452  int                       i = 0;
453
454  SM_DBG3(("smIOInit: start\n"));
455
456  SMLIST_INIT_HDR(&(smAllShared->freeIOList));
457  SMLIST_INIT_HDR(&(smAllShared->mainIOList));
458
459  for(i=0;i<SM_MAX_IO;i++)
460  {
461    SMLIST_INIT_ELEMENT(&(smIOCommand[i].satIoBodyLink));
462    smIOCommand[i].id = i;
463    smIOCommand[i].InUse = agFALSE;
464    smIOCommand[i].ioStarted = agFALSE;
465    smIOCommand[i].ioCompleted = agFALSE;
466    smIOCommand[i].reTries = 0;
467
468    smIOCommand[i].smDevHandle = agNULL;
469    smIOCommand[i].smIORequest = agNULL;
470    smIOCommand[i].smIOToBeAbortedRequest = agNULL;
471    smIOCommand[i].transport.SATA.satIOContext.satOrgIOContext = agNULL;
472
473    sm_memset(&(smIOCommand[i].transport.SATA.agSATARequestBody), 0, sizeof(agsaSATAInitiatorRequest_t));
474
475
476    SMLIST_ENQUEUE_AT_TAIL(&(smIOCommand[i].satIoBodyLink), &(smAllShared->freeIOList));
477  }
478
479  return;
480}
481
482FORCEINLINE void
483smIOReInit(
484          smRoot_t          *smRoot,
485          smIORequestBody_t *smIORequestBody
486          )
487{
488  SM_DBG3(("smIOReInit: start\n"));
489  smIORequestBody->InUse = agTRUE;
490  smIORequestBody->ioStarted = agFALSE;
491  smIORequestBody->ioCompleted = agFALSE;
492  smIORequestBody->reTries = 0;
493  smIORequestBody->smDevHandle = agNULL;
494  smIORequestBody->smIORequest = agNULL;
495  smIORequestBody->smIOToBeAbortedRequest = agNULL;
496  smIORequestBody->transport.SATA.satIOContext.satOrgIOContext = agNULL;
497  /*sm_memset(&(smIORequestBody->transport.SATA.agSATARequestBody), 0, sizeof(agsaSATAInitiatorRequest_t));*/
498  return;
499}
500
501/* end smapi defined APIS */
502
503