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
ttdssInit(tiRoot_t * tiRoot,tiTargetResource_t * targetResource,tiTdSharedMem_t * tdSharedMem)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
ttdssGetOperatingOptionParams(tiRoot_t * tiRoot,ttdssOperatingOption_t * OperatingOption)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
ttdssGetResource(tiRoot_t * tiRoot,tiTargetResource_t * targetResource)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
ttdssGetTargetParams(tiRoot_t * tiRoot)459 ttdssGetTargetParams(
460 tiRoot_t *tiRoot
461 )
462 {
463 TI_DBG6(("ttdssGetTargetParams: start\n"));
464 return;
465 }
466
467 osGLOBAL agBOOLEAN
ttdsaXchgInit(tiRoot_t * tiRoot,ttdsaXchgData_t * ttdsaXchgData,tiTargetMem_t * tgtMem,bit32 maxNumXchgs)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
ttdsaXchgLinkInit(tiRoot_t * tiRoot,ttdsaXchg_t * ttdsaXchg)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
ttdsaXchgFreeStruct(tiRoot_t * tiRoot,ttdsaXchg_t * ttdsaXchg)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 */
ttdsaXchgGetStruct(agsaRoot_t * agRoot)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
ttdsaDumpallXchg(tiRoot_t * tiRoot)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
tiTGTPassthroughCmndRegister(tiRoot_t * tiRoot,tiPortalContext_t * tiportalContext,tiPassthroughProtocol_t tiProtocol,tiPassthroughSubProtocol_t tiSubProtocol,tiPassthroughFrameType_t tiFrameType,ostiProcessPassthroughCmnd_t agPasthroughCB)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