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