summaryrefslogtreecommitdiffstats
path: root/sys/dev/pms/RefTisa/tisa/sassata/sas/tgt/ttdio.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/dev/pms/RefTisa/tisa/sassata/sas/tgt/ttdio.c')
-rw-r--r--sys/dev/pms/RefTisa/tisa/sassata/sas/tgt/ttdio.c2401
1 files changed, 2401 insertions, 0 deletions
diff --git a/sys/dev/pms/RefTisa/tisa/sassata/sas/tgt/ttdio.c b/sys/dev/pms/RefTisa/tisa/sassata/sas/tgt/ttdio.c
new file mode 100644
index 0000000..d688e18
--- /dev/null
+++ b/sys/dev/pms/RefTisa/tisa/sassata/sas/tgt/ttdio.c
@@ -0,0 +1,2401 @@
+/*******************************************************************************
+*Copyright (c) 2014 PMC-Sierra, Inc. All rights reserved.
+*
+*Redistribution and use in source and binary forms, with or without modification, are permitted provided
+*that the following conditions are met:
+*1. Redistributions of source code must retain the above copyright notice, this list of conditions and the
+*following disclaimer.
+*2. Redistributions in binary form must reproduce the above copyright notice,
+*this list of conditions and the following disclaimer in the documentation and/or other materials provided
+*with the distribution.
+*
+*THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED
+*WARRANTIES,INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+*FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+*FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+*NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+*BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+*LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+*SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE
+ ********************************************************************************/
+/*******************************************************************************/
+/** \file
+ *
+ * $RCSfile: ttdio.c,v $
+ *
+ * Copyright 2006 PMC-Sierra, Inc.
+ *
+ *
+ * This file contains initiator IO related functions in TD layer
+ *
+ */
+#include <osenv.h>
+#include <ostypes.h>
+#include <osdebug.h>
+
+#include <sa.h>
+#include <saapi.h>
+#include <saosapi.h>
+
+#include <titypes.h>
+#include <ostiapi.h>
+#include <tiapi.h>
+#include <tiglobal.h>
+
+#include <tdtypes.h>
+#include <osstring.h>
+#include <tdutil.h>
+
+#ifdef INITIATOR_DRIVER
+#include <itdtypes.h>
+#include <itddefs.h>
+#include <itdglobl.h>
+#endif
+
+#ifdef TARGET_DRIVER
+#include <ttdglobl.h>
+#include <ttdtxchg.h>
+#include <ttdtypes.h>
+#endif
+
+#include <tdsatypes.h>
+#include <tdproto.h>
+
+
+/* Start For trace only */
+#ifdef REMOVED
+unsigned __int64
+GetHiResTimeStamp(void);
+#endif
+#undef TD_DEBUG_TRACE_ENABLE
+#define TD_DEBUG_IO_TRACE_BUFFER_MAX 1024
+
+
+typedef struct TDDebugTraceEntry_s
+{
+ bit64 Time;
+ ttdsaXchg_t ttdsaXchg;
+ tdsaDeviceData_t oneDeviceData;
+} TDDebugTraceEntry_t;
+
+typedef struct TDDebugTrace_s
+{
+ bit32 Idx;
+ bit32 pad;
+ TDDebugTraceEntry_t Data[TD_DEBUG_IO_TRACE_BUFFER_MAX];
+} TDDebugTrace_t;
+
+void TDTraceInit(void);
+void TDTraceAdd(ttdsaXchg_t *ttdsaXchg, tdsaDeviceData_t *oneDeviceData);
+
+#ifdef TD_DEBUG_TRACE_ENABLE
+#define TD_DEBUG_TRACE(ttdsaXchg, oneDeviceData) TDTraceAdd(ttdsaXchg, oneDeviceData)
+#else
+#define TD_DEBUG_TRACE(ttdsaXchg, oneDeviceData)
+#endif
+
+TDDebugTrace_t TraceData;
+
+void TDTraceInit(void)
+{
+ osti_memset(&TraceData, 0, sizeof(TraceData));
+}
+
+void TDTraceAdd(ttdsaXchg_t *ttdsaXchg, tdsaDeviceData_t *oneDeviceData)
+{
+ static bit32 TraceIdx = 0;
+
+ TraceData.Idx = TraceIdx;
+#ifdef REMOVED
+ TraceData.Data[TraceIdx].Time = GetHiResTimeStamp();
+#endif
+ osti_memcpy((bit8 *)&(TraceData.Data[TraceIdx].ttdsaXchg), (bit8 *)ttdsaXchg, sizeof(ttdsaXchg_t));
+ osti_memcpy((bit8 *)&(TraceData.Data[TraceIdx].oneDeviceData), (bit8 *)oneDeviceData, sizeof(tdsaDeviceData_t));
+#ifdef REMOVED
+ TraceData.Data[TraceIdx].ttdsaXchg = ttdsaXchg;
+ TraceData.Data[TraceIdx].oneDeviceData = oneDeviceData;
+#endif
+
+ TraceIdx++;
+ if (TraceIdx >= TD_DEBUG_IO_TRACE_BUFFER_MAX)
+ {
+ TraceIdx = 0;
+ }
+
+ return;
+}
+
+
+/* End For trace only */
+
+
+osGLOBAL void
+ttdsaSSPReqReceived(
+ agsaRoot_t *agRoot,
+ agsaDevHandle_t *agDevHandle,
+ agsaFrameHandle_t agFrameHandle,
+ bit32 agInitiatorTag,
+ bit32 parameter,
+ bit32 agFrameLen
+)
+{
+ tdsaRootOsData_t *osData = (tdsaRootOsData_t *)agRoot->osData;
+ tiRoot_t *tiRoot = (tiRoot_t *)osData->tiRoot;
+ ttdsaXchg_t *ttdsaXchg;
+ /* agsaSSPCmdInfoUnit_t cmdIU; */
+ tdsaDeviceData_t *oneDeviceData = agNULL;
+ bit32 agFrameType, TLR;
+
+ TD_XCHG_CONTEXT_NO_CMD_RCVD(tiRoot) = TD_XCHG_CONTEXT_NO_CMD_RCVD(tiRoot)+1;
+
+ TI_DBG4(("ttdsaSSPReqReceived: start\n"));
+
+ agFrameType = TD_GET_FRAME_TYPE(parameter);
+ TLR = TD_GET_TLR(parameter);
+
+
+ /*note:
+ in ini, agDevHandle->osData = tdsaDeviceData_t
+ is set in tdssAddDevicedataToSharedcontext()
+
+ in tdsaDeviceDataInit()
+ oneDeviceData->tiDeviceHandle.tdData has been initialized
+ */
+ oneDeviceData = (tdsaDeviceData_t *)agDevHandle->osData;
+
+ if (oneDeviceData == agNULL)
+ {
+ TI_DBG1(("ttdsaSSPReqReceived: no device data\n"));
+ return;
+ }
+
+
+
+ ttdsaXchg = ttdsaXchgGetStruct(agRoot);
+
+ if (ttdsaXchg == agNULL)
+ {
+ TI_DBG1(("ttdsaSSPReqReceived: no free xchg structures\n"));
+ // ttdsaDumpallXchg(tiRoot);
+ return;
+ }
+
+ if (ttdsaXchg->IORequestBody.tiIORequest == agNULL)
+ {
+ TI_DBG1(("ttdsaSSPReqReceived: tiIORequest is NULL\n"));
+ // ttdsaDumpallXchg(tiRoot);
+ return;
+ }
+
+ oneDeviceData->agDevHandle = agDevHandle;
+ oneDeviceData->agRoot = agRoot;
+
+ /* saving the device */
+ ttdsaXchg->DeviceData = oneDeviceData;
+
+ ttdsaXchg->agRoot = agRoot;
+ ttdsaXchg->tiRoot = tiRoot;
+
+ ttdsaXchg->IORequestBody.agIORequest.sdkData = agNULL;
+
+ /* initiator tag */
+ ttdsaXchg->tag = (bit16)agInitiatorTag;
+ ttdsaXchg->IORequestBody.transport.SAS.agSASRequestBody.sspTargetReq.agTag
+ = ttdsaXchg->tag;
+ ttdsaXchg->IORequestBody.transport.SAS.agSASRequestBody.sspTargetResponse.agTag
+ = ttdsaXchg->tag;
+
+ TI_DBG6(("ttdsaSSPReqReceived: initiator tag 0x%x\n", agInitiatorTag));
+
+ if (agFrameType == OSSA_FRAME_TYPE_SSP_CMD)
+ {
+ TI_DBG4(("ttdsaSSPReqReceived: CMD frame type\n"));
+ /* reads agsaSSPResponseInfoUnit_t */
+ saFrameReadBlock(
+ agRoot,
+ agFrameHandle,
+ 0,
+ &ttdsaXchg->agSSPCmndIU,
+ agFrameLen
+ );
+
+ tdsaProcessCDB(&ttdsaXchg->agSSPCmndIU, ttdsaXchg);
+ ttdsaXchg->FrameType = SAS_CMND;
+
+ /*
+ ** As the last thing we call the disk module to handle the SCSI CDB.
+ ** The disk module will call tiTGTIOStart to start a data phase.
+ */
+
+ /* typedef struct
+ {
+ bit8 *reqCDB;
+ bit8 *scsiLun,
+ bit32 taskAttribute;
+ bi32 taskId;
+ bit32 crn;
+ } tiTargetScsiCmnd_t;
+ */
+ /* what about reqCDB and scsiLun */
+
+ /* coverting task attributes from SAS TISA */
+ switch (SA_SSPCMD_GET_TASKATTRIB(&ttdsaXchg->agSSPCmndIU))
+ {
+ case 0:
+ ttdsaXchg->tiTgtScsiCmnd.taskAttribute = TASK_SIMPLE;
+ break;
+ case 1:
+ ttdsaXchg->tiTgtScsiCmnd.taskAttribute = TASK_HEAD_OF_QUEUE;
+ break;
+ case 2:
+ ttdsaXchg->tiTgtScsiCmnd.taskAttribute = TASK_ORDERED;
+ break;
+ case 3:
+ TI_DBG1(("ttdsaSSPReqReceived: reserved taskAttribute 0x%x\n",ttdsaXchg->agSSPCmndIU.efb_tp_taskAttribute));
+ ttdsaXchg->tiTgtScsiCmnd.taskAttribute = TASK_SIMPLE;
+ break;
+ case 4:
+ ttdsaXchg->tiTgtScsiCmnd.taskAttribute = TASK_ACA;
+ break;
+ default:
+ TI_DBG1(("ttdsaSSPReqReceived: unknown taskAttribute 0x%x\n",ttdsaXchg->agSSPCmndIU.efb_tp_taskAttribute));
+ ttdsaXchg->agSSPCmndIU.efb_tp_taskAttribute = TASK_SIMPLE;
+ break;
+ }
+
+ ttdsaXchg->tiTgtScsiCmnd.taskId = agInitiatorTag;
+ ttdsaXchg->tiTgtScsiCmnd.crn = 0;
+ ttdsaXchg->TLR = TLR;
+
+ /* call ostiProcessScsiReq */
+ ostiProcessScsiReq( tiRoot,
+ &ttdsaXchg->tiTgtScsiCmnd,
+ agFrameHandle,
+ 0,
+ ttdsaXchg->IORequestBody.tiIORequest,
+ &ttdsaXchg->DeviceData->tiDeviceHandle);
+
+
+ }
+ else if (agFrameType == OSSA_FRAME_TYPE_SSP_TASK)
+ {
+ TI_DBG4(("ttdsaSSPReqReceived: TM frame type\n"));
+
+ /*
+ reads aagsaSSPScsiTaskMgntReq_t
+ including lun
+ */
+ saFrameReadBlock(
+ agRoot,
+ agFrameHandle,
+ 0,
+ &ttdsaXchg->agTMIU,
+ agFrameLen
+ );
+
+ ttdsaXchg->FrameType = SAS_TM;
+ /*
+ call task process mangement fn
+ */
+ ttdsaTMProcess(tiRoot, ttdsaXchg);
+ return;
+ }
+ else
+ {
+ TI_DBG1(("ttdsaSSPReqReceived: unknown frame type\n"));
+ return;
+ }
+
+ return;
+}
+
+void
+dumpCDB(bit8 *cdb)
+{
+ bit32 i;
+ for(i=0;i<10;i++)
+ {
+ TI_DBG4(("cdb[%d] 0x%x\n", i, cdb[i]));
+ }
+ return;
+}
+
+osGLOBAL void
+tdsaProcessCDB(
+ agsaSSPCmdInfoUnit_t *cmdIU,
+ ttdsaXchg_t *ttdsaXchg
+)
+{
+ tdsaRoot_t *tdsaRoot = (tdsaRoot_t *) ttdsaXchg->tiRoot->tdData;
+ tdsaContext_t *tdsaAllShared = (tdsaContext_t *) &tdsaRoot->tdsaAllShared;
+ ttdsaTgt_t *Target = (ttdsaTgt_t *) tdsaAllShared->ttdsaTgt;
+ bit8 group;
+#ifdef TD_DEBUG_ENABLE
+ CDB6_t *cdb6;
+#endif
+ CDB10_t *cdb10;
+ CDB12_t *cdb12;
+ CDB16_t *cdb16;
+ bit32 unknown = agFALSE;
+ bit32 len=0;
+ group = cmdIU->cdb[0] & CDB_GRP_MASK;
+
+ TI_DBG4(("tdsaProcessCDB: start\n"));
+
+ switch (cmdIU->cdb[0])
+ {
+ case SCSIOPC_REPORT_LUN:
+ TI_DBG4(("tdsaProcessCDB: REPORT_LUN\n"));
+ ttdsaXchg->XchType = AGSA_SSP_TGT_READ_DATA;
+ break;
+ case SCSIOPC_INQUIRY:
+ TI_DBG4(("tdsaProcessCDB: INQUIRY\n"));
+ ttdsaXchg->XchType = AGSA_SSP_TGT_READ_DATA;
+ break;
+
+ case SCSIOPC_TEST_UNIT_READY:
+ TI_DBG4(("tdsaProcessCDB: TEST_UNIT_READY\n"));
+ ttdsaXchg->XchType = AGSA_SSP_TGT_READ_DATA;
+ break;
+
+ case SCSIOPC_READ_CAPACITY_10:
+ case SCSIOPC_READ_CAPACITY_16:
+ TI_DBG4(("tdsaProcessCDB: READ CAPACITY\n"));
+ ttdsaXchg->XchType = AGSA_SSP_TGT_READ_DATA;
+ break;
+
+ case SCSIOPC_READ_6: /* fall through */
+ case SCSIOPC_READ_10:
+ TI_DBG4(("tdsaProcessCDB: READ\n"));
+ ttdsaXchg->XchType = AGSA_SSP_TGT_READ_DATA;
+ break;
+
+ case SCSIOPC_WRITE_6: /* fall through */
+ case SCSIOPC_WRITE_10:
+ TI_DBG4(("tdsaProcessCDB: WRITE\n"));
+ ttdsaXchg->XchType = AGSA_SSP_TGT_WRITE_DATA;
+ break;
+
+ case SCSIOPC_MODE_SENSE_6: /* fall through */
+ case SCSIOPC_MODE_SENSE_10:
+ TI_DBG4(("tdsaProcessCDB: MODE SENSE\n"));
+ ttdsaXchg->XchType = AGSA_SSP_TGT_READ_DATA;
+ break;
+ case SCSIOPC_SYNCHRONIZE_CACHE_10:
+ TI_DBG4(("tdsaProcessCDB: SCSIOPC_SYNCHRONIZE_CACHE_10\n"));
+ ttdsaXchg->XchType = AGSA_SSP_TGT_CMD_OR_TASK_RSP;
+ break;
+ case SCSIOPC_REQUEST_SENSE:
+ TI_DBG2(("tdsaProcessCDB: SCSIOPC_REQUEST_SENSE\n"));
+ ttdsaXchg->XchType = AGSA_SSP_TGT_READ_DATA;
+ break;
+ default:
+ TI_DBG4(("tdsaProcessCDB: UNKNOWN, cbd %d 0x%x\n", cmdIU->cdb[0], cmdIU->cdb[0]));
+ ttdsaXchg->XchType = TargetUnknown;
+ break;
+ }
+
+ /* parse datalen */
+ switch (group)
+ {
+ case CDB_6BYTE:
+ TI_DBG4(("tdsaProcessCDB: CDB 6 byte, not yet\n"));
+#ifdef TD_DEBUG_ENABLE
+ cdb6 = (CDB6_t *)(cmdIU->cdb);
+#endif
+ TI_DBG4(("tdsaProcessCDB: CDB len 0x%x\n", cdb6->len));
+ break;
+ case CDB_10BYTE1: /* fall through */
+ case CDB_10BYTE2:
+ TI_DBG4(("tdsaProcessCDB: CDB 10 byte\n"));
+ cdb10 = (CDB10_t *)(cmdIU->cdb);
+ OSSA_READ_BE_16(AGROOT, &len, cdb10->len, 0);
+ TI_DBG4(("tdsaProcessCDB: CDB len 0x%x\n", len));
+ dumpCDB(cmdIU->cdb);
+ break;
+ case CDB_12BYTE:
+ TI_DBG4(("tdsaProcessCDB: CDB 12 byte, not yet\n"));
+ cdb12 = (CDB12_t *)(cmdIU->cdb);
+ OSSA_READ_BE_32(AGROOT, &len, cdb12->len, 0);
+ TI_DBG4(("tdsaProcessCDB: CDB len 0x%x\n", len));
+ break;
+ case CDB_16BYTE:
+ TI_DBG4(("tdsaProcessCDB: CDB 16 byte, not yet\n"));
+ cdb16 = (CDB16_t *)(cmdIU->cdb);
+ OSSA_READ_BE_32(AGROOT, &len, cdb16->len, 0);
+ TI_DBG4(("tdsaProcessCDB: CDB len 0x%x\n", len));
+ break;
+ default:
+ TI_DBG4(("tdsaProcessCDB: unknow CDB, group %d 0x%x\n", group, group));
+ len = 0;
+ unknown = agTRUE;
+ break;
+ }
+ if (cmdIU->cdb[0] == SCSIOPC_READ_6 || cmdIU->cdb[0] == SCSIOPC_READ_10 ||
+ cmdIU->cdb[0] == SCSIOPC_WRITE_6 || cmdIU->cdb[0] == SCSIOPC_WRITE_10 )
+ {
+ ttdsaXchg->dataLen = len * Target->OperatingOption.BlockSize;
+ }
+ else
+ {
+ ttdsaXchg->dataLen = len;
+ }
+
+ if (ttdsaXchg->dataLen == 0 && unknown == agFALSE)
+ {
+ /* this is needed because of min operation in tiTGTIOstart() */
+ ttdsaXchg->dataLen = 0xffffffff;
+ }
+ /* TI_DBG4(("tdsaProcessCDB: datalen 0x%x %d\n", ttdsaXchg->dataLen, ttdsaXchg->dataLen)); */
+ return;
+}
+
+
+
+
+/*****************************************************************************
+ *
+ * tiTGTIOStart
+ *
+ * Purpose: This function is called by the target OS Specific Module to start
+ * the next phase of a SCSI Request.
+ *
+ * Parameters:
+ * tiRoot: Pointer to driver Instance.
+ * tiIORequest: Pointer to the I/O request context for this I/O.
+ * This context was initially passed to the OS Specific Module
+ * in ostiProcessScsiReq().
+ * dataOffset: Offset into the buffer space for this phase.
+ * dataLength: Length of data to move for this phase.
+ * dataSGL: Length/Address pair of where the data is. The SGL list is
+ * allocated and initialized by the OS Specific module.
+ * sglVirtualAddr: The virtual address of the first element in agSgl1 when
+ * agSgl1 is used with the type tiSglList.
+ * This field is needed for the TD Layer.
+ *
+ * Return:
+ * tiSuccess: I/O request successfully initiated.
+ * tiBusy: No resources available, try again later.
+ * tiError: Other errors that prevent the I/O request to be started.
+ *
+ * Note:
+ *
+ *****************************************************************************/
+osGLOBAL bit32
+tiTGTIOStart( tiRoot_t *tiRoot,
+ tiIORequest_t *tiIORequest,
+ bit32 dataOffset,
+ bit32 dataLength,
+ tiSgl_t *dataSGL,
+ void *sglVirtualAddr
+)
+
+{
+ ttdsaXchg_t *ttdsaXchg;
+ agsaSSPTargetRequest_t *agSSPTargetReq;
+ bit32 tiStatus;
+ bit32 saStatus;
+ bit32 tdStatus;
+ tdsaPortContext_t *onePortContext = agNULL;
+ tdsaDeviceData_t *oneDeviceData = agNULL;
+
+ TI_DBG4(("tiTGTIOStart: start\n"));
+ TI_DBG4(("tiTGTIOStart: dataLength 0x%x %d\n", dataLength, dataLength));
+ TI_DBG4(("tiTGTIOStart: dataOffset 0x%x %d\n", dataOffset, dataOffset));
+
+ /* save infor in ttdsaXchg */
+ ttdsaXchg = (ttdsaXchg_t *)tiIORequest->tdData;
+
+ /* check the state of port */
+ oneDeviceData = ttdsaXchg->DeviceData;
+ onePortContext= oneDeviceData->tdPortContext;
+ if (onePortContext->valid == agFALSE)
+ {
+ TI_DBG1(("tiTGTIOStart: portcontext pid %d is invalid\n", onePortContext->id));
+ return tiError;
+ }
+
+
+ agSSPTargetReq
+ = &(ttdsaXchg->IORequestBody.transport.SAS.agSASRequestBody.sspTargetReq);
+
+ /* fills in agsaSASRequestBody_t.agsaSSPTargetRequest_t */
+ agSSPTargetReq->dataLength = (bit32) MIN(dataLength, ttdsaXchg->dataLen);
+ agSSPTargetReq->offset = dataOffset;
+ agSSPTargetReq->agTag = ttdsaXchg->tag;
+ /* SSPTargetReq->agTag has been set in ttdsaSSPReqReceived() */
+
+ /* Process TLR */
+ if (ttdsaXchg->TLR == 2)
+ {
+ /* diable TLR */
+ agSSPTargetReq->sspOption = 0;
+ }
+ else
+ {
+ /* enable TLR */
+ /* bit5: 0 1 11 11 :bit0 */
+ agSSPTargetReq->sspOption = 0x1F;
+ }
+
+ ttdsaXchg->IORequestBody.IOType.TargetIO.TargetIOType.RegIO.sglVirtualAddr
+ = sglVirtualAddr;
+
+ if (agSSPTargetReq->dataLength != 0)
+ {
+ TI_DBG6(("tiTGTIOStart: pos 1\n"));
+ ttdsaXchg->IORequestBody.IOType.TargetIO.TargetIOType.RegIO.tiSgl1
+ = *dataSGL;
+ }
+ else
+ {
+ TI_DBG6(("tiTGTIOStart: pos 2\n"));
+ ttdsaXchg->IORequestBody.IOType.TargetIO.TargetIOType.RegIO.tiSgl1.len
+ = 0;
+ ttdsaXchg->IORequestBody.IOType.TargetIO.TargetIOType.RegIO.tiSgl1.type
+ = tiSgl;
+
+ /* let's send response frame */
+ if (ttdsaXchg->resp.length != 0)
+ {
+ /* senselen != 0, send respsonse */
+ TI_DBG4(("tiTGTIOStart: send respsonse\n"));
+ TI_DBG4(("tiTGTIOStart: resp.length 0x%x\n",
+ ttdsaXchg->resp.length));
+ ttdsaXchg->responseSent = agTRUE;
+ ttdsaXchg->DeviceData->IOResponse++;
+ TD_DEBUG_TRACE(ttdsaXchg, ttdsaXchg->DeviceData);
+ tdStatus = ttdsaSendResp(ttdsaXchg->agRoot, ttdsaXchg);
+ if (tdStatus == AGSA_RC_SUCCESS)
+ {
+ return tiSuccess;
+ }
+ else if (tdStatus == AGSA_RC_FAILURE)
+ {
+ TI_DBG1(("tiTGTIOStart: (ttdsaSendResp) sending not successful\n"));
+ return tiError;
+ }
+ else
+ {
+ TI_DBG1(("tiTGTIOStart: (ttdsaSendResp) sending busy\n"));
+ return tiBusy;
+ }
+ }
+ }
+
+
+ /* sets SSPTargetReq->agSgl */
+ tiStatus = ttdssIOPrepareSGL(tiRoot, &ttdsaXchg->IORequestBody, dataSGL, NULL, sglVirtualAddr);
+
+ if (tiStatus != tiSuccess)
+ {
+ TI_DBG1(("tiTGTIOStart: ttdIOPrepareSGL did not return success\n"));
+ return tiStatus;
+ }
+
+ TI_DBG4(("tiTGTIOStart: agroot %p ttdsaXchg %p\n", ttdsaXchg->agRoot, ttdsaXchg));
+ TI_DBG4(("tiTGTIOStart: agDevHanlde %p\n", ttdsaXchg->DeviceData->agDevHandle));
+
+ if ( (ttdsaXchg->readRspCollapsed == agTRUE) || (ttdsaXchg->wrtRspCollapsed == agTRUE) )
+ {
+ /* collapse good response with read */
+ TI_DBG4(("tiTGTIOStart: read rsp collapse\n"));
+ TI_DBG4(("tiTGTIOStart: initiator tag 0x%x\n", ttdsaXchg->tag));
+
+ TD_XCHG_CONTEXT_NO_START_IO(tiRoot) = TD_XCHG_CONTEXT_NO_START_IO(tiRoot)+1;
+ ttdsaXchg->DeviceData->IOStart++;
+ TD_DEBUG_TRACE(ttdsaXchg, ttdsaXchg->DeviceData);
+ saStatus = saSSPStart(
+ ttdsaXchg->agRoot,
+ &ttdsaXchg->IORequestBody.agIORequest,
+ tdsaRotateQnumber(tiRoot, oneDeviceData),
+ ttdsaXchg->DeviceData->agDevHandle,
+ ttdsaXchg->readRspCollapsed ? AGSA_SSP_TGT_READ_GOOD_RESP : AGSA_SSP_TGT_WRITE_GOOD_RESP,
+ &ttdsaXchg->IORequestBody.transport.SAS.agSASRequestBody,
+ agNULL,
+ &ossaSSPCompleted
+ );
+ }
+ else
+ {
+ TI_DBG4(("tiTGTIOStart: normal\n"));
+ TI_DBG4(("tiTGTIOStart: initiator tag 0x%x\n", ttdsaXchg->tag));
+ TD_XCHG_CONTEXT_NO_START_IO(tiRoot) = TD_XCHG_CONTEXT_NO_START_IO(tiRoot)+1;
+ ttdsaXchg->DeviceData->IOStart++;
+ TD_DEBUG_TRACE(ttdsaXchg, ttdsaXchg->DeviceData);
+ saStatus = saSSPStart(
+ ttdsaXchg->agRoot, /* agRoot, */
+ &ttdsaXchg->IORequestBody.agIORequest,
+ tdsaRotateQnumber(tiRoot, oneDeviceData),
+ ttdsaXchg->DeviceData->agDevHandle,
+ ttdsaXchg->XchType,
+ &ttdsaXchg->IORequestBody.transport.SAS.agSASRequestBody,
+ agNULL,
+ &ossaSSPCompleted
+ );
+
+ }
+
+ if (saStatus == AGSA_RC_SUCCESS)
+ {
+ return tiSuccess;
+ }
+ else if (saStatus == AGSA_RC_FAILURE)
+ {
+ TI_DBG1(("tiTGTIOStart: sending not successful\n"));
+ return tiError;
+ }
+ else
+ {
+ TI_DBG1(("tiTGTIOStart: sending busy\n"));
+ return tiBusy;
+ }
+
+}
+
+#ifdef EDC_ENABLE
+/*****************************************************************************
+ *
+ * tiTGTIOStart
+ *
+ * Purpose: This function is called by the target OS Specific Module to start
+ * the next phase of a SCSI Request.
+ *
+ * Parameters:
+ * tiRoot: Pointer to driver Instance.
+ * tiIORequest: Pointer to the I/O request context for this I/O.
+ * This context was initially passed to the OS Specific Module
+ * in ostiProcessScsiReq().
+ * dataOffset: Offset into the buffer space for this phase.
+ * dataLength: Length of data to move for this phase.
+ * dataSGL: Length/Address pair of where the data is. The SGL list is
+ * allocated and initialized by the OS Specific module.
+ * sglVirtualAddr: The virtual address of the first element in agSgl1 when
+ * agSgl1 is used with the type tiSglList.
+ * This field is needed for the TD Layer.
+ * difOption: DIF option.
+ *
+ * Return:
+ * tiSuccess: I/O request successfully initiated.
+ * tiBusy: No resources available, try again later.
+ * tiError: Other errors that prevent the I/O request to be started.
+ *
+ * Note:
+ *
+ *****************************************************************************/
+osGLOBAL bit32 tiTGTIOStartDif(
+ tiRoot_t *tiRoot,
+ tiIORequest_t *tiIORequest,
+ bit32 dataOffset,
+ bit32 dataLength,
+ tiSgl_t *dataSGL,
+ void *sglVirtualAddr,
+ tiDif_t *difOption
+)
+{
+
+ /* This function was never used by SAS/SATA. Use tiTGTSuperIOStart() instead. */
+ return tiBusy;
+}
+#endif
+
+osGLOBAL bit32
+ttdssIOPrepareSGL(
+ tiRoot_t *tiRoot,
+ tdIORequestBody_t *tdIORequestBody,
+ tiSgl_t *tiSgl1,
+ tiSgl_t *tiSgl2,
+ void *sglVirtualAddr
+)
+{
+ agsaSgl_t *agSgl;
+
+ TI_DBG6(("ttdssIOPrepareSGL: start\n"));
+
+ agSgl = &(tdIORequestBody->transport.SAS.agSASRequestBody.sspTargetReq.agSgl);
+
+ agSgl->len = 0;
+
+ if (tiSgl1 == agNULL)
+ {
+ TI_DBG1(("ttdssIOPrepareSGL: Error tiSgl1 is NULL\n"));
+ return tiError;
+ }
+
+ agSgl->sgUpper = tiSgl1->upper;
+ agSgl->sgLower = tiSgl1->lower;
+ agSgl->len = tiSgl1->len;
+ agSgl->extReserved = tiSgl1->type;
+
+ return tiSuccess;
+}
+
+/* temp for debugging */
+void
+dumpresp(bit8 *resp, bit32 len)
+{
+ bit32 i;
+
+ for(i=0;i<len;i++)
+ {
+ TI_DBG4(("resp[%d] 0x%x\n", i, resp[i]));
+ }
+
+ return;
+}
+
+osGLOBAL bit32
+ttdsaSendResp(
+ agsaRoot_t *agRoot,
+ ttdsaXchg_t *ttdsaXchg
+)
+{
+ tdsaRootOsData_t *osData = (tdsaRootOsData_t *)agRoot->osData;
+ tiRoot_t *tiRoot = (tiRoot_t *)osData->tiRoot;
+ tdsaDeviceData_t *oneDeviceData = agNULL;
+ bit32 agRequestType;
+ bit32 saStatus;
+ agsaSSPTargetResponse_t *agSSPTargetResp;
+ agRequestType = AGSA_SSP_TGT_CMD_OR_TASK_RSP;
+
+ TI_DBG4(("ttdsaSendResp: start\n"));
+ TI_DBG4(("ttdsaSendResp: agroot %p ttdsaXchg %p\n", ttdsaXchg->agRoot, ttdsaXchg));
+
+ TI_DBG4(("ttdsaSendResp:: agDevHanlde %p\n", ttdsaXchg->DeviceData->agDevHandle));
+
+ /* sas response */
+ TI_DBG4(("ttdsaSendResp: len 0x%x \n",
+ ttdsaXchg->resp.length));
+ TI_DBG4(("ttdsaSendResp: upper 0x%x \n",
+ ttdsaXchg->resp.phyAddrUpper));
+ TI_DBG4(("ttdsaSendResp: lower 0x%x \n",
+ ttdsaXchg->resp.phyAddrLower));
+ TI_DBG4(("ttdsaSendResp: initiator tag 0x%x\n", ttdsaXchg->tag));
+
+ agSSPTargetResp = &(ttdsaXchg->IORequestBody.transport.SAS.agSASRequestBody.sspTargetResponse);
+ agSSPTargetResp->agTag = ttdsaXchg->tag;
+ agSSPTargetResp->respBufLength = ttdsaXchg->resp.length;
+ agSSPTargetResp->respBufUpper = ttdsaXchg->resp.phyAddrUpper;
+ agSSPTargetResp->respBufLower = ttdsaXchg->resp.phyAddrLower;
+ agSSPTargetResp->respOption = 3; /* Retry on both ACK/NAK timeout and NAK received */
+ /* temporary solution for T2D Combo*/
+#if defined (INITIATOR_DRIVER) && defined (TARGET_DRIVER)
+ /* nothing */
+#else
+ if (agSSPTargetResp->respBufLength <= AGSA_MAX_SSPPAYLOAD_VIA_SFO)
+ agSSPTargetResp->frameBuf = ttdsaXchg->resp.virtAddr;
+ else
+ agSSPTargetResp->frameBuf = NULL;
+#endif
+ dumpresp((bit8 *)ttdsaXchg->resp.virtAddr, ttdsaXchg->resp.length);
+
+ TD_XCHG_CONTEXT_NO_SEND_RSP(TD_GET_TIROOT(agRoot)) =
+ TD_XCHG_CONTEXT_NO_SEND_RSP(TD_GET_TIROOT(agRoot))+1;
+
+ oneDeviceData = ttdsaXchg->DeviceData;
+ saStatus = saSSPStart(
+ ttdsaXchg->agRoot, /* agRoot,*/
+ &ttdsaXchg->IORequestBody.agIORequest,
+ tdsaRotateQnumber(tiRoot, oneDeviceData),
+ ttdsaXchg->DeviceData->agDevHandle, /* agDevHandle, */
+ agRequestType,
+ &ttdsaXchg->IORequestBody.transport.SAS.agSASRequestBody,
+ agNULL,
+ &ossaSSPCompleted
+ );
+
+ if (saStatus == AGSA_RC_SUCCESS)
+ {
+ TI_DBG4(("ttdsaSendResp: sending successful\n"));
+ return AGSA_RC_SUCCESS;
+ }
+ else if (saStatus == AGSA_RC_FAILURE)
+ {
+ TI_DBG1(("ttdsaSendResp: sending not successful\n"));
+ return AGSA_RC_FAILURE;
+ }
+ else
+ {
+ TI_DBG1(("ttdsaSendResp: sending busy\n"));
+ return AGSA_RC_BUSY;
+ }
+
+}
+
+osGLOBAL void
+ttdsaIOCompleted(
+ agsaRoot_t *agRoot,
+ agsaIORequest_t *agIORequest,
+ bit32 agIOStatus,
+ bit32 agIOInfoLen,
+ agsaFrameHandle_t agFrameHandle,
+ bit32 agOtherInfo
+)
+{
+
+ ttdsaXchg_t *ttdsaXchg = (ttdsaXchg_t *)agIORequest->osData;
+ /* done in ttdsaXchgInit() */
+ bit32 IOFailed = agFALSE;
+ bit32 status;
+ bit32 statusDetail = 0;
+ tiRoot_t *tiRoot;
+#ifdef REMOVED
+ tdsaRoot_t *tdsaRoot;
+ tdsaContext_t *tdsaAllShared;
+#endif
+ bit32 tdStatus;
+ bit32 saStatus = AGSA_RC_FAILURE;
+#ifdef TD_DEBUG_ENABLE
+ agsaDifDetails_t *DifDetail;
+#endif
+
+ TI_DBG4(("ttdsaIOCompleted: start\n"));
+ tiRoot = ((tdsaRootOsData_t *)agRoot->osData)->tiRoot;
+#ifdef REMOVED
+ tdsaRoot = (tdsaRoot_t *) tiRoot->tdData;
+ tdsaAllShared = (tdsaContext_t *)&tdsaRoot->tdsaAllShared;
+#endif
+#ifdef TD_DEBUG_ENABLE
+ DifDetail = (agsaDifDetails_t *)agFrameHandle;
+#endif
+
+ if (tiRoot == agNULL)
+ {
+ TI_DBG1(("ttdsaIOCompleted: tiRoot is NULL\n"));
+ return;
+ }
+
+ TD_XCHG_CONTEXT_NO_IO_COMPLETED(tiRoot) = TD_XCHG_CONTEXT_NO_IO_COMPLETED(tiRoot)+1;
+
+ if(TD_XCHG_GET_STATE(ttdsaXchg) != TD_XCHG_STATE_ACTIVE)
+ {
+ TI_DBG1(("ttdsaIOCompleted: XCHG is not active *****************\n"));
+ return;
+ }
+
+ if (ttdsaXchg->isTMRequest != agTRUE)
+ {
+ TI_DBG6(("ttdsaIOCompleted: COMMAND \n"));
+ TI_DBG6(("ttdsaIOCompleted: ttdsaXchg %p\n", ttdsaXchg));
+ TI_DBG6(("ttdsaIOCompleted: ttdsaXchg->IORequestBody.EsglPageList %p\n", &ttdsaXchg->IORequestBody.EsglPageList));
+ TI_DBG6(("ttdsaIOCompleted: command initiator tag 0x%x\n", ttdsaXchg->tag));
+
+#ifdef REMOVED
+ /* call tdsafreeesglpages only for xchg that used eslg */
+ if (ttdsaXchg->usedEsgl == agTRUE)
+ {
+ tdsaFreeEsglPages(tiRoot, &ttdsaXchg->IORequestBody.EsglPageList);
+ ttdsaXchg->usedEsgl = agFALSE;
+ }
+#endif
+
+ /* successful case */
+ if (agIOStatus == OSSA_IO_SUCCESS)
+ {
+ TI_DBG6(("ttdsaIOCompleted: osIOSuccess\n"));
+ if ( (ttdsaXchg->readRspCollapsed == agTRUE) || (ttdsaXchg->wrtRspCollapsed == agTRUE) )
+ {
+ ttdsaXchg->responseSent = agTRUE;
+ TI_DBG4(("ttdsaIOCompleted: read rsp collapse\n"));
+ }
+
+ if (ttdsaXchg->statusSent == agTRUE)
+ {
+ /*
+ the response has already been set and ready
+ but has NOT been sent
+ */
+ if (ttdsaXchg->responseSent == agFALSE)
+ {
+ /* let's send the response for IO */
+ TI_DBG6(("ttdsaIOCompleted: sending response\n"));
+ TD_DEBUG_TRACE(ttdsaXchg, ttdsaXchg->DeviceData);
+ tdStatus = ttdsaSendResp(agRoot, ttdsaXchg);
+ if (tdStatus != AGSA_RC_SUCCESS)
+ {
+ TI_DBG1(("ttdsaIOCompleted: attention needed\n"));
+ return;
+ }
+ ttdsaXchg->responseSent = agTRUE;
+ }
+ else
+ {
+ TI_DBG4(("ttdsaIOCompleted: read rsp collapse and complete \n"));
+ /* the response has been sent */
+ TI_DBG6(("ttdsaIOCompleted: already sent response, notify OS\n"));
+
+ if (TD_XCHG_GET_STATE(ttdsaXchg) == TD_XCHG_STATE_INACTIVE)
+ {
+ TI_DBG1(("ttdsaIOCompleted: wrong DEQUEUE_THIS\n"));
+ }
+
+ /*
+ * Notify the OS Specific Module, so it can free its resource.
+ */
+ TI_DBG4(("ttdsaIOCompleted: calling ostiTargetIOCompleted\n"));
+ ostiTargetIOCompleted( tiRoot,
+ ttdsaXchg->IORequestBody.tiIORequest,
+ tiIOSuccess );
+
+ /* clean up resources */
+ ttdsaXchgFreeStruct(tiRoot,ttdsaXchg);
+ }
+ } /* sent */
+ else
+ {
+ TI_DBG4(("ttdsaIOCompleted: osIOSuccess: nextphase\n"));
+ /* the response has not been set; still in data phase */
+ /* we need to tell the disk module to start the next phase */
+ ostiNextDataPhase(ttdsaXchg->tiRoot,
+ ttdsaXchg->IORequestBody.tiIORequest );
+ }
+ return;
+ } /* success */
+
+ /* handle error cases */
+ if (agIOStatus == OSSA_IO_XFR_ERROR_DIF_APPLICATION_TAG_MISMATCH || agIOStatus == OSSA_IO_XFR_ERROR_DIF_REFERENCE_TAG_MISMATCH
+ || agIOStatus == OSSA_IO_XFR_ERROR_DIF_CRC_MISMATCH)
+ {
+ TI_DBG1(("ttdsaIOCompleted: DIF detail UpperLBA 0x%08x LowerLBA 0x%08x\n", DifDetail->UpperLBA, DifDetail->LowerLBA));
+ }
+ switch (agIOStatus)
+ {
+ case OSSA_IO_ABORTED:
+ TI_DBG1(("ttdsaIOCompleted: ABORTED\n"));
+ status = tiIOFailed;
+ statusDetail = tiDetailAborted;
+ IOFailed = agTRUE;
+ break;
+#ifdef REMOVED
+ case OSSA_IO_OVERFLOW:
+ TI_DBG1(("ttdsaIOCompleted: OVERFLOW\n"));
+ status = tiIOOverRun;
+ IOFailed = agTRUE;
+ break;
+#endif
+ case OSSA_IO_UNDERFLOW:
+ TI_DBG1(("ttdsaIOCompleted: UNDERFLOW\n"));
+ status = tiIOUnderRun;
+ IOFailed = agTRUE;
+ break;
+ case OSSA_IO_ABORT_RESET:
+ TI_DBG1(("ttdsaIOCompleted: ABORT_RESET\n"));
+ status = tiIOFailed;
+ statusDetail = tiDetailAbortReset;
+ IOFailed = agTRUE;
+ break;
+ case OSSA_IO_XFR_ERROR_DEK_KEY_CACHE_MISS:
+ TI_DBG1(("ttdsaIOCompleted: OSSA_IO_XFR_ERROR_DEK_KEY_CACHE_MISS\n"));
+ status = tiIOEncryptError;
+ statusDetail = tiDetailDekKeyCacheMiss;
+ IOFailed = agTRUE;
+ break;
+ case OSSA_IO_XFR_ERROR_DEK_KEY_TAG_MISMATCH:
+ TI_DBG1(("ttdsaIOCompleted: OSSA_IO_XFR_ERROR_DEK_KEY_TAG_MISMATCH\n"));
+ status = tiIOEncryptError;
+ statusDetail = tiDetailDekKeyCacheMiss;
+ IOFailed = agTRUE;
+ break;
+ case OSSA_IO_XFR_ERROR_DIF_APPLICATION_TAG_MISMATCH:
+ TI_DBG1(("ttdsaIOCompleted: OSSA_IO_XFR_ERROR_DIF_APPLICATION_TAG_MISMATCH\n"));
+ status = tiIODifError;
+ statusDetail = tiDetailDifAppTagMismatch;
+ IOFailed = agTRUE;
+ break;
+ case OSSA_IO_XFR_ERROR_DIF_REFERENCE_TAG_MISMATCH:
+ TI_DBG1(("ttdsaIOCompleted: OSSA_IO_XFR_ERROR_DIF_REFERENCE_TAG_MISMATCH\n"));
+ status = tiIODifError;
+ statusDetail = tiDetailDifRefTagMismatch;
+ IOFailed = agTRUE;
+ break;
+ case OSSA_IO_XFR_ERROR_DIF_CRC_MISMATCH:
+ TI_DBG1(("ttdsaIOCompleted: OSSA_IO_XFR_ERROR_DIF_CRC_MISMATCH\n"));
+ status = tiIODifError;
+ statusDetail = tiDetailDifCrcMismatch;
+ IOFailed = agTRUE;
+ break;
+ case OSSA_IO_FAILED: /* fall through */
+ case OSSA_IO_NO_DEVICE: /* fall through */
+ //case OSSA_IO_NO_SUPPORT: /* fall through */ /*added to compile tgt_drv (TP)*/
+ case OSSA_IO_LINK_FAILURE: /* fall through */
+ case OSSA_IO_PROG_ERROR: /* fall through */
+ case OSSA_IO_DS_NON_OPERATIONAL: /* fall through */
+ case OSSA_IO_DS_IN_RECOVERY: /* fall through */
+ case OSSA_IO_TM_TAG_NOT_FOUND: /* fall through */
+ case OSSA_MPI_ERR_IO_RESOURCE_UNAVAILABLE: /* fall through */
+ default:
+ status = tiIOFailed;
+ statusDetail = tiDetailOtherError;
+ IOFailed = agTRUE;
+ TI_DBG1(("ttdsaIOCompleted: Fail!!!!!!! agIOStatus=0x%x agIOInfoLen=0x%x agOtherInfo=0x%x\n", agIOStatus, agIOInfoLen, agOtherInfo));
+ // ttdsaDumpallXchg(tiRoot);
+ if (agIOStatus == OSSA_IO_XFER_OPEN_RETRY_TIMEOUT)
+ {
+ TI_DBG1(("ttdsaIOCompleted: OSSA_IO_XFER_OPEN_RETRY_TIMEOUT ttdsaXchg->id 0x%x datalen 0x%x offset 0x%x agTag 0x%x\n",
+ ttdsaXchg->id,
+ ttdsaXchg->IORequestBody.transport.SAS.agSASRequestBody.sspTargetReq.dataLength,
+ ttdsaXchg->IORequestBody.transport.SAS.agSASRequestBody.sspTargetReq.offset,
+ ttdsaXchg->IORequestBody.transport.SAS.agSASRequestBody.sspTargetReq.agTag));
+ TI_DBG1(("ttdsaIOCompleted: statusSent %d responseSent %d\n", ttdsaXchg->statusSent, ttdsaXchg->responseSent));
+
+ }
+ break;
+ } /* switch */
+
+ if (IOFailed == agTRUE)
+ {
+ if (agIORequest->sdkData == agNULL)
+ {
+ tiIORequest_t tiIORequest;
+ TI_DBG1(("ttdsaIOCompleted: ERROR ttdsaXchg=%p agIOStatus= 0x%x\n",
+ ttdsaXchg,
+ agIOStatus ));
+ 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",
+ ttdsaXchg->agSSPCmndIU.cdb[0],
+ ttdsaXchg->agSSPCmndIU.cdb[1],
+ ttdsaXchg->agSSPCmndIU.cdb[2],
+ ttdsaXchg->agSSPCmndIU.cdb[3],
+ ttdsaXchg->agSSPCmndIU.cdb[4],
+ ttdsaXchg->agSSPCmndIU.cdb[5],
+ ttdsaXchg->agSSPCmndIU.cdb[6],
+ ttdsaXchg->agSSPCmndIU.cdb[7],
+ ttdsaXchg->agSSPCmndIU.cdb[8],
+ ttdsaXchg->agSSPCmndIU.cdb[9],
+ ttdsaXchg->agSSPCmndIU.cdb[10],
+ ttdsaXchg->agSSPCmndIU.cdb[11],
+ ttdsaXchg->agSSPCmndIU.cdb[12],
+ ttdsaXchg->agSSPCmndIU.cdb[13],
+ ttdsaXchg->agSSPCmndIU.cdb[14],
+ ttdsaXchg->agSSPCmndIU.cdb[15] ));
+
+ if (TD_XCHG_GET_STATE(ttdsaXchg) == TD_XCHG_STATE_INACTIVE)
+ {
+ TI_DBG1(("ttdsaIOCompleted: wrong DEQUEUE_THIS 1\n"));
+ }
+ if (ttdsaXchg->retries <= OPEN_RETRY_RETRIES && agIOStatus == OSSA_IO_XFER_OPEN_RETRY_TIMEOUT)
+ {
+ TI_DBG2(("ttdsaIOCompleted: 1 loc retries on OSSA_IO_XFER_OPEN_RETRY_TIMEOUT\n"));
+ if ( (agOtherInfo & 0x1) == 1)
+ {
+ /* repsonse phase */
+ TI_DBG2(("ttdsaIOCompleted: 0 loc response retry\n"));
+ /* repsonse retry */
+ saStatus = ttdsaSendResp(ttdsaXchg->agRoot, ttdsaXchg);
+ if (saStatus == AGSA_RC_SUCCESS)
+ {
+ TI_DBG2(("ttdsaIOCompleted: 0 loc retried\n"));
+ ttdsaXchg->retries++;
+ }
+ else
+ {
+ TI_DBG1(("ttdsaIOCompleted: 0 loc retry failed\n"));
+ ttdsaXchg->retries = 0;
+ /*
+ * because we are freeing up the exchange
+ * we must let the oslayer know that
+ * we are releasing the resources by
+ * setting the tdData to NULL
+ */
+ tiIORequest = ttdsaXchg->IORequestBody.IOType.TargetIO.tiIORequest;
+ tiIORequest.tdData = agNULL;
+
+ ostiTargetIOError(
+ tiRoot,
+ &tiIORequest,
+ status,
+ statusDetail
+ );
+
+ /* clean up resources */
+ ttdsaXchgFreeStruct(tiRoot,ttdsaXchg);
+ }
+ }
+ else if ( (ttdsaXchg->readRspCollapsed == agTRUE) || (ttdsaXchg->wrtRspCollapsed == agTRUE) )
+ {
+ saStatus = saSSPStart(
+ ttdsaXchg->agRoot, /* agRoot, */
+ &ttdsaXchg->IORequestBody.agIORequest,
+ 0,
+ ttdsaXchg->DeviceData->agDevHandle, /* agDevHandle, */
+ ttdsaXchg->readRspCollapsed ? AGSA_SSP_TGT_READ_GOOD_RESP : AGSA_SSP_TGT_WRITE_GOOD_RESP,
+ &ttdsaXchg->IORequestBody.transport.SAS.agSASRequestBody,
+ agNULL,
+ &ossaSSPCompleted
+ );
+ if (saStatus == AGSA_RC_SUCCESS)
+ {
+ TI_DBG1(("ttdsaIOCompleted: 1 loc retried\n"));
+ ttdsaXchg->retries++;
+ }
+ else
+ {
+ TI_DBG1(("ttdsaIOCompleted: 1 loc retry failed\n"));
+ ttdsaXchg->retries = 0;
+ /*
+ * because we are freeing up the exchange
+ * we must let the oslayer know that
+ * we are releasing the resources by
+ * setting the tdData to NULL
+ */
+ tiIORequest = ttdsaXchg->IORequestBody.IOType.TargetIO.tiIORequest;
+ tiIORequest.tdData = agNULL;
+
+ ostiTargetIOError(
+ tiRoot,
+ &tiIORequest,
+ status,
+ statusDetail
+ );
+
+ /* clean up resources */
+ ttdsaXchgFreeStruct(tiRoot,ttdsaXchg);
+ }
+ }
+ else
+ {
+ if (ttdsaXchg->responseSent == agFALSE)
+ {
+ saStatus = saSSPStart(
+ ttdsaXchg->agRoot, /* agRoot, */
+ &ttdsaXchg->IORequestBody.agIORequest, /*agIORequest, */
+ 0, /* queue number */
+ ttdsaXchg->DeviceData->agDevHandle, /* agDevHandle, */
+ ttdsaXchg->XchType,
+ &ttdsaXchg->IORequestBody.transport.SAS.agSASRequestBody,
+ agNULL,
+ &ossaSSPCompleted
+ );
+ }
+ else
+ {
+ /* repsonse retry */
+ TI_DBG1(("ttdsaIOCompleted: 2 loc reponse retry\n"));
+ saStatus = ttdsaSendResp(ttdsaXchg->agRoot, ttdsaXchg);
+ }
+ if (saStatus == AGSA_RC_SUCCESS)
+ {
+ TI_DBG1(("ttdsaIOCompleted: 2 loc retried\n"));
+ ttdsaXchg->retries++;
+ }
+ else
+ {
+ TI_DBG1(("ttdsaIOCompleted: 2 loc retry failed\n"));
+ ttdsaXchg->retries = 0;
+ /*
+ * because we are freeing up the exchange
+ * we must let the oslayer know that
+ * we are releasing the resources by
+ * setting the tdData to NULL
+ */
+ tiIORequest = ttdsaXchg->IORequestBody.IOType.TargetIO.tiIORequest;
+ tiIORequest.tdData = agNULL;
+
+ ostiTargetIOError(
+ tiRoot,
+ &tiIORequest,
+ status,
+ statusDetail
+ );
+
+ /* clean up resources */
+ ttdsaXchgFreeStruct(tiRoot,ttdsaXchg);
+ }
+ }
+ }
+ else
+ {
+ ttdsaXchg->retries = 0;
+ /*
+ * because we are freeing up the exchange
+ * we must let the oslayer know that
+ * we are releasing the resources by
+ * setting the tdData to NULL
+ */
+ tiIORequest = ttdsaXchg->IORequestBody.IOType.TargetIO.tiIORequest;
+ tiIORequest.tdData = agNULL;
+
+ ostiTargetIOError(
+ tiRoot,
+ &tiIORequest,
+ status,
+ statusDetail
+ );
+
+ /* clean up resources */
+ ttdsaXchgFreeStruct(tiRoot,ttdsaXchg);
+ }
+ } /* saData == agNULL */
+ else
+ {
+ tiIORequest_t tiIORequest;
+
+ TI_DBG1(("ttdsaIOCompleted: 2\n"));
+ if (TD_XCHG_GET_STATE(ttdsaXchg) == TD_XCHG_STATE_INACTIVE)
+ {
+ TI_DBG1(("ttdsaIOCompleted: wrong DEQUEUE_THIS 2\n"));
+ }
+ if (ttdsaXchg->retries <= OPEN_RETRY_RETRIES && agIOStatus == OSSA_IO_XFER_OPEN_RETRY_TIMEOUT)
+ {
+ TI_DBG1(("ttdsaIOCompleted: 2 loc retries on OSSA_IO_XFER_OPEN_RETRY_TIMEOUT\n"));
+ if ( (agOtherInfo & 0x1) == 1)
+ {
+ /* repsonse phase */
+ TI_DBG2(("ttdsaIOCompleted: 0 loc response retry\n"));
+ /* repsonse retry */
+ saStatus = ttdsaSendResp(ttdsaXchg->agRoot, ttdsaXchg);
+ if (saStatus == AGSA_RC_SUCCESS)
+ {
+ TI_DBG2(("ttdsaIOCompleted: 0 loc retried\n"));
+ ttdsaXchg->retries++;
+ }
+ else
+ {
+ TI_DBG1(("ttdsaIOCompleted: 0 loc retry failed\n"));
+ ttdsaXchg->retries = 0;
+ /*
+ * because we are freeing up the exchange
+ * we must let the oslayer know that
+ * we are releasing the resources by
+ * setting the tdData to NULL
+ */
+ tiIORequest = ttdsaXchg->IORequestBody.IOType.TargetIO.tiIORequest;
+ tiIORequest.tdData = agNULL;
+
+ ostiTargetIOError(
+ tiRoot,
+ &tiIORequest,
+ status,
+ statusDetail
+ );
+
+ /* clean up resources */
+ ttdsaXchgFreeStruct(tiRoot,ttdsaXchg);
+ }
+ }
+ else if ( (ttdsaXchg->readRspCollapsed == agTRUE) || (ttdsaXchg->wrtRspCollapsed == agTRUE) )
+ {
+ saStatus = saSSPStart(
+ ttdsaXchg->agRoot, /* agRoot, */
+ &ttdsaXchg->IORequestBody.agIORequest, /* agIORequest, */
+ 0, /* queue number */
+ ttdsaXchg->DeviceData->agDevHandle, /* agDevHandle, */
+ ttdsaXchg->readRspCollapsed ? AGSA_SSP_TGT_READ_GOOD_RESP : AGSA_SSP_TGT_WRITE_GOOD_RESP,
+ &ttdsaXchg->IORequestBody.transport.SAS.agSASRequestBody,
+ agNULL,
+ &ossaSSPCompleted
+ );
+ if (saStatus == AGSA_RC_SUCCESS)
+ {
+ TI_DBG1(("ttdsaIOCompleted: 1 loc retried\n"));
+ ttdsaXchg->retries++;
+ }
+ else
+ {
+ TI_DBG1(("ttdsaIOCompleted: 1 loc retry failed\n"));
+ ttdsaXchg->retries = 0;
+ /*
+ * because we are freeing up the exchange
+ * we must let the oslayer know that
+ * we are releasing the resources by
+ * setting the tdData to NULL
+ */
+ tiIORequest = ttdsaXchg->IORequestBody.IOType.TargetIO.tiIORequest;
+ tiIORequest.tdData = agNULL;
+
+ ostiTargetIOError(
+ tiRoot,
+ &tiIORequest,
+ status,
+ statusDetail
+ );
+
+ /* clean up resources */
+ ttdsaXchgFreeStruct(tiRoot,ttdsaXchg);
+ }
+ }
+ else
+ {
+ TI_DBG1(("ttdsaIOCompleted: 2 loc ttdsaXchg->id 0x%x datalen 0x%x offset 0x%x agTag 0x%x\n",
+ ttdsaXchg->id,
+ ttdsaXchg->IORequestBody.transport.SAS.agSASRequestBody.sspTargetReq.dataLength,
+ ttdsaXchg->IORequestBody.transport.SAS.agSASRequestBody.sspTargetReq.offset,
+ ttdsaXchg->IORequestBody.transport.SAS.agSASRequestBody.sspTargetReq.agTag));
+ if (ttdsaXchg->responseSent == agFALSE)
+ {
+ saStatus = saSSPStart(
+ ttdsaXchg->agRoot, /* agRoot, */
+ &ttdsaXchg->IORequestBody.agIORequest, /* agIORequest, */
+ 0, /* queue number */
+ ttdsaXchg->DeviceData->agDevHandle, /* agDevHandle, */
+ ttdsaXchg->XchType,
+ &ttdsaXchg->IORequestBody.transport.SAS.agSASRequestBody,
+ agNULL,
+ &ossaSSPCompleted
+ );
+ }
+ else
+ {
+ TI_DBG1(("ttdsaIOCompleted: 2 loc response retry\n"));
+ /* repsonse retry */
+ saStatus = ttdsaSendResp(ttdsaXchg->agRoot, ttdsaXchg);
+ }
+ if (saStatus == AGSA_RC_SUCCESS)
+ {
+ TI_DBG1(("ttdsaIOCompleted: 2 loc retried\n"));
+ ttdsaXchg->retries++;
+ }
+ else
+ {
+ TI_DBG1(("ttdsaIOCompleted: 2 loc retry failed\n"));
+ ttdsaXchg->retries = 0;
+ /*
+ * because we are freeing up the exchange
+ * we must let the oslayer know that
+ * we are releasing the resources by
+ * setting the tdData to NULL
+ */
+ tiIORequest = ttdsaXchg->IORequestBody.IOType.TargetIO.tiIORequest;
+ tiIORequest.tdData = agNULL;
+
+ ostiTargetIOError(
+ tiRoot,
+ &tiIORequest,
+ status,
+ statusDetail
+ );
+
+ /* clean up resources */
+ ttdsaXchgFreeStruct(tiRoot,ttdsaXchg);
+ }
+ }
+ }
+ else
+ {
+ TI_DBG1(("ttdsaIOCompleted: retry is over\n"));
+ ttdsaXchg->retries = 0;
+
+ tiIORequest = ttdsaXchg->IORequestBody.IOType.TargetIO.tiIORequest;
+ tiIORequest.tdData = agNULL;
+
+ ostiTargetIOError(
+ tiRoot,
+ &tiIORequest,
+ status,
+ statusDetail
+ );
+
+ /* clean up resources */
+ ttdsaXchgFreeStruct(tiRoot,ttdsaXchg);
+ }
+ } /* saData != agNULL */
+ }/* if (IOFailed == agTRUE) */
+ } /* not TMrequest */
+ else /* TMrequest */
+ {
+ TI_DBG1(("ttdsaIOCompleted: TM request\n"));
+ TI_DBG1(("ttdsaIOCompleted: TM initiator tag 0x%x\n", ttdsaXchg->tag));
+
+ switch(agIOStatus)
+ {
+ case OSSA_IO_SUCCESS:
+ TI_DBG1(("ttdsaIOCompleted: success\n"));
+ status = tiIOSuccess;
+ break;
+ case OSSA_IO_ABORTED:
+ TI_DBG1(("ttdsaIOCompleted: ABORTED\n"));
+ status = tiIOFailed;
+ statusDetail = tiDetailAborted;
+ IOFailed = agTRUE;
+ break;
+ case OSSA_IO_ABORT_RESET:
+ TI_DBG1(("ttdsaIOCompleted: ABORT_RESET\n"));
+ status = tiIOFailed;
+ statusDetail = tiDetailAbortReset;
+ IOFailed = agTRUE;
+ break;
+#ifdef REMOVED
+ case OSSA_IO_OVERFLOW: /* fall through */
+#endif
+ case OSSA_IO_UNDERFLOW: /* fall through */
+ case OSSA_IO_FAILED: /* fall through */
+#ifdef REMOVED
+ case OSSA_IO_NOT_VALID: /* fall through */
+#endif
+ case OSSA_IO_NO_DEVICE: /* fall through */
+ //case OSSA_IO_NO_SUPPORT: /* fall through */ /*added to compile tgt_drv (TP)*/
+ case OSSA_IO_LINK_FAILURE: /* fall through */
+ case OSSA_IO_PROG_ERROR: /* fall through */
+ case OSSA_IO_DS_NON_OPERATIONAL: /* fall through */
+ case OSSA_IO_DS_IN_RECOVERY: /* fall through */
+ case OSSA_IO_TM_TAG_NOT_FOUND: /* fall through */
+ case OSSA_MPI_ERR_IO_RESOURCE_UNAVAILABLE: /* fall through */
+ default:
+ status = tiIOFailed;
+ statusDetail = tiDetailOtherError;
+ IOFailed = agTRUE;
+ break;
+ } /* switch */
+
+ /* for not found IO, we don't call OS */
+ if (ttdsaXchg->io_found == agTRUE)
+ {
+ ostiTargetTmCompleted(
+ tiRoot,
+ ttdsaXchg->IORequestBody.tiIORequest,
+ status,
+ statusDetail
+ );
+ }
+
+ /* clean up resources */
+ ttdsaXchgFreeStruct(tiRoot, ttdsaXchg);
+
+
+ } /* TM Request */
+ return;
+}
+
+osGLOBAL void
+ttdsaTMProcess(
+ tiRoot_t *tiRoot,
+ ttdsaXchg_t *ttdsaXchg
+)
+{
+ tdsaRoot_t *tdsaRoot = (tdsaRoot_t *) tiRoot->tdData;
+ tdsaContext_t *tdsaAllShared = (tdsaContext_t *)&tdsaRoot->tdsaAllShared;
+
+ ttdsaTgt_t *Target = (ttdsaTgt_t *)tdsaAllShared->ttdsaTgt;
+ agsaSSPScsiTaskMgntReq_t *agTMIU;
+ bit8 TMFun;
+ bit32 tiTMFun;
+ tiIORequest_t *reftiIORequest = agNULL;
+ tdList_t *IOList;
+ bit32 IOFound = agFALSE;
+ ttdsaXchg_t *tmp_ttdsaXchg = agNULL;
+ agsaRoot_t *agRoot = (agsaRoot_t *)&(tdsaAllShared->agRootNonInt);
+ agsaIORequest_t *agIORequest = agNULL;
+ agsaIORequest_t *agIOAbortRequest = agNULL;
+ tdsaDeviceData_t *oneDeviceData = agNULL;
+ agsaDevHandle_t *agDevHandle = agNULL;
+
+ TI_DBG1(("ttdsaTMProcess: start\n"));
+
+ ttdsaXchg->isTMRequest = agTRUE;
+
+ agTMIU = (agsaSSPScsiTaskMgntReq_t *)&(ttdsaXchg->agTMIU);
+ TMFun = agTMIU->taskMgntFunction;
+
+ switch (TMFun)
+ {
+ case AGSA_ABORT_TASK:
+ TI_DBG1(("ttdsaTMProcess: ABORT_TASK\n"));
+ tiTMFun = AG_ABORT_TASK;
+ break;
+ case AGSA_ABORT_TASK_SET:
+ TI_DBG1(("ttdsaTMProcess: ABORT_TASK_SET\n"));
+ tiTMFun = AG_ABORT_TASK_SET;
+ break;
+ case AGSA_CLEAR_TASK_SET:
+ TI_DBG1(("ttdsaTMProcess: CLEAR_TASK_SET\n"));
+ tiTMFun = AG_CLEAR_TASK_SET;
+ break;
+ case AGSA_LOGICAL_UNIT_RESET:
+ TI_DBG1(("ttdsaTMProcess: LOGICAL_UNIT_RESET\n"));
+ tiTMFun = AG_LOGICAL_UNIT_RESET;
+ break;
+ case AGSA_CLEAR_ACA:
+ TI_DBG1(("ttdsaTMProcess: CLEAR_ACA\n"));
+ tiTMFun = AG_CLEAR_ACA;
+ break;
+ case AGSA_QUERY_TASK:
+ TI_DBG1(("ttdsaTMProcess: QUERY_TASK\n"));
+ tiTMFun = AG_QUERY_TASK;
+ break;
+ default:
+ TI_DBG1(("ttdsaTMProcess: RESERVED TM 0x%x %d\n", TMFun, TMFun));
+ tiTMFun = 0xff; /* unknown task management request */
+ break;
+ }
+
+ /*
+ * Give the OS Specific module to apply it's Task management policy.
+ */
+
+
+ /*
+ osGLOBAL void ostiTaskManagement (
+ tiRoot_t *tiRoot,
+ bit32 task,
+ bit8 *scsiLun,
+ tiIORequest_t *refTiIORequest,
+ tiIORequest_t *tiTMRequest,
+ tiDeviceHandle_t *tiDeviceHandle);
+ */
+ if (TMFun == AGSA_ABORT_TASK)
+ {
+ TI_DBG1(("ttdsaTMProcess: if abort task; to be tested \n"));
+ /*
+ needs to find a reftIIORequest and set it
+ */
+
+ IOList = Target->ttdsaXchgData.xchgBusyList.flink;
+ IOFound = agFALSE;
+
+ /* search through the current IOList */
+ while (IOList != &Target->ttdsaXchgData.xchgBusyList)
+ {
+
+ tmp_ttdsaXchg = TDLIST_OBJECT_BASE(ttdsaXchg_t, XchgLinks, IOList);
+ if (tmp_ttdsaXchg->tag == agTMIU->tagOfTaskToBeManaged)
+ {
+ TI_DBG1(("ttdsaTMProcess: tag 0x%x\n",tmp_ttdsaXchg->tag));
+ IOFound = agTRUE;
+ break;
+ }
+ IOList = IOList->flink;
+ } /* while */
+
+ if (IOFound == agTRUE)
+ {
+
+ TI_DBG1(("ttdsaTMProcess: found \n"));
+ /* call saSSPAbort() */
+
+ TI_DBG1(("ttdsaTMProcess: loc 1\n"));
+ /* abort taskmanagement itself */
+ agIOAbortRequest = (agsaIORequest_t *)&(ttdsaXchg->IORequestBody.agIORequest);
+
+ /* IO to be aborted */
+ agIORequest = (agsaIORequest_t *)&(tmp_ttdsaXchg->IORequestBody.agIORequest);
+ oneDeviceData = tmp_ttdsaXchg->DeviceData;
+ agDevHandle = oneDeviceData->agDevHandle;
+
+ if (agIORequest == agNULL)
+ {
+ TI_DBG1(("ttdsaTMProcess: agIORequest is NULL\n"));
+ }
+ else
+ {
+ TI_DBG1(("ttdsaTMProcess: agIORequest is NOT NULL\n"));
+ if (agIORequest->sdkData == agNULL)
+ {
+ TI_DBG1(("ttdsaTMProcess: agIORequest->saData is NULL\n"));
+ }
+ else
+ {
+ TI_DBG1(("ttdsaTMProcess: agIORequest->saData is NOT NULL\n"));
+#ifdef RPM_SOC
+ saSSPAbort(agRoot, agIORequest);
+#else
+ saSSPAbort(agRoot, agIOAbortRequest,0,agDevHandle,0,agIORequest, agNULL);
+#endif
+ }
+ }
+
+ } /* FOUND */
+ else
+ {
+ ttdsaXchg->io_found = agFALSE;
+ tiTGTSendTmResp(tiRoot,
+ ttdsaXchg->IORequestBody.tiIORequest,
+ tiError /* this is FUNCTION_FAILED */ );
+ TI_DBG1(("ttdsaTMProcess: ABORT_TASK not found\n"));
+ return;
+ }
+
+ } /* ABORT_TASK */
+ /*
+ reftiIORequest: referred IO request.
+ If found, not null. But not used in ramdisk
+ */
+ TI_DBG1(("ttdsaTMProcess: calling ostiTaskManagement\n"));
+ ostiTaskManagement(
+ tiRoot,
+ tiTMFun,
+ ttdsaXchg->agTMIU.lun,
+ reftiIORequest,
+ ttdsaXchg->IORequestBody.tiIORequest,
+ &ttdsaXchg->DeviceData->tiDeviceHandle
+ );
+
+
+
+ return;
+}
+
+/*****************************************************************************
+ *
+ * tiTGTIOAbort
+ *
+ * Purpose: This function is called to abort an IO previously reported
+ * to oslayer through ostiProcessRequest() function.
+ *
+ * Parameters:
+ * tiRoot: Pointer to driver Instance.
+ * tiIORequest: Pointer to the I/O request context for this I/O.
+ * This context was initially passed to the OS Specific
+ * Module in ostiProcessScsiReq().
+ * Return:
+ * tiSuccess: Abort request was successfully initiated
+ * tiBusy: No resources available, try again later
+ * tiError: Other errors that prevent the abort request from being
+ * started
+ * Note:
+ *
+ *****************************************************************************/
+osGLOBAL bit32
+tiTGTIOAbort (
+ tiRoot_t *tiRoot,
+ tiIORequest_t *taskTag
+)
+{
+ ttdsaXchg_t *ttdsaXchg;
+ ttdsaXchg_t *ttdsaIOAbortXchg;
+ tdsaRoot_t *tdsaRoot = (tdsaRoot_t *) tiRoot->tdData;
+ tdsaContext_t *tdsaAllShared = (tdsaContext_t *)&tdsaRoot->tdsaAllShared;
+ agsaRoot_t *agRoot = (agsaRoot_t *)&(tdsaAllShared->agRootNonInt);
+ agsaIORequest_t *agIORequest = agNULL;
+ agsaIORequest_t *agIOAbortRequest = agNULL;
+ tdsaDeviceData_t *oneDeviceData = agNULL;
+ agsaDevHandle_t *agDevHandle = agNULL;
+
+ TI_DBG1(("tiTGTIOAbort: start\n"));
+
+ ttdsaXchg = (ttdsaXchg_t *)taskTag->tdData;
+
+ if (ttdsaXchg == agNULL)
+ {
+ TI_DBG1(("tiTGTIOAbort: IOError 1 \n"));
+ /*
+ * this exchange has already been freed.
+ * No need to free it
+ */
+ ostiTargetIOError(
+ tiRoot,
+ taskTag,
+ tiIOFailed,
+ tiDetailAborted
+ );
+ }
+ else if (ttdsaXchg->IORequestBody.agIORequest.sdkData == agNULL)
+ {
+ TI_DBG1(("tiTGTIOAbort: IOError 2 \n"));
+ /* We have not issued this IO to the salayer.
+ * Abort it right here.
+ */
+ if (TD_XCHG_GET_STATE(ttdsaXchg) == TD_XCHG_STATE_INACTIVE)
+ {
+ TI_DBG1(("tiTGTIOAbort: wrong DEQUEUE_THIS\n"));
+ }
+
+ TI_DBG1(("tiTGTIOAbort: IOError 3\n"));
+
+ ostiTargetIOError(
+ tiRoot,
+ taskTag,
+ tiIOFailed,
+ tiDetailAborted
+ );
+ TI_DBG1(("tiTGTIOAbort: IOError 4\n"));
+
+ ttdsaXchgFreeStruct(
+ ttdsaXchg->tiRoot,
+ ttdsaXchg
+ );
+ TI_DBG1(("tiTGTIOAbort: IOError 5\n"));
+
+ }
+ else /* to be tested */
+ {
+ TI_DBG1(("tiTGTIOAbort: aborting; to be tested \n"));
+ /* abort io request itself */
+ ttdsaIOAbortXchg = ttdsaXchgGetStruct(agRoot);
+
+ if (ttdsaIOAbortXchg == agNULL)
+ {
+ TI_DBG1(("tiTGTIOAbort: no free xchg structures\n"));
+ // ttdsaDumpallXchg(tiRoot);
+ return tiError;
+ }
+ ttdsaIOAbortXchg->agRoot = agRoot;
+ ttdsaIOAbortXchg->tiRoot = tiRoot;
+ agIOAbortRequest= &(ttdsaXchg->IORequestBody.agIORequest);
+ /* remember IO to be aborted */
+ ttdsaIOAbortXchg->tiIOToBeAbortedRequest = taskTag;
+ ttdsaIOAbortXchg->XchgToBeAborted = ttdsaXchg;
+
+ // ttdsaIOAbortXchg->FrameType = SAS_TM;
+
+ /* io is being aborted */
+ ttdsaXchg->oslayerAborting = agTRUE;
+ agIORequest = (agsaIORequest_t *)&(ttdsaXchg->IORequestBody.agIORequest);
+ oneDeviceData = ttdsaXchg->DeviceData;
+ if (oneDeviceData == agNULL)
+ {
+ TI_DBG1(("tiTGTIOAbort: oneDeviceData is null; wrong\n"));
+ }
+ else
+ {
+ agDevHandle = oneDeviceData->agDevHandle;
+ ttdsaIOAbortXchg->DeviceData = oneDeviceData;
+ }
+#ifdef RPM_SOC
+ saSSPAbort(agRoot, agIORequest);
+#else
+ saSSPAbort(agRoot, agIOAbortRequest,0,agDevHandle,0,agIORequest, agNULL);
+ }
+
+ return tiSuccess;
+}
+
+osGLOBAL bit32
+tiTGTIOAbortAll(
+ tiRoot_t *tiRoot,
+ tiDeviceHandle_t *tiDeviceHandle
+)
+{
+ agsaRoot_t *agRoot = agNULL;
+ tdsaDeviceData_t *oneDeviceData = agNULL;
+ bit32 status = tiError;
+
+ TI_DBG3(("tiTGTIOAbortAll: start\n"));
+
+ oneDeviceData = (tdsaDeviceData_t *)tiDeviceHandle->tdData;
+
+ if (oneDeviceData == agNULL)
+ {
+ TI_DBG1(("tiTGTIOAbortAll: oneDeviceData is NULL!!!\n"));
+ return tiError;
+ }
+
+ /* for hotplug */
+ if (oneDeviceData->valid != agTRUE || oneDeviceData->registered != agTRUE ||
+ oneDeviceData->tdPortContext == agNULL )
+ {
+ TI_DBG1(("tiTGTIOAbortAll: NO Device did %d\n", oneDeviceData->id ));
+ TI_DBG1(("tiTGTIOAbortAll: device AddrHi 0x%08x\n", oneDeviceData->SASAddressID.sasAddressHi));
+ TI_DBG1(("tiTGTIOAbortAll: device AddrLo 0x%08x\n", oneDeviceData->SASAddressID.sasAddressLo));
+ return tiError;
+ }
+
+ agRoot = oneDeviceData->agRoot;
+
+ if (agRoot == agNULL)
+ {
+ TI_DBG1(("tiTGTIOAbortAll: agRoot is NULL!!!\n"));
+ return tiError;
+ }
+
+ /* this is processed in ossaSSPAbortCB, ossaSATAAbortCB, ossaSMPAbortCB */
+ oneDeviceData->OSAbortAll = agTRUE;
+
+ status = tdsaAbortAll(tiRoot, agRoot, oneDeviceData);
+
+ return status;
+
+}
+
+
+/*****************************************************************************
+ *
+ * tiTGTSendTmResp
+ *
+ * Purpose: This function is called to abort an IO previously reported
+ * to oslayer through ostiProcessRequest() function.
+ *
+ * Parameters:
+ * tiRoot: Pointer to driver Instance.
+ * tiIORequest: Pointer to the I/O request context for this I/O.
+ * This context was initially passed to the OS Specific
+ * Module in ostiProcessScsiReq().
+ * Return:
+ * tiSuccess: Abort request was successfully initiated
+ * tiBusy: No resources available, try again later
+ * tiError: Other errors that prevent the abort request from being
+ * started
+ * Note:
+ *
+ *****************************************************************************/
+osGLOBAL bit32
+tiTGTSendTmResp(
+ tiRoot_t *tiRoot,
+ tiIORequest_t *tiTMRequest,
+ bit32 status
+)
+{
+ ttdsaXchg_t *ttdsaXchg;
+ sas_resp_t *SASResp;
+ bit32 tdStatus;
+ TI_DBG1(("tiTGTSendTmResp: start 1\n"));
+
+ ttdsaXchg = (ttdsaXchg_t *)tiTMRequest->tdData;
+ /* set the response and send it */
+ /* response status is 0 */
+ /* status is TM status */
+
+ TI_DBG1(("tiTGTSendTmResp: start 2\n"));
+ SASResp = (sas_resp_t *)ttdsaXchg->resp.virtAddr;
+ TI_DBG1(("tiTGTSendTmResp: start 3\n"));
+
+ if (ttdsaXchg->FrameType == SAS_TM)
+ {
+ SASResp->agResp.status = 0;
+ SASResp->agResp.dataPres = RESPONSE_DATA;
+ OSSA_WRITE_BE_32(agRoot, SASResp->agResp.responsedataLen, 0, RESPONSE_DATA_LEN);
+ OSSA_WRITE_BE_32(agRoot, SASResp->agResp.senseDataLen, 0, 0);
+ switch (status)
+ {
+ case tiSuccess:
+ TI_DBG2(("tiTGTSendTmResp: tiSuccess\n"));
+ SASResp->RespData[3] = AGSA_TASK_MANAGEMENT_FUNCTION_SUCCEEDED;
+ break;
+ case tiError:
+ TI_DBG1(("tiTGTSendTmResp: tiError\n"));
+ SASResp->RespData[3] = AGSA_TASK_MANAGEMENT_FUNCTION_FAILED;
+ break;
+ case tiBusy:
+ TI_DBG1(("tiTGTSendTmResp: tibusy\n"));
+ SASResp->RespData[3] = AGSA_TASK_MANAGEMENT_FUNCTION_FAILED;
+ break;
+ case tiIONoDevice:
+ TI_DBG1(("tiTGTSendTmResp: tiionodevicee\n"));
+ SASResp->RespData[3] = AGSA_TASK_MANAGEMENT_FUNCTION_FAILED;
+ break;
+ case tiMemoryTooLarge:
+ TI_DBG1(("tiTGTSendTmResp: timemorytoolarge\n"));
+ SASResp->RespData[3] = AGSA_TASK_MANAGEMENT_FUNCTION_FAILED;
+ break;
+ case tiMemoryNotAvail:
+ TI_DBG1(("tiTGTSendTmResp: timemorynotavail\n"));
+ SASResp->RespData[3] = AGSA_TASK_MANAGEMENT_FUNCTION_FAILED;
+ break;
+ case tiInvalidHandle:
+ TI_DBG1(("tiTGTSendTmResp: tiinvalidhandle\n"));
+ SASResp->RespData[3] = AGSA_TASK_MANAGEMENT_FUNCTION_FAILED;
+ break;
+ case tiNotSupported:
+ TI_DBG1(("tiTGTSendTmResp: tiNotsupported\n"));
+ SASResp->RespData[3] = AGSA_TASK_MANAGEMENT_FUNCTION_NOT_SUPPORTED;
+ break;
+ case tiReject:
+ TI_DBG1(("tiTGTSendTmResp: tireject\n"));
+ SASResp->RespData[3] = AGSA_TASK_MANAGEMENT_FUNCTION_FAILED;
+ break;
+ case tiIncorrectLun:
+ TI_DBG1(("tiTGTSendTmResp: tiincorrectlun\n"));
+ SASResp->RespData[3] = AGSA_INCORRECT_LOGICAL_UNIT_NUMBER;
+ break;
+ default:
+ TI_DBG1(("tiTGTSendTmResp: default\n"));
+ SASResp->RespData[3] = AGSA_TASK_MANAGEMENT_FUNCTION_FAILED;
+ break;
+ }
+ ttdsaXchg->resp.length = sizeof(agsaSSPResponseInfoUnit_t) + RESPONSE_DATA_LEN;
+ ttdsaXchg->statusSent = agTRUE;
+ }
+ else
+ {
+ TI_DBG1(("tiTGTSendTmResp: not TM frame\n"));
+ return tiError;
+ }
+
+ tdStatus = ttdsaSendResp(ttdsaXchg->agRoot, ttdsaXchg);
+ if (tdStatus == AGSA_RC_SUCCESS)
+ {
+ TI_DBG1(("tiTGTSendTmResp: send success\n"));
+ return tiSuccess;
+ }
+ else if (tdStatus == AGSA_RC_FAILURE)
+ {
+ TI_DBG1(("tiTGTSendTmResp: sending not successful\n"));
+ return tiError;
+ }
+ else
+ {
+ TI_DBG1(("tiTGTSendTmResp: send busy\n"));
+ return tiBusy;
+ }
+
+
+#ifdef REMOVED
+
+ tiTGTSetResp(tiRoot, tiTMRequest, 0, 0, 0);
+#endif
+
+#ifdef REMOVED
+
+ if (ttdsaXchg->resp.length != 0)
+ {
+ TI_DBG1(("tiTGTSendTmResp: respsonse is set \n"));
+ TI_DBG1(("tiTGTSendTmResp: resp.length 0x%x\n",
+ ttdsaXchg->resp.length));
+ ttdsaXchg->responseSent = agTRUE;
+
+ ttdsaSendResp(ttdsaXchg->agRoot, ttdsaXchg);
+ }
+ else
+ {
+ /* no respsonse is set, direct call */
+ TI_DBG1(("tiTGTSendTmResp: direct call\n"));
+ tiTGTSetResp(tiRoot, tiTMRequest, 0, 0, 0);
+ ttdsaXchg->responseSent = agTRUE;
+ ttdsaSendResp(ttdsaXchg->agRoot, ttdsaXchg);
+ }
+
+#define TASK_MANAGEMENT_FUNCTION_COMPLETE 0x0
+#define INVALID_FRAME 0x2
+#define TASK_MANAGEMENT_FUNCTION_NOT_SUPPORTED 0x4
+#define TASK_MANAGEMENT_FUNCTION_FAILED 0x5
+#define TASK_MANAGEMENT_FUNCTION_SUCCEEDED 0x8
+#define INVALID_LOGICAL_UNIT_NUMBER 0x9
+#endif
+
+}
+
+
+
+/*****************************************************************************
+ *
+ * tiTGTSenseBufferGet
+ *
+ * Purpose: This function is called to get the address of sense buffer from
+ * the target specific Transport Dependent Layer.
+ *
+ * Parameters:
+ * tiRoot: Pointer to driver/port instance.
+ * tiIORequest: I/O request context.
+ * length: Lenght in bytes of the sense buffer.
+ *
+ * Return: none
+ *
+ * Note:
+ *
+ *****************************************************************************/
+osGLOBAL void *tiTGTSenseBufferGet( tiRoot_t *tiRoot,
+ tiIORequest_t *tiIORequest,
+ bit32 length
+)
+{
+
+ ttdsaXchg_t *ttdsaXchg;
+
+ ttdsaXchg = (ttdsaXchg_t *)tiIORequest->tdData;
+
+ TI_DBG4(("tiTGTSenseBufferGet: start\n"));
+ OS_ASSERT((length <= 64), "length too big in tiTGTSenseBufferGet");
+
+ return &ttdsaXchg->resp.virtAddr[sizeof(agsaSSPResponseInfoUnit_t)];
+}
+
+/*****************************************************************************
+ *
+ * tiTGTSetResp
+ *
+ * Purpose: This function is called when the target OS Specific Module is ready
+ * to send a response with the next tiTGTIOStart()
+ * function call. This function allows the TD Layer to setup its
+ * portion of the status and mark it to be sent on the next
+ * tiTGTIOStart() function call.
+ *
+ * Parameters:
+ * tiRoot: Pointer to driver Instance.
+ * tiIORequest: Pointer to the I/O request context for this I/O.
+ * This context was initially passed to the OS Specific Module
+ * in ostiProcessScsiReq().
+ * dataSentLength: How much data sent or received for this Request.
+ * ScsiStatus: Status for this SCSI command.
+ * senseLength: Length of sense data if any.
+ *
+ * Return: none
+ *
+ * Note:
+ *
+ *****************************************************************************/
+osGLOBAL void
+tiTGTSetResp( tiRoot_t *tiRoot,
+ tiIORequest_t *tiIORequest,
+ bit32 dataSentLength,
+ bit8 ScsiStatus,
+ bit32 senseLength
+)
+{
+ /* no call to saSSPStart() in this function */
+ /*
+ response is normally for task management
+ sense is for command with error
+ need to know this is for TM or cmd
+ */
+ /*
+ tiTGTSetResp(rdRoot->pTiRoot,
+ rdIORequest->tiIORequest,
+ dataSentLength,
+ ScsiStatus,
+ senseLength);
+
+
+
+ */
+ ttdsaXchg_t *ttdsaXchg;
+ tdsaRoot_t *tdsaRoot = (tdsaRoot_t *)tiRoot->tdData;
+#ifdef REMOVED
+ agsaSSPTargetResponse_t *agSSPTargetResp;
+#endif
+ sas_resp_t *SASResp;
+ bit32 TotalRespLen = 0;
+
+ TI_DBG4 (("tiTGTSetResp: start\n"));
+ TI_DBG4 (("tiTGTSetResp: datelen %d senselen %d\n", dataSentLength, senseLength));
+
+ ttdsaXchg = (ttdsaXchg_t *)tiIORequest->tdData;
+ SASResp = (sas_resp_t *)ttdsaXchg->resp.virtAddr;
+
+ SASResp->agResp.status = ScsiStatus;
+
+ if (ttdsaXchg->FrameType == SAS_TM)
+ {
+
+ TI_DBG1(("tiTGTSetResp: TM\n"));
+ if (senseLength != 0)
+ {
+ TI_DBG1 (("tiTGTSetResp: non-zero sensedatalen for TM\n"));
+ return;
+ }
+ SASResp->agResp.dataPres = RESPONSE_DATA;
+ OSSA_WRITE_BE_32(agRoot, SASResp->agResp.responsedataLen, 0, RESPONSE_DATA_LEN);
+ OSSA_WRITE_BE_32(agRoot, SASResp->agResp.senseDataLen, 0, 0);
+ SASResp->RespData[3] = AGSA_TASK_MANAGEMENT_FUNCTION_NOT_SUPPORTED;
+ TotalRespLen = sizeof(agsaSSPResponseInfoUnit_t) + RESPONSE_DATA_LEN;
+ }
+ else
+ {
+ if (senseLength == 0)
+ {
+ TI_DBG4 (("tiTGTSetResp: CMND, no data\n"));
+ /* good and no data present */
+ SASResp->agResp.dataPres = NO_DATA;
+ OSSA_WRITE_BE_32(agRoot, SASResp->agResp.responsedataLen, 0, 0);
+ OSSA_WRITE_BE_32(agRoot, SASResp->agResp.senseDataLen, 0, 0);
+ TotalRespLen = sizeof(agsaSSPResponseInfoUnit_t);
+ /* collapse good response with READ */
+ if (ttdsaXchg->XchType == AGSA_SSP_TGT_READ_DATA)
+ {
+ TI_DBG4(("tiTGTSetResp: read rsp collapse\n"));
+
+ if (tdsaRoot->autoGoodRSP & READ_GOOD_RESPONSE)
+ ttdsaXchg->readRspCollapsed = agTRUE;
+ }
+ /* collapse good response with WRITE */
+ if (ttdsaXchg->XchType == AGSA_SSP_TGT_WRITE_DATA)
+ {
+ TI_DBG4(("tiTGTSetResp: write rsp collapse\n"));
+ if (tdsaRoot->autoGoodRSP & WRITE_GOOD_RESPONSE)
+ {
+ if (tiIS_SPC(TI_TIROOT_TO_AGROOT(tiRoot)))
+ {
+ ttdsaXchg->wrtRspCollapsed = agFALSE;
+ }
+ else
+ {
+ ttdsaXchg->wrtRspCollapsed = agTRUE;
+ }
+
+ }
+ }
+ }
+ else
+ {
+ TI_DBG4 (("tiTGTSetResp: CMND, sense data\n"));
+ /* bad and sense data */
+ SASResp->agResp.dataPres = SENSE_DATA;
+ OSSA_WRITE_BE_32(agRoot, SASResp->agResp.responsedataLen, 0, 0);
+ OSSA_WRITE_BE_32(agRoot, SASResp->agResp.senseDataLen, 0, senseLength);
+ TotalRespLen = sizeof(agsaSSPResponseInfoUnit_t) + senseLength;
+ }
+ }
+
+ ttdsaXchg->statusSent = agTRUE;
+
+ TI_DBG4(("tiTGTSetResp: ttdsaXchg %p\n", ttdsaXchg));
+ TI_DBG4(("tiTGTSetResp: TotalRespLen 0x%x \n", TotalRespLen));
+ TI_DBG4(("tiTGTSetResp: upper 0x%x \n",
+ ttdsaXchg->resp.phyAddrUpper));
+ TI_DBG4(("tiTGTSetResp: lower 0x%x \n",
+ ttdsaXchg->resp.phyAddrLower));
+
+
+
+ /* set the correct response length */
+ ttdsaXchg->resp.length = TotalRespLen;
+
+ dumpresp((bit8 *)ttdsaXchg->resp.virtAddr, ttdsaXchg->resp.length);
+
+#ifdef REMOVED
+ /*
+ send TM reponse (which has only response data not sense data here
+ since ramdisk does not call IOstart for this
+ */
+
+ if (ttdsaXchg->FrameType == SAS_TM)
+ {
+ TI_DBG1(("tiTGTSetResp: respsonse is set \n"));
+ TI_DBG1(("tiTGTSetResp: resp.length 0x%x\n",
+ ttdsaXchg->resp.length));
+ ttdsaSendResp(ttdsaXchg->agRoot, ttdsaXchg);
+ }
+#endif
+#ifdef REMOVED
+ /* sas response */
+ agSSPTargetResp =
+ &(ttdsaXchg->IORequestBody.transport.SAS.agSASRequestBody.sspTargetResponse);
+
+ agSSPTargetResp->agTag = ttdsaXchg->tag;
+ agSSPTargetResp->respBufLength = TotalRespLen;
+ agSSPTargetResp->respBufUpper
+ = ttdsaXchg->IORequestBody.transport.SAS.agSASRequestBody.sspTargetResponse.respBufUpper;
+ agSSPTargetResp->respBufLower
+ = ttdsaXchg->IORequestBody.transport.SAS.agSASRequestBody.sspTargetResponse.respBufLower;
+
+
+
+ TI_DBG4(("tiTGTSetResp: len 0x%x \n",
+ ttdsaXchg->IORequestBody.transport.SAS.agSASRequestBody.sspTargetResponse.respBufLength));
+ TI_DBG4(("tiTGTSetResp: upper 0x%x \n",
+ ttdsaXchg->IORequestBody.transport.SAS.agSASRequestBody.sspTargetResponse.respBufUpper));
+ TI_DBG4(("tiTGTSetResp: lower 0x%x \n",
+ ttdsaXchg->IORequestBody.transport.SAS.agSASRequestBody.sspTargetResponse.respBufLower));
+#endif
+
+ return;
+}
+
+
+
+/******************************************************************************
+ *
+ * tiTGTGetDeviceHandles
+ *
+ * Purpose: This routine is called to to return the device handles for each
+ * device currently available.
+ *
+ * Parameters:
+ * tiRoot: Pointer to driver Instance.
+ * agDev[]: Array to receive pointers to the device handles.
+ * maxDevs: Number of device handles which will fit in array pointed
+ * by agDev.
+ * Return:
+ * Number of device handle slots present (however, only maxDevs
+ * are copied into tiDev[]) which may be greater than the number of
+ * handles actually present.
+ *
+ * Note:
+ *
+ ******************************************************************************/
+
+osGLOBAL bit32
+tiTGTGetDeviceHandles(
+ tiRoot_t *tiRoot,
+ tiPortalContext_t *tiPortalContext,
+ tiDeviceHandle_t *tiDev[],
+ bit32 maxDevs
+)
+{
+ tdsaRoot_t *tdsaRoot = (tdsaRoot_t *) tiRoot->tdData;
+ tdsaContext_t *tdsaAllShared = (tdsaContext_t *)&tdsaRoot->tdsaAllShared;
+ ttdsaTgt_t *Target = (ttdsaTgt_t *)tdsaAllShared->ttdsaTgt;
+ bit32 deviceToReturn;
+ bit32 devicePresent=0;
+ bit32 deviceIndex=0;
+ tdList_t *PortContextList;
+ tdsaPortContext_t *onePortContext = agNULL;
+ tdList_t *DeviceListList;
+ tdsaDeviceData_t *oneDeviceData = agNULL;
+ bit32 found = agFALSE;
+
+
+ TI_DBG4 (("tiTGTGetDeviceHandles: start\n"));
+
+ /* Check boundary condition */
+ if (maxDevs > Target->OperatingOption.MaxTargets)
+ {
+ deviceToReturn = Target->OperatingOption.MaxTargets;
+ }
+ else
+ {
+ deviceToReturn = maxDevs;
+ }
+
+
+ /* make sure tiPortalContext is valid */
+ PortContextList = tdsaAllShared->MainPortContextList.flink;
+ while (PortContextList != &(tdsaAllShared->MainPortContextList))
+ {
+ onePortContext = TDLIST_OBJECT_BASE(tdsaPortContext_t, MainLink, PortContextList);
+ if (onePortContext->tiPortalContext == tiPortalContext)
+ {
+ TI_DBG4(("tiTGTGetDeviceHandles: found; oneportContext ID %d\n", onePortContext->id));
+ found = agTRUE;
+ break;
+ }
+ PortContextList = PortContextList->flink;
+ }
+
+ if (found == agFALSE)
+ {
+ TI_DBG4(("tiTGTGetDeviceHandles: No corressponding tdsaPortContext\n"));
+ return 0;
+ }
+
+
+ /* go through device list and returns them */
+ DeviceListList = tdsaAllShared->MainDeviceList.flink;
+ while (DeviceListList != &(tdsaAllShared->MainDeviceList))
+ {
+ oneDeviceData = TDLIST_OBJECT_BASE(tdsaDeviceData_t, MainLink, DeviceListList);
+ TI_DBG4(("tiTGTGetDeviceHandles: pid %d did %d\n", onePortContext->id, oneDeviceData->id));
+ TI_DBG4(("tiTGTGetDeviceHandles: device AddrHi 0x%08x\n", oneDeviceData->SASAddressID.sasAddressHi));
+ TI_DBG4(("tiTGTGetDeviceHandles: device AddrLo 0x%08x\n", oneDeviceData->SASAddressID.sasAddressLo));
+ TI_DBG4(("tiTGTGetDeviceHandles: handle %p\n", &(oneDeviceData->tiDeviceHandle)));
+ if (oneDeviceData->valid == agTRUE)
+ {
+ TI_DBG4(("tiTGTGetDeviceHandles: valid deviceindex %d devicePresent %d\n", deviceIndex, devicePresent));
+
+ tiDev[deviceIndex] = &(oneDeviceData->tiDeviceHandle);
+ devicePresent++;
+ }
+ else
+ {
+ tiDev[deviceIndex] = agNULL;
+ TI_DBG4(("tiTGTGetDeviceHandles: not valid deviceindex %d devicePresent %d\n", deviceIndex, devicePresent));
+ }
+ deviceIndex++;
+
+ if (devicePresent >= deviceToReturn )
+ {
+ break;
+ }
+ DeviceListList = DeviceListList->flink;
+ }
+
+ return devicePresent;
+}
+
+
+
+
+/******************************************************************************
+ *
+ * tiTGTGetDeviceInfo
+ *
+ * Purpose: This routine is called to to return the device information for
+ * specified device handle.
+ *
+ * Parameters:
+ * tiRoot: Pointer to driver Instance.
+ * tiDeviceHandle: device handle associated with the device for which
+ * information is queried
+ * tiDeviceInfo: device information structure containing address and name.
+ *
+ * Return:
+ * tiSuccess: if the device handle is valid.
+ * tiError : if the device handle is not valid.
+ *
+ * Note:
+ *
+ ******************************************************************************/
+osGLOBAL bit32
+tiTGTGetDeviceInfo(
+ tiRoot_t *tiRoot,
+ tiDeviceHandle_t *tiDeviceHandle,
+ tiDeviceInfo_t *tiDeviceInfo)
+{
+ tdsaDeviceData_t *oneDeviceData = agNULL;
+
+
+ TI_DBG4 (("tiTGTGetDeviceInfo: start\n"));
+
+ if (tiDeviceHandle == agNULL)
+ {
+ TI_DBG4 (("tiTGTGetDeviceInfo: tiDeviceHandle is NULL\n"));
+ return tiError;
+ }
+
+ oneDeviceData = (tdsaDeviceData_t *)tiDeviceHandle->tdData;
+
+ if (oneDeviceData == agNULL)
+ {
+ TI_DBG4 (("tiTGTGetDeviceInfo: oneDeviceData is NULL\n"));
+ return tiError;
+ }
+
+ /* filling in the link rate */
+ if (oneDeviceData->registered == agTRUE)
+ {
+ tiDeviceInfo->info.devType_S_Rate = oneDeviceData->agDeviceInfo.devType_S_Rate;
+ }
+ else
+ {
+ tiDeviceInfo->info.devType_S_Rate = oneDeviceData->agDeviceInfo.devType_S_Rate & 0x0f;
+ }
+
+ /* temp just returning local and remote SAS address; doesn't have a name */
+ tiDeviceInfo->remoteName = (char *)&(oneDeviceData->tdPortContext->sasRemoteAddressHi);
+ tiDeviceInfo->remoteAddress = (char *)&(oneDeviceData->tdPortContext->sasRemoteAddressLo);
+
+ tiDeviceInfo->localName = (char *)&(oneDeviceData->tdPortContext->sasLocalAddressHi);
+ tiDeviceInfo->localAddress = (char *)&(oneDeviceData->tdPortContext->sasLocalAddressLo);
+
+ return tiSuccess;
+}
+
+/*****************************************************************************
+ *! \brief ttdssIOAbortedHandler
+ *
+ * Purpose: This function processes I/Os completed and returned by SAS/SATA lower
+ * layer with agIOStatus = OSSA_IO_ABORTED
+ *
+ * \param agRoot: pointer to port instance
+ * \param agIORequest: pointer to I/O request
+ * \param agIOStatus: I/O status given by LL layer
+ * \param agIOInfoLen: lenth of complete SAS RESP frame
+ * \param agParam A Handle used to refer to the response frame or handle
+ * of abort request
+ * \param agOtherInfo Residual count
+ * \return: None
+ *
+ *
+ *****************************************************************************/
+/* see itdosIOCompleted() and itdinit.c and itdIoAbortedHandler in itdio.c*/
+osGLOBAL void
+ttdssIOAbortedHandler (
+ agsaRoot_t *agRoot,
+ agsaIORequest_t *agIORequest,
+ bit32 agIOStatus,
+ bit32 agIOInfoLen,
+ void *agParam,
+ bit32 agOtherInfo
+)
+{
+ tdsaRootOsData_t *osData = (tdsaRootOsData_t *)agRoot->osData;
+ tiRoot_t *tiRoot = (tiRoot_t *)osData->tiRoot;
+ tdIORequestBody_t *tdIORequestBody;
+
+ TI_DBG1(("itdssIOAbortedHandler: start\n"));
+ tdIORequestBody = (tdIORequestBody_t *)agIORequest->osData;
+
+ if (agIOStatus != OSSA_IO_ABORTED)
+ {
+ TI_DBG1(("itdssIOAbortedHandler: incorrect agIOStatus 0x%x\n", agIOStatus));
+
+ }
+
+ ostiTargetIOError(
+ tiRoot,
+ tdIORequestBody->tiIORequest,
+ tiIOFailed,
+ tiDetailAborted
+ );
+
+ return;
+}
+
+
OpenPOWER on IntegriCloud