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: ttdio.c,v $
26 * Copyright 2006 PMC-Sierra, Inc.
29 * This file contains initiator IO related functions in TD layer
49 #ifdef INITIATOR_DRIVER
61 #include <tdsatypes.h>
65 /* Start For trace only */
68 GetHiResTimeStamp(void);
70 #undef TD_DEBUG_TRACE_ENABLE
71 #define TD_DEBUG_IO_TRACE_BUFFER_MAX 1024
74 typedef struct TDDebugTraceEntry_s
77 ttdsaXchg_t ttdsaXchg;
78 tdsaDeviceData_t oneDeviceData;
79 } TDDebugTraceEntry_t;
81 typedef struct TDDebugTrace_s
85 TDDebugTraceEntry_t Data[TD_DEBUG_IO_TRACE_BUFFER_MAX];
88 void TDTraceInit(void);
89 void TDTraceAdd(ttdsaXchg_t *ttdsaXchg, tdsaDeviceData_t *oneDeviceData);
91 #ifdef TD_DEBUG_TRACE_ENABLE
92 #define TD_DEBUG_TRACE(ttdsaXchg, oneDeviceData) TDTraceAdd(ttdsaXchg, oneDeviceData)
94 #define TD_DEBUG_TRACE(ttdsaXchg, oneDeviceData)
97 TDDebugTrace_t TraceData;
99 void TDTraceInit(void)
101 osti_memset(&TraceData, 0, sizeof(TraceData));
104 void TDTraceAdd(ttdsaXchg_t *ttdsaXchg, tdsaDeviceData_t *oneDeviceData)
106 static bit32 TraceIdx = 0;
108 TraceData.Idx = TraceIdx;
110 TraceData.Data[TraceIdx].Time = GetHiResTimeStamp();
112 osti_memcpy((bit8 *)&(TraceData.Data[TraceIdx].ttdsaXchg), (bit8 *)ttdsaXchg, sizeof(ttdsaXchg_t));
113 osti_memcpy((bit8 *)&(TraceData.Data[TraceIdx].oneDeviceData), (bit8 *)oneDeviceData, sizeof(tdsaDeviceData_t));
115 TraceData.Data[TraceIdx].ttdsaXchg = ttdsaXchg;
116 TraceData.Data[TraceIdx].oneDeviceData = oneDeviceData;
120 if (TraceIdx >= TD_DEBUG_IO_TRACE_BUFFER_MAX)
129 /* End For trace only */
135 agsaDevHandle_t *agDevHandle,
136 agsaFrameHandle_t agFrameHandle,
137 bit32 agInitiatorTag,
142 tdsaRootOsData_t *osData = (tdsaRootOsData_t *)agRoot->osData;
143 tiRoot_t *tiRoot = (tiRoot_t *)osData->tiRoot;
144 ttdsaXchg_t *ttdsaXchg;
145 /* agsaSSPCmdInfoUnit_t cmdIU; */
146 tdsaDeviceData_t *oneDeviceData = agNULL;
147 bit32 agFrameType, TLR;
149 TD_XCHG_CONTEXT_NO_CMD_RCVD(tiRoot) = TD_XCHG_CONTEXT_NO_CMD_RCVD(tiRoot)+1;
151 TI_DBG4(("ttdsaSSPReqReceived: start\n"));
153 agFrameType = TD_GET_FRAME_TYPE(parameter);
154 TLR = TD_GET_TLR(parameter);
158 in ini, agDevHandle->osData = tdsaDeviceData_t
159 is set in tdssAddDevicedataToSharedcontext()
161 in tdsaDeviceDataInit()
162 oneDeviceData->tiDeviceHandle.tdData has been initialized
164 oneDeviceData = (tdsaDeviceData_t *)agDevHandle->osData;
166 if (oneDeviceData == agNULL)
168 TI_DBG1(("ttdsaSSPReqReceived: no device data\n"));
174 ttdsaXchg = ttdsaXchgGetStruct(agRoot);
176 if (ttdsaXchg == agNULL)
178 TI_DBG1(("ttdsaSSPReqReceived: no free xchg structures\n"));
179 // ttdsaDumpallXchg(tiRoot);
183 if (ttdsaXchg->IORequestBody.tiIORequest == agNULL)
185 TI_DBG1(("ttdsaSSPReqReceived: tiIORequest is NULL\n"));
186 // ttdsaDumpallXchg(tiRoot);
190 oneDeviceData->agDevHandle = agDevHandle;
191 oneDeviceData->agRoot = agRoot;
193 /* saving the device */
194 ttdsaXchg->DeviceData = oneDeviceData;
196 ttdsaXchg->agRoot = agRoot;
197 ttdsaXchg->tiRoot = tiRoot;
199 ttdsaXchg->IORequestBody.agIORequest.sdkData = agNULL;
202 ttdsaXchg->tag = (bit16)agInitiatorTag;
203 ttdsaXchg->IORequestBody.transport.SAS.agSASRequestBody.sspTargetReq.agTag
205 ttdsaXchg->IORequestBody.transport.SAS.agSASRequestBody.sspTargetResponse.agTag
208 TI_DBG6(("ttdsaSSPReqReceived: initiator tag 0x%x\n", agInitiatorTag));
210 if (agFrameType == OSSA_FRAME_TYPE_SSP_CMD)
212 TI_DBG4(("ttdsaSSPReqReceived: CMD frame type\n"));
213 /* reads agsaSSPResponseInfoUnit_t */
218 &ttdsaXchg->agSSPCmndIU,
222 tdsaProcessCDB(&ttdsaXchg->agSSPCmndIU, ttdsaXchg);
223 ttdsaXchg->FrameType = SAS_CMND;
226 ** As the last thing we call the disk module to handle the SCSI CDB.
227 ** The disk module will call tiTGTIOStart to start a data phase.
237 } tiTargetScsiCmnd_t;
239 /* what about reqCDB and scsiLun */
241 /* coverting task attributes from SAS TISA */
242 switch (SA_SSPCMD_GET_TASKATTRIB(&ttdsaXchg->agSSPCmndIU))
245 ttdsaXchg->tiTgtScsiCmnd.taskAttribute = TASK_SIMPLE;
248 ttdsaXchg->tiTgtScsiCmnd.taskAttribute = TASK_HEAD_OF_QUEUE;
251 ttdsaXchg->tiTgtScsiCmnd.taskAttribute = TASK_ORDERED;
254 TI_DBG1(("ttdsaSSPReqReceived: reserved taskAttribute 0x%x\n",ttdsaXchg->agSSPCmndIU.efb_tp_taskAttribute));
255 ttdsaXchg->tiTgtScsiCmnd.taskAttribute = TASK_SIMPLE;
258 ttdsaXchg->tiTgtScsiCmnd.taskAttribute = TASK_ACA;
261 TI_DBG1(("ttdsaSSPReqReceived: unknown taskAttribute 0x%x\n",ttdsaXchg->agSSPCmndIU.efb_tp_taskAttribute));
262 ttdsaXchg->agSSPCmndIU.efb_tp_taskAttribute = TASK_SIMPLE;
266 ttdsaXchg->tiTgtScsiCmnd.taskId = agInitiatorTag;
267 ttdsaXchg->tiTgtScsiCmnd.crn = 0;
268 ttdsaXchg->TLR = TLR;
270 /* call ostiProcessScsiReq */
271 ostiProcessScsiReq( tiRoot,
272 &ttdsaXchg->tiTgtScsiCmnd,
275 ttdsaXchg->IORequestBody.tiIORequest,
276 &ttdsaXchg->DeviceData->tiDeviceHandle);
280 else if (agFrameType == OSSA_FRAME_TYPE_SSP_TASK)
282 TI_DBG4(("ttdsaSSPReqReceived: TM frame type\n"));
285 reads aagsaSSPScsiTaskMgntReq_t
296 ttdsaXchg->FrameType = SAS_TM;
298 call task process mangement fn
300 ttdsaTMProcess(tiRoot, ttdsaXchg);
305 TI_DBG1(("ttdsaSSPReqReceived: unknown frame type\n"));
318 TI_DBG4(("cdb[%d] 0x%x\n", i, cdb[i]));
325 agsaSSPCmdInfoUnit_t *cmdIU,
326 ttdsaXchg_t *ttdsaXchg
329 tdsaRoot_t *tdsaRoot = (tdsaRoot_t *) ttdsaXchg->tiRoot->tdData;
330 tdsaContext_t *tdsaAllShared = (tdsaContext_t *) &tdsaRoot->tdsaAllShared;
331 ttdsaTgt_t *Target = (ttdsaTgt_t *) tdsaAllShared->ttdsaTgt;
333 #ifdef TD_DEBUG_ENABLE
339 bit32 unknown = agFALSE;
341 group = cmdIU->cdb[0] & CDB_GRP_MASK;
343 TI_DBG4(("tdsaProcessCDB: start\n"));
345 switch (cmdIU->cdb[0])
347 case SCSIOPC_REPORT_LUN:
348 TI_DBG4(("tdsaProcessCDB: REPORT_LUN\n"));
349 ttdsaXchg->XchType = AGSA_SSP_TGT_READ_DATA;
351 case SCSIOPC_INQUIRY:
352 TI_DBG4(("tdsaProcessCDB: INQUIRY\n"));
353 ttdsaXchg->XchType = AGSA_SSP_TGT_READ_DATA;
356 case SCSIOPC_TEST_UNIT_READY:
357 TI_DBG4(("tdsaProcessCDB: TEST_UNIT_READY\n"));
358 ttdsaXchg->XchType = AGSA_SSP_TGT_READ_DATA;
361 case SCSIOPC_READ_CAPACITY_10:
362 case SCSIOPC_READ_CAPACITY_16:
363 TI_DBG4(("tdsaProcessCDB: READ CAPACITY\n"));
364 ttdsaXchg->XchType = AGSA_SSP_TGT_READ_DATA;
367 case SCSIOPC_READ_6: /* fall through */
368 case SCSIOPC_READ_10:
369 TI_DBG4(("tdsaProcessCDB: READ\n"));
370 ttdsaXchg->XchType = AGSA_SSP_TGT_READ_DATA;
373 case SCSIOPC_WRITE_6: /* fall through */
374 case SCSIOPC_WRITE_10:
375 TI_DBG4(("tdsaProcessCDB: WRITE\n"));
376 ttdsaXchg->XchType = AGSA_SSP_TGT_WRITE_DATA;
379 case SCSIOPC_MODE_SENSE_6: /* fall through */
380 case SCSIOPC_MODE_SENSE_10:
381 TI_DBG4(("tdsaProcessCDB: MODE SENSE\n"));
382 ttdsaXchg->XchType = AGSA_SSP_TGT_READ_DATA;
384 case SCSIOPC_SYNCHRONIZE_CACHE_10:
385 TI_DBG4(("tdsaProcessCDB: SCSIOPC_SYNCHRONIZE_CACHE_10\n"));
386 ttdsaXchg->XchType = AGSA_SSP_TGT_CMD_OR_TASK_RSP;
388 case SCSIOPC_REQUEST_SENSE:
389 TI_DBG2(("tdsaProcessCDB: SCSIOPC_REQUEST_SENSE\n"));
390 ttdsaXchg->XchType = AGSA_SSP_TGT_READ_DATA;
393 TI_DBG4(("tdsaProcessCDB: UNKNOWN, cbd %d 0x%x\n", cmdIU->cdb[0], cmdIU->cdb[0]));
394 ttdsaXchg->XchType = TargetUnknown;
402 TI_DBG4(("tdsaProcessCDB: CDB 6 byte, not yet\n"));
403 #ifdef TD_DEBUG_ENABLE
404 cdb6 = (CDB6_t *)(cmdIU->cdb);
406 TI_DBG4(("tdsaProcessCDB: CDB len 0x%x\n", cdb6->len));
408 case CDB_10BYTE1: /* fall through */
410 TI_DBG4(("tdsaProcessCDB: CDB 10 byte\n"));
411 cdb10 = (CDB10_t *)(cmdIU->cdb);
412 OSSA_READ_BE_16(AGROOT, &len, cdb10->len, 0);
413 TI_DBG4(("tdsaProcessCDB: CDB len 0x%x\n", len));
417 TI_DBG4(("tdsaProcessCDB: CDB 12 byte, not yet\n"));
418 cdb12 = (CDB12_t *)(cmdIU->cdb);
419 OSSA_READ_BE_32(AGROOT, &len, cdb12->len, 0);
420 TI_DBG4(("tdsaProcessCDB: CDB len 0x%x\n", len));
423 TI_DBG4(("tdsaProcessCDB: CDB 16 byte, not yet\n"));
424 cdb16 = (CDB16_t *)(cmdIU->cdb);
425 OSSA_READ_BE_32(AGROOT, &len, cdb16->len, 0);
426 TI_DBG4(("tdsaProcessCDB: CDB len 0x%x\n", len));
429 TI_DBG4(("tdsaProcessCDB: unknow CDB, group %d 0x%x\n", group, group));
434 if (cmdIU->cdb[0] == SCSIOPC_READ_6 || cmdIU->cdb[0] == SCSIOPC_READ_10 ||
435 cmdIU->cdb[0] == SCSIOPC_WRITE_6 || cmdIU->cdb[0] == SCSIOPC_WRITE_10 )
437 ttdsaXchg->dataLen = len * Target->OperatingOption.BlockSize;
441 ttdsaXchg->dataLen = len;
444 if (ttdsaXchg->dataLen == 0 && unknown == agFALSE)
446 /* this is needed because of min operation in tiTGTIOstart() */
447 ttdsaXchg->dataLen = 0xffffffff;
449 /* TI_DBG4(("tdsaProcessCDB: datalen 0x%x %d\n", ttdsaXchg->dataLen, ttdsaXchg->dataLen)); */
456 /*****************************************************************************
460 * Purpose: This function is called by the target OS Specific Module to start
461 * the next phase of a SCSI Request.
464 * tiRoot: Pointer to driver Instance.
465 * tiIORequest: Pointer to the I/O request context for this I/O.
466 * This context was initially passed to the OS Specific Module
467 * in ostiProcessScsiReq().
468 * dataOffset: Offset into the buffer space for this phase.
469 * dataLength: Length of data to move for this phase.
470 * dataSGL: Length/Address pair of where the data is. The SGL list is
471 * allocated and initialized by the OS Specific module.
472 * sglVirtualAddr: The virtual address of the first element in agSgl1 when
473 * agSgl1 is used with the type tiSglList.
474 * This field is needed for the TD Layer.
477 * tiSuccess: I/O request successfully initiated.
478 * tiBusy: No resources available, try again later.
479 * tiError: Other errors that prevent the I/O request to be started.
483 *****************************************************************************/
485 tiTGTIOStart( tiRoot_t *tiRoot,
486 tiIORequest_t *tiIORequest,
494 ttdsaXchg_t *ttdsaXchg;
495 agsaSSPTargetRequest_t *agSSPTargetReq;
499 tdsaPortContext_t *onePortContext = agNULL;
500 tdsaDeviceData_t *oneDeviceData = agNULL;
502 TI_DBG4(("tiTGTIOStart: start\n"));
503 TI_DBG4(("tiTGTIOStart: dataLength 0x%x %d\n", dataLength, dataLength));
504 TI_DBG4(("tiTGTIOStart: dataOffset 0x%x %d\n", dataOffset, dataOffset));
506 /* save infor in ttdsaXchg */
507 ttdsaXchg = (ttdsaXchg_t *)tiIORequest->tdData;
509 /* check the state of port */
510 oneDeviceData = ttdsaXchg->DeviceData;
511 onePortContext= oneDeviceData->tdPortContext;
512 if (onePortContext->valid == agFALSE)
514 TI_DBG1(("tiTGTIOStart: portcontext pid %d is invalid\n", onePortContext->id));
520 = &(ttdsaXchg->IORequestBody.transport.SAS.agSASRequestBody.sspTargetReq);
522 /* fills in agsaSASRequestBody_t.agsaSSPTargetRequest_t */
523 agSSPTargetReq->dataLength = (bit32) MIN(dataLength, ttdsaXchg->dataLen);
524 agSSPTargetReq->offset = dataOffset;
525 agSSPTargetReq->agTag = ttdsaXchg->tag;
526 /* SSPTargetReq->agTag has been set in ttdsaSSPReqReceived() */
529 if (ttdsaXchg->TLR == 2)
532 agSSPTargetReq->sspOption = 0;
537 /* bit5: 0 1 11 11 :bit0 */
538 agSSPTargetReq->sspOption = 0x1F;
541 ttdsaXchg->IORequestBody.IOType.TargetIO.TargetIOType.RegIO.sglVirtualAddr
544 if (agSSPTargetReq->dataLength != 0)
546 TI_DBG6(("tiTGTIOStart: pos 1\n"));
547 ttdsaXchg->IORequestBody.IOType.TargetIO.TargetIOType.RegIO.tiSgl1
552 TI_DBG6(("tiTGTIOStart: pos 2\n"));
553 ttdsaXchg->IORequestBody.IOType.TargetIO.TargetIOType.RegIO.tiSgl1.len
555 ttdsaXchg->IORequestBody.IOType.TargetIO.TargetIOType.RegIO.tiSgl1.type
558 /* let's send response frame */
559 if (ttdsaXchg->resp.length != 0)
561 /* senselen != 0, send respsonse */
562 TI_DBG4(("tiTGTIOStart: send respsonse\n"));
563 TI_DBG4(("tiTGTIOStart: resp.length 0x%x\n",
564 ttdsaXchg->resp.length));
565 ttdsaXchg->responseSent = agTRUE;
566 ttdsaXchg->DeviceData->IOResponse++;
567 TD_DEBUG_TRACE(ttdsaXchg, ttdsaXchg->DeviceData);
568 tdStatus = ttdsaSendResp(ttdsaXchg->agRoot, ttdsaXchg);
569 if (tdStatus == AGSA_RC_SUCCESS)
573 else if (tdStatus == AGSA_RC_FAILURE)
575 TI_DBG1(("tiTGTIOStart: (ttdsaSendResp) sending not successful\n"));
580 TI_DBG1(("tiTGTIOStart: (ttdsaSendResp) sending busy\n"));
587 /* sets SSPTargetReq->agSgl */
588 tiStatus = ttdssIOPrepareSGL(tiRoot, &ttdsaXchg->IORequestBody, dataSGL, NULL, sglVirtualAddr);
590 if (tiStatus != tiSuccess)
592 TI_DBG1(("tiTGTIOStart: ttdIOPrepareSGL did not return success\n"));
596 TI_DBG4(("tiTGTIOStart: agroot %p ttdsaXchg %p\n", ttdsaXchg->agRoot, ttdsaXchg));
597 TI_DBG4(("tiTGTIOStart: agDevHanlde %p\n", ttdsaXchg->DeviceData->agDevHandle));
599 if ( (ttdsaXchg->readRspCollapsed == agTRUE) || (ttdsaXchg->wrtRspCollapsed == agTRUE) )
601 /* collapse good response with read */
602 TI_DBG4(("tiTGTIOStart: read rsp collapse\n"));
603 TI_DBG4(("tiTGTIOStart: initiator tag 0x%x\n", ttdsaXchg->tag));
605 TD_XCHG_CONTEXT_NO_START_IO(tiRoot) = TD_XCHG_CONTEXT_NO_START_IO(tiRoot)+1;
606 ttdsaXchg->DeviceData->IOStart++;
607 TD_DEBUG_TRACE(ttdsaXchg, ttdsaXchg->DeviceData);
608 saStatus = saSSPStart(
610 &ttdsaXchg->IORequestBody.agIORequest,
611 tdsaRotateQnumber(tiRoot, oneDeviceData),
612 ttdsaXchg->DeviceData->agDevHandle,
613 ttdsaXchg->readRspCollapsed ? AGSA_SSP_TGT_READ_GOOD_RESP : AGSA_SSP_TGT_WRITE_GOOD_RESP,
614 &ttdsaXchg->IORequestBody.transport.SAS.agSASRequestBody,
621 TI_DBG4(("tiTGTIOStart: normal\n"));
622 TI_DBG4(("tiTGTIOStart: initiator tag 0x%x\n", ttdsaXchg->tag));
623 TD_XCHG_CONTEXT_NO_START_IO(tiRoot) = TD_XCHG_CONTEXT_NO_START_IO(tiRoot)+1;
624 ttdsaXchg->DeviceData->IOStart++;
625 TD_DEBUG_TRACE(ttdsaXchg, ttdsaXchg->DeviceData);
626 saStatus = saSSPStart(
627 ttdsaXchg->agRoot, /* agRoot, */
628 &ttdsaXchg->IORequestBody.agIORequest,
629 tdsaRotateQnumber(tiRoot, oneDeviceData),
630 ttdsaXchg->DeviceData->agDevHandle,
632 &ttdsaXchg->IORequestBody.transport.SAS.agSASRequestBody,
639 if (saStatus == AGSA_RC_SUCCESS)
643 else if (saStatus == AGSA_RC_FAILURE)
645 TI_DBG1(("tiTGTIOStart: sending not successful\n"));
650 TI_DBG1(("tiTGTIOStart: sending busy\n"));
657 /*****************************************************************************
661 * Purpose: This function is called by the target OS Specific Module to start
662 * the next phase of a SCSI Request.
665 * tiRoot: Pointer to driver Instance.
666 * tiIORequest: Pointer to the I/O request context for this I/O.
667 * This context was initially passed to the OS Specific Module
668 * in ostiProcessScsiReq().
669 * dataOffset: Offset into the buffer space for this phase.
670 * dataLength: Length of data to move for this phase.
671 * dataSGL: Length/Address pair of where the data is. The SGL list is
672 * allocated and initialized by the OS Specific module.
673 * sglVirtualAddr: The virtual address of the first element in agSgl1 when
674 * agSgl1 is used with the type tiSglList.
675 * This field is needed for the TD Layer.
676 * difOption: DIF option.
679 * tiSuccess: I/O request successfully initiated.
680 * tiBusy: No resources available, try again later.
681 * tiError: Other errors that prevent the I/O request to be started.
685 *****************************************************************************/
686 osGLOBAL bit32 tiTGTIOStartDif(
688 tiIORequest_t *tiIORequest,
692 void *sglVirtualAddr,
697 /* This function was never used by SAS/SATA. Use tiTGTSuperIOStart() instead. */
705 tdIORequestBody_t *tdIORequestBody,
713 TI_DBG6(("ttdssIOPrepareSGL: start\n"));
715 agSgl = &(tdIORequestBody->transport.SAS.agSASRequestBody.sspTargetReq.agSgl);
719 if (tiSgl1 == agNULL)
721 TI_DBG1(("ttdssIOPrepareSGL: Error tiSgl1 is NULL\n"));
725 agSgl->sgUpper = tiSgl1->upper;
726 agSgl->sgLower = tiSgl1->lower;
727 agSgl->len = tiSgl1->len;
728 agSgl->extReserved = tiSgl1->type;
733 /* temp for debugging */
735 dumpresp(bit8 *resp, bit32 len)
741 TI_DBG4(("resp[%d] 0x%x\n", i, resp[i]));
750 ttdsaXchg_t *ttdsaXchg
753 tdsaRootOsData_t *osData = (tdsaRootOsData_t *)agRoot->osData;
754 tiRoot_t *tiRoot = (tiRoot_t *)osData->tiRoot;
755 tdsaDeviceData_t *oneDeviceData = agNULL;
758 agsaSSPTargetResponse_t *agSSPTargetResp;
759 agRequestType = AGSA_SSP_TGT_CMD_OR_TASK_RSP;
761 TI_DBG4(("ttdsaSendResp: start\n"));
762 TI_DBG4(("ttdsaSendResp: agroot %p ttdsaXchg %p\n", ttdsaXchg->agRoot, ttdsaXchg));
764 TI_DBG4(("ttdsaSendResp:: agDevHanlde %p\n", ttdsaXchg->DeviceData->agDevHandle));
767 TI_DBG4(("ttdsaSendResp: len 0x%x \n",
768 ttdsaXchg->resp.length));
769 TI_DBG4(("ttdsaSendResp: upper 0x%x \n",
770 ttdsaXchg->resp.phyAddrUpper));
771 TI_DBG4(("ttdsaSendResp: lower 0x%x \n",
772 ttdsaXchg->resp.phyAddrLower));
773 TI_DBG4(("ttdsaSendResp: initiator tag 0x%x\n", ttdsaXchg->tag));
775 agSSPTargetResp = &(ttdsaXchg->IORequestBody.transport.SAS.agSASRequestBody.sspTargetResponse);
776 agSSPTargetResp->agTag = ttdsaXchg->tag;
777 agSSPTargetResp->respBufLength = ttdsaXchg->resp.length;
778 agSSPTargetResp->respBufUpper = ttdsaXchg->resp.phyAddrUpper;
779 agSSPTargetResp->respBufLower = ttdsaXchg->resp.phyAddrLower;
780 agSSPTargetResp->respOption = 3; /* Retry on both ACK/NAK timeout and NAK received */
781 /* temporary solution for T2D Combo*/
782 #if defined (INITIATOR_DRIVER) && defined (TARGET_DRIVER)
785 if (agSSPTargetResp->respBufLength <= AGSA_MAX_SSPPAYLOAD_VIA_SFO)
786 agSSPTargetResp->frameBuf = ttdsaXchg->resp.virtAddr;
788 agSSPTargetResp->frameBuf = NULL;
790 dumpresp((bit8 *)ttdsaXchg->resp.virtAddr, ttdsaXchg->resp.length);
792 TD_XCHG_CONTEXT_NO_SEND_RSP(TD_GET_TIROOT(agRoot)) =
793 TD_XCHG_CONTEXT_NO_SEND_RSP(TD_GET_TIROOT(agRoot))+1;
795 oneDeviceData = ttdsaXchg->DeviceData;
796 saStatus = saSSPStart(
797 ttdsaXchg->agRoot, /* agRoot,*/
798 &ttdsaXchg->IORequestBody.agIORequest,
799 tdsaRotateQnumber(tiRoot, oneDeviceData),
800 ttdsaXchg->DeviceData->agDevHandle, /* agDevHandle, */
802 &ttdsaXchg->IORequestBody.transport.SAS.agSASRequestBody,
807 if (saStatus == AGSA_RC_SUCCESS)
809 TI_DBG4(("ttdsaSendResp: sending successful\n"));
810 return AGSA_RC_SUCCESS;
812 else if (saStatus == AGSA_RC_FAILURE)
814 TI_DBG1(("ttdsaSendResp: sending not successful\n"));
815 return AGSA_RC_FAILURE;
819 TI_DBG1(("ttdsaSendResp: sending busy\n"));
828 agsaIORequest_t *agIORequest,
831 agsaFrameHandle_t agFrameHandle,
836 ttdsaXchg_t *ttdsaXchg = (ttdsaXchg_t *)agIORequest->osData;
837 /* done in ttdsaXchgInit() */
838 bit32 IOFailed = agFALSE;
840 bit32 statusDetail = 0;
843 tdsaRoot_t *tdsaRoot;
844 tdsaContext_t *tdsaAllShared;
847 bit32 saStatus = AGSA_RC_FAILURE;
848 #ifdef TD_DEBUG_ENABLE
849 agsaDifDetails_t *DifDetail;
852 TI_DBG4(("ttdsaIOCompleted: start\n"));
853 tiRoot = ((tdsaRootOsData_t *)agRoot->osData)->tiRoot;
855 tdsaRoot = (tdsaRoot_t *) tiRoot->tdData;
856 tdsaAllShared = (tdsaContext_t *)&tdsaRoot->tdsaAllShared;
858 #ifdef TD_DEBUG_ENABLE
859 DifDetail = (agsaDifDetails_t *)agFrameHandle;
862 if (tiRoot == agNULL)
864 TI_DBG1(("ttdsaIOCompleted: tiRoot is NULL\n"));
868 TD_XCHG_CONTEXT_NO_IO_COMPLETED(tiRoot) = TD_XCHG_CONTEXT_NO_IO_COMPLETED(tiRoot)+1;
870 if(TD_XCHG_GET_STATE(ttdsaXchg) != TD_XCHG_STATE_ACTIVE)
872 TI_DBG1(("ttdsaIOCompleted: XCHG is not active *****************\n"));
876 if (ttdsaXchg->isTMRequest != agTRUE)
878 TI_DBG6(("ttdsaIOCompleted: COMMAND \n"));
879 TI_DBG6(("ttdsaIOCompleted: ttdsaXchg %p\n", ttdsaXchg));
880 TI_DBG6(("ttdsaIOCompleted: ttdsaXchg->IORequestBody.EsglPageList %p\n", &ttdsaXchg->IORequestBody.EsglPageList));
881 TI_DBG6(("ttdsaIOCompleted: command initiator tag 0x%x\n", ttdsaXchg->tag));
884 /* call tdsafreeesglpages only for xchg that used eslg */
885 if (ttdsaXchg->usedEsgl == agTRUE)
887 tdsaFreeEsglPages(tiRoot, &ttdsaXchg->IORequestBody.EsglPageList);
888 ttdsaXchg->usedEsgl = agFALSE;
892 /* successful case */
893 if (agIOStatus == OSSA_IO_SUCCESS)
895 TI_DBG6(("ttdsaIOCompleted: osIOSuccess\n"));
896 if ( (ttdsaXchg->readRspCollapsed == agTRUE) || (ttdsaXchg->wrtRspCollapsed == agTRUE) )
898 ttdsaXchg->responseSent = agTRUE;
899 TI_DBG4(("ttdsaIOCompleted: read rsp collapse\n"));
902 if (ttdsaXchg->statusSent == agTRUE)
905 the response has already been set and ready
906 but has NOT been sent
908 if (ttdsaXchg->responseSent == agFALSE)
910 /* let's send the response for IO */
911 TI_DBG6(("ttdsaIOCompleted: sending response\n"));
912 TD_DEBUG_TRACE(ttdsaXchg, ttdsaXchg->DeviceData);
913 tdStatus = ttdsaSendResp(agRoot, ttdsaXchg);
914 if (tdStatus != AGSA_RC_SUCCESS)
916 TI_DBG1(("ttdsaIOCompleted: attention needed\n"));
919 ttdsaXchg->responseSent = agTRUE;
923 TI_DBG4(("ttdsaIOCompleted: read rsp collapse and complete \n"));
924 /* the response has been sent */
925 TI_DBG6(("ttdsaIOCompleted: already sent response, notify OS\n"));
927 if (TD_XCHG_GET_STATE(ttdsaXchg) == TD_XCHG_STATE_INACTIVE)
929 TI_DBG1(("ttdsaIOCompleted: wrong DEQUEUE_THIS\n"));
933 * Notify the OS Specific Module, so it can free its resource.
935 TI_DBG4(("ttdsaIOCompleted: calling ostiTargetIOCompleted\n"));
936 ostiTargetIOCompleted( tiRoot,
937 ttdsaXchg->IORequestBody.tiIORequest,
940 /* clean up resources */
941 ttdsaXchgFreeStruct(tiRoot,ttdsaXchg);
946 TI_DBG4(("ttdsaIOCompleted: osIOSuccess: nextphase\n"));
947 /* the response has not been set; still in data phase */
948 /* we need to tell the disk module to start the next phase */
949 ostiNextDataPhase(ttdsaXchg->tiRoot,
950 ttdsaXchg->IORequestBody.tiIORequest );
955 /* handle error cases */
956 if (agIOStatus == OSSA_IO_XFR_ERROR_DIF_APPLICATION_TAG_MISMATCH || agIOStatus == OSSA_IO_XFR_ERROR_DIF_REFERENCE_TAG_MISMATCH
957 || agIOStatus == OSSA_IO_XFR_ERROR_DIF_CRC_MISMATCH)
959 TI_DBG1(("ttdsaIOCompleted: DIF detail UpperLBA 0x%08x LowerLBA 0x%08x\n", DifDetail->UpperLBA, DifDetail->LowerLBA));
963 case OSSA_IO_ABORTED:
964 TI_DBG1(("ttdsaIOCompleted: ABORTED\n"));
966 statusDetail = tiDetailAborted;
970 case OSSA_IO_OVERFLOW:
971 TI_DBG1(("ttdsaIOCompleted: OVERFLOW\n"));
972 status = tiIOOverRun;
976 case OSSA_IO_UNDERFLOW:
977 TI_DBG1(("ttdsaIOCompleted: UNDERFLOW\n"));
978 status = tiIOUnderRun;
981 case OSSA_IO_ABORT_RESET:
982 TI_DBG1(("ttdsaIOCompleted: ABORT_RESET\n"));
984 statusDetail = tiDetailAbortReset;
987 case OSSA_IO_XFR_ERROR_DEK_KEY_CACHE_MISS:
988 TI_DBG1(("ttdsaIOCompleted: OSSA_IO_XFR_ERROR_DEK_KEY_CACHE_MISS\n"));
989 status = tiIOEncryptError;
990 statusDetail = tiDetailDekKeyCacheMiss;
993 case OSSA_IO_XFR_ERROR_DEK_KEY_TAG_MISMATCH:
994 TI_DBG1(("ttdsaIOCompleted: OSSA_IO_XFR_ERROR_DEK_KEY_TAG_MISMATCH\n"));
995 status = tiIOEncryptError;
996 statusDetail = tiDetailDekKeyCacheMiss;
999 case OSSA_IO_XFR_ERROR_DIF_APPLICATION_TAG_MISMATCH:
1000 TI_DBG1(("ttdsaIOCompleted: OSSA_IO_XFR_ERROR_DIF_APPLICATION_TAG_MISMATCH\n"));
1001 status = tiIODifError;
1002 statusDetail = tiDetailDifAppTagMismatch;
1005 case OSSA_IO_XFR_ERROR_DIF_REFERENCE_TAG_MISMATCH:
1006 TI_DBG1(("ttdsaIOCompleted: OSSA_IO_XFR_ERROR_DIF_REFERENCE_TAG_MISMATCH\n"));
1007 status = tiIODifError;
1008 statusDetail = tiDetailDifRefTagMismatch;
1011 case OSSA_IO_XFR_ERROR_DIF_CRC_MISMATCH:
1012 TI_DBG1(("ttdsaIOCompleted: OSSA_IO_XFR_ERROR_DIF_CRC_MISMATCH\n"));
1013 status = tiIODifError;
1014 statusDetail = tiDetailDifCrcMismatch;
1017 case OSSA_IO_FAILED: /* fall through */
1018 case OSSA_IO_NO_DEVICE: /* fall through */
1019 //case OSSA_IO_NO_SUPPORT: /* fall through */ /*added to compile tgt_drv (TP)*/
1020 case OSSA_IO_LINK_FAILURE: /* fall through */
1021 case OSSA_IO_PROG_ERROR: /* fall through */
1022 case OSSA_IO_DS_NON_OPERATIONAL: /* fall through */
1023 case OSSA_IO_DS_IN_RECOVERY: /* fall through */
1024 case OSSA_IO_TM_TAG_NOT_FOUND: /* fall through */
1025 case OSSA_MPI_ERR_IO_RESOURCE_UNAVAILABLE: /* fall through */
1027 status = tiIOFailed;
1028 statusDetail = tiDetailOtherError;
1030 TI_DBG1(("ttdsaIOCompleted: Fail!!!!!!! agIOStatus=0x%x agIOInfoLen=0x%x agOtherInfo=0x%x\n", agIOStatus, agIOInfoLen, agOtherInfo));
1031 // ttdsaDumpallXchg(tiRoot);
1032 if (agIOStatus == OSSA_IO_XFER_OPEN_RETRY_TIMEOUT)
1034 TI_DBG1(("ttdsaIOCompleted: OSSA_IO_XFER_OPEN_RETRY_TIMEOUT ttdsaXchg->id 0x%x datalen 0x%x offset 0x%x agTag 0x%x\n",
1036 ttdsaXchg->IORequestBody.transport.SAS.agSASRequestBody.sspTargetReq.dataLength,
1037 ttdsaXchg->IORequestBody.transport.SAS.agSASRequestBody.sspTargetReq.offset,
1038 ttdsaXchg->IORequestBody.transport.SAS.agSASRequestBody.sspTargetReq.agTag));
1039 TI_DBG1(("ttdsaIOCompleted: statusSent %d responseSent %d\n", ttdsaXchg->statusSent, ttdsaXchg->responseSent));
1045 if (IOFailed == agTRUE)
1047 if (agIORequest->sdkData == agNULL)
1049 tiIORequest_t tiIORequest;
1050 TI_DBG1(("ttdsaIOCompleted: ERROR ttdsaXchg=%p agIOStatus= 0x%x\n",
1053 TI_DBG1(("CDB= 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x\n",
1054 ttdsaXchg->agSSPCmndIU.cdb[0],
1055 ttdsaXchg->agSSPCmndIU.cdb[1],
1056 ttdsaXchg->agSSPCmndIU.cdb[2],
1057 ttdsaXchg->agSSPCmndIU.cdb[3],
1058 ttdsaXchg->agSSPCmndIU.cdb[4],
1059 ttdsaXchg->agSSPCmndIU.cdb[5],
1060 ttdsaXchg->agSSPCmndIU.cdb[6],
1061 ttdsaXchg->agSSPCmndIU.cdb[7],
1062 ttdsaXchg->agSSPCmndIU.cdb[8],
1063 ttdsaXchg->agSSPCmndIU.cdb[9],
1064 ttdsaXchg->agSSPCmndIU.cdb[10],
1065 ttdsaXchg->agSSPCmndIU.cdb[11],
1066 ttdsaXchg->agSSPCmndIU.cdb[12],
1067 ttdsaXchg->agSSPCmndIU.cdb[13],
1068 ttdsaXchg->agSSPCmndIU.cdb[14],
1069 ttdsaXchg->agSSPCmndIU.cdb[15] ));
1071 if (TD_XCHG_GET_STATE(ttdsaXchg) == TD_XCHG_STATE_INACTIVE)
1073 TI_DBG1(("ttdsaIOCompleted: wrong DEQUEUE_THIS 1\n"));
1075 if (ttdsaXchg->retries <= OPEN_RETRY_RETRIES && agIOStatus == OSSA_IO_XFER_OPEN_RETRY_TIMEOUT)
1077 TI_DBG2(("ttdsaIOCompleted: 1 loc retries on OSSA_IO_XFER_OPEN_RETRY_TIMEOUT\n"));
1078 if ( (agOtherInfo & 0x1) == 1)
1080 /* repsonse phase */
1081 TI_DBG2(("ttdsaIOCompleted: 0 loc response retry\n"));
1082 /* repsonse retry */
1083 saStatus = ttdsaSendResp(ttdsaXchg->agRoot, ttdsaXchg);
1084 if (saStatus == AGSA_RC_SUCCESS)
1086 TI_DBG2(("ttdsaIOCompleted: 0 loc retried\n"));
1087 ttdsaXchg->retries++;
1091 TI_DBG1(("ttdsaIOCompleted: 0 loc retry failed\n"));
1092 ttdsaXchg->retries = 0;
1094 * because we are freeing up the exchange
1095 * we must let the oslayer know that
1096 * we are releasing the resources by
1097 * setting the tdData to NULL
1099 tiIORequest = ttdsaXchg->IORequestBody.IOType.TargetIO.tiIORequest;
1100 tiIORequest.tdData = agNULL;
1109 /* clean up resources */
1110 ttdsaXchgFreeStruct(tiRoot,ttdsaXchg);
1113 else if ( (ttdsaXchg->readRspCollapsed == agTRUE) || (ttdsaXchg->wrtRspCollapsed == agTRUE) )
1115 saStatus = saSSPStart(
1116 ttdsaXchg->agRoot, /* agRoot, */
1117 &ttdsaXchg->IORequestBody.agIORequest,
1119 ttdsaXchg->DeviceData->agDevHandle, /* agDevHandle, */
1120 ttdsaXchg->readRspCollapsed ? AGSA_SSP_TGT_READ_GOOD_RESP : AGSA_SSP_TGT_WRITE_GOOD_RESP,
1121 &ttdsaXchg->IORequestBody.transport.SAS.agSASRequestBody,
1125 if (saStatus == AGSA_RC_SUCCESS)
1127 TI_DBG1(("ttdsaIOCompleted: 1 loc retried\n"));
1128 ttdsaXchg->retries++;
1132 TI_DBG1(("ttdsaIOCompleted: 1 loc retry failed\n"));
1133 ttdsaXchg->retries = 0;
1135 * because we are freeing up the exchange
1136 * we must let the oslayer know that
1137 * we are releasing the resources by
1138 * setting the tdData to NULL
1140 tiIORequest = ttdsaXchg->IORequestBody.IOType.TargetIO.tiIORequest;
1141 tiIORequest.tdData = agNULL;
1150 /* clean up resources */
1151 ttdsaXchgFreeStruct(tiRoot,ttdsaXchg);
1156 if (ttdsaXchg->responseSent == agFALSE)
1158 saStatus = saSSPStart(
1159 ttdsaXchg->agRoot, /* agRoot, */
1160 &ttdsaXchg->IORequestBody.agIORequest, /*agIORequest, */
1161 0, /* queue number */
1162 ttdsaXchg->DeviceData->agDevHandle, /* agDevHandle, */
1164 &ttdsaXchg->IORequestBody.transport.SAS.agSASRequestBody,
1171 /* repsonse retry */
1172 TI_DBG1(("ttdsaIOCompleted: 2 loc reponse retry\n"));
1173 saStatus = ttdsaSendResp(ttdsaXchg->agRoot, ttdsaXchg);
1175 if (saStatus == AGSA_RC_SUCCESS)
1177 TI_DBG1(("ttdsaIOCompleted: 2 loc retried\n"));
1178 ttdsaXchg->retries++;
1182 TI_DBG1(("ttdsaIOCompleted: 2 loc retry failed\n"));
1183 ttdsaXchg->retries = 0;
1185 * because we are freeing up the exchange
1186 * we must let the oslayer know that
1187 * we are releasing the resources by
1188 * setting the tdData to NULL
1190 tiIORequest = ttdsaXchg->IORequestBody.IOType.TargetIO.tiIORequest;
1191 tiIORequest.tdData = agNULL;
1200 /* clean up resources */
1201 ttdsaXchgFreeStruct(tiRoot,ttdsaXchg);
1207 ttdsaXchg->retries = 0;
1209 * because we are freeing up the exchange
1210 * we must let the oslayer know that
1211 * we are releasing the resources by
1212 * setting the tdData to NULL
1214 tiIORequest = ttdsaXchg->IORequestBody.IOType.TargetIO.tiIORequest;
1215 tiIORequest.tdData = agNULL;
1224 /* clean up resources */
1225 ttdsaXchgFreeStruct(tiRoot,ttdsaXchg);
1227 } /* saData == agNULL */
1230 tiIORequest_t tiIORequest;
1232 TI_DBG1(("ttdsaIOCompleted: 2\n"));
1233 if (TD_XCHG_GET_STATE(ttdsaXchg) == TD_XCHG_STATE_INACTIVE)
1235 TI_DBG1(("ttdsaIOCompleted: wrong DEQUEUE_THIS 2\n"));
1237 if (ttdsaXchg->retries <= OPEN_RETRY_RETRIES && agIOStatus == OSSA_IO_XFER_OPEN_RETRY_TIMEOUT)
1239 TI_DBG1(("ttdsaIOCompleted: 2 loc retries on OSSA_IO_XFER_OPEN_RETRY_TIMEOUT\n"));
1240 if ( (agOtherInfo & 0x1) == 1)
1242 /* repsonse phase */
1243 TI_DBG2(("ttdsaIOCompleted: 0 loc response retry\n"));
1244 /* repsonse retry */
1245 saStatus = ttdsaSendResp(ttdsaXchg->agRoot, ttdsaXchg);
1246 if (saStatus == AGSA_RC_SUCCESS)
1248 TI_DBG2(("ttdsaIOCompleted: 0 loc retried\n"));
1249 ttdsaXchg->retries++;
1253 TI_DBG1(("ttdsaIOCompleted: 0 loc retry failed\n"));
1254 ttdsaXchg->retries = 0;
1256 * because we are freeing up the exchange
1257 * we must let the oslayer know that
1258 * we are releasing the resources by
1259 * setting the tdData to NULL
1261 tiIORequest = ttdsaXchg->IORequestBody.IOType.TargetIO.tiIORequest;
1262 tiIORequest.tdData = agNULL;
1271 /* clean up resources */
1272 ttdsaXchgFreeStruct(tiRoot,ttdsaXchg);
1275 else if ( (ttdsaXchg->readRspCollapsed == agTRUE) || (ttdsaXchg->wrtRspCollapsed == agTRUE) )
1277 saStatus = saSSPStart(
1278 ttdsaXchg->agRoot, /* agRoot, */
1279 &ttdsaXchg->IORequestBody.agIORequest, /* agIORequest, */
1280 0, /* queue number */
1281 ttdsaXchg->DeviceData->agDevHandle, /* agDevHandle, */
1282 ttdsaXchg->readRspCollapsed ? AGSA_SSP_TGT_READ_GOOD_RESP : AGSA_SSP_TGT_WRITE_GOOD_RESP,
1283 &ttdsaXchg->IORequestBody.transport.SAS.agSASRequestBody,
1287 if (saStatus == AGSA_RC_SUCCESS)
1289 TI_DBG1(("ttdsaIOCompleted: 1 loc retried\n"));
1290 ttdsaXchg->retries++;
1294 TI_DBG1(("ttdsaIOCompleted: 1 loc retry failed\n"));
1295 ttdsaXchg->retries = 0;
1297 * because we are freeing up the exchange
1298 * we must let the oslayer know that
1299 * we are releasing the resources by
1300 * setting the tdData to NULL
1302 tiIORequest = ttdsaXchg->IORequestBody.IOType.TargetIO.tiIORequest;
1303 tiIORequest.tdData = agNULL;
1312 /* clean up resources */
1313 ttdsaXchgFreeStruct(tiRoot,ttdsaXchg);
1318 TI_DBG1(("ttdsaIOCompleted: 2 loc ttdsaXchg->id 0x%x datalen 0x%x offset 0x%x agTag 0x%x\n",
1320 ttdsaXchg->IORequestBody.transport.SAS.agSASRequestBody.sspTargetReq.dataLength,
1321 ttdsaXchg->IORequestBody.transport.SAS.agSASRequestBody.sspTargetReq.offset,
1322 ttdsaXchg->IORequestBody.transport.SAS.agSASRequestBody.sspTargetReq.agTag));
1323 if (ttdsaXchg->responseSent == agFALSE)
1325 saStatus = saSSPStart(
1326 ttdsaXchg->agRoot, /* agRoot, */
1327 &ttdsaXchg->IORequestBody.agIORequest, /* agIORequest, */
1328 0, /* queue number */
1329 ttdsaXchg->DeviceData->agDevHandle, /* agDevHandle, */
1331 &ttdsaXchg->IORequestBody.transport.SAS.agSASRequestBody,
1338 TI_DBG1(("ttdsaIOCompleted: 2 loc response retry\n"));
1339 /* repsonse retry */
1340 saStatus = ttdsaSendResp(ttdsaXchg->agRoot, ttdsaXchg);
1342 if (saStatus == AGSA_RC_SUCCESS)
1344 TI_DBG1(("ttdsaIOCompleted: 2 loc retried\n"));
1345 ttdsaXchg->retries++;
1349 TI_DBG1(("ttdsaIOCompleted: 2 loc retry failed\n"));
1350 ttdsaXchg->retries = 0;
1352 * because we are freeing up the exchange
1353 * we must let the oslayer know that
1354 * we are releasing the resources by
1355 * setting the tdData to NULL
1357 tiIORequest = ttdsaXchg->IORequestBody.IOType.TargetIO.tiIORequest;
1358 tiIORequest.tdData = agNULL;
1367 /* clean up resources */
1368 ttdsaXchgFreeStruct(tiRoot,ttdsaXchg);
1374 TI_DBG1(("ttdsaIOCompleted: retry is over\n"));
1375 ttdsaXchg->retries = 0;
1377 tiIORequest = ttdsaXchg->IORequestBody.IOType.TargetIO.tiIORequest;
1378 tiIORequest.tdData = agNULL;
1387 /* clean up resources */
1388 ttdsaXchgFreeStruct(tiRoot,ttdsaXchg);
1390 } /* saData != agNULL */
1391 }/* if (IOFailed == agTRUE) */
1392 } /* not TMrequest */
1393 else /* TMrequest */
1395 TI_DBG1(("ttdsaIOCompleted: TM request\n"));
1396 TI_DBG1(("ttdsaIOCompleted: TM initiator tag 0x%x\n", ttdsaXchg->tag));
1400 case OSSA_IO_SUCCESS:
1401 TI_DBG1(("ttdsaIOCompleted: success\n"));
1402 status = tiIOSuccess;
1404 case OSSA_IO_ABORTED:
1405 TI_DBG1(("ttdsaIOCompleted: ABORTED\n"));
1406 status = tiIOFailed;
1407 statusDetail = tiDetailAborted;
1410 case OSSA_IO_ABORT_RESET:
1411 TI_DBG1(("ttdsaIOCompleted: ABORT_RESET\n"));
1412 status = tiIOFailed;
1413 statusDetail = tiDetailAbortReset;
1417 case OSSA_IO_OVERFLOW: /* fall through */
1419 case OSSA_IO_UNDERFLOW: /* fall through */
1420 case OSSA_IO_FAILED: /* fall through */
1422 case OSSA_IO_NOT_VALID: /* fall through */
1424 case OSSA_IO_NO_DEVICE: /* fall through */
1425 //case OSSA_IO_NO_SUPPORT: /* fall through */ /*added to compile tgt_drv (TP)*/
1426 case OSSA_IO_LINK_FAILURE: /* fall through */
1427 case OSSA_IO_PROG_ERROR: /* fall through */
1428 case OSSA_IO_DS_NON_OPERATIONAL: /* fall through */
1429 case OSSA_IO_DS_IN_RECOVERY: /* fall through */
1430 case OSSA_IO_TM_TAG_NOT_FOUND: /* fall through */
1431 case OSSA_MPI_ERR_IO_RESOURCE_UNAVAILABLE: /* fall through */
1433 status = tiIOFailed;
1434 statusDetail = tiDetailOtherError;
1439 /* for not found IO, we don't call OS */
1440 if (ttdsaXchg->io_found == agTRUE)
1442 ostiTargetTmCompleted(
1444 ttdsaXchg->IORequestBody.tiIORequest,
1450 /* clean up resources */
1451 ttdsaXchgFreeStruct(tiRoot, ttdsaXchg);
1461 ttdsaXchg_t *ttdsaXchg
1464 tdsaRoot_t *tdsaRoot = (tdsaRoot_t *) tiRoot->tdData;
1465 tdsaContext_t *tdsaAllShared = (tdsaContext_t *)&tdsaRoot->tdsaAllShared;
1467 ttdsaTgt_t *Target = (ttdsaTgt_t *)tdsaAllShared->ttdsaTgt;
1468 agsaSSPScsiTaskMgntReq_t *agTMIU;
1471 tiIORequest_t *reftiIORequest = agNULL;
1473 bit32 IOFound = agFALSE;
1474 ttdsaXchg_t *tmp_ttdsaXchg = agNULL;
1475 agsaRoot_t *agRoot = (agsaRoot_t *)&(tdsaAllShared->agRootNonInt);
1476 agsaIORequest_t *agIORequest = agNULL;
1477 agsaIORequest_t *agIOAbortRequest = agNULL;
1478 tdsaDeviceData_t *oneDeviceData = agNULL;
1479 agsaDevHandle_t *agDevHandle = agNULL;
1481 TI_DBG1(("ttdsaTMProcess: start\n"));
1483 ttdsaXchg->isTMRequest = agTRUE;
1485 agTMIU = (agsaSSPScsiTaskMgntReq_t *)&(ttdsaXchg->agTMIU);
1486 TMFun = agTMIU->taskMgntFunction;
1490 case AGSA_ABORT_TASK:
1491 TI_DBG1(("ttdsaTMProcess: ABORT_TASK\n"));
1492 tiTMFun = AG_ABORT_TASK;
1494 case AGSA_ABORT_TASK_SET:
1495 TI_DBG1(("ttdsaTMProcess: ABORT_TASK_SET\n"));
1496 tiTMFun = AG_ABORT_TASK_SET;
1498 case AGSA_CLEAR_TASK_SET:
1499 TI_DBG1(("ttdsaTMProcess: CLEAR_TASK_SET\n"));
1500 tiTMFun = AG_CLEAR_TASK_SET;
1502 case AGSA_LOGICAL_UNIT_RESET:
1503 TI_DBG1(("ttdsaTMProcess: LOGICAL_UNIT_RESET\n"));
1504 tiTMFun = AG_LOGICAL_UNIT_RESET;
1506 case AGSA_CLEAR_ACA:
1507 TI_DBG1(("ttdsaTMProcess: CLEAR_ACA\n"));
1508 tiTMFun = AG_CLEAR_ACA;
1510 case AGSA_QUERY_TASK:
1511 TI_DBG1(("ttdsaTMProcess: QUERY_TASK\n"));
1512 tiTMFun = AG_QUERY_TASK;
1515 TI_DBG1(("ttdsaTMProcess: RESERVED TM 0x%x %d\n", TMFun, TMFun));
1516 tiTMFun = 0xff; /* unknown task management request */
1521 * Give the OS Specific module to apply it's Task management policy.
1526 osGLOBAL void ostiTaskManagement (
1530 tiIORequest_t *refTiIORequest,
1531 tiIORequest_t *tiTMRequest,
1532 tiDeviceHandle_t *tiDeviceHandle);
1534 if (TMFun == AGSA_ABORT_TASK)
1536 TI_DBG1(("ttdsaTMProcess: if abort task; to be tested \n"));
1538 needs to find a reftIIORequest and set it
1541 IOList = Target->ttdsaXchgData.xchgBusyList.flink;
1544 /* search through the current IOList */
1545 while (IOList != &Target->ttdsaXchgData.xchgBusyList)
1548 tmp_ttdsaXchg = TDLIST_OBJECT_BASE(ttdsaXchg_t, XchgLinks, IOList);
1549 if (tmp_ttdsaXchg->tag == agTMIU->tagOfTaskToBeManaged)
1551 TI_DBG1(("ttdsaTMProcess: tag 0x%x\n",tmp_ttdsaXchg->tag));
1555 IOList = IOList->flink;
1558 if (IOFound == agTRUE)
1561 TI_DBG1(("ttdsaTMProcess: found \n"));
1562 /* call saSSPAbort() */
1564 TI_DBG1(("ttdsaTMProcess: loc 1\n"));
1565 /* abort taskmanagement itself */
1566 agIOAbortRequest = (agsaIORequest_t *)&(ttdsaXchg->IORequestBody.agIORequest);
1568 /* IO to be aborted */
1569 agIORequest = (agsaIORequest_t *)&(tmp_ttdsaXchg->IORequestBody.agIORequest);
1570 oneDeviceData = tmp_ttdsaXchg->DeviceData;
1571 agDevHandle = oneDeviceData->agDevHandle;
1573 if (agIORequest == agNULL)
1575 TI_DBG1(("ttdsaTMProcess: agIORequest is NULL\n"));
1579 TI_DBG1(("ttdsaTMProcess: agIORequest is NOT NULL\n"));
1580 if (agIORequest->sdkData == agNULL)
1582 TI_DBG1(("ttdsaTMProcess: agIORequest->saData is NULL\n"));
1586 TI_DBG1(("ttdsaTMProcess: agIORequest->saData is NOT NULL\n"));
1588 saSSPAbort(agRoot, agIORequest);
1590 saSSPAbort(agRoot, agIOAbortRequest,0,agDevHandle,0,agIORequest, agNULL);
1598 ttdsaXchg->io_found = agFALSE;
1599 tiTGTSendTmResp(tiRoot,
1600 ttdsaXchg->IORequestBody.tiIORequest,
1601 tiError /* this is FUNCTION_FAILED */ );
1602 TI_DBG1(("ttdsaTMProcess: ABORT_TASK not found\n"));
1608 reftiIORequest: referred IO request.
1609 If found, not null. But not used in ramdisk
1611 TI_DBG1(("ttdsaTMProcess: calling ostiTaskManagement\n"));
1615 ttdsaXchg->agTMIU.lun,
1617 ttdsaXchg->IORequestBody.tiIORequest,
1618 &ttdsaXchg->DeviceData->tiDeviceHandle
1626 /*****************************************************************************
1630 * Purpose: This function is called to abort an IO previously reported
1631 * to oslayer through ostiProcessRequest() function.
1634 * tiRoot: Pointer to driver Instance.
1635 * tiIORequest: Pointer to the I/O request context for this I/O.
1636 * This context was initially passed to the OS Specific
1637 * Module in ostiProcessScsiReq().
1639 * tiSuccess: Abort request was successfully initiated
1640 * tiBusy: No resources available, try again later
1641 * tiError: Other errors that prevent the abort request from being
1645 *****************************************************************************/
1649 tiIORequest_t *taskTag
1652 ttdsaXchg_t *ttdsaXchg;
1653 ttdsaXchg_t *ttdsaIOAbortXchg;
1654 tdsaRoot_t *tdsaRoot = (tdsaRoot_t *) tiRoot->tdData;
1655 tdsaContext_t *tdsaAllShared = (tdsaContext_t *)&tdsaRoot->tdsaAllShared;
1656 agsaRoot_t *agRoot = (agsaRoot_t *)&(tdsaAllShared->agRootNonInt);
1657 agsaIORequest_t *agIORequest = agNULL;
1658 agsaIORequest_t *agIOAbortRequest = agNULL;
1659 tdsaDeviceData_t *oneDeviceData = agNULL;
1660 agsaDevHandle_t *agDevHandle = agNULL;
1662 TI_DBG1(("tiTGTIOAbort: start\n"));
1664 ttdsaXchg = (ttdsaXchg_t *)taskTag->tdData;
1666 if (ttdsaXchg == agNULL)
1668 TI_DBG1(("tiTGTIOAbort: IOError 1 \n"));
1670 * this exchange has already been freed.
1671 * No need to free it
1680 else if (ttdsaXchg->IORequestBody.agIORequest.sdkData == agNULL)
1682 TI_DBG1(("tiTGTIOAbort: IOError 2 \n"));
1683 /* We have not issued this IO to the salayer.
1684 * Abort it right here.
1686 if (TD_XCHG_GET_STATE(ttdsaXchg) == TD_XCHG_STATE_INACTIVE)
1688 TI_DBG1(("tiTGTIOAbort: wrong DEQUEUE_THIS\n"));
1691 TI_DBG1(("tiTGTIOAbort: IOError 3\n"));
1699 TI_DBG1(("tiTGTIOAbort: IOError 4\n"));
1701 ttdsaXchgFreeStruct(
1705 TI_DBG1(("tiTGTIOAbort: IOError 5\n"));
1708 else /* to be tested */
1710 TI_DBG1(("tiTGTIOAbort: aborting; to be tested \n"));
1711 /* abort io request itself */
1712 ttdsaIOAbortXchg = ttdsaXchgGetStruct(agRoot);
1714 if (ttdsaIOAbortXchg == agNULL)
1716 TI_DBG1(("tiTGTIOAbort: no free xchg structures\n"));
1717 // ttdsaDumpallXchg(tiRoot);
1720 ttdsaIOAbortXchg->agRoot = agRoot;
1721 ttdsaIOAbortXchg->tiRoot = tiRoot;
1722 agIOAbortRequest= &(ttdsaXchg->IORequestBody.agIORequest);
1723 /* remember IO to be aborted */
1724 ttdsaIOAbortXchg->tiIOToBeAbortedRequest = taskTag;
1725 ttdsaIOAbortXchg->XchgToBeAborted = ttdsaXchg;
1727 // ttdsaIOAbortXchg->FrameType = SAS_TM;
1729 /* io is being aborted */
1730 ttdsaXchg->oslayerAborting = agTRUE;
1731 agIORequest = (agsaIORequest_t *)&(ttdsaXchg->IORequestBody.agIORequest);
1732 oneDeviceData = ttdsaXchg->DeviceData;
1733 if (oneDeviceData == agNULL)
1735 TI_DBG1(("tiTGTIOAbort: oneDeviceData is null; wrong\n"));
1739 agDevHandle = oneDeviceData->agDevHandle;
1740 ttdsaIOAbortXchg->DeviceData = oneDeviceData;
1743 saSSPAbort(agRoot, agIORequest);
1745 saSSPAbort(agRoot, agIOAbortRequest,0,agDevHandle,0,agIORequest, agNULL);
1754 tiDeviceHandle_t *tiDeviceHandle
1757 agsaRoot_t *agRoot = agNULL;
1758 tdsaDeviceData_t *oneDeviceData = agNULL;
1759 bit32 status = tiError;
1761 TI_DBG3(("tiTGTIOAbortAll: start\n"));
1763 oneDeviceData = (tdsaDeviceData_t *)tiDeviceHandle->tdData;
1765 if (oneDeviceData == agNULL)
1767 TI_DBG1(("tiTGTIOAbortAll: oneDeviceData is NULL!!!\n"));
1772 if (oneDeviceData->valid != agTRUE || oneDeviceData->registered != agTRUE ||
1773 oneDeviceData->tdPortContext == agNULL )
1775 TI_DBG1(("tiTGTIOAbortAll: NO Device did %d\n", oneDeviceData->id ));
1776 TI_DBG1(("tiTGTIOAbortAll: device AddrHi 0x%08x\n", oneDeviceData->SASAddressID.sasAddressHi));
1777 TI_DBG1(("tiTGTIOAbortAll: device AddrLo 0x%08x\n", oneDeviceData->SASAddressID.sasAddressLo));
1781 agRoot = oneDeviceData->agRoot;
1783 if (agRoot == agNULL)
1785 TI_DBG1(("tiTGTIOAbortAll: agRoot is NULL!!!\n"));
1789 /* this is processed in ossaSSPAbortCB, ossaSATAAbortCB, ossaSMPAbortCB */
1790 oneDeviceData->OSAbortAll = agTRUE;
1792 status = tdsaAbortAll(tiRoot, agRoot, oneDeviceData);
1799 /*****************************************************************************
1803 * Purpose: This function is called to abort an IO previously reported
1804 * to oslayer through ostiProcessRequest() function.
1807 * tiRoot: Pointer to driver Instance.
1808 * tiIORequest: Pointer to the I/O request context for this I/O.
1809 * This context was initially passed to the OS Specific
1810 * Module in ostiProcessScsiReq().
1812 * tiSuccess: Abort request was successfully initiated
1813 * tiBusy: No resources available, try again later
1814 * tiError: Other errors that prevent the abort request from being
1818 *****************************************************************************/
1822 tiIORequest_t *tiTMRequest,
1826 ttdsaXchg_t *ttdsaXchg;
1827 sas_resp_t *SASResp;
1829 TI_DBG1(("tiTGTSendTmResp: start 1\n"));
1831 ttdsaXchg = (ttdsaXchg_t *)tiTMRequest->tdData;
1832 /* set the response and send it */
1833 /* response status is 0 */
1834 /* status is TM status */
1836 TI_DBG1(("tiTGTSendTmResp: start 2\n"));
1837 SASResp = (sas_resp_t *)ttdsaXchg->resp.virtAddr;
1838 TI_DBG1(("tiTGTSendTmResp: start 3\n"));
1840 if (ttdsaXchg->FrameType == SAS_TM)
1842 SASResp->agResp.status = 0;
1843 SASResp->agResp.dataPres = RESPONSE_DATA;
1844 OSSA_WRITE_BE_32(agRoot, SASResp->agResp.responsedataLen, 0, RESPONSE_DATA_LEN);
1845 OSSA_WRITE_BE_32(agRoot, SASResp->agResp.senseDataLen, 0, 0);
1849 TI_DBG2(("tiTGTSendTmResp: tiSuccess\n"));
1850 SASResp->RespData[3] = AGSA_TASK_MANAGEMENT_FUNCTION_SUCCEEDED;
1853 TI_DBG1(("tiTGTSendTmResp: tiError\n"));
1854 SASResp->RespData[3] = AGSA_TASK_MANAGEMENT_FUNCTION_FAILED;
1857 TI_DBG1(("tiTGTSendTmResp: tibusy\n"));
1858 SASResp->RespData[3] = AGSA_TASK_MANAGEMENT_FUNCTION_FAILED;
1861 TI_DBG1(("tiTGTSendTmResp: tiionodevicee\n"));
1862 SASResp->RespData[3] = AGSA_TASK_MANAGEMENT_FUNCTION_FAILED;
1864 case tiMemoryTooLarge:
1865 TI_DBG1(("tiTGTSendTmResp: timemorytoolarge\n"));
1866 SASResp->RespData[3] = AGSA_TASK_MANAGEMENT_FUNCTION_FAILED;
1868 case tiMemoryNotAvail:
1869 TI_DBG1(("tiTGTSendTmResp: timemorynotavail\n"));
1870 SASResp->RespData[3] = AGSA_TASK_MANAGEMENT_FUNCTION_FAILED;
1872 case tiInvalidHandle:
1873 TI_DBG1(("tiTGTSendTmResp: tiinvalidhandle\n"));
1874 SASResp->RespData[3] = AGSA_TASK_MANAGEMENT_FUNCTION_FAILED;
1876 case tiNotSupported:
1877 TI_DBG1(("tiTGTSendTmResp: tiNotsupported\n"));
1878 SASResp->RespData[3] = AGSA_TASK_MANAGEMENT_FUNCTION_NOT_SUPPORTED;
1881 TI_DBG1(("tiTGTSendTmResp: tireject\n"));
1882 SASResp->RespData[3] = AGSA_TASK_MANAGEMENT_FUNCTION_FAILED;
1884 case tiIncorrectLun:
1885 TI_DBG1(("tiTGTSendTmResp: tiincorrectlun\n"));
1886 SASResp->RespData[3] = AGSA_INCORRECT_LOGICAL_UNIT_NUMBER;
1889 TI_DBG1(("tiTGTSendTmResp: default\n"));
1890 SASResp->RespData[3] = AGSA_TASK_MANAGEMENT_FUNCTION_FAILED;
1893 ttdsaXchg->resp.length = sizeof(agsaSSPResponseInfoUnit_t) + RESPONSE_DATA_LEN;
1894 ttdsaXchg->statusSent = agTRUE;
1898 TI_DBG1(("tiTGTSendTmResp: not TM frame\n"));
1902 tdStatus = ttdsaSendResp(ttdsaXchg->agRoot, ttdsaXchg);
1903 if (tdStatus == AGSA_RC_SUCCESS)
1905 TI_DBG1(("tiTGTSendTmResp: send success\n"));
1908 else if (tdStatus == AGSA_RC_FAILURE)
1910 TI_DBG1(("tiTGTSendTmResp: sending not successful\n"));
1915 TI_DBG1(("tiTGTSendTmResp: send busy\n"));
1922 tiTGTSetResp(tiRoot, tiTMRequest, 0, 0, 0);
1927 if (ttdsaXchg->resp.length != 0)
1929 TI_DBG1(("tiTGTSendTmResp: respsonse is set \n"));
1930 TI_DBG1(("tiTGTSendTmResp: resp.length 0x%x\n",
1931 ttdsaXchg->resp.length));
1932 ttdsaXchg->responseSent = agTRUE;
1934 ttdsaSendResp(ttdsaXchg->agRoot, ttdsaXchg);
1938 /* no respsonse is set, direct call */
1939 TI_DBG1(("tiTGTSendTmResp: direct call\n"));
1940 tiTGTSetResp(tiRoot, tiTMRequest, 0, 0, 0);
1941 ttdsaXchg->responseSent = agTRUE;
1942 ttdsaSendResp(ttdsaXchg->agRoot, ttdsaXchg);
1945 #define TASK_MANAGEMENT_FUNCTION_COMPLETE 0x0
1946 #define INVALID_FRAME 0x2
1947 #define TASK_MANAGEMENT_FUNCTION_NOT_SUPPORTED 0x4
1948 #define TASK_MANAGEMENT_FUNCTION_FAILED 0x5
1949 #define TASK_MANAGEMENT_FUNCTION_SUCCEEDED 0x8
1950 #define INVALID_LOGICAL_UNIT_NUMBER 0x9
1957 /*****************************************************************************
1959 * tiTGTSenseBufferGet
1961 * Purpose: This function is called to get the address of sense buffer from
1962 * the target specific Transport Dependent Layer.
1965 * tiRoot: Pointer to driver/port instance.
1966 * tiIORequest: I/O request context.
1967 * length: Lenght in bytes of the sense buffer.
1973 *****************************************************************************/
1974 osGLOBAL void *tiTGTSenseBufferGet( tiRoot_t *tiRoot,
1975 tiIORequest_t *tiIORequest,
1980 ttdsaXchg_t *ttdsaXchg;
1982 ttdsaXchg = (ttdsaXchg_t *)tiIORequest->tdData;
1984 TI_DBG4(("tiTGTSenseBufferGet: start\n"));
1985 OS_ASSERT((length <= 64), "length too big in tiTGTSenseBufferGet");
1987 return &ttdsaXchg->resp.virtAddr[sizeof(agsaSSPResponseInfoUnit_t)];
1990 /*****************************************************************************
1994 * Purpose: This function is called when the target OS Specific Module is ready
1995 * to send a response with the next tiTGTIOStart()
1996 * function call. This function allows the TD Layer to setup its
1997 * portion of the status and mark it to be sent on the next
1998 * tiTGTIOStart() function call.
2001 * tiRoot: Pointer to driver Instance.
2002 * tiIORequest: Pointer to the I/O request context for this I/O.
2003 * This context was initially passed to the OS Specific Module
2004 * in ostiProcessScsiReq().
2005 * dataSentLength: How much data sent or received for this Request.
2006 * ScsiStatus: Status for this SCSI command.
2007 * senseLength: Length of sense data if any.
2013 *****************************************************************************/
2015 tiTGTSetResp( tiRoot_t *tiRoot,
2016 tiIORequest_t *tiIORequest,
2017 bit32 dataSentLength,
2022 /* no call to saSSPStart() in this function */
2024 response is normally for task management
2025 sense is for command with error
2026 need to know this is for TM or cmd
2029 tiTGTSetResp(rdRoot->pTiRoot,
2030 rdIORequest->tiIORequest,
2038 ttdsaXchg_t *ttdsaXchg;
2039 tdsaRoot_t *tdsaRoot = (tdsaRoot_t *)tiRoot->tdData;
2041 agsaSSPTargetResponse_t *agSSPTargetResp;
2043 sas_resp_t *SASResp;
2044 bit32 TotalRespLen = 0;
2046 TI_DBG4 (("tiTGTSetResp: start\n"));
2047 TI_DBG4 (("tiTGTSetResp: datelen %d senselen %d\n", dataSentLength, senseLength));
2049 ttdsaXchg = (ttdsaXchg_t *)tiIORequest->tdData;
2050 SASResp = (sas_resp_t *)ttdsaXchg->resp.virtAddr;
2052 SASResp->agResp.status = ScsiStatus;
2054 if (ttdsaXchg->FrameType == SAS_TM)
2057 TI_DBG1(("tiTGTSetResp: TM\n"));
2058 if (senseLength != 0)
2060 TI_DBG1 (("tiTGTSetResp: non-zero sensedatalen for TM\n"));
2063 SASResp->agResp.dataPres = RESPONSE_DATA;
2064 OSSA_WRITE_BE_32(agRoot, SASResp->agResp.responsedataLen, 0, RESPONSE_DATA_LEN);
2065 OSSA_WRITE_BE_32(agRoot, SASResp->agResp.senseDataLen, 0, 0);
2066 SASResp->RespData[3] = AGSA_TASK_MANAGEMENT_FUNCTION_NOT_SUPPORTED;
2067 TotalRespLen = sizeof(agsaSSPResponseInfoUnit_t) + RESPONSE_DATA_LEN;
2071 if (senseLength == 0)
2073 TI_DBG4 (("tiTGTSetResp: CMND, no data\n"));
2074 /* good and no data present */
2075 SASResp->agResp.dataPres = NO_DATA;
2076 OSSA_WRITE_BE_32(agRoot, SASResp->agResp.responsedataLen, 0, 0);
2077 OSSA_WRITE_BE_32(agRoot, SASResp->agResp.senseDataLen, 0, 0);
2078 TotalRespLen = sizeof(agsaSSPResponseInfoUnit_t);
2079 /* collapse good response with READ */
2080 if (ttdsaXchg->XchType == AGSA_SSP_TGT_READ_DATA)
2082 TI_DBG4(("tiTGTSetResp: read rsp collapse\n"));
2084 if (tdsaRoot->autoGoodRSP & READ_GOOD_RESPONSE)
2085 ttdsaXchg->readRspCollapsed = agTRUE;
2087 /* collapse good response with WRITE */
2088 if (ttdsaXchg->XchType == AGSA_SSP_TGT_WRITE_DATA)
2090 TI_DBG4(("tiTGTSetResp: write rsp collapse\n"));
2091 if (tdsaRoot->autoGoodRSP & WRITE_GOOD_RESPONSE)
2093 if (tiIS_SPC(TI_TIROOT_TO_AGROOT(tiRoot)))
2095 ttdsaXchg->wrtRspCollapsed = agFALSE;
2099 ttdsaXchg->wrtRspCollapsed = agTRUE;
2107 TI_DBG4 (("tiTGTSetResp: CMND, sense data\n"));
2108 /* bad and sense data */
2109 SASResp->agResp.dataPres = SENSE_DATA;
2110 OSSA_WRITE_BE_32(agRoot, SASResp->agResp.responsedataLen, 0, 0);
2111 OSSA_WRITE_BE_32(agRoot, SASResp->agResp.senseDataLen, 0, senseLength);
2112 TotalRespLen = sizeof(agsaSSPResponseInfoUnit_t) + senseLength;
2116 ttdsaXchg->statusSent = agTRUE;
2118 TI_DBG4(("tiTGTSetResp: ttdsaXchg %p\n", ttdsaXchg));
2119 TI_DBG4(("tiTGTSetResp: TotalRespLen 0x%x \n", TotalRespLen));
2120 TI_DBG4(("tiTGTSetResp: upper 0x%x \n",
2121 ttdsaXchg->resp.phyAddrUpper));
2122 TI_DBG4(("tiTGTSetResp: lower 0x%x \n",
2123 ttdsaXchg->resp.phyAddrLower));
2127 /* set the correct response length */
2128 ttdsaXchg->resp.length = TotalRespLen;
2130 dumpresp((bit8 *)ttdsaXchg->resp.virtAddr, ttdsaXchg->resp.length);
2134 send TM reponse (which has only response data not sense data here
2135 since ramdisk does not call IOstart for this
2138 if (ttdsaXchg->FrameType == SAS_TM)
2140 TI_DBG1(("tiTGTSetResp: respsonse is set \n"));
2141 TI_DBG1(("tiTGTSetResp: resp.length 0x%x\n",
2142 ttdsaXchg->resp.length));
2143 ttdsaSendResp(ttdsaXchg->agRoot, ttdsaXchg);
2149 &(ttdsaXchg->IORequestBody.transport.SAS.agSASRequestBody.sspTargetResponse);
2151 agSSPTargetResp->agTag = ttdsaXchg->tag;
2152 agSSPTargetResp->respBufLength = TotalRespLen;
2153 agSSPTargetResp->respBufUpper
2154 = ttdsaXchg->IORequestBody.transport.SAS.agSASRequestBody.sspTargetResponse.respBufUpper;
2155 agSSPTargetResp->respBufLower
2156 = ttdsaXchg->IORequestBody.transport.SAS.agSASRequestBody.sspTargetResponse.respBufLower;
2160 TI_DBG4(("tiTGTSetResp: len 0x%x \n",
2161 ttdsaXchg->IORequestBody.transport.SAS.agSASRequestBody.sspTargetResponse.respBufLength));
2162 TI_DBG4(("tiTGTSetResp: upper 0x%x \n",
2163 ttdsaXchg->IORequestBody.transport.SAS.agSASRequestBody.sspTargetResponse.respBufUpper));
2164 TI_DBG4(("tiTGTSetResp: lower 0x%x \n",
2165 ttdsaXchg->IORequestBody.transport.SAS.agSASRequestBody.sspTargetResponse.respBufLower));
2173 /******************************************************************************
2175 * tiTGTGetDeviceHandles
2177 * Purpose: This routine is called to to return the device handles for each
2178 * device currently available.
2181 * tiRoot: Pointer to driver Instance.
2182 * agDev[]: Array to receive pointers to the device handles.
2183 * maxDevs: Number of device handles which will fit in array pointed
2186 * Number of device handle slots present (however, only maxDevs
2187 * are copied into tiDev[]) which may be greater than the number of
2188 * handles actually present.
2192 ******************************************************************************/
2195 tiTGTGetDeviceHandles(
2197 tiPortalContext_t *tiPortalContext,
2198 tiDeviceHandle_t *tiDev[],
2202 tdsaRoot_t *tdsaRoot = (tdsaRoot_t *) tiRoot->tdData;
2203 tdsaContext_t *tdsaAllShared = (tdsaContext_t *)&tdsaRoot->tdsaAllShared;
2204 ttdsaTgt_t *Target = (ttdsaTgt_t *)tdsaAllShared->ttdsaTgt;
2205 bit32 deviceToReturn;
2206 bit32 devicePresent=0;
2207 bit32 deviceIndex=0;
2208 tdList_t *PortContextList;
2209 tdsaPortContext_t *onePortContext = agNULL;
2210 tdList_t *DeviceListList;
2211 tdsaDeviceData_t *oneDeviceData = agNULL;
2212 bit32 found = agFALSE;
2215 TI_DBG4 (("tiTGTGetDeviceHandles: start\n"));
2217 /* Check boundary condition */
2218 if (maxDevs > Target->OperatingOption.MaxTargets)
2220 deviceToReturn = Target->OperatingOption.MaxTargets;
2224 deviceToReturn = maxDevs;
2228 /* make sure tiPortalContext is valid */
2229 PortContextList = tdsaAllShared->MainPortContextList.flink;
2230 while (PortContextList != &(tdsaAllShared->MainPortContextList))
2232 onePortContext = TDLIST_OBJECT_BASE(tdsaPortContext_t, MainLink, PortContextList);
2233 if (onePortContext->tiPortalContext == tiPortalContext)
2235 TI_DBG4(("tiTGTGetDeviceHandles: found; oneportContext ID %d\n", onePortContext->id));
2239 PortContextList = PortContextList->flink;
2242 if (found == agFALSE)
2244 TI_DBG4(("tiTGTGetDeviceHandles: No corressponding tdsaPortContext\n"));
2249 /* go through device list and returns them */
2250 DeviceListList = tdsaAllShared->MainDeviceList.flink;
2251 while (DeviceListList != &(tdsaAllShared->MainDeviceList))
2253 oneDeviceData = TDLIST_OBJECT_BASE(tdsaDeviceData_t, MainLink, DeviceListList);
2254 TI_DBG4(("tiTGTGetDeviceHandles: pid %d did %d\n", onePortContext->id, oneDeviceData->id));
2255 TI_DBG4(("tiTGTGetDeviceHandles: device AddrHi 0x%08x\n", oneDeviceData->SASAddressID.sasAddressHi));
2256 TI_DBG4(("tiTGTGetDeviceHandles: device AddrLo 0x%08x\n", oneDeviceData->SASAddressID.sasAddressLo));
2257 TI_DBG4(("tiTGTGetDeviceHandles: handle %p\n", &(oneDeviceData->tiDeviceHandle)));
2258 if (oneDeviceData->valid == agTRUE)
2260 TI_DBG4(("tiTGTGetDeviceHandles: valid deviceindex %d devicePresent %d\n", deviceIndex, devicePresent));
2262 tiDev[deviceIndex] = &(oneDeviceData->tiDeviceHandle);
2267 tiDev[deviceIndex] = agNULL;
2268 TI_DBG4(("tiTGTGetDeviceHandles: not valid deviceindex %d devicePresent %d\n", deviceIndex, devicePresent));
2272 if (devicePresent >= deviceToReturn )
2276 DeviceListList = DeviceListList->flink;
2279 return devicePresent;
2285 /******************************************************************************
2287 * tiTGTGetDeviceInfo
2289 * Purpose: This routine is called to to return the device information for
2290 * specified device handle.
2293 * tiRoot: Pointer to driver Instance.
2294 * tiDeviceHandle: device handle associated with the device for which
2295 * information is queried
2296 * tiDeviceInfo: device information structure containing address and name.
2299 * tiSuccess: if the device handle is valid.
2300 * tiError : if the device handle is not valid.
2304 ******************************************************************************/
2308 tiDeviceHandle_t *tiDeviceHandle,
2309 tiDeviceInfo_t *tiDeviceInfo)
2311 tdsaDeviceData_t *oneDeviceData = agNULL;
2314 TI_DBG4 (("tiTGTGetDeviceInfo: start\n"));
2316 if (tiDeviceHandle == agNULL)
2318 TI_DBG4 (("tiTGTGetDeviceInfo: tiDeviceHandle is NULL\n"));
2322 oneDeviceData = (tdsaDeviceData_t *)tiDeviceHandle->tdData;
2324 if (oneDeviceData == agNULL)
2326 TI_DBG4 (("tiTGTGetDeviceInfo: oneDeviceData is NULL\n"));
2330 /* filling in the link rate */
2331 if (oneDeviceData->registered == agTRUE)
2333 tiDeviceInfo->info.devType_S_Rate = oneDeviceData->agDeviceInfo.devType_S_Rate;
2337 tiDeviceInfo->info.devType_S_Rate = oneDeviceData->agDeviceInfo.devType_S_Rate & 0x0f;
2340 /* temp just returning local and remote SAS address; doesn't have a name */
2341 tiDeviceInfo->remoteName = (char *)&(oneDeviceData->tdPortContext->sasRemoteAddressHi);
2342 tiDeviceInfo->remoteAddress = (char *)&(oneDeviceData->tdPortContext->sasRemoteAddressLo);
2344 tiDeviceInfo->localName = (char *)&(oneDeviceData->tdPortContext->sasLocalAddressHi);
2345 tiDeviceInfo->localAddress = (char *)&(oneDeviceData->tdPortContext->sasLocalAddressLo);
2350 /*****************************************************************************
2351 *! \brief ttdssIOAbortedHandler
2353 * Purpose: This function processes I/Os completed and returned by SAS/SATA lower
2354 * layer with agIOStatus = OSSA_IO_ABORTED
2356 * \param agRoot: pointer to port instance
2357 * \param agIORequest: pointer to I/O request
2358 * \param agIOStatus: I/O status given by LL layer
2359 * \param agIOInfoLen: lenth of complete SAS RESP frame
2360 * \param agParam A Handle used to refer to the response frame or handle
2362 * \param agOtherInfo Residual count
2366 *****************************************************************************/
2367 /* see itdosIOCompleted() and itdinit.c and itdIoAbortedHandler in itdio.c*/
2369 ttdssIOAbortedHandler (
2371 agsaIORequest_t *agIORequest,
2378 tdsaRootOsData_t *osData = (tdsaRootOsData_t *)agRoot->osData;
2379 tiRoot_t *tiRoot = (tiRoot_t *)osData->tiRoot;
2380 tdIORequestBody_t *tdIORequestBody;
2382 TI_DBG1(("itdssIOAbortedHandler: start\n"));
2383 tdIORequestBody = (tdIORequestBody_t *)agIORequest->osData;
2385 if (agIOStatus != OSSA_IO_ABORTED)
2387 TI_DBG1(("itdssIOAbortedHandler: incorrect agIOStatus 0x%x\n", agIOStatus));
2393 tdIORequestBody->tiIORequest,