1 /*******************************************************************************
2 *Copyright (c) 2014 PMC-Sierra, Inc. All rights reserved.
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
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.
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 /*******************************************************************************/
24 * $RCSfile: ttdinit.c,v $
26 * Copyright 2006 PMC-Sierra, Inc.
30 * $Date: 2012-04-16 14:35:19 -0700 (Mon, 16 Apr 2012) $
32 * This file contains initiator IO related functions in TD layer
52 #ifdef INITIATOR_DRIVER
64 #include <tdsatypes.h>
68 extern void TDTraceInit(void);
75 tiTargetResource_t *targetResource,
76 tiTdSharedMem_t *tdSharedMem
79 tdsaRoot_t *tdsaRoot = (tdsaRoot_t *)tiRoot->tdData;
80 tiTargetMem_t *tgtMem;
82 ttdssOperatingOption_t *OperatingOption;
86 char *pLastUsedChar = agNULL;
87 char tmpBuffer[DEFAULT_KEY_BUFFER_SIZE];
88 char globalStr[] = "OSParms";
90 TI_DBG5(("ttdssInit: start\n"));
93 first set the values to Default values
94 Then, overwrite them using ostiGetTransportParam()
97 /* to remove compiler warnings */
98 buffer = &tmpBuffer[0];
99 buffLen = sizeof (tmpBuffer);
101 osti_memset(buffer, 0, buffLen);
103 tgtMem = &targetResource->targetMem;
106 * Cached mem for target Transport Dependent Layer main functionality
108 Target = tgtMem->tdMem[0].virtPtr;
110 OperatingOption = &Target->OperatingOption;
112 * Get default parameters from the OS Specific area
113 * and reads parameters from the configuration file
115 ttdssGetOperatingOptionParams(tiRoot, OperatingOption);
119 * Update TD operating options
121 OperatingOption->UsecsPerTick =
122 targetResource->targetOption.usecsPerTick;
123 OperatingOption->numXchgs = tgtMem->tdMem[1].numElements;
126 if (ttdsaXchgInit(tiRoot,
127 &Target->ttdsaXchgData,
129 OperatingOption->numXchgs
132 TI_DBG1(("ttdInit: ttdsaXchgInit failed\n"));
136 /* Get number of AutoGoodResponse entry */
137 if ((ostiGetTransportParam(
149 ) == tiSuccess) && (lenRecv != 0))
151 if (osti_strncmp(buffer, "0x", 2) == 0)
153 tdsaRoot->autoGoodRSP = osti_strtoul (buffer, &pLastUsedChar, 0);
157 tdsaRoot->autoGoodRSP = osti_strtoul (buffer, &pLastUsedChar, 10);
166 this combines ttdGetDefaultParams and ttdGetTargetParms
170 ttdssGetOperatingOptionParams(
172 ttdssOperatingOption_t *OperatingOption
176 char *subkey1 = agNULL;
177 char *subkey2 = agNULL;
181 char *pLastUsedChar = agNULL;
182 char tmpBuffer[DEFAULT_KEY_BUFFER_SIZE];
183 char globalStr[] = "Global";
184 char iniParmsStr[] = "TargetParms";
186 TI_DBG5(("ttdssGetOperatingOptionParams: start\n"));
189 first set the values to Default values
190 Then, overwrite them using ostiGetTransportParam()
194 /* to remove compiler warnings */
195 pLastUsedChar = pLastUsedChar;
200 buffer = &tmpBuffer[0];
201 buffLen = sizeof (tmpBuffer);
203 osti_memset(buffer, 0, buffLen);
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;
213 /* defaults are overwritten in the following */
214 /* Get number of exchanges */
215 if ((ostiGetTransportParam(
227 ) == tiSuccess) && (lenRecv != 0))
229 if (osti_strncmp(buffer, "0x", 2) == 0)
231 OperatingOption->numXchgs = osti_strtoul (buffer, &pLastUsedChar, 0);
235 OperatingOption->numXchgs = osti_strtoul (buffer, &pLastUsedChar, 10);
240 osti_memset(buffer, 0, buffLen);
243 /* Get number of MaxTargets */
244 if ((ostiGetTransportParam(
256 ) == tiSuccess) && (lenRecv != 0))
258 if (osti_strncmp(buffer, "0x", 2) == 0)
260 OperatingOption->MaxTargets = osti_strtoul (buffer, &pLastUsedChar, 0);
264 OperatingOption->MaxTargets = osti_strtoul (buffer, &pLastUsedChar, 10);
268 osti_memset(buffer, 0, buffLen);
271 /* Get number of BlockSize */
272 if ((ostiGetTransportParam(
284 ) == tiSuccess) && (lenRecv != 0))
286 if (osti_strncmp(buffer, "0x", 2) == 0)
288 OperatingOption->BlockSize = osti_strtoul (buffer, &pLastUsedChar, 0);
292 OperatingOption->BlockSize = osti_strtoul (buffer, &pLastUsedChar, 10);
295 osti_memset(buffer, 0, buffLen);
300 TI_DBG5(("ttdssGetOperatingOptionParams: NumberExchanges %d UsecsPerTick %d MaxTargets %d BlockSize %d\n", OperatingOption->numXchgs, OperatingOption->UsecsPerTick, OperatingOption->MaxTargets, OperatingOption->BlockSize));
309 tiTargetResource_t *targetResource
312 tiTargetMem_t *tgtMem;
314 ttdssOperatingOption_t OperatingOption;
319 TI_DBG4(("ttdssGetResource: start\n"));
321 tgtMem = &targetResource->targetMem;
324 only 4 memory descriptors are used
328 /* initiailization */
329 for (i = 0 ; i < 10 ; i++)
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;
344 * Get default parameters from the OS Specific area
345 * and reads parameters from the configuration file
347 ttdssGetOperatingOptionParams(tiRoot, &OperatingOption);
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;
364 * Cached memory for I/O exchange structures
366 xchgSize = sizeof(ttdsaXchg_t);
367 xchgSize = AG_ALIGNSIZE(xchgSize, 8);
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;
382 * Uncached memory for response buffer structures
384 TI_DBG4(("ttdssGetResource: sas_resp_t size 0x%x %d\n",
385 (unsigned int)sizeof(sas_resp_t), (int)sizeof(sas_resp_t)));
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;
405 * Uncached memory for SMP response buffer structures
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));
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;
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;
433 This is not used in OS like Linux which supports dynamic memeory allocation
434 In short, this is for Windows
436 /* Estimate dynamic DMA memory */
437 targetResource->targetOption.dynamicDmaMem.alignment = sizeof(void *);
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;
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;
459 ttdssGetTargetParams(
463 TI_DBG6(("ttdssGetTargetParams: start\n"));
470 ttdsaXchgData_t *ttdsaXchgData,
471 tiTargetMem_t *tgtMem,
475 ttdsaXchg_t *ttdsaXchg;
478 bit32 phyAddrLower, phyAddrUpper;
480 bit32 smpphyAddrLower, smpphyAddrUpper;
481 bit8 *smpvirtualAddr;
485 TI_DBG5(("ttdsaXchgInit: start\n"));
491 * Set and initialize some global exchange information
493 TDLIST_INIT_HDR(&ttdsaXchgData->xchgFreeList);
494 TDLIST_INIT_HDR(&ttdsaXchgData->xchgBusyList);
496 ttdsaXchgData->maxNumXchgs = maxNumXchgs;
498 /* Initialize exchange and response buffer structures */
499 ttdsaXchg = (ttdsaXchg_t *) tgtMem->tdMem[1].virtPtr;
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;
507 ttdsaXchg->resp.virtAddr = virtualAddr;
508 ttdsaXchg->resp.phyAddrUpper = phyAddrUpper;
509 ttdsaXchg->resp.phyAddrLower = phyAddrLower;
510 ttdsaXchg->resp.length = respLen;
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;
518 ttdsaXchg->smpresp.virtAddr = smpvirtualAddr;
519 ttdsaXchg->smpresp.phyAddrUpper = smpphyAddrUpper;
520 ttdsaXchg->smpresp.phyAddrLower = smpphyAddrLower;
521 ttdsaXchg->smpresp.length = smprespLen;
523 /* Initialization of callback and etc */
524 for (i=0;i<maxNumXchgs;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;
535 TDLIST_INIT_ELEMENT(&ttdsaXchg->XchgLinks );
537 ttdsaXchg->IORequestBody.agIORequest.osData = (void *)ttdsaXchg;
538 ttdsaXchg->IORequestBody.tiIORequest
539 = &(ttdsaXchg->IORequestBody.IOType.TargetIO.tiIORequest);
541 /* Init the tdData portion of tiIORequest context for this exchange */
542 ttdsaXchg->IORequestBody.tiIORequest->tdData = ttdsaXchg;
545 ttdsaXchg->SMPRequestBody.agIORequest.osData = (void *)ttdsaXchg;
546 /* ttdsaXchg->SMPRequestBody.agIORequest.osData = (void *)&ttdsaXchg->SMPRequestBody; */
547 /*ttdsaXchg->SMPRequestBody.tiIORequest.tdData = (void *)&ttdsaXchg->SMPRequestBody; */
552 /* Initialize the CDB and LUN addresses */
553 ttdsaXchg->tiTgtScsiCmnd.reqCDB = &(ttdsaXchg->agSSPCmndIU.cdb[0]);
554 ttdsaXchg->tiTgtScsiCmnd.scsiLun = &(ttdsaXchg->agSSPCmndIU.lun[0]);
556 ttdsaXchg->index = i;
557 ttdsaXchg->respLen = respLen; /* 100 */
558 ttdsaXchg->smprespLen = smprespLen; /* 100 */
560 TD_XCHG_SET_STATE(ttdsaXchg, TD_XCHG_STATE_INACTIVE);
561 ttdsaXchg->retries = 0;
563 ttdsaXchgLinkInit(tiRoot,ttdsaXchg);
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;
571 TI_DBG5(("ttdsaXchgInit: +1 before\n"));
572 if (i == (maxNumXchgs - 1))
574 /* at the last one */
575 TI_DBG5(("ttdsaXchgInit: last one break\n"));
579 /* Advance to next exchange */
580 ttdsaXchg = ttdsaXchg + 1;
581 TI_DBG5(("ttdsaXchgInit: +1 after\n"));
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"));
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;
601 /* Reinitialize counters.
602 * This must be done at the end
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;
611 TI_DBG5(("ttdsaXchgInit: end\n"));
618 ttdsaXchg_t *ttdsaXchg
621 tdsaRoot_t *tdsaRoot = (tdsaRoot_t *)tiRoot->tdData;
622 tdsaContext_t *tdsaAllShared = (tdsaContext_t *)&tdsaRoot->tdsaAllShared;
623 ttdsaTgt_t *Target = (ttdsaTgt_t *)tdsaAllShared->ttdsaTgt;
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));
632 if (TD_XCHG_GET_STATE(ttdsaXchg) == TD_XCHG_STATE_ACTIVE)
634 TI_DBG1(("ttdsaXchgLinkInit: active xchg *****************; wrong\n"));
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;
654 osti_memset((void *)ttdsaXchg->resp.virtAddr, 0, ttdsaXchg->respLen);
655 osti_memset((void *)ttdsaXchg->smpresp.virtAddr, 0, ttdsaXchg->smprespLen);
657 data = (bit8 *)ttdsaXchg->resp.virtAddr;
658 for (i = 0; i< ttdsaXchg->respLen; i++)
662 TI_DBG5(("!! ttdsaXchgLinkInit: data[%d] 0x%x\n", i, data[i]));
666 ttdsaXchg->resp.length = 0;
668 ttdsaXchg->DeviceData = agNULL;
669 TI_DBG5(("ttdsaXchgLinkInit: id %d\n", ttdsaXchg->id));
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);
677 TD_XCHG_CONTEXT_NO_FREED(tiRoot) = TD_XCHG_CONTEXT_NO_FREED(tiRoot) +1;
678 TI_DBG5(("ttdsaXchgLinkInit: end\n"));
683 before: ttdsaXchg is in xchgBusyList
684 after: ttdsaXchg is in xchgFreeList
689 ttdsaXchg_t *ttdsaXchg
692 tdsaRoot_t *tdsaRoot = (tdsaRoot_t *)tiRoot->tdData;
693 tdsaContext_t *tdsaAllShared = (tdsaContext_t *)&tdsaRoot->tdsaAllShared;
694 ttdsaTgt_t *Target = (ttdsaTgt_t *)tdsaAllShared->ttdsaTgt;
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));
703 if (TD_XCHG_GET_STATE(ttdsaXchg) == TD_XCHG_STATE_INACTIVE)
705 TI_DBG1(("tdsaXchgFreeStruct: INACTIVE xchg *****************, wrong\n"));
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;
725 osti_memset((void *)ttdsaXchg->resp.virtAddr, 0, ttdsaXchg->respLen);
726 osti_memset((void *)ttdsaXchg->smpresp.virtAddr, 0, ttdsaXchg->smprespLen);
728 data = (bit8 *)ttdsaXchg->resp.virtAddr;
729 for (i = 0; i< ttdsaXchg->respLen; i++)
733 TI_DBG5(("!! ttdsaXchgFreeStruct: data[%d] 0x%x\n", i, data[i]));
737 ttdsaXchg->resp.length = 0;
739 ttdsaXchg->DeviceData = agNULL;
740 TI_DBG5(("ttdsaXchgFreeStruct: id %d\n", ttdsaXchg->id));
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);
748 TD_XCHG_CONTEXT_NO_FREED(tiRoot) = TD_XCHG_CONTEXT_NO_FREED(tiRoot) +1;
749 TI_DBG5(("ttdsaXchgFreeStruct: end\n"));
755 before: ttdsaXchg is in xchgFreeList
756 after: ttdsaXchg is in xchgBusyList
758 osGLOBAL ttdsaXchg_t *ttdsaXchgGetStruct(agsaRoot_t *agRoot)
760 tdsaRootOsData_t *osData = (tdsaRootOsData_t *)agRoot->osData;
761 tiRoot_t *tiRoot = (tiRoot_t *)osData->tiRoot;
762 ttdsaTgt_t *Target = (ttdsaTgt_t *)osData->ttdsaTgt;
764 ttdsaXchg_t *ttdsaXchg = agNULL;
766 TI_DBG3 (("ttdsaXchgGetStruct: enter\n"));
768 tdsaSingleThreadedEnter(tiRoot, TD_TGT_LOCK);
769 if (TDLIST_EMPTY(&(Target->ttdsaXchgData.xchgFreeList)))
771 tdsaSingleThreadedLeave(tiRoot, TD_TGT_LOCK);
772 TI_DBG1(("ttdsaXchgGetStruct: no free ttdsaXchgData\n"));
773 // ttdsaDumpallXchg(tiRoot);
777 TDLIST_DEQUEUE_FROM_HEAD(&Link, &Target->ttdsaXchgData.xchgFreeList);
778 if ( Link == agNULL )
780 tdsaSingleThreadedLeave(tiRoot, TD_TGT_LOCK);
781 TI_DBG1(("ttdsaXchgGetStruct: Link NULL: PRBLM \n"));
785 ttdsaXchg = TDLIST_OBJECT_BASE(ttdsaXchg_t, XchgLinks, Link);
787 if (TD_XCHG_GET_STATE(ttdsaXchg) == TD_XCHG_STATE_ACTIVE)
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);
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);
803 TD_XCHG_CONTEXT_NO_USED(tiRoot) = TD_XCHG_CONTEXT_NO_USED(tiRoot) +1;
804 TI_DBG5(("ttdsaXchgGetStruct: id %d\n", ttdsaXchg->id));
810 ttdsaDumpallXchg(tiRoot_t *tiRoot)
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;
817 #ifdef TD_DEBUG_ENABLE
818 ttdsaXchg_t *ttdsaXchg = agNULL;
823 tdsaSingleThreadedEnter(tiRoot, TD_TGT_LOCK);
824 if (TDLIST_EMPTY(&(tmpTarget->ttdsaXchgData.xchgFreeList)))
826 tdsaSingleThreadedLeave(tiRoot, TD_TGT_LOCK);
827 TI_DBG1(("ttdsaDumpallXchg: no FREE ttdsaXchgData\n"));
831 tdsaSingleThreadedLeave(tiRoot, TD_TGT_LOCK);
832 XchgList = tmpTarget->ttdsaXchgData.xchgFreeList.flink;
834 while(XchgList != &(tmpTarget->ttdsaXchgData.xchgFreeList))
836 #ifdef TD_DEBUG_ENABLE
837 ttdsaXchg = TDLIST_OBJECT_BASE(ttdsaXchg_t, XchgLinks, XchgList);
839 TI_DBG1(("ttdsaDumpallXchg: FREE id %d state %d\n", ttdsaXchg->id, TD_XCHG_GET_STATE(ttdsaXchg)));
840 XchgList = XchgList->flink;
844 tdsaSingleThreadedEnter(tiRoot, TD_TGT_LOCK);
845 if (TDLIST_EMPTY(&(tmpTarget->ttdsaXchgData.xchgBusyList)))
847 tdsaSingleThreadedLeave(tiRoot, TD_TGT_LOCK);
848 TI_DBG1(("ttdsaDumpallXchg: no BUSY ttdsaXchgData\n"));
852 tdsaSingleThreadedLeave(tiRoot, TD_TGT_LOCK);
853 XchgList = tmpTarget->ttdsaXchgData.xchgBusyList.flink;
855 while(XchgList != &(tmpTarget->ttdsaXchgData.xchgBusyList))
857 #ifdef TD_DEBUG_ENABLE
858 ttdsaXchg = TDLIST_OBJECT_BASE(ttdsaXchg_t, XchgLinks, XchgList);
860 TI_DBG1(("ttdsaDumpallXchg: BUSY id %d state %d\n", ttdsaXchg->id, TD_XCHG_GET_STATE(ttdsaXchg)));
861 XchgList = XchgList->flink;
873 tiTGTPassthroughCmndRegister(
875 tiPortalContext_t *tiportalContext,
876 tiPassthroughProtocol_t tiProtocol,
877 tiPassthroughSubProtocol_t tiSubProtocol,
878 tiPassthroughFrameType_t tiFrameType,
879 ostiProcessPassthroughCmnd_t agPasthroughCB
882 tdsaRoot_t *tdsaRoot = (tdsaRoot_t *) tiRoot->tdData;
883 tdsaContext_t *tdsaAllShared = (tdsaContext_t *)&tdsaRoot->tdsaAllShared;
884 ttdsaTgt_t *Target = (ttdsaTgt_t *)tdsaAllShared->ttdsaTgt;
886 TI_DBG1(("tiTGTPassthroughCmndRegister: start\n"));
888 if (tiProtocol != tiSASATA)
890 TI_DBG1(("tiTGTPassthroughCmndRegister: not supported protocol %d\n", tiProtocol));
894 if (tiSubProtocol != tiSSP || tiSubProtocol != tiSTP || tiSubProtocol != tiSMP)
896 TI_DBG1(("tiTGTPassthroughCmndRegister: not supported sub protocol %d\n", tiSubProtocol));
901 if (tiFrameType == tiSMPResponse)
903 TI_DBG1(("tiTGTPassthroughCmndRegister: SMP response frametype %d\n"));
904 Target->PasthroughCB = agPasthroughCB;
907 else if (tiFrameType == tiSSPPMC)
909 TI_DBG1(("tiTGTPassthroughCmndRegister: RMC response frametype %d\n"));
910 Target->PasthroughCB = agPasthroughCB;
914 TI_DBG1(("tiTGTPassthroughCmndRegister: not supported frametype %d\n", tiFrameType));