xref: /freebsd/sys/dev/pms/RefTisa/tisa/sassata/sas/tgt/ttdinit.c (revision fd5e3f3ec6c6248e892c9e7b2f17da3bfe7b6837)
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 /** \file
23  *
24  * $RCSfile: ttdinit.c,v $
25  *
26  * Copyright 2006 PMC-Sierra, Inc.
27  *
28  * $Author: vempatin $
29  * $Revision: 113679 $
30  * $Date: 2012-04-16 14:35:19 -0700 (Mon, 16 Apr 2012) $
31  *
32  * This file contains initiator IO related functions in TD layer
33  *
34  */
35 #include <osenv.h>
36 #include <ostypes.h>
37 #include <osdebug.h>
38 
39 #include <sa.h>
40 #include <saapi.h>
41 #include <saosapi.h>
42 
43 #include <titypes.h>
44 #include <ostiapi.h>
45 #include <tiapi.h>
46 #include <tiglobal.h>
47 
48 #include <tdtypes.h>
49 #include <osstring.h>
50 #include <tdutil.h>
51 
52 #ifdef INITIATOR_DRIVER
53 #include <itdtypes.h>
54 #include <itddefs.h>
55 #include <itdglobl.h>
56 #endif
57 
58 #ifdef TARGET_DRIVER
59 #include "ttdglobl.h"
60 #include "ttdtxchg.h"
61 #include "ttdtypes.h"
62 #endif
63 
64 #include <tdsatypes.h>
65 #include <tdproto.h>
66 
67 /* io trace only */
68 extern void TDTraceInit(void);
69 /* io trace only */
70 
71 
72 osGLOBAL bit32
73 ttdssInit(
74         tiRoot_t              *tiRoot,
75         tiTargetResource_t    *targetResource,
76         tiTdSharedMem_t       *tdSharedMem
77 )
78 {
79     tdsaRoot_t                *tdsaRoot  = (tdsaRoot_t *)tiRoot->tdData;
80     tiTargetMem_t             *tgtMem;
81     ttdsaTgt_t                *Target;
82     ttdssOperatingOption_t    *OperatingOption;
83     char                      *buffer;
84     bit32                     buffLen;
85     bit32                     lenRecv = 0;
86     char                      *pLastUsedChar = agNULL;
87     char                      tmpBuffer[DEFAULT_KEY_BUFFER_SIZE];
88     char                      globalStr[]     = "OSParms";
89 
90     TI_DBG5(("ttdssInit: start\n"));
91 
92     /*
93      first set the values to Default values
94      Then, overwrite them using ostiGetTransportParam()
95      */
96 
97     /* to remove compiler warnings */
98     buffer          = &tmpBuffer[0];
99     buffLen         = sizeof (tmpBuffer);
100 
101     osti_memset(buffer, 0, buffLen);
102 
103     tgtMem = &targetResource->targetMem;
104 
105     /*
106      * Cached mem for target Transport Dependent Layer main functionality
107      */
108     Target = tgtMem->tdMem[0].virtPtr;
109 
110     OperatingOption = &Target->OperatingOption;
111     /*
112      * Get default parameters from the OS Specific area
113      * and reads parameters from the configuration file
114      */
115     ttdssGetOperatingOptionParams(tiRoot, OperatingOption);
116 
117 
118     /*
119      * Update TD operating options
120      */
121     OperatingOption->UsecsPerTick =
122             targetResource->targetOption.usecsPerTick;
123     OperatingOption->numXchgs = tgtMem->tdMem[1].numElements;
124 
125 
126     if (ttdsaXchgInit(tiRoot,
127             &Target->ttdsaXchgData,
128             tgtMem,
129             OperatingOption->numXchgs
130     ) == agFALSE)
131     {
132         TI_DBG1(("ttdInit: ttdsaXchgInit failed\n"));
133         return tiError;
134     }
135 
136     /* Get number of AutoGoodResponse entry */
137     if ((ostiGetTransportParam(
138                                 tiRoot,
139                                 globalStr,
140                                 agNULL,
141                                 agNULL,
142                                 agNULL,
143                                 agNULL,
144                                 agNULL,
145                                 "AutoGoodResponse",
146                                 buffer,
147                                 buffLen,
148                                 &lenRecv
149                               ) == tiSuccess) && (lenRecv != 0))
150     {
151         if (osti_strncmp(buffer, "0x", 2) == 0)
152         {
153             tdsaRoot->autoGoodRSP = osti_strtoul (buffer, &pLastUsedChar, 0);
154         }
155         else
156         {
157             tdsaRoot->autoGoodRSP = osti_strtoul (buffer, &pLastUsedChar, 10);
158         }
159 
160     }
161 
162     return tiSuccess;
163 }
164 
165 /*
166   this combines ttdGetDefaultParams and ttdGetTargetParms
167 
168  */
169 osGLOBAL void
170 ttdssGetOperatingOptionParams(
171         tiRoot_t                *tiRoot,
172         ttdssOperatingOption_t  *OperatingOption
173 )
174 {
175     char    *key = agNULL;
176     char    *subkey1 = agNULL;
177     char    *subkey2 = agNULL;
178     char    *buffer;
179     bit32   buffLen;
180     bit32   lenRecv = 0;
181     char    *pLastUsedChar = agNULL;
182     char    tmpBuffer[DEFAULT_KEY_BUFFER_SIZE];
183     char    globalStr[]     = "Global";
184     char    iniParmsStr[]   = "TargetParms";
185 
186     TI_DBG5(("ttdssGetOperatingOptionParams: start\n"));
187 
188     /*
189      first set the values to Default values
190      Then, overwrite them using ostiGetTransportParam()
191      */
192 
193 
194     /* to remove compiler warnings */
195     pLastUsedChar   = pLastUsedChar;
196     lenRecv         = lenRecv;
197     subkey2         = subkey2;
198     subkey1         = subkey1;
199     key             = key;
200     buffer          = &tmpBuffer[0];
201     buffLen         = sizeof (tmpBuffer);
202 
203     osti_memset(buffer, 0, buffLen);
204 
205 
206     /* in ttgglobl.h */
207     OperatingOption->numXchgs = DEFAULT_XCHGS;
208     OperatingOption->UsecsPerTick = DEFAULT_TGT_TIMER_TICK; /* 1 sec */
209     OperatingOption->MaxTargets = DEFAULT_MAX_TARGETS;
210     OperatingOption->BlockSize = DEFAULT_BLOCK_SIZE;
211 
212 
213     /* defaults are overwritten in the following */
214     /* Get number of exchanges */
215     if ((ostiGetTransportParam(
216             tiRoot,
217             globalStr,
218             iniParmsStr,
219             agNULL,
220             agNULL,
221             agNULL,
222             agNULL,
223             "NumberExchanges",
224             buffer,
225             buffLen,
226             &lenRecv
227     ) == tiSuccess) && (lenRecv != 0))
228     {
229         if (osti_strncmp(buffer, "0x", 2) == 0)
230         {
231             OperatingOption->numXchgs = osti_strtoul (buffer, &pLastUsedChar, 0);
232         }
233         else
234         {
235             OperatingOption->numXchgs = osti_strtoul (buffer, &pLastUsedChar, 10);
236         }
237 
238     }
239 
240     osti_memset(buffer, 0, buffLen);
241     lenRecv = 0;
242 
243     /* Get number of MaxTargets */
244     if ((ostiGetTransportParam(
245             tiRoot,
246             globalStr,
247             iniParmsStr,
248             agNULL,
249             agNULL,
250             agNULL,
251             agNULL,
252             "MaxTargets",
253             buffer,
254             buffLen,
255             &lenRecv
256     ) == tiSuccess) && (lenRecv != 0))
257     {
258         if (osti_strncmp(buffer, "0x", 2) == 0)
259         {
260             OperatingOption->MaxTargets = osti_strtoul (buffer, &pLastUsedChar, 0);
261         }
262         else
263         {
264             OperatingOption->MaxTargets = osti_strtoul (buffer, &pLastUsedChar, 10);
265         }
266 
267     }
268     osti_memset(buffer, 0, buffLen);
269     lenRecv = 0;
270 
271     /* Get number of BlockSize */
272     if ((ostiGetTransportParam(
273             tiRoot,
274             globalStr,
275             iniParmsStr,
276             agNULL,
277             agNULL,
278             agNULL,
279             agNULL,
280             "BlockSize",
281             buffer,
282             buffLen,
283             &lenRecv
284     ) == tiSuccess) && (lenRecv != 0))
285     {
286         if (osti_strncmp(buffer, "0x", 2) == 0)
287         {
288             OperatingOption->BlockSize = osti_strtoul (buffer, &pLastUsedChar, 0);
289         }
290         else
291         {
292             OperatingOption->BlockSize = osti_strtoul (buffer, &pLastUsedChar, 10);
293         }
294     }
295     osti_memset(buffer, 0, buffLen);
296     lenRecv = 0;
297 
298 
299 
300     TI_DBG5(("ttdssGetOperatingOptionParams: NumberExchanges %d UsecsPerTick %d MaxTargets %d BlockSize %d\n", OperatingOption->numXchgs, OperatingOption->UsecsPerTick, OperatingOption->MaxTargets, OperatingOption->BlockSize));
301 
302     return;
303 }
304 
305 /* not yet */
306 osGLOBAL void
307 ttdssGetResource(
308         tiRoot_t              *tiRoot,
309         tiTargetResource_t    *targetResource
310 )
311 {
312     tiTargetMem_t            *tgtMem;
313     int i;
314     ttdssOperatingOption_t   OperatingOption;
315     bit32                     xchgSize;
316     bit32                     respSize;
317     bit32                     smprespSize;
318 
319     TI_DBG4(("ttdssGetResource: start\n"));
320 
321     tgtMem = &targetResource->targetMem;
322 
323     /*
324     only 4 memory descriptors are used
325      */
326     tgtMem->count = 4;
327 
328     /* initiailization */
329     for (i = 0 ; i < 10 ; i++)
330     {
331         tgtMem->tdMem[i].singleElementLength  = 0;
332         tgtMem->tdMem[i].numElements          = 0;
333         tgtMem->tdMem[i].totalLength          = 0;
334         tgtMem->tdMem[i].alignment            = 0;
335         tgtMem->tdMem[i].type                 = TI_CACHED_MEM;
336         tgtMem->tdMem[i].reserved             = 0;
337         tgtMem->tdMem[i].virtPtr               = agNULL;
338         tgtMem->tdMem[i].osHandle              = agNULL;
339         tgtMem->tdMem[i].physAddrUpper         = 0;
340         tgtMem->tdMem[i].physAddrLower         = 0;
341     }
342 
343     /*
344      * Get default parameters from the OS Specific area
345      * and reads parameters from the configuration file
346      */
347     ttdssGetOperatingOptionParams(tiRoot, &OperatingOption);
348 
349     /* target */
350     tgtMem->tdMem[0].singleElementLength  = sizeof(ttdsaTgt_t);
351     tgtMem->tdMem[0].numElements          = 1;
352     tgtMem->tdMem[0].totalLength          =
353             tgtMem->tdMem[0].singleElementLength *
354             tgtMem->tdMem[0].numElements;
355     tgtMem->tdMem[0].alignment            = sizeof (void *);
356     tgtMem->tdMem[0].type                 = TI_CACHED_MEM;
357     tgtMem->tdMem[0].reserved             = 0;
358     tgtMem->tdMem[0].virtPtr               = agNULL;
359     tgtMem->tdMem[0].osHandle              = agNULL;
360     tgtMem->tdMem[0].physAddrUpper         = 0;
361     tgtMem->tdMem[0].physAddrLower         = 0;
362 
363     /*
364      * Cached memory for I/O exchange structures
365      */
366     xchgSize = sizeof(ttdsaXchg_t);
367     xchgSize = AG_ALIGNSIZE(xchgSize, 8);
368 
369     tgtMem->tdMem[1].singleElementLength = xchgSize;
370     tgtMem->tdMem[1].numElements         = OperatingOption.numXchgs;
371     tgtMem->tdMem[1].totalLength         = tgtMem->tdMem[1].singleElementLength *
372             tgtMem->tdMem[1].numElements;
373     tgtMem->tdMem[1].alignment           = sizeof(void *);
374     tgtMem->tdMem[1].type                = TI_CACHED_MEM;
375     tgtMem->tdMem[1].reserved             = 0;
376     tgtMem->tdMem[1].virtPtr               = agNULL;
377     tgtMem->tdMem[1].osHandle              = agNULL;
378     tgtMem->tdMem[1].physAddrUpper         = 0;
379     tgtMem->tdMem[1].physAddrLower         = 0;
380 
381     /*
382      * Uncached memory for response buffer structures
383      */
384     TI_DBG4(("ttdssGetResource: sas_resp_t size 0x%x %d\n",
385             (unsigned int)sizeof(sas_resp_t), (int)sizeof(sas_resp_t)));
386 
387     respSize = (sizeof(sas_resp_t) + AG_WORD_ALIGN_ADD) & AG_WORD_ALIGN_MASK;
388     TI_DBG4(("ttdssGetResource: response size 0x%x %d\n", respSize,respSize));
389     respSize = AG_ALIGNSIZE(respSize, 8);
390     TI_DBG4(("ttdssGetResource: response size 0x%x %d\n", respSize,respSize));
391     tgtMem->tdMem[2].singleElementLength = 0x1000; /* respSize; 0x1000;  */
392     tgtMem->tdMem[2].numElements         = OperatingOption.numXchgs;  /* Same as num of xchg */
393     tgtMem->tdMem[2].totalLength         = tgtMem->tdMem[2].singleElementLength *
394             tgtMem->tdMem[2].numElements;
395     /* 8;4;16;256;sizeof(void *); all worked */
396     tgtMem->tdMem[2].alignment           = 16;
397     tgtMem->tdMem[2].type                = TI_DMA_MEM;  /* uncached memory */
398     tgtMem->tdMem[2].reserved             = 0;
399     tgtMem->tdMem[2].virtPtr               = agNULL;
400     tgtMem->tdMem[2].osHandle              = agNULL;
401     tgtMem->tdMem[2].physAddrUpper         = 0;
402     tgtMem->tdMem[2].physAddrLower         = 0;
403 
404     /*
405      * Uncached memory for SMP response buffer structures
406      */
407     smprespSize = sizeof(smp_resp_t);
408     smprespSize = AG_ALIGNSIZE(smprespSize, 8);
409     TI_DBG4(("ttdssGetResource: SMP response size 0x%x %d\n", smprespSize,smprespSize));
410 
411     tgtMem->tdMem[3].singleElementLength = smprespSize; /*0x1000; smprespSize; */
412     tgtMem->tdMem[3].numElements         = OperatingOption.numXchgs;  /* Same as num of xchg */
413     tgtMem->tdMem[3].totalLength
414     = tgtMem->tdMem[3].singleElementLength * tgtMem->tdMem[3].numElements;
415     tgtMem->tdMem[3].alignment           = 16; /* 4; 256; 16; sizeof(void *); */
416     tgtMem->tdMem[3].type                = TI_DMA_MEM;  /* uncached memory */
417     tgtMem->tdMem[3].reserved             = 0;
418     tgtMem->tdMem[3].virtPtr               = agNULL;
419     tgtMem->tdMem[3].osHandle              = agNULL;
420     tgtMem->tdMem[3].physAddrUpper         = 0;
421     tgtMem->tdMem[3].physAddrLower         = 0;
422 
423 
424 
425     targetResource->targetOption.usecsPerTick = OperatingOption.UsecsPerTick;
426     targetResource->targetOption.pageSize     = 0; /* not applicable to SAS/SATA */
427     targetResource->targetOption.numLgns      = 0; /* not applicable to SAS/SATA */
428     targetResource->targetOption.numSessions  = 0; /* not applicable to SAS/SATA */
429     targetResource->targetOption.numXchgs     = OperatingOption.numXchgs;
430 
431 
432     /*
433     This is not used in OS like Linux which supports dynamic memeory allocation
434     In short, this is for Windows
435      */
436     /* Estimate dynamic DMA memory */
437     targetResource->targetOption.dynamicDmaMem.alignment = sizeof(void *);
438 
439     targetResource->targetOption.dynamicDmaMem.numElements = 128;
440     targetResource->targetOption.dynamicDmaMem.singleElementLength = sizeof(tdssSMPRequestBody_t);
441     targetResource->targetOption.dynamicDmaMem.totalLength =
442             targetResource->targetOption.dynamicDmaMem.numElements *
443             targetResource->targetOption.dynamicDmaMem.singleElementLength;
444 
445     /* Estimate dynamic cached memory */
446     targetResource->targetOption.dynamicCachedMem.alignment =  sizeof(void *);
447     targetResource->targetOption.dynamicCachedMem.numElements = 128;
448     targetResource->targetOption.dynamicCachedMem.singleElementLength = sizeof(tdssSMPRequestBody_t);
449     targetResource->targetOption.dynamicCachedMem.totalLength =
450             targetResource->targetOption.dynamicCachedMem.numElements *
451             targetResource->targetOption.dynamicCachedMem.singleElementLength;
452 
453 
454     return;
455 }
456 
457 /* not in use */
458 osGLOBAL void
459 ttdssGetTargetParams(
460         tiRoot_t          *tiRoot
461 )
462 {
463     TI_DBG6(("ttdssGetTargetParams: start\n"));
464     return;
465 }
466 
467 osGLOBAL agBOOLEAN
468 ttdsaXchgInit(
469         tiRoot_t           *tiRoot,
470         ttdsaXchgData_t    *ttdsaXchgData,
471         tiTargetMem_t      *tgtMem,
472         bit32              maxNumXchgs
473 )
474 {
475     ttdsaXchg_t       *ttdsaXchg;
476     bit32             i, respLen;
477     bit8              *virtualAddr;
478     bit32             phyAddrLower, phyAddrUpper;
479     bit32             smprespLen;
480     bit32             smpphyAddrLower, smpphyAddrUpper;
481     bit8              *smpvirtualAddr;
482 
483 
484 
485     TI_DBG5(("ttdsaXchgInit: start\n"));
486     /* io trace only */
487     TDTraceInit();
488     /* io trace only */
489 
490     /*
491      * Set and initialize some global exchange information
492      */
493     TDLIST_INIT_HDR(&ttdsaXchgData->xchgFreeList);
494     TDLIST_INIT_HDR(&ttdsaXchgData->xchgBusyList);
495 
496     ttdsaXchgData->maxNumXchgs = maxNumXchgs;
497 
498     /* Initialize exchange and response buffer structures */
499     ttdsaXchg = (ttdsaXchg_t *) tgtMem->tdMem[1].virtPtr;
500 
501     /* Initialize response buffer */
502     virtualAddr  = tgtMem->tdMem[2].virtPtr;
503     phyAddrUpper = tgtMem->tdMem[2].physAddrUpper;
504     phyAddrLower = tgtMem->tdMem[2].physAddrLower;
505     respLen      = tgtMem->tdMem[2].singleElementLength;
506 
507     ttdsaXchg->resp.virtAddr      = virtualAddr;
508     ttdsaXchg->resp.phyAddrUpper = phyAddrUpper;
509     ttdsaXchg->resp.phyAddrLower = phyAddrLower;
510     ttdsaXchg->resp.length = respLen;
511 
512     /* Initialize SMP response buffer */
513     smpvirtualAddr  = tgtMem->tdMem[3].virtPtr;
514     smpphyAddrUpper = tgtMem->tdMem[3].physAddrUpper;
515     smpphyAddrLower = tgtMem->tdMem[3].physAddrLower;
516     smprespLen      = tgtMem->tdMem[3].singleElementLength;
517 
518     ttdsaXchg->smpresp.virtAddr      = smpvirtualAddr;
519     ttdsaXchg->smpresp.phyAddrUpper = smpphyAddrUpper;
520     ttdsaXchg->smpresp.phyAddrLower = smpphyAddrLower;
521     ttdsaXchg->smpresp.length = smprespLen;
522 
523     /* Initialization of callback and etc */
524     for (i=0;i<maxNumXchgs;i++)
525     {
526         ttdsaXchg->id = i;
527         ttdsaXchg->usedEsgl = agFALSE;
528         ttdsaXchg->io_found = agTRUE;
529         ttdsaXchg->DeviceData = agNULL;
530         /* callback for IO(ssp) and SMP */
531         ttdsaXchg->IORequestBody.IOCompletionFunc = ttdsaIOCompleted;
532         ttdsaXchg->SMPRequestBody.SMPCompletionFunc = ttdsaSMPCompleted;
533 
534 
535         TDLIST_INIT_ELEMENT(&ttdsaXchg->XchgLinks );
536 
537         ttdsaXchg->IORequestBody.agIORequest.osData = (void *)ttdsaXchg;
538         ttdsaXchg->IORequestBody.tiIORequest
539         = &(ttdsaXchg->IORequestBody.IOType.TargetIO.tiIORequest);
540 
541         /* Init the tdData portion of tiIORequest context for this exchange */
542         ttdsaXchg->IORequestBody.tiIORequest->tdData = ttdsaXchg;
543 
544         /* SMP */
545         ttdsaXchg->SMPRequestBody.agIORequest.osData = (void *)ttdsaXchg;
546         /* ttdsaXchg->SMPRequestBody.agIORequest.osData = (void *)&ttdsaXchg->SMPRequestBody; */
547         /*ttdsaXchg->SMPRequestBody.tiIORequest.tdData = (void *)&ttdsaXchg->SMPRequestBody; */
548 
549 
550 
551 
552         /* Initialize the CDB and LUN addresses */
553         ttdsaXchg->tiTgtScsiCmnd.reqCDB  = &(ttdsaXchg->agSSPCmndIU.cdb[0]);
554         ttdsaXchg->tiTgtScsiCmnd.scsiLun = &(ttdsaXchg->agSSPCmndIU.lun[0]);
555 
556         ttdsaXchg->index = i;
557         ttdsaXchg->respLen = respLen; /* 100 */
558         ttdsaXchg->smprespLen = smprespLen; /* 100 */
559         ttdsaXchg->TLR = 0;
560         TD_XCHG_SET_STATE(ttdsaXchg, TD_XCHG_STATE_INACTIVE);
561         ttdsaXchg->retries = 0;
562 
563         ttdsaXchgLinkInit(tiRoot,ttdsaXchg);
564 
565         /* Save current response payload/buffer address */
566         virtualAddr  = ttdsaXchg->resp.virtAddr;
567         phyAddrLower = ttdsaXchg->resp.phyAddrLower;
568         smpvirtualAddr  = ttdsaXchg->smpresp.virtAddr;
569         smpphyAddrLower = ttdsaXchg->smpresp.phyAddrLower;
570 
571         TI_DBG5(("ttdsaXchgInit: +1 before\n"));
572         if (i == (maxNumXchgs - 1))
573         {
574             /* at the last one */
575             TI_DBG5(("ttdsaXchgInit: last one break\n"));
576             break;
577         }
578 
579         /* Advance to next exchange */
580         ttdsaXchg = ttdsaXchg + 1;
581         TI_DBG5(("ttdsaXchgInit: +1 after\n"));
582 
583         /* Update response payload/buffer address */
584         ttdsaXchg->resp.virtAddr      = virtualAddr + respLen;
585         TI_DBG5(("ttdsaXchgInit: pos 1\n"));
586         ttdsaXchg->resp.phyAddrUpper = phyAddrUpper;
587         TI_DBG5(("ttdsaXchgInit: pos 2\n"));
588         ttdsaXchg->resp.phyAddrLower = phyAddrLower + respLen;
589         TI_DBG5(("ttdsaXchgInit: pos 3\n"));
590         ttdsaXchg->resp.length = respLen;
591         TI_DBG5(("ttdsaXchgInit: pos 4\n"));
592 
593         /* Update SMP response payload/buffer address */
594         ttdsaXchg->smpresp.virtAddr      = smpvirtualAddr + smprespLen;
595         ttdsaXchg->smpresp.phyAddrUpper = smpphyAddrUpper;
596         ttdsaXchg->smpresp.phyAddrLower = smpphyAddrLower + smprespLen;
597         ttdsaXchg->smpresp.length = smprespLen;
598 
599     }
600 
601     /* Reinitialize counters.
602      * This must be done at the end
603      */
604     TD_XCHG_CONTEXT_NO_USED(tiRoot)            = 0;
605     TD_XCHG_CONTEXT_NO_FREED(tiRoot)           = 0;
606     TD_XCHG_CONTEXT_NO_CMD_RCVD(tiRoot)        = 0;
607     TD_XCHG_CONTEXT_NO_START_IO(tiRoot)        = 0;
608     TD_XCHG_CONTEXT_NO_SEND_RSP(tiRoot)        = 0;
609     TD_XCHG_CONTEXT_NO_IO_COMPLETED(tiRoot)    = 0;
610 
611     TI_DBG5(("ttdsaXchgInit: end\n"));
612     return agTRUE;
613 }
614 
615 osGLOBAL void
616 ttdsaXchgLinkInit(
617         tiRoot_t           *tiRoot,
618         ttdsaXchg_t        *ttdsaXchg
619 )
620 {
621     tdsaRoot_t        *tdsaRoot    = (tdsaRoot_t *)tiRoot->tdData;
622     tdsaContext_t     *tdsaAllShared = (tdsaContext_t *)&tdsaRoot->tdsaAllShared;
623     ttdsaTgt_t         *Target = (ttdsaTgt_t *)tdsaAllShared->ttdsaTgt;
624     bit32              i;
625     bit8               *data;
626 
627     TI_DBG5(("ttdsaXchgLinkInit: start\n"));
628     TI_DBG5(("ttdsaXchgLinkInit: xchg %p\n",ttdsaXchg));
629     TI_DBG5(("ttdsaXchgLinkInit: resp %p\n",ttdsaXchg->resp.virtAddr));
630     TI_DBG5(("ttdsaXchgLinkInit: smpresp %p\n",ttdsaXchg->smpresp.virtAddr));
631 
632     if (TD_XCHG_GET_STATE(ttdsaXchg) == TD_XCHG_STATE_ACTIVE)
633     {
634         TI_DBG1(("ttdsaXchgLinkInit: active xchg *****************; wrong\n"));
635         return;
636     }
637 
638     ttdsaXchg->tag = 0xFFFF;
639     ttdsaXchg->IORequestBody.agIORequest.sdkData  = agNULL;
640     ttdsaXchg->SMPRequestBody.agIORequest.sdkData  = agNULL;
641     ttdsaXchg->statusSent        = agFALSE;
642     ttdsaXchg->responseSent      = agFALSE;
643     ttdsaXchg->readRspCollapsed  = agFALSE;
644     ttdsaXchg->wrtRspCollapsed  = agFALSE;
645     ttdsaXchg->pTMResp           = agNULL;
646     ttdsaXchg->oustandingIos     = 0;
647     ttdsaXchg->isAborting        = agFALSE;
648     ttdsaXchg->oslayerAborting   = agFALSE;
649     ttdsaXchg->isTMRequest       = agFALSE;
650     ttdsaXchg->io_found          = agTRUE;
651     ttdsaXchg->tiIOToBeAbortedRequest          = agNULL;
652     ttdsaXchg->XchgToBeAborted          = agNULL;
653 
654     osti_memset((void *)ttdsaXchg->resp.virtAddr, 0, ttdsaXchg->respLen);
655     osti_memset((void *)ttdsaXchg->smpresp.virtAddr, 0, ttdsaXchg->smprespLen);
656 
657     data = (bit8 *)ttdsaXchg->resp.virtAddr;
658     for (i = 0; i< ttdsaXchg->respLen; i++)
659     {
660         if (data[i] != 0)
661         {
662             TI_DBG5(("!! ttdsaXchgLinkInit: data[%d] 0x%x\n", i, data[i]));
663         }
664     }
665 
666     ttdsaXchg->resp.length       = 0;
667 
668     ttdsaXchg->DeviceData = agNULL;
669     TI_DBG5(("ttdsaXchgLinkInit: id %d\n", ttdsaXchg->id));
670 
671     TD_XCHG_SET_STATE(ttdsaXchg, TD_XCHG_STATE_INACTIVE);
672     tdsaSingleThreadedEnter(tiRoot, TD_TGT_LOCK);
673     TDLIST_ENQUEUE_AT_TAIL( &ttdsaXchg->XchgLinks, &Target->ttdsaXchgData.xchgFreeList);
674     tdsaSingleThreadedLeave(tiRoot, TD_TGT_LOCK);
675 
676 
677     TD_XCHG_CONTEXT_NO_FREED(tiRoot)           = TD_XCHG_CONTEXT_NO_FREED(tiRoot) +1;
678     TI_DBG5(("ttdsaXchgLinkInit: end\n"));
679     return;
680 }
681 
682 /*
683    before: ttdsaXchg is in xchgBusyList
684    after: ttdsaXchg is in xchgFreeList
685  */
686 osGLOBAL void
687 ttdsaXchgFreeStruct(
688         tiRoot_t           *tiRoot,
689         ttdsaXchg_t        *ttdsaXchg
690 )
691 {
692     tdsaRoot_t        *tdsaRoot    = (tdsaRoot_t *)tiRoot->tdData;
693     tdsaContext_t     *tdsaAllShared = (tdsaContext_t *)&tdsaRoot->tdsaAllShared;
694     ttdsaTgt_t        *Target = (ttdsaTgt_t *)tdsaAllShared->ttdsaTgt;
695     bit32             i;
696     bit8              *data;
697 
698     TI_DBG5(("ttdsaXchgFreeStruct: start\n"));
699     TI_DBG5(("ttdsaXchgFreeStruct: xchg %p\n",ttdsaXchg));
700     TI_DBG5(("ttdsaXchgFreeStruct: resp %p\n",ttdsaXchg->resp.virtAddr));
701     TI_DBG5(("ttdsaXchgFreeStruct: smpresp %p\n",ttdsaXchg->smpresp.virtAddr));
702 
703     if (TD_XCHG_GET_STATE(ttdsaXchg) == TD_XCHG_STATE_INACTIVE)
704     {
705         TI_DBG1(("tdsaXchgFreeStruct: INACTIVE xchg *****************, wrong\n"));
706         return;
707     }
708 
709     ttdsaXchg->tag = 0xFFFF;
710     ttdsaXchg->IORequestBody.agIORequest.sdkData  = agNULL;
711     ttdsaXchg->SMPRequestBody.agIORequest.sdkData  = agNULL;
712     ttdsaXchg->statusSent        = agFALSE;
713     ttdsaXchg->responseSent      = agFALSE;
714     ttdsaXchg->readRspCollapsed  = agFALSE;
715     ttdsaXchg->wrtRspCollapsed  = agFALSE;
716     ttdsaXchg->pTMResp           = agNULL;
717     ttdsaXchg->oustandingIos     = 0;
718     ttdsaXchg->isAborting        = agFALSE;
719     ttdsaXchg->oslayerAborting   = agFALSE;
720     ttdsaXchg->isTMRequest       = agFALSE;
721     ttdsaXchg->io_found          = agTRUE;
722     ttdsaXchg->tiIOToBeAbortedRequest          = agNULL;
723     ttdsaXchg->XchgToBeAborted          = agNULL;
724 
725     osti_memset((void *)ttdsaXchg->resp.virtAddr, 0, ttdsaXchg->respLen);
726     osti_memset((void *)ttdsaXchg->smpresp.virtAddr, 0, ttdsaXchg->smprespLen);
727 
728     data = (bit8 *)ttdsaXchg->resp.virtAddr;
729     for (i = 0; i< ttdsaXchg->respLen; i++)
730     {
731         if (data[i] != 0)
732         {
733             TI_DBG5(("!! ttdsaXchgFreeStruct: data[%d] 0x%x\n", i, data[i]));
734         }
735     }
736 
737     ttdsaXchg->resp.length       = 0;
738 
739     ttdsaXchg->DeviceData = agNULL;
740     TI_DBG5(("ttdsaXchgFreeStruct: id %d\n", ttdsaXchg->id));
741 
742     tdsaSingleThreadedEnter(tiRoot, TD_TGT_LOCK);
743     TD_XCHG_SET_STATE(ttdsaXchg, TD_XCHG_STATE_INACTIVE);
744     TDLIST_DEQUEUE_THIS(&ttdsaXchg->XchgLinks);
745     TDLIST_ENQUEUE_AT_TAIL( &ttdsaXchg->XchgLinks, &Target->ttdsaXchgData.xchgFreeList);
746     tdsaSingleThreadedLeave(tiRoot, TD_TGT_LOCK);
747 
748     TD_XCHG_CONTEXT_NO_FREED(tiRoot)           = TD_XCHG_CONTEXT_NO_FREED(tiRoot) +1;
749     TI_DBG5(("ttdsaXchgFreeStruct: end\n"));
750     return;
751 }
752 
753 
754 /*
755    before: ttdsaXchg is in xchgFreeList
756    after: ttdsaXchg is in xchgBusyList
757  */
758 osGLOBAL ttdsaXchg_t *ttdsaXchgGetStruct(agsaRoot_t *agRoot)
759 {
760     tdsaRootOsData_t       *osData = (tdsaRootOsData_t *)agRoot->osData;
761     tiRoot_t               *tiRoot = (tiRoot_t *)osData->tiRoot;
762     ttdsaTgt_t             *Target = (ttdsaTgt_t *)osData->ttdsaTgt;
763     tdList_t               *Link;
764     ttdsaXchg_t            *ttdsaXchg = agNULL;
765 
766     TI_DBG3 (("ttdsaXchgGetStruct: enter\n"));
767 
768     tdsaSingleThreadedEnter(tiRoot, TD_TGT_LOCK);
769     if (TDLIST_EMPTY(&(Target->ttdsaXchgData.xchgFreeList)))
770     {
771         tdsaSingleThreadedLeave(tiRoot, TD_TGT_LOCK);
772         TI_DBG1(("ttdsaXchgGetStruct: no free ttdsaXchgData\n"));
773         //    ttdsaDumpallXchg(tiRoot);
774         return agNULL;
775     }
776 
777     TDLIST_DEQUEUE_FROM_HEAD(&Link, &Target->ttdsaXchgData.xchgFreeList);
778     if ( Link == agNULL )
779     {
780         tdsaSingleThreadedLeave(tiRoot, TD_TGT_LOCK);
781         TI_DBG1(("ttdsaXchgGetStruct: Link NULL: PRBLM \n"));
782         return agNULL;
783     }
784 
785     ttdsaXchg = TDLIST_OBJECT_BASE(ttdsaXchg_t, XchgLinks, Link);
786 
787     if (TD_XCHG_GET_STATE(ttdsaXchg) == TD_XCHG_STATE_ACTIVE)
788     {
789         TI_DBG1(("ttdsaXchgGetStruct: ACTIVE xchg *****************, wrong\n"));
790         TDLIST_DEQUEUE_THIS(&ttdsaXchg->XchgLinks);
791         TDLIST_ENQUEUE_AT_TAIL(&ttdsaXchg->XchgLinks, &Target->ttdsaXchgData.xchgFreeList);
792         TD_XCHG_SET_STATE(ttdsaXchg, TD_XCHG_STATE_INACTIVE);
793         tdsaSingleThreadedLeave(tiRoot, TD_TGT_LOCK);
794 
795         return agNULL;
796     }
797 
798     TDLIST_DEQUEUE_THIS(&ttdsaXchg->XchgLinks);
799     TDLIST_ENQUEUE_AT_TAIL(&ttdsaXchg->XchgLinks, &Target->ttdsaXchgData.xchgBusyList);
800     TD_XCHG_SET_STATE(ttdsaXchg, TD_XCHG_STATE_ACTIVE);
801     tdsaSingleThreadedLeave(tiRoot, TD_TGT_LOCK);
802 
803     TD_XCHG_CONTEXT_NO_USED(tiRoot)           = TD_XCHG_CONTEXT_NO_USED(tiRoot) +1;
804     TI_DBG5(("ttdsaXchgGetStruct: id %d\n", ttdsaXchg->id));
805     return ttdsaXchg;
806 }
807 
808 /* for debugging */
809 osGLOBAL void
810 ttdsaDumpallXchg(tiRoot_t           *tiRoot)
811 {
812     tdsaRoot_t        *tdsaRoot        = (tdsaRoot_t *) tiRoot->tdData;
813     tdsaContext_t     *tdsaAllShared = (tdsaContext_t *)&tdsaRoot->tdsaAllShared;
814     ttdsaTgt_t        *Target = (ttdsaTgt_t *)tdsaAllShared->ttdsaTgt;
815     ttdsaTgt_t        *tmpTarget;
816     tdList_t          *XchgList;
817 #ifdef TD_DEBUG_ENABLE
818     ttdsaXchg_t       *ttdsaXchg = agNULL;
819 #endif
820 
821     tmpTarget = Target;
822 
823     tdsaSingleThreadedEnter(tiRoot, TD_TGT_LOCK);
824     if (TDLIST_EMPTY(&(tmpTarget->ttdsaXchgData.xchgFreeList)))
825     {
826         tdsaSingleThreadedLeave(tiRoot, TD_TGT_LOCK);
827         TI_DBG1(("ttdsaDumpallXchg: no FREE ttdsaXchgData\n"));
828     }
829     else
830     {
831         tdsaSingleThreadedLeave(tiRoot, TD_TGT_LOCK);
832         XchgList = tmpTarget->ttdsaXchgData.xchgFreeList.flink;
833 
834         while(XchgList != &(tmpTarget->ttdsaXchgData.xchgFreeList))
835         {
836 #ifdef TD_DEBUG_ENABLE
837             ttdsaXchg = TDLIST_OBJECT_BASE(ttdsaXchg_t, XchgLinks, XchgList);
838 #endif
839             TI_DBG1(("ttdsaDumpallXchg: FREE id %d state %d\n", ttdsaXchg->id, TD_XCHG_GET_STATE(ttdsaXchg)));
840             XchgList = XchgList->flink;
841         }
842     }
843 
844     tdsaSingleThreadedEnter(tiRoot, TD_TGT_LOCK);
845     if (TDLIST_EMPTY(&(tmpTarget->ttdsaXchgData.xchgBusyList)))
846     {
847         tdsaSingleThreadedLeave(tiRoot, TD_TGT_LOCK);
848         TI_DBG1(("ttdsaDumpallXchg: no BUSY ttdsaXchgData\n"));
849     }
850     else
851     {
852         tdsaSingleThreadedLeave(tiRoot, TD_TGT_LOCK);
853         XchgList = tmpTarget->ttdsaXchgData.xchgBusyList.flink;
854 
855         while(XchgList != &(tmpTarget->ttdsaXchgData.xchgBusyList))
856         {
857 #ifdef TD_DEBUG_ENABLE
858             ttdsaXchg = TDLIST_OBJECT_BASE(ttdsaXchg_t, XchgLinks, XchgList);
859 #endif
860             TI_DBG1(("ttdsaDumpallXchg: BUSY id %d state %d\n", ttdsaXchg->id, TD_XCHG_GET_STATE(ttdsaXchg)));
861             XchgList = XchgList->flink;
862         }
863     }
864 
865 
866     return;
867 }
868 
869 
870 #ifdef PASSTHROUGH
871 
872 osGLOBAL bit32
873 tiTGTPassthroughCmndRegister(
874         tiRoot_t                        *tiRoot,
875         tiPortalContext_t               *tiportalContext,
876         tiPassthroughProtocol_t        tiProtocol,
877         tiPassthroughSubProtocol_t        tiSubProtocol,
878         tiPassthroughFrameType_t        tiFrameType,
879         ostiProcessPassthroughCmnd_t    agPasthroughCB
880 )
881 {
882     tdsaRoot_t                *tdsaRoot        = (tdsaRoot_t *) tiRoot->tdData;
883     tdsaContext_t             *tdsaAllShared = (tdsaContext_t *)&tdsaRoot->tdsaAllShared;
884     ttdsaTgt_t                *Target = (ttdsaTgt_t *)tdsaAllShared->ttdsaTgt;
885 
886     TI_DBG1(("tiTGTPassthroughCmndRegister: start\n"));
887     /* error checking */
888     if (tiProtocol != tiSASATA)
889     {
890         TI_DBG1(("tiTGTPassthroughCmndRegister: not supported protocol %d\n", tiProtocol));
891         return tiError;
892     }
893 
894     if (tiSubProtocol != tiSSP || tiSubProtocol != tiSTP || tiSubProtocol != tiSMP)
895     {
896         TI_DBG1(("tiTGTPassthroughCmndRegister: not supported sub protocol %d\n", tiSubProtocol));
897         return tiError;
898     }
899 
900 
901     if (tiFrameType == tiSMPResponse)
902     {
903         TI_DBG1(("tiTGTPassthroughCmndRegister: SMP response frametype %d\n"));
904         Target->PasthroughCB = agPasthroughCB;
905     }
906 
907     else if (tiFrameType == tiSSPPMC)
908     {
909         TI_DBG1(("tiTGTPassthroughCmndRegister: RMC response frametype %d\n"));
910         Target->PasthroughCB = agPasthroughCB;
911     }
912     else
913     {
914         TI_DBG1(("tiTGTPassthroughCmndRegister: not supported frametype %d\n", tiFrameType));
915         return tiError;
916     }
917 
918 
919     return tiSuccess;
920 }
921 
922 #endif
923