1/*******************************************************************************
2*Copyright (c) 2014 PMC-Sierra, Inc.  All rights reserved.
3*
4*Redistribution and use in source and binary forms, with or without modification, are permitted provided
5*that the following conditions are met:
6*1. Redistributions of source code must retain the above copyright notice, this list of conditions and the
7*following disclaimer.
8*2. Redistributions in binary form must reproduce the above copyright notice,
9*this list of conditions and the following disclaimer in the documentation and/or other materials provided
10*with the distribution.
11*
12*THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED
13*WARRANTIES,INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
14*FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
15*FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
16*NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
17*BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
18*LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
19*SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE
20 ********************************************************************************/
21/*******************************************************************************/
22/** \file
23 *
24 * $RCSfile: ttdio.c,v $
25 *
26 * Copyright 2006 PMC-Sierra, Inc.
27 *
28 *
29 * This file contains initiator IO related functions in TD layer
30 *
31 */
32#include <osenv.h>
33#include <ostypes.h>
34#include <osdebug.h>
35
36#include <sa.h>
37#include <saapi.h>
38#include <saosapi.h>
39
40#include <titypes.h>
41#include <ostiapi.h>
42#include <tiapi.h>
43#include <tiglobal.h>
44
45#include <tdtypes.h>
46#include <osstring.h>
47#include <tdutil.h>
48
49#ifdef INITIATOR_DRIVER
50#include <itdtypes.h>
51#include <itddefs.h>
52#include <itdglobl.h>
53#endif
54
55#ifdef TARGET_DRIVER
56#include <ttdglobl.h>
57#include <ttdtxchg.h>
58#include <ttdtypes.h>
59#endif
60
61#include <tdsatypes.h>
62#include <tdproto.h>
63
64
65/*  Start For trace only */
66#ifdef REMOVED
67unsigned __int64
68GetHiResTimeStamp(void);
69#endif
70#undef TD_DEBUG_TRACE_ENABLE
71#define TD_DEBUG_IO_TRACE_BUFFER_MAX  1024
72
73
74typedef struct TDDebugTraceEntry_s
75{
76    bit64             Time;
77    ttdsaXchg_t       ttdsaXchg;
78    tdsaDeviceData_t  oneDeviceData;
79} TDDebugTraceEntry_t;
80
81typedef struct TDDebugTrace_s
82{
83    bit32                 Idx;
84    bit32                 pad;
85    TDDebugTraceEntry_t  Data[TD_DEBUG_IO_TRACE_BUFFER_MAX];
86} TDDebugTrace_t;
87
88void TDTraceInit(void);
89void TDTraceAdd(ttdsaXchg_t *ttdsaXchg, tdsaDeviceData_t  *oneDeviceData);
90
91#ifdef TD_DEBUG_TRACE_ENABLE
92#define TD_DEBUG_TRACE(ttdsaXchg, oneDeviceData) TDTraceAdd(ttdsaXchg, oneDeviceData)
93#else
94#define TD_DEBUG_TRACE(ttdsaXchg, oneDeviceData)
95#endif
96
97TDDebugTrace_t TraceData;
98
99void TDTraceInit(void)
100{
101    osti_memset(&TraceData, 0, sizeof(TraceData));
102}
103
104void TDTraceAdd(ttdsaXchg_t *ttdsaXchg, tdsaDeviceData_t  *oneDeviceData)
105{
106    static bit32 TraceIdx = 0;
107
108    TraceData.Idx = TraceIdx;
109#ifdef REMOVED
110    TraceData.Data[TraceIdx].Time = GetHiResTimeStamp();
111#endif
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));
114#ifdef REMOVED
115    TraceData.Data[TraceIdx].ttdsaXchg = ttdsaXchg;
116    TraceData.Data[TraceIdx].oneDeviceData = oneDeviceData;
117#endif
118
119    TraceIdx++;
120    if (TraceIdx >= TD_DEBUG_IO_TRACE_BUFFER_MAX)
121    {
122        TraceIdx = 0;
123    }
124
125    return;
126}
127
128
129/*  End For trace only */
130
131
132osGLOBAL void
133ttdsaSSPReqReceived(
134        agsaRoot_t           *agRoot,
135        agsaDevHandle_t      *agDevHandle,
136        agsaFrameHandle_t    agFrameHandle,
137        bit32                agInitiatorTag,
138        bit32                parameter,
139        bit32                      agFrameLen
140)
141{
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;
148
149    TD_XCHG_CONTEXT_NO_CMD_RCVD(tiRoot)        = TD_XCHG_CONTEXT_NO_CMD_RCVD(tiRoot)+1;
150
151    TI_DBG4(("ttdsaSSPReqReceived: start\n"));
152
153    agFrameType = TD_GET_FRAME_TYPE(parameter);
154    TLR = TD_GET_TLR(parameter);
155
156
157    /*note:
158    in ini, agDevHandle->osData =  tdsaDeviceData_t
159    is set in tdssAddDevicedataToSharedcontext()
160
161    in tdsaDeviceDataInit()
162    oneDeviceData->tiDeviceHandle.tdData has been initialized
163     */
164    oneDeviceData = (tdsaDeviceData_t *)agDevHandle->osData;
165
166    if (oneDeviceData == agNULL)
167    {
168        TI_DBG1(("ttdsaSSPReqReceived: no device data\n"));
169        return;
170    }
171
172
173
174    ttdsaXchg = ttdsaXchgGetStruct(agRoot);
175
176    if (ttdsaXchg == agNULL)
177    {
178        TI_DBG1(("ttdsaSSPReqReceived: no free xchg structures\n"));
179        //    ttdsaDumpallXchg(tiRoot);
180        return;
181    }
182
183    if (ttdsaXchg->IORequestBody.tiIORequest == agNULL)
184    {
185        TI_DBG1(("ttdsaSSPReqReceived: tiIORequest is NULL\n"));
186        //    ttdsaDumpallXchg(tiRoot);
187        return;
188    }
189
190    oneDeviceData->agDevHandle = agDevHandle;
191    oneDeviceData->agRoot = agRoot;
192
193    /* saving the device */
194    ttdsaXchg->DeviceData = oneDeviceData;
195
196    ttdsaXchg->agRoot  = agRoot;
197    ttdsaXchg->tiRoot  = tiRoot;
198
199    ttdsaXchg->IORequestBody.agIORequest.sdkData = agNULL;
200
201    /* initiator tag */
202    ttdsaXchg->tag      = (bit16)agInitiatorTag;
203    ttdsaXchg->IORequestBody.transport.SAS.agSASRequestBody.sspTargetReq.agTag
204    = ttdsaXchg->tag;
205    ttdsaXchg->IORequestBody.transport.SAS.agSASRequestBody.sspTargetResponse.agTag
206    = ttdsaXchg->tag;
207
208    TI_DBG6(("ttdsaSSPReqReceived: initiator tag 0x%x\n", agInitiatorTag));
209
210    if (agFrameType == OSSA_FRAME_TYPE_SSP_CMD)
211    {
212        TI_DBG4(("ttdsaSSPReqReceived: CMD frame type\n"));
213        /* reads agsaSSPResponseInfoUnit_t */
214        saFrameReadBlock(
215                agRoot,
216                agFrameHandle,
217                0,
218                &ttdsaXchg->agSSPCmndIU,
219                agFrameLen
220        );
221
222        tdsaProcessCDB(&ttdsaXchg->agSSPCmndIU, ttdsaXchg);
223        ttdsaXchg->FrameType = SAS_CMND;
224
225        /*
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.
228         */
229
230        /* typedef struct
231       {
232       bit8      *reqCDB;
233       bit8      *scsiLun,
234       bit32     taskAttribute;
235       bi32      taskId;
236       bit32     crn;
237       } tiTargetScsiCmnd_t;
238         */
239        /* what about reqCDB and scsiLun */
240
241        /* coverting task attributes from SAS TISA */
242        switch (SA_SSPCMD_GET_TASKATTRIB(&ttdsaXchg->agSSPCmndIU))
243        {
244        case 0:
245            ttdsaXchg->tiTgtScsiCmnd.taskAttribute = TASK_SIMPLE;
246            break;
247        case 1:
248            ttdsaXchg->tiTgtScsiCmnd.taskAttribute = TASK_HEAD_OF_QUEUE;
249            break;
250        case 2:
251            ttdsaXchg->tiTgtScsiCmnd.taskAttribute = TASK_ORDERED;
252            break;
253        case 3:
254            TI_DBG1(("ttdsaSSPReqReceived: reserved taskAttribute 0x%x\n",ttdsaXchg->agSSPCmndIU.efb_tp_taskAttribute));
255            ttdsaXchg->tiTgtScsiCmnd.taskAttribute = TASK_SIMPLE;
256            break;
257        case 4:
258            ttdsaXchg->tiTgtScsiCmnd.taskAttribute = TASK_ACA;
259            break;
260        default:
261            TI_DBG1(("ttdsaSSPReqReceived: unknown taskAttribute 0x%x\n",ttdsaXchg->agSSPCmndIU.efb_tp_taskAttribute));
262            ttdsaXchg->agSSPCmndIU.efb_tp_taskAttribute = TASK_SIMPLE;
263            break;
264        }
265
266        ttdsaXchg->tiTgtScsiCmnd.taskId = agInitiatorTag;
267        ttdsaXchg->tiTgtScsiCmnd.crn = 0;
268        ttdsaXchg->TLR = TLR;
269
270        /* call ostiProcessScsiReq */
271        ostiProcessScsiReq( tiRoot,
272                &ttdsaXchg->tiTgtScsiCmnd,
273                agFrameHandle,
274                0,
275                ttdsaXchg->IORequestBody.tiIORequest,
276                &ttdsaXchg->DeviceData->tiDeviceHandle);
277
278
279    }
280    else if (agFrameType == OSSA_FRAME_TYPE_SSP_TASK)
281    {
282        TI_DBG4(("ttdsaSSPReqReceived: TM frame type\n"));
283
284        /*
285      reads aagsaSSPScsiTaskMgntReq_t
286      including lun
287         */
288        saFrameReadBlock(
289                agRoot,
290                agFrameHandle,
291                0,
292                &ttdsaXchg->agTMIU,
293                agFrameLen
294        );
295
296        ttdsaXchg->FrameType = SAS_TM;
297        /*
298      call task process mangement fn
299         */
300        ttdsaTMProcess(tiRoot, ttdsaXchg);
301        return;
302    }
303    else
304    {
305        TI_DBG1(("ttdsaSSPReqReceived: unknown frame type\n"));
306        return;
307    }
308
309    return;
310}
311
312void
313dumpCDB(bit8 *cdb)
314{
315    bit32 i;
316    for(i=0;i<10;i++)
317    {
318        TI_DBG4(("cdb[%d] 0x%x\n", i, cdb[i]));
319    }
320    return;
321}
322
323osGLOBAL void
324tdsaProcessCDB(
325        agsaSSPCmdInfoUnit_t      *cmdIU,
326        ttdsaXchg_t               *ttdsaXchg
327)
328{
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;
332    bit8 group;
333#ifdef TD_DEBUG_ENABLE
334    CDB6_t *cdb6;
335#endif
336    CDB10_t *cdb10;
337    CDB12_t *cdb12;
338    CDB16_t *cdb16;
339    bit32   unknown = agFALSE;
340    bit32   len=0;
341    group = cmdIU->cdb[0] & CDB_GRP_MASK;
342
343    TI_DBG4(("tdsaProcessCDB: start\n"));
344
345    switch (cmdIU->cdb[0])
346    {
347    case SCSIOPC_REPORT_LUN:
348        TI_DBG4(("tdsaProcessCDB: REPORT_LUN\n"));
349        ttdsaXchg->XchType = AGSA_SSP_TGT_READ_DATA;
350        break;
351    case SCSIOPC_INQUIRY:
352        TI_DBG4(("tdsaProcessCDB: INQUIRY\n"));
353        ttdsaXchg->XchType = AGSA_SSP_TGT_READ_DATA;
354        break;
355
356    case SCSIOPC_TEST_UNIT_READY:
357        TI_DBG4(("tdsaProcessCDB: TEST_UNIT_READY\n"));
358        ttdsaXchg->XchType = AGSA_SSP_TGT_READ_DATA;
359        break;
360
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;
365        break;
366
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;
371        break;
372
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;
377        break;
378
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;
383        break;
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;
387        break;
388    case SCSIOPC_REQUEST_SENSE:
389        TI_DBG2(("tdsaProcessCDB: SCSIOPC_REQUEST_SENSE\n"));
390        ttdsaXchg->XchType = AGSA_SSP_TGT_READ_DATA;
391        break;
392    default:
393        TI_DBG4(("tdsaProcessCDB: UNKNOWN, cbd %d 0x%x\n", cmdIU->cdb[0], cmdIU->cdb[0]));
394        ttdsaXchg->XchType = TargetUnknown;
395        break;
396    }
397
398    /* parse datalen */
399    switch (group)
400    {
401    case CDB_6BYTE:
402        TI_DBG4(("tdsaProcessCDB: CDB 6 byte, not yet\n"));
403#ifdef TD_DEBUG_ENABLE
404        cdb6 = (CDB6_t *)(cmdIU->cdb);
405#endif
406        TI_DBG4(("tdsaProcessCDB: CDB len 0x%x\n", cdb6->len));
407        break;
408    case CDB_10BYTE1: /* fall through */
409    case CDB_10BYTE2:
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));
414        dumpCDB(cmdIU->cdb);
415        break;
416    case CDB_12BYTE:
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));
421        break;
422    case CDB_16BYTE:
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));
427        break;
428    default:
429        TI_DBG4(("tdsaProcessCDB: unknow CDB, group %d 0x%x\n", group, group));
430        len = 0;
431        unknown = agTRUE;
432        break;
433    }
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  )
436    {
437      ttdsaXchg->dataLen  = len * Target->OperatingOption.BlockSize;
438    }
439    else
440    {
441      ttdsaXchg->dataLen  = len;
442    }
443
444    if (ttdsaXchg->dataLen == 0 && unknown == agFALSE)
445    {
446        /* this is needed because of min operation in tiTGTIOstart() */
447        ttdsaXchg->dataLen      = 0xffffffff;
448    }
449    /*  TI_DBG4(("tdsaProcessCDB: datalen 0x%x %d\n", ttdsaXchg->dataLen, ttdsaXchg->dataLen)); */
450    return;
451}
452
453
454
455
456/*****************************************************************************
457 *
458 *  tiTGTIOStart
459 *
460 *  Purpose: This function is called by the target OS Specific Module to start
461 *           the next phase of a SCSI Request.
462 *
463 *  Parameters:
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.
475 *
476 *  Return:
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.
480 *
481 *  Note:
482 *
483 *****************************************************************************/
484osGLOBAL bit32
485tiTGTIOStart( tiRoot_t         *tiRoot,
486        tiIORequest_t    *tiIORequest,
487        bit32             dataOffset,
488        bit32             dataLength,
489        tiSgl_t          *dataSGL,
490        void             *sglVirtualAddr
491)
492
493{
494    ttdsaXchg_t               *ttdsaXchg;
495    agsaSSPTargetRequest_t    *agSSPTargetReq;
496    bit32                     tiStatus;
497    bit32                     saStatus;
498    bit32                     tdStatus;
499    tdsaPortContext_t         *onePortContext = agNULL;
500    tdsaDeviceData_t          *oneDeviceData = agNULL;
501
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));
505
506    /* save infor in ttdsaXchg */
507    ttdsaXchg     = (ttdsaXchg_t *)tiIORequest->tdData;
508
509    /* check the state of port */
510    oneDeviceData = ttdsaXchg->DeviceData;
511    onePortContext= oneDeviceData->tdPortContext;
512    if (onePortContext->valid == agFALSE)
513    {
514        TI_DBG1(("tiTGTIOStart: portcontext pid %d is invalid\n", onePortContext->id));
515        return tiError;
516    }
517
518
519    agSSPTargetReq
520    = &(ttdsaXchg->IORequestBody.transport.SAS.agSASRequestBody.sspTargetReq);
521
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() */
527
528    /* Process TLR */
529    if (ttdsaXchg->TLR == 2)
530    {
531        /* diable TLR */
532        agSSPTargetReq->sspOption = 0;
533    }
534    else
535    {
536        /* enable TLR */
537        /* bit5: 0 1 11 11 :bit0 */
538        agSSPTargetReq->sspOption = 0x1F;
539    }
540
541    ttdsaXchg->IORequestBody.IOType.TargetIO.TargetIOType.RegIO.sglVirtualAddr
542    = sglVirtualAddr;
543
544    if (agSSPTargetReq->dataLength != 0)
545    {
546        TI_DBG6(("tiTGTIOStart: pos 1\n"));
547        ttdsaXchg->IORequestBody.IOType.TargetIO.TargetIOType.RegIO.tiSgl1
548        = *dataSGL;
549    }
550    else
551    {
552        TI_DBG6(("tiTGTIOStart: pos 2\n"));
553        ttdsaXchg->IORequestBody.IOType.TargetIO.TargetIOType.RegIO.tiSgl1.len
554        = 0;
555        ttdsaXchg->IORequestBody.IOType.TargetIO.TargetIOType.RegIO.tiSgl1.type
556        = tiSgl;
557
558        /* let's send response frame */
559        if (ttdsaXchg->resp.length != 0)
560        {
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)
570            {
571                return tiSuccess;
572            }
573            else if (tdStatus == AGSA_RC_FAILURE)
574            {
575                TI_DBG1(("tiTGTIOStart: (ttdsaSendResp) sending not successful\n"));
576                return tiError;
577            }
578            else
579            {
580                TI_DBG1(("tiTGTIOStart: (ttdsaSendResp) sending busy\n"));
581                return tiBusy;
582            }
583        }
584    }
585
586
587    /* sets SSPTargetReq->agSgl */
588    tiStatus = ttdssIOPrepareSGL(tiRoot, &ttdsaXchg->IORequestBody, dataSGL, NULL, sglVirtualAddr);
589
590    if (tiStatus != tiSuccess)
591    {
592        TI_DBG1(("tiTGTIOStart: ttdIOPrepareSGL did not return success\n"));
593        return tiStatus;
594    }
595
596    TI_DBG4(("tiTGTIOStart: agroot %p ttdsaXchg %p\n", ttdsaXchg->agRoot, ttdsaXchg));
597    TI_DBG4(("tiTGTIOStart: agDevHanlde %p\n", ttdsaXchg->DeviceData->agDevHandle));
598
599    if ( (ttdsaXchg->readRspCollapsed == agTRUE) || (ttdsaXchg->wrtRspCollapsed == agTRUE) )
600    {
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));
604
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(
609                ttdsaXchg->agRoot,
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,
615                        agNULL,
616                        &ossaSSPCompleted
617        );
618    }
619    else
620    {
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,
631                ttdsaXchg->XchType,
632                &ttdsaXchg->IORequestBody.transport.SAS.agSASRequestBody,
633                agNULL,
634                &ossaSSPCompleted
635        );
636
637    }
638
639    if (saStatus == AGSA_RC_SUCCESS)
640    {
641        return tiSuccess;
642    }
643    else if (saStatus == AGSA_RC_FAILURE)
644    {
645        TI_DBG1(("tiTGTIOStart: sending not successful\n"));
646        return tiError;
647    }
648    else
649    {
650        TI_DBG1(("tiTGTIOStart: sending busy\n"));
651        return tiBusy;
652    }
653
654}
655
656#ifdef EDC_ENABLE
657/*****************************************************************************
658 *
659 *  tiTGTIOStart
660 *
661 *  Purpose: This function is called by the target OS Specific Module to start
662 *           the next phase of a SCSI Request.
663 *
664 *  Parameters:
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.
677 *
678 *  Return:
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.
682 *
683 *  Note:
684 *
685 *****************************************************************************/
686osGLOBAL bit32 tiTGTIOStartDif(
687        tiRoot_t        *tiRoot,
688        tiIORequest_t   *tiIORequest,
689        bit32           dataOffset,
690        bit32           dataLength,
691        tiSgl_t         *dataSGL,
692        void            *sglVirtualAddr,
693        tiDif_t         *difOption
694)
695{
696
697    /* This function was never used by SAS/SATA. Use tiTGTSuperIOStart() instead. */
698    return tiBusy;
699}
700#endif
701
702osGLOBAL bit32
703ttdssIOPrepareSGL(
704        tiRoot_t                 *tiRoot,
705        tdIORequestBody_t        *tdIORequestBody,
706        tiSgl_t                  *tiSgl1,
707        tiSgl_t                  *tiSgl2,
708        void                     *sglVirtualAddr
709)
710{
711    agsaSgl_t                 *agSgl;
712
713    TI_DBG6(("ttdssIOPrepareSGL: start\n"));
714
715    agSgl = &(tdIORequestBody->transport.SAS.agSASRequestBody.sspTargetReq.agSgl);
716
717    agSgl->len = 0;
718
719    if (tiSgl1 == agNULL)
720    {
721        TI_DBG1(("ttdssIOPrepareSGL: Error tiSgl1 is NULL\n"));
722        return tiError;
723    }
724
725    agSgl->sgUpper = tiSgl1->upper;
726    agSgl->sgLower = tiSgl1->lower;
727    agSgl->len = tiSgl1->len;
728    agSgl->extReserved = tiSgl1->type;
729
730    return tiSuccess;
731}
732
733/* temp for debugging */
734void
735dumpresp(bit8 *resp, bit32 len)
736{
737    bit32 i;
738
739    for(i=0;i<len;i++)
740    {
741        TI_DBG4(("resp[%d] 0x%x\n", i, resp[i]));
742    }
743
744    return;
745}
746
747osGLOBAL bit32
748ttdsaSendResp(
749        agsaRoot_t            *agRoot,
750        ttdsaXchg_t           *ttdsaXchg
751)
752{
753    tdsaRootOsData_t          *osData = (tdsaRootOsData_t *)agRoot->osData;
754    tiRoot_t                  *tiRoot = (tiRoot_t *)osData->tiRoot;
755    tdsaDeviceData_t          *oneDeviceData = agNULL;
756    bit32                     agRequestType;
757    bit32                     saStatus;
758    agsaSSPTargetResponse_t   *agSSPTargetResp;
759    agRequestType = AGSA_SSP_TGT_CMD_OR_TASK_RSP;
760
761    TI_DBG4(("ttdsaSendResp: start\n"));
762    TI_DBG4(("ttdsaSendResp: agroot %p ttdsaXchg %p\n", ttdsaXchg->agRoot, ttdsaXchg));
763
764    TI_DBG4(("ttdsaSendResp:: agDevHanlde %p\n", ttdsaXchg->DeviceData->agDevHandle));
765
766    /* sas response */
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));
774
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)
783    /* nothing */
784#else
785    if (agSSPTargetResp->respBufLength <= AGSA_MAX_SSPPAYLOAD_VIA_SFO)
786        agSSPTargetResp->frameBuf = ttdsaXchg->resp.virtAddr;
787    else
788        agSSPTargetResp->frameBuf = NULL;
789#endif
790    dumpresp((bit8 *)ttdsaXchg->resp.virtAddr, ttdsaXchg->resp.length);
791
792    TD_XCHG_CONTEXT_NO_SEND_RSP(TD_GET_TIROOT(agRoot))        =
793            TD_XCHG_CONTEXT_NO_SEND_RSP(TD_GET_TIROOT(agRoot))+1;
794
795    oneDeviceData = ttdsaXchg->DeviceData;
796    saStatus = saSSPStart(
797            ttdsaXchg->agRoot, /* agRoot,*/
798            &ttdsaXchg->IORequestBody.agIORequest,
799            tdsaRotateQnumber(tiRoot, oneDeviceData),
800            ttdsaXchg->DeviceData->agDevHandle, /* agDevHandle, */
801            agRequestType,
802            &ttdsaXchg->IORequestBody.transport.SAS.agSASRequestBody,
803            agNULL,
804            &ossaSSPCompleted
805    );
806
807    if (saStatus == AGSA_RC_SUCCESS)
808    {
809        TI_DBG4(("ttdsaSendResp: sending successful\n"));
810        return AGSA_RC_SUCCESS;
811    }
812    else if (saStatus == AGSA_RC_FAILURE)
813    {
814        TI_DBG1(("ttdsaSendResp: sending not successful\n"));
815        return AGSA_RC_FAILURE;
816    }
817    else
818    {
819        TI_DBG1(("ttdsaSendResp: sending busy\n"));
820        return AGSA_RC_BUSY;
821    }
822
823}
824
825osGLOBAL void
826ttdsaIOCompleted(
827        agsaRoot_t             *agRoot,
828        agsaIORequest_t        *agIORequest,
829        bit32                  agIOStatus,
830        bit32                  agIOInfoLen,
831        agsaFrameHandle_t      agFrameHandle,
832        bit32                  agOtherInfo
833)
834{
835
836    ttdsaXchg_t       *ttdsaXchg    = (ttdsaXchg_t *)agIORequest->osData;
837    /* done in ttdsaXchgInit() */
838    bit32             IOFailed = agFALSE;
839    bit32             status;
840    bit32             statusDetail = 0;
841    tiRoot_t          *tiRoot;
842#ifdef REMOVED
843    tdsaRoot_t        *tdsaRoot;
844    tdsaContext_t     *tdsaAllShared;
845#endif
846    bit32             tdStatus;
847    bit32             saStatus = AGSA_RC_FAILURE;
848#ifdef  TD_DEBUG_ENABLE
849    agsaDifDetails_t  *DifDetail;
850#endif
851
852    TI_DBG4(("ttdsaIOCompleted: start\n"));
853    tiRoot = ((tdsaRootOsData_t *)agRoot->osData)->tiRoot;
854#ifdef REMOVED
855    tdsaRoot        = (tdsaRoot_t *) tiRoot->tdData;
856    tdsaAllShared = (tdsaContext_t *)&tdsaRoot->tdsaAllShared;
857#endif
858#ifdef  TD_DEBUG_ENABLE
859    DifDetail = (agsaDifDetails_t *)agFrameHandle;
860#endif
861
862    if (tiRoot == agNULL)
863    {
864        TI_DBG1(("ttdsaIOCompleted: tiRoot is NULL\n"));
865        return;
866    }
867
868    TD_XCHG_CONTEXT_NO_IO_COMPLETED(tiRoot)    = TD_XCHG_CONTEXT_NO_IO_COMPLETED(tiRoot)+1;
869
870    if(TD_XCHG_GET_STATE(ttdsaXchg) != TD_XCHG_STATE_ACTIVE)
871    {
872        TI_DBG1(("ttdsaIOCompleted: XCHG is not active *****************\n"));
873        return;
874    }
875
876    if (ttdsaXchg->isTMRequest != agTRUE)
877    {
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));
882
883#ifdef REMOVED
884        /* call tdsafreeesglpages only for xchg that used eslg */
885        if (ttdsaXchg->usedEsgl == agTRUE)
886        {
887            tdsaFreeEsglPages(tiRoot, &ttdsaXchg->IORequestBody.EsglPageList);
888            ttdsaXchg->usedEsgl = agFALSE;
889        }
890#endif
891
892        /* successful case */
893        if (agIOStatus ==  OSSA_IO_SUCCESS)
894        {
895            TI_DBG6(("ttdsaIOCompleted: osIOSuccess\n"));
896            if ( (ttdsaXchg->readRspCollapsed == agTRUE) || (ttdsaXchg->wrtRspCollapsed == agTRUE) )
897            {
898                ttdsaXchg->responseSent = agTRUE;
899                TI_DBG4(("ttdsaIOCompleted: read rsp collapse\n"));
900            }
901
902            if (ttdsaXchg->statusSent == agTRUE)
903            {
904                /*
905          the response has already been set and ready
906          but has NOT been sent
907                 */
908                if (ttdsaXchg->responseSent == agFALSE)
909                {
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)
915                    {
916                        TI_DBG1(("ttdsaIOCompleted: attention needed\n"));
917                        return;
918                    }
919                    ttdsaXchg->responseSent = agTRUE;
920                }
921                else
922                {
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"));
926
927                    if (TD_XCHG_GET_STATE(ttdsaXchg) == TD_XCHG_STATE_INACTIVE)
928                    {
929                        TI_DBG1(("ttdsaIOCompleted: wrong DEQUEUE_THIS\n"));
930                    }
931
932                    /*
933                     * Notify the OS Specific Module, so it can free its resource.
934                     */
935                    TI_DBG4(("ttdsaIOCompleted: calling ostiTargetIOCompleted\n"));
936                    ostiTargetIOCompleted( tiRoot,
937                            ttdsaXchg->IORequestBody.tiIORequest,
938                            tiIOSuccess );
939
940                    /* clean up resources */
941                    ttdsaXchgFreeStruct(tiRoot,ttdsaXchg);
942                }
943            } /* sent */
944            else
945            {
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 );
951            }
952            return;
953        } /* success */
954
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)
958        {
959            TI_DBG1(("ttdsaIOCompleted: DIF detail UpperLBA 0x%08x LowerLBA 0x%08x\n", DifDetail->UpperLBA, DifDetail->LowerLBA));
960        }
961        switch (agIOStatus)
962        {
963        case OSSA_IO_ABORTED:
964            TI_DBG1(("ttdsaIOCompleted: ABORTED\n"));
965            status        = tiIOFailed;
966            statusDetail  = tiDetailAborted;
967            IOFailed      = agTRUE;
968            break;
969#ifdef REMOVED
970        case OSSA_IO_OVERFLOW:
971            TI_DBG1(("ttdsaIOCompleted: OVERFLOW\n"));
972            status        = tiIOOverRun;
973            IOFailed      = agTRUE;
974            break;
975#endif
976        case OSSA_IO_UNDERFLOW:
977            TI_DBG1(("ttdsaIOCompleted: UNDERFLOW\n"));
978            status        = tiIOUnderRun;
979            IOFailed      = agTRUE;
980            break;
981        case OSSA_IO_ABORT_RESET:
982            TI_DBG1(("ttdsaIOCompleted: ABORT_RESET\n"));
983            status        = tiIOFailed;
984            statusDetail  = tiDetailAbortReset;
985            IOFailed      = agTRUE;
986            break;
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;
991            IOFailed      = agTRUE;
992            break;
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;
997            IOFailed      = agTRUE;
998            break;
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;
1003            IOFailed      = agTRUE;
1004            break;
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;
1009            IOFailed      = agTRUE;
1010            break;
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;
1015            IOFailed      = agTRUE;
1016            break;
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 */
1026        default:
1027            status        = tiIOFailed;
1028            statusDetail  = tiDetailOtherError;
1029            IOFailed      = agTRUE;
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)
1033            {
1034                TI_DBG1(("ttdsaIOCompleted: OSSA_IO_XFER_OPEN_RETRY_TIMEOUT ttdsaXchg->id 0x%x datalen 0x%x offset 0x%x agTag 0x%x\n",
1035                        ttdsaXchg->id,
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));
1040
1041            }
1042            break;
1043        } /* switch */
1044
1045        if (IOFailed == agTRUE)
1046        {
1047            if (agIORequest->sdkData == agNULL)
1048            {
1049                tiIORequest_t tiIORequest;
1050                TI_DBG1(("ttdsaIOCompleted: ERROR ttdsaXchg=%p agIOStatus= 0x%x\n",
1051                        ttdsaXchg,
1052                        agIOStatus ));
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] ));
1070
1071                if (TD_XCHG_GET_STATE(ttdsaXchg) == TD_XCHG_STATE_INACTIVE)
1072                {
1073                    TI_DBG1(("ttdsaIOCompleted: wrong DEQUEUE_THIS  1\n"));
1074                }
1075                if (ttdsaXchg->retries <= OPEN_RETRY_RETRIES && agIOStatus == OSSA_IO_XFER_OPEN_RETRY_TIMEOUT)
1076                {
1077                    TI_DBG2(("ttdsaIOCompleted: 1 loc retries on OSSA_IO_XFER_OPEN_RETRY_TIMEOUT\n"));
1078                    if ( (agOtherInfo & 0x1) == 1)
1079                    {
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)
1085                        {
1086                            TI_DBG2(("ttdsaIOCompleted: 0 loc retried\n"));
1087                            ttdsaXchg->retries++;
1088                        }
1089                        else
1090                        {
1091                            TI_DBG1(("ttdsaIOCompleted: 0 loc retry failed\n"));
1092                            ttdsaXchg->retries = 0;
1093                            /*
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
1098                             */
1099                            tiIORequest = ttdsaXchg->IORequestBody.IOType.TargetIO.tiIORequest;
1100                            tiIORequest.tdData = agNULL;
1101
1102                            ostiTargetIOError(
1103                                    tiRoot,
1104                                    &tiIORequest,
1105                                    status,
1106                                    statusDetail
1107                            );
1108
1109                            /* clean up resources */
1110                            ttdsaXchgFreeStruct(tiRoot,ttdsaXchg);
1111                        }
1112                    }
1113                    else if ( (ttdsaXchg->readRspCollapsed == agTRUE) || (ttdsaXchg->wrtRspCollapsed == agTRUE) )
1114                    {
1115                        saStatus = saSSPStart(
1116                                ttdsaXchg->agRoot, /* agRoot, */
1117                                &ttdsaXchg->IORequestBody.agIORequest,
1118                                0,
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,
1122                                        agNULL,
1123                                        &ossaSSPCompleted
1124                        );
1125                        if (saStatus == AGSA_RC_SUCCESS)
1126                        {
1127                            TI_DBG1(("ttdsaIOCompleted: 1 loc retried\n"));
1128                            ttdsaXchg->retries++;
1129                        }
1130                        else
1131                        {
1132                            TI_DBG1(("ttdsaIOCompleted: 1 loc retry failed\n"));
1133                            ttdsaXchg->retries = 0;
1134                            /*
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
1139                             */
1140                            tiIORequest = ttdsaXchg->IORequestBody.IOType.TargetIO.tiIORequest;
1141                            tiIORequest.tdData = agNULL;
1142
1143                            ostiTargetIOError(
1144                                    tiRoot,
1145                                    &tiIORequest,
1146                                    status,
1147                                    statusDetail
1148                            );
1149
1150                            /* clean up resources */
1151                            ttdsaXchgFreeStruct(tiRoot,ttdsaXchg);
1152                        }
1153                    }
1154                    else
1155                    {
1156                        if (ttdsaXchg->responseSent == agFALSE)
1157                        {
1158                            saStatus = saSSPStart(
1159                                    ttdsaXchg->agRoot, /* agRoot, */
1160                                    &ttdsaXchg->IORequestBody.agIORequest, /*agIORequest, */
1161                                    0, /* queue number */
1162                                    ttdsaXchg->DeviceData->agDevHandle, /* agDevHandle, */
1163                                    ttdsaXchg->XchType,
1164                                    &ttdsaXchg->IORequestBody.transport.SAS.agSASRequestBody,
1165                                    agNULL,
1166                                    &ossaSSPCompleted
1167                            );
1168                        }
1169                        else
1170                        {
1171                            /* repsonse retry */
1172                            TI_DBG1(("ttdsaIOCompleted: 2 loc reponse retry\n"));
1173                            saStatus = ttdsaSendResp(ttdsaXchg->agRoot, ttdsaXchg);
1174                        }
1175                        if (saStatus == AGSA_RC_SUCCESS)
1176                        {
1177                            TI_DBG1(("ttdsaIOCompleted: 2 loc retried\n"));
1178                            ttdsaXchg->retries++;
1179                        }
1180                        else
1181                        {
1182                            TI_DBG1(("ttdsaIOCompleted: 2 loc retry failed\n"));
1183                            ttdsaXchg->retries = 0;
1184                            /*
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
1189                             */
1190                            tiIORequest = ttdsaXchg->IORequestBody.IOType.TargetIO.tiIORequest;
1191                            tiIORequest.tdData = agNULL;
1192
1193                            ostiTargetIOError(
1194                                    tiRoot,
1195                                    &tiIORequest,
1196                                    status,
1197                                    statusDetail
1198                            );
1199
1200                            /* clean up resources */
1201                            ttdsaXchgFreeStruct(tiRoot,ttdsaXchg);
1202                        }
1203                    }
1204                }
1205                else
1206                {
1207                    ttdsaXchg->retries = 0;
1208                    /*
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
1213                     */
1214                    tiIORequest = ttdsaXchg->IORequestBody.IOType.TargetIO.tiIORequest;
1215                    tiIORequest.tdData = agNULL;
1216
1217                    ostiTargetIOError(
1218                            tiRoot,
1219                            &tiIORequest,
1220                            status,
1221                            statusDetail
1222                    );
1223
1224                    /* clean up resources */
1225                    ttdsaXchgFreeStruct(tiRoot,ttdsaXchg);
1226                }
1227            } /* saData == agNULL */
1228            else
1229            {
1230                tiIORequest_t tiIORequest;
1231
1232                TI_DBG1(("ttdsaIOCompleted: 2\n"));
1233                if (TD_XCHG_GET_STATE(ttdsaXchg) == TD_XCHG_STATE_INACTIVE)
1234                {
1235                    TI_DBG1(("ttdsaIOCompleted: wrong DEQUEUE_THIS  2\n"));
1236                }
1237                if (ttdsaXchg->retries <= OPEN_RETRY_RETRIES && agIOStatus == OSSA_IO_XFER_OPEN_RETRY_TIMEOUT)
1238                {
1239                    TI_DBG1(("ttdsaIOCompleted: 2 loc retries on OSSA_IO_XFER_OPEN_RETRY_TIMEOUT\n"));
1240                    if ( (agOtherInfo & 0x1) == 1)
1241                    {
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)
1247                        {
1248                            TI_DBG2(("ttdsaIOCompleted: 0 loc retried\n"));
1249                            ttdsaXchg->retries++;
1250                        }
1251                        else
1252                        {
1253                            TI_DBG1(("ttdsaIOCompleted: 0 loc retry failed\n"));
1254                            ttdsaXchg->retries = 0;
1255                            /*
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
1260                             */
1261                            tiIORequest = ttdsaXchg->IORequestBody.IOType.TargetIO.tiIORequest;
1262                            tiIORequest.tdData = agNULL;
1263
1264                            ostiTargetIOError(
1265                                    tiRoot,
1266                                    &tiIORequest,
1267                                    status,
1268                                    statusDetail
1269                            );
1270
1271                            /* clean up resources */
1272                            ttdsaXchgFreeStruct(tiRoot,ttdsaXchg);
1273                        }
1274                    }
1275                    else if ( (ttdsaXchg->readRspCollapsed == agTRUE) || (ttdsaXchg->wrtRspCollapsed == agTRUE) )
1276                    {
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,
1284                                        agNULL,
1285                                        &ossaSSPCompleted
1286                        );
1287                        if (saStatus == AGSA_RC_SUCCESS)
1288                        {
1289                            TI_DBG1(("ttdsaIOCompleted: 1 loc retried\n"));
1290                            ttdsaXchg->retries++;
1291                        }
1292                        else
1293                        {
1294                            TI_DBG1(("ttdsaIOCompleted: 1 loc retry failed\n"));
1295                            ttdsaXchg->retries = 0;
1296                            /*
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
1301                             */
1302                            tiIORequest = ttdsaXchg->IORequestBody.IOType.TargetIO.tiIORequest;
1303                            tiIORequest.tdData = agNULL;
1304
1305                            ostiTargetIOError(
1306                                    tiRoot,
1307                                    &tiIORequest,
1308                                    status,
1309                                    statusDetail
1310                            );
1311
1312                            /* clean up resources */
1313                            ttdsaXchgFreeStruct(tiRoot,ttdsaXchg);
1314                        }
1315                    }
1316                    else
1317                    {
1318                        TI_DBG1(("ttdsaIOCompleted: 2 loc ttdsaXchg->id 0x%x datalen 0x%x offset 0x%x agTag 0x%x\n",
1319                                ttdsaXchg->id,
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)
1324                        {
1325                            saStatus = saSSPStart(
1326                                    ttdsaXchg->agRoot, /* agRoot, */
1327                                    &ttdsaXchg->IORequestBody.agIORequest, /* agIORequest, */
1328                                    0, /* queue number */
1329                                    ttdsaXchg->DeviceData->agDevHandle, /* agDevHandle, */
1330                                    ttdsaXchg->XchType,
1331                                    &ttdsaXchg->IORequestBody.transport.SAS.agSASRequestBody,
1332                                    agNULL,
1333                                    &ossaSSPCompleted
1334                            );
1335                        }
1336                        else
1337                        {
1338                            TI_DBG1(("ttdsaIOCompleted: 2 loc response retry\n"));
1339                            /* repsonse retry */
1340                            saStatus = ttdsaSendResp(ttdsaXchg->agRoot, ttdsaXchg);
1341                        }
1342                        if (saStatus == AGSA_RC_SUCCESS)
1343                        {
1344                            TI_DBG1(("ttdsaIOCompleted: 2 loc retried\n"));
1345                            ttdsaXchg->retries++;
1346                        }
1347                        else
1348                        {
1349                            TI_DBG1(("ttdsaIOCompleted: 2 loc retry failed\n"));
1350                            ttdsaXchg->retries = 0;
1351                            /*
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
1356                             */
1357                            tiIORequest = ttdsaXchg->IORequestBody.IOType.TargetIO.tiIORequest;
1358                            tiIORequest.tdData = agNULL;
1359
1360                            ostiTargetIOError(
1361                                    tiRoot,
1362                                    &tiIORequest,
1363                                    status,
1364                                    statusDetail
1365                            );
1366
1367                            /* clean up resources */
1368                            ttdsaXchgFreeStruct(tiRoot,ttdsaXchg);
1369                        }
1370                    }
1371                }
1372                else
1373                {
1374                    TI_DBG1(("ttdsaIOCompleted: retry is over\n"));
1375                    ttdsaXchg->retries = 0;
1376
1377                    tiIORequest = ttdsaXchg->IORequestBody.IOType.TargetIO.tiIORequest;
1378                    tiIORequest.tdData = agNULL;
1379
1380                    ostiTargetIOError(
1381                            tiRoot,
1382                            &tiIORequest,
1383                            status,
1384                            statusDetail
1385                    );
1386
1387                    /* clean up resources */
1388                    ttdsaXchgFreeStruct(tiRoot,ttdsaXchg);
1389                }
1390            } /* saData != agNULL */
1391        }/* if (IOFailed == agTRUE) */
1392    } /* not TMrequest */
1393    else /* TMrequest */
1394    {
1395        TI_DBG1(("ttdsaIOCompleted: TM request\n"));
1396        TI_DBG1(("ttdsaIOCompleted: TM initiator tag 0x%x\n", ttdsaXchg->tag));
1397
1398        switch(agIOStatus)
1399        {
1400        case OSSA_IO_SUCCESS:
1401            TI_DBG1(("ttdsaIOCompleted: success\n"));
1402            status = tiIOSuccess;
1403            break;
1404        case OSSA_IO_ABORTED:
1405            TI_DBG1(("ttdsaIOCompleted: ABORTED\n"));
1406            status        = tiIOFailed;
1407            statusDetail  = tiDetailAborted;
1408            IOFailed      = agTRUE;
1409            break;
1410        case OSSA_IO_ABORT_RESET:
1411            TI_DBG1(("ttdsaIOCompleted: ABORT_RESET\n"));
1412            status        = tiIOFailed;
1413            statusDetail  = tiDetailAbortReset;
1414            IOFailed      = agTRUE;
1415            break;
1416#ifdef REMOVED
1417        case OSSA_IO_OVERFLOW: /* fall through */
1418#endif
1419        case OSSA_IO_UNDERFLOW: /* fall through */
1420        case OSSA_IO_FAILED: /* fall through */
1421#ifdef REMOVED
1422        case OSSA_IO_NOT_VALID: /* fall through */
1423#endif
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 */
1432        default:
1433            status        = tiIOFailed;
1434            statusDetail  = tiDetailOtherError;
1435            IOFailed      = agTRUE;
1436            break;
1437        } /* switch */
1438
1439        /* for not found IO, we don't call OS */
1440        if (ttdsaXchg->io_found == agTRUE)
1441        {
1442            ostiTargetTmCompleted(
1443                    tiRoot,
1444                    ttdsaXchg->IORequestBody.tiIORequest,
1445                    status,
1446                    statusDetail
1447            );
1448        }
1449
1450        /* clean up resources */
1451        ttdsaXchgFreeStruct(tiRoot, ttdsaXchg);
1452
1453
1454    } /* TM Request */
1455    return;
1456}
1457
1458osGLOBAL void
1459ttdsaTMProcess(
1460        tiRoot_t    *tiRoot,
1461        ttdsaXchg_t *ttdsaXchg
1462)
1463{
1464    tdsaRoot_t                *tdsaRoot        = (tdsaRoot_t *) tiRoot->tdData;
1465    tdsaContext_t             *tdsaAllShared = (tdsaContext_t *)&tdsaRoot->tdsaAllShared;
1466
1467    ttdsaTgt_t                *Target = (ttdsaTgt_t *)tdsaAllShared->ttdsaTgt;
1468    agsaSSPScsiTaskMgntReq_t  *agTMIU;
1469    bit8                       TMFun;
1470    bit32                      tiTMFun;
1471    tiIORequest_t              *reftiIORequest = agNULL;
1472    tdList_t                   *IOList;
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;
1480
1481    TI_DBG1(("ttdsaTMProcess: start\n"));
1482
1483    ttdsaXchg->isTMRequest = agTRUE;
1484
1485    agTMIU = (agsaSSPScsiTaskMgntReq_t *)&(ttdsaXchg->agTMIU);
1486    TMFun = agTMIU->taskMgntFunction;
1487
1488    switch (TMFun)
1489    {
1490    case AGSA_ABORT_TASK:
1491        TI_DBG1(("ttdsaTMProcess: ABORT_TASK\n"));
1492        tiTMFun = AG_ABORT_TASK;
1493        break;
1494    case AGSA_ABORT_TASK_SET:
1495        TI_DBG1(("ttdsaTMProcess: ABORT_TASK_SET\n"));
1496        tiTMFun = AG_ABORT_TASK_SET;
1497        break;
1498    case AGSA_CLEAR_TASK_SET:
1499        TI_DBG1(("ttdsaTMProcess: CLEAR_TASK_SET\n"));
1500        tiTMFun = AG_CLEAR_TASK_SET;
1501        break;
1502    case AGSA_LOGICAL_UNIT_RESET:
1503        TI_DBG1(("ttdsaTMProcess: LOGICAL_UNIT_RESET\n"));
1504        tiTMFun = AG_LOGICAL_UNIT_RESET;
1505        break;
1506    case AGSA_CLEAR_ACA:
1507        TI_DBG1(("ttdsaTMProcess: CLEAR_ACA\n"));
1508        tiTMFun = AG_CLEAR_ACA;
1509        break;
1510    case AGSA_QUERY_TASK:
1511        TI_DBG1(("ttdsaTMProcess: QUERY_TASK\n"));
1512        tiTMFun = AG_QUERY_TASK;
1513        break;
1514    default:
1515        TI_DBG1(("ttdsaTMProcess: RESERVED TM 0x%x %d\n", TMFun, TMFun));
1516        tiTMFun = 0xff; /* unknown task management request */
1517        break;
1518    }
1519
1520    /*
1521     * Give the OS Specific module to apply it's Task management policy.
1522     */
1523
1524
1525    /*
1526     osGLOBAL void ostiTaskManagement (
1527                        tiRoot_t          *tiRoot,
1528                        bit32             task,
1529                        bit8              *scsiLun,
1530                        tiIORequest_t     *refTiIORequest,
1531                        tiIORequest_t     *tiTMRequest,
1532                        tiDeviceHandle_t  *tiDeviceHandle);
1533     */
1534    if (TMFun == AGSA_ABORT_TASK)
1535    {
1536        TI_DBG1(("ttdsaTMProcess: if abort task; to be tested \n"));
1537        /*
1538      needs to find a reftIIORequest and set it
1539         */
1540
1541        IOList = Target->ttdsaXchgData.xchgBusyList.flink;
1542        IOFound = agFALSE;
1543
1544        /* search through the current IOList */
1545        while (IOList != &Target->ttdsaXchgData.xchgBusyList)
1546        {
1547
1548            tmp_ttdsaXchg = TDLIST_OBJECT_BASE(ttdsaXchg_t, XchgLinks, IOList);
1549            if (tmp_ttdsaXchg->tag == agTMIU->tagOfTaskToBeManaged)
1550            {
1551                TI_DBG1(("ttdsaTMProcess: tag 0x%x\n",tmp_ttdsaXchg->tag));
1552                IOFound = agTRUE;
1553                break;
1554            }
1555            IOList = IOList->flink;
1556        } /* while */
1557
1558        if (IOFound == agTRUE)
1559        {
1560
1561            TI_DBG1(("ttdsaTMProcess: found \n"));
1562            /* call saSSPAbort() */
1563
1564            TI_DBG1(("ttdsaTMProcess: loc 1\n"));
1565            /* abort taskmanagement itself */
1566            agIOAbortRequest = (agsaIORequest_t *)&(ttdsaXchg->IORequestBody.agIORequest);
1567
1568            /* IO to be aborted */
1569            agIORequest = (agsaIORequest_t *)&(tmp_ttdsaXchg->IORequestBody.agIORequest);
1570            oneDeviceData = tmp_ttdsaXchg->DeviceData;
1571            agDevHandle = oneDeviceData->agDevHandle;
1572
1573            if (agIORequest == agNULL)
1574            {
1575                TI_DBG1(("ttdsaTMProcess: agIORequest is NULL\n"));
1576            }
1577            else
1578            {
1579              TI_DBG1(("ttdsaTMProcess: agIORequest is NOT NULL\n"));
1580              if (agIORequest->sdkData == agNULL)
1581              {
1582                TI_DBG1(("ttdsaTMProcess: agIORequest->saData is NULL\n"));
1583              }
1584              else
1585              {
1586                TI_DBG1(("ttdsaTMProcess: agIORequest->saData is NOT NULL\n"));
1587#ifdef RPM_SOC
1588                saSSPAbort(agRoot, agIORequest);
1589#else
1590                saSSPAbort(agRoot, agIOAbortRequest,0,agDevHandle,0,agIORequest, agNULL);
1591#endif
1592              }
1593            }
1594
1595        } /* FOUND */
1596        else
1597        {
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"));
1603            return;
1604        }
1605
1606    } /* ABORT_TASK */
1607    /*
1608    reftiIORequest: referred IO request.
1609    If found, not null. But not used in ramdisk
1610     */
1611    TI_DBG1(("ttdsaTMProcess: calling ostiTaskManagement\n"));
1612    ostiTaskManagement(
1613            tiRoot,
1614            tiTMFun,
1615            ttdsaXchg->agTMIU.lun,
1616            reftiIORequest,
1617            ttdsaXchg->IORequestBody.tiIORequest,
1618            &ttdsaXchg->DeviceData->tiDeviceHandle
1619    );
1620
1621
1622
1623    return;
1624}
1625
1626/*****************************************************************************
1627 *
1628 *  tiTGTIOAbort
1629 *
1630 *  Purpose: This function is called to abort an IO previously reported
1631 *           to oslayer through ostiProcessRequest() function.
1632 *
1633 *  Parameters:
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().
1638 *  Return:
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
1642 *                   started
1643 *  Note:
1644 *
1645 *****************************************************************************/
1646osGLOBAL bit32
1647tiTGTIOAbort (
1648        tiRoot_t            *tiRoot,
1649        tiIORequest_t       *taskTag
1650)
1651{
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;
1661
1662    TI_DBG1(("tiTGTIOAbort: start\n"));
1663
1664    ttdsaXchg        = (ttdsaXchg_t *)taskTag->tdData;
1665
1666    if (ttdsaXchg == agNULL)
1667    {
1668        TI_DBG1(("tiTGTIOAbort: IOError 1 \n"));
1669        /*
1670         * this exchange has already been freed.
1671         * No need to free it
1672         */
1673        ostiTargetIOError(
1674                tiRoot,
1675                taskTag,
1676                tiIOFailed,
1677                tiDetailAborted
1678        );
1679    }
1680    else if (ttdsaXchg->IORequestBody.agIORequest.sdkData == agNULL)
1681    {
1682        TI_DBG1(("tiTGTIOAbort: IOError 2 \n"));
1683        /* We have not issued this IO to the salayer.
1684         * Abort it right here.
1685         */
1686        if (TD_XCHG_GET_STATE(ttdsaXchg) == TD_XCHG_STATE_INACTIVE)
1687        {
1688            TI_DBG1(("tiTGTIOAbort: wrong DEQUEUE_THIS\n"));
1689        }
1690
1691        TI_DBG1(("tiTGTIOAbort: IOError 3\n"));
1692
1693        ostiTargetIOError(
1694                tiRoot,
1695                taskTag,
1696                tiIOFailed,
1697                tiDetailAborted
1698        );
1699        TI_DBG1(("tiTGTIOAbort: IOError 4\n"));
1700
1701        ttdsaXchgFreeStruct(
1702                ttdsaXchg->tiRoot,
1703                ttdsaXchg
1704        );
1705        TI_DBG1(("tiTGTIOAbort: IOError 5\n"));
1706
1707    }
1708    else /* to be tested */
1709    {
1710        TI_DBG1(("tiTGTIOAbort: aborting; to be tested \n"));
1711        /* abort io request itself */
1712        ttdsaIOAbortXchg = ttdsaXchgGetStruct(agRoot);
1713
1714        if (ttdsaIOAbortXchg == agNULL)
1715        {
1716            TI_DBG1(("tiTGTIOAbort: no free xchg structures\n"));
1717            //      ttdsaDumpallXchg(tiRoot);
1718            return tiError;
1719        }
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;
1726
1727        //    ttdsaIOAbortXchg->FrameType = SAS_TM;
1728
1729        /* io is being aborted */
1730        ttdsaXchg->oslayerAborting = agTRUE;
1731        agIORequest = (agsaIORequest_t *)&(ttdsaXchg->IORequestBody.agIORequest);
1732        oneDeviceData = ttdsaXchg->DeviceData;
1733        if (oneDeviceData == agNULL)
1734        {
1735            TI_DBG1(("tiTGTIOAbort: oneDeviceData is null; wrong\n"));
1736        }
1737        else
1738        {
1739          agDevHandle = oneDeviceData->agDevHandle;
1740          ttdsaIOAbortXchg->DeviceData = oneDeviceData;
1741        }
1742#ifdef RPM_SOC
1743        saSSPAbort(agRoot, agIORequest);
1744#else
1745        saSSPAbort(agRoot, agIOAbortRequest,0,agDevHandle,0,agIORequest, agNULL);
1746    }
1747
1748    return tiSuccess;
1749}
1750
1751osGLOBAL bit32
1752tiTGTIOAbortAll(
1753        tiRoot_t            *tiRoot,
1754        tiDeviceHandle_t    *tiDeviceHandle
1755)
1756{
1757    agsaRoot_t                *agRoot = agNULL;
1758    tdsaDeviceData_t          *oneDeviceData = agNULL;
1759    bit32                     status = tiError;
1760
1761    TI_DBG3(("tiTGTIOAbortAll: start\n"));
1762
1763    oneDeviceData = (tdsaDeviceData_t *)tiDeviceHandle->tdData;
1764
1765    if (oneDeviceData == agNULL)
1766    {
1767        TI_DBG1(("tiTGTIOAbortAll: oneDeviceData is NULL!!!\n"));
1768        return tiError;
1769    }
1770
1771    /* for hotplug */
1772    if (oneDeviceData->valid != agTRUE || oneDeviceData->registered != agTRUE ||
1773            oneDeviceData->tdPortContext == agNULL )
1774    {
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));
1778        return tiError;
1779    }
1780
1781    agRoot = oneDeviceData->agRoot;
1782
1783    if (agRoot == agNULL)
1784    {
1785        TI_DBG1(("tiTGTIOAbortAll: agRoot is NULL!!!\n"));
1786        return tiError;
1787    }
1788
1789    /* this is processed in ossaSSPAbortCB, ossaSATAAbortCB, ossaSMPAbortCB */
1790    oneDeviceData->OSAbortAll = agTRUE;
1791
1792    status = tdsaAbortAll(tiRoot, agRoot, oneDeviceData);
1793
1794    return status;
1795
1796}
1797
1798
1799/*****************************************************************************
1800 *
1801 *  tiTGTSendTmResp
1802 *
1803 *  Purpose: This function is called to abort an IO previously reported
1804 *           to oslayer through ostiProcessRequest() function.
1805 *
1806 *  Parameters:
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().
1811 *  Return:
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
1815 *                   started
1816 *  Note:
1817 *
1818 *****************************************************************************/
1819osGLOBAL bit32
1820tiTGTSendTmResp(
1821        tiRoot_t          *tiRoot,
1822        tiIORequest_t     *tiTMRequest,
1823        bit32             status
1824)
1825{
1826    ttdsaXchg_t               *ttdsaXchg;
1827    sas_resp_t                *SASResp;
1828    bit32                     tdStatus;
1829    TI_DBG1(("tiTGTSendTmResp: start 1\n"));
1830
1831    ttdsaXchg     = (ttdsaXchg_t *)tiTMRequest->tdData;
1832    /* set the response and send it */
1833    /* response status is 0 */
1834    /* status is TM status */
1835
1836    TI_DBG1(("tiTGTSendTmResp: start 2\n"));
1837    SASResp = (sas_resp_t *)ttdsaXchg->resp.virtAddr;
1838    TI_DBG1(("tiTGTSendTmResp: start 3\n"));
1839
1840    if (ttdsaXchg->FrameType == SAS_TM)
1841    {
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);
1846        switch (status)
1847        {
1848        case tiSuccess:
1849            TI_DBG2(("tiTGTSendTmResp: tiSuccess\n"));
1850            SASResp->RespData[3] = AGSA_TASK_MANAGEMENT_FUNCTION_SUCCEEDED;
1851            break;
1852        case tiError:
1853            TI_DBG1(("tiTGTSendTmResp: tiError\n"));
1854            SASResp->RespData[3] = AGSA_TASK_MANAGEMENT_FUNCTION_FAILED;
1855            break;
1856        case tiBusy:
1857            TI_DBG1(("tiTGTSendTmResp: tibusy\n"));
1858            SASResp->RespData[3] = AGSA_TASK_MANAGEMENT_FUNCTION_FAILED;
1859            break;
1860        case tiIONoDevice:
1861            TI_DBG1(("tiTGTSendTmResp: tiionodevicee\n"));
1862            SASResp->RespData[3] = AGSA_TASK_MANAGEMENT_FUNCTION_FAILED;
1863            break;
1864        case tiMemoryTooLarge:
1865            TI_DBG1(("tiTGTSendTmResp: timemorytoolarge\n"));
1866            SASResp->RespData[3] = AGSA_TASK_MANAGEMENT_FUNCTION_FAILED;
1867            break;
1868        case tiMemoryNotAvail:
1869            TI_DBG1(("tiTGTSendTmResp: timemorynotavail\n"));
1870            SASResp->RespData[3] = AGSA_TASK_MANAGEMENT_FUNCTION_FAILED;
1871            break;
1872        case tiInvalidHandle:
1873            TI_DBG1(("tiTGTSendTmResp: tiinvalidhandle\n"));
1874            SASResp->RespData[3] = AGSA_TASK_MANAGEMENT_FUNCTION_FAILED;
1875            break;
1876        case tiNotSupported:
1877            TI_DBG1(("tiTGTSendTmResp: tiNotsupported\n"));
1878            SASResp->RespData[3] = AGSA_TASK_MANAGEMENT_FUNCTION_NOT_SUPPORTED;
1879            break;
1880        case tiReject:
1881            TI_DBG1(("tiTGTSendTmResp: tireject\n"));
1882            SASResp->RespData[3] = AGSA_TASK_MANAGEMENT_FUNCTION_FAILED;
1883            break;
1884        case tiIncorrectLun:
1885            TI_DBG1(("tiTGTSendTmResp: tiincorrectlun\n"));
1886            SASResp->RespData[3] = AGSA_INCORRECT_LOGICAL_UNIT_NUMBER;
1887            break;
1888        default:
1889            TI_DBG1(("tiTGTSendTmResp: default\n"));
1890            SASResp->RespData[3] = AGSA_TASK_MANAGEMENT_FUNCTION_FAILED;
1891            break;
1892        }
1893        ttdsaXchg->resp.length = sizeof(agsaSSPResponseInfoUnit_t) + RESPONSE_DATA_LEN;
1894        ttdsaXchg->statusSent = agTRUE;
1895    }
1896    else
1897    {
1898        TI_DBG1(("tiTGTSendTmResp: not TM frame\n"));
1899        return tiError;
1900    }
1901
1902    tdStatus = ttdsaSendResp(ttdsaXchg->agRoot, ttdsaXchg);
1903    if (tdStatus == AGSA_RC_SUCCESS)
1904    {
1905        TI_DBG1(("tiTGTSendTmResp: send success\n"));
1906        return tiSuccess;
1907    }
1908    else if (tdStatus == AGSA_RC_FAILURE)
1909    {
1910        TI_DBG1(("tiTGTSendTmResp: sending not successful\n"));
1911        return tiError;
1912    }
1913    else
1914    {
1915        TI_DBG1(("tiTGTSendTmResp: send busy\n"));
1916        return tiBusy;
1917    }
1918
1919
1920#ifdef REMOVED
1921
1922    tiTGTSetResp(tiRoot, tiTMRequest, 0, 0, 0);
1923#endif
1924
1925#ifdef REMOVED
1926
1927    if (ttdsaXchg->resp.length != 0)
1928    {
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;
1933
1934        ttdsaSendResp(ttdsaXchg->agRoot, ttdsaXchg);
1935    }
1936    else
1937    {
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);
1943    }
1944
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
1951#endif
1952
1953}
1954
1955
1956
1957/*****************************************************************************
1958 *
1959 *  tiTGTSenseBufferGet
1960 *
1961 *  Purpose: This function is called to get the address of sense buffer from
1962 *           the target specific Transport Dependent Layer.
1963 *
1964 *  Parameters:
1965 *     tiRoot:        Pointer to driver/port instance.
1966 *     tiIORequest:   I/O request context.
1967 *     length:        Lenght in bytes of the sense buffer.
1968 *
1969 *  Return:  none
1970 *
1971 *  Note:
1972 *
1973 *****************************************************************************/
1974osGLOBAL void *tiTGTSenseBufferGet( tiRoot_t      *tiRoot,
1975        tiIORequest_t *tiIORequest,
1976        bit32          length
1977)
1978{
1979
1980    ttdsaXchg_t         *ttdsaXchg;
1981
1982    ttdsaXchg = (ttdsaXchg_t *)tiIORequest->tdData;
1983
1984    TI_DBG4(("tiTGTSenseBufferGet: start\n"));
1985    OS_ASSERT((length <= 64), "length too big in tiTGTSenseBufferGet");
1986
1987    return &ttdsaXchg->resp.virtAddr[sizeof(agsaSSPResponseInfoUnit_t)];
1988}
1989
1990/*****************************************************************************
1991 *
1992 *  tiTGTSetResp
1993 *
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.
1999 *
2000 *  Parameters:
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.
2008 *
2009 *  Return: none
2010 *
2011 *  Note:
2012 *
2013 *****************************************************************************/
2014osGLOBAL void
2015tiTGTSetResp( tiRoot_t        *tiRoot,
2016        tiIORequest_t   *tiIORequest,
2017        bit32            dataSentLength,
2018        bit8             ScsiStatus,
2019        bit32            senseLength
2020)
2021{
2022    /* no call to saSSPStart() in this function */
2023    /*
2024    response is normally for task management
2025    sense is for command with error
2026    need to know this is for TM or cmd
2027     */
2028    /*
2029  tiTGTSetResp(rdRoot->pTiRoot,
2030               rdIORequest->tiIORequest,
2031               dataSentLength,
2032               ScsiStatus,
2033               senseLength);
2034
2035
2036
2037     */
2038    ttdsaXchg_t               *ttdsaXchg;
2039    tdsaRoot_t                *tdsaRoot  = (tdsaRoot_t *)tiRoot->tdData;
2040#ifdef REMOVED
2041    agsaSSPTargetResponse_t   *agSSPTargetResp;
2042#endif
2043    sas_resp_t                *SASResp;
2044    bit32                      TotalRespLen = 0;
2045
2046    TI_DBG4 (("tiTGTSetResp: start\n"));
2047    TI_DBG4 (("tiTGTSetResp: datelen %d senselen %d\n", dataSentLength, senseLength));
2048
2049    ttdsaXchg = (ttdsaXchg_t *)tiIORequest->tdData;
2050    SASResp = (sas_resp_t *)ttdsaXchg->resp.virtAddr;
2051
2052    SASResp->agResp.status = ScsiStatus;
2053
2054    if (ttdsaXchg->FrameType == SAS_TM)
2055    {
2056
2057        TI_DBG1(("tiTGTSetResp: TM\n"));
2058        if (senseLength != 0)
2059        {
2060            TI_DBG1 (("tiTGTSetResp: non-zero sensedatalen for TM\n"));
2061            return;
2062        }
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;
2068    }
2069    else
2070    {
2071        if (senseLength == 0)
2072        {
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)
2081            {
2082                TI_DBG4(("tiTGTSetResp: read rsp collapse\n"));
2083
2084                if (tdsaRoot->autoGoodRSP & READ_GOOD_RESPONSE)
2085                    ttdsaXchg->readRspCollapsed = agTRUE;
2086            }
2087            /* collapse good response with WRITE */
2088            if (ttdsaXchg->XchType == AGSA_SSP_TGT_WRITE_DATA)
2089            {
2090                TI_DBG4(("tiTGTSetResp: write rsp collapse\n"));
2091                if (tdsaRoot->autoGoodRSP & WRITE_GOOD_RESPONSE)
2092                {
2093                  if (tiIS_SPC(TI_TIROOT_TO_AGROOT(tiRoot)))
2094                  {
2095                    ttdsaXchg->wrtRspCollapsed = agFALSE;
2096                  }
2097                  else
2098                  {
2099                    ttdsaXchg->wrtRspCollapsed = agTRUE;
2100                  }
2101
2102                }
2103            }
2104        }
2105        else
2106        {
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;
2113        }
2114    }
2115
2116    ttdsaXchg->statusSent = agTRUE;
2117
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));
2124
2125
2126
2127    /* set the correct response length */
2128    ttdsaXchg->resp.length = TotalRespLen;
2129
2130    dumpresp((bit8 *)ttdsaXchg->resp.virtAddr, ttdsaXchg->resp.length);
2131
2132#ifdef REMOVED
2133    /*
2134    send TM reponse (which has only  response data not sense data here
2135    since ramdisk does not call IOstart for this
2136     */
2137
2138    if (ttdsaXchg->FrameType == SAS_TM)
2139    {
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);
2144    }
2145#endif
2146#ifdef REMOVED
2147    /* sas response */
2148    agSSPTargetResp =
2149            &(ttdsaXchg->IORequestBody.transport.SAS.agSASRequestBody.sspTargetResponse);
2150
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;
2157
2158
2159
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));
2166#endif
2167
2168    return;
2169}
2170
2171
2172
2173/******************************************************************************
2174 *
2175 *  tiTGTGetDeviceHandles
2176 *
2177 *  Purpose: This routine is called to to return the device handles for each
2178 *           device currently available.
2179 *
2180 *  Parameters:
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
2184 *               by agDev.
2185 *  Return:
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.
2189 *
2190 *  Note:
2191 *
2192 ******************************************************************************/
2193
2194osGLOBAL bit32
2195tiTGTGetDeviceHandles(
2196        tiRoot_t            *tiRoot,
2197        tiPortalContext_t   *tiPortalContext,
2198        tiDeviceHandle_t    *tiDev[],
2199        bit32               maxDevs
2200)
2201{
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;
2213
2214
2215    TI_DBG4 (("tiTGTGetDeviceHandles: start\n"));
2216
2217    /* Check boundary condition */
2218    if (maxDevs > Target->OperatingOption.MaxTargets)
2219    {
2220        deviceToReturn = Target->OperatingOption.MaxTargets;
2221    }
2222    else
2223    {
2224        deviceToReturn = maxDevs;
2225    }
2226
2227
2228    /* make sure tiPortalContext is valid */
2229    PortContextList = tdsaAllShared->MainPortContextList.flink;
2230    while (PortContextList != &(tdsaAllShared->MainPortContextList))
2231    {
2232        onePortContext = TDLIST_OBJECT_BASE(tdsaPortContext_t, MainLink, PortContextList);
2233        if (onePortContext->tiPortalContext == tiPortalContext)
2234        {
2235            TI_DBG4(("tiTGTGetDeviceHandles: found; oneportContext ID %d\n", onePortContext->id));
2236            found = agTRUE;
2237            break;
2238        }
2239        PortContextList = PortContextList->flink;
2240    }
2241
2242    if (found == agFALSE)
2243    {
2244        TI_DBG4(("tiTGTGetDeviceHandles: No corressponding tdsaPortContext\n"));
2245        return 0;
2246    }
2247
2248
2249    /* go through device list and returns them */
2250    DeviceListList = tdsaAllShared->MainDeviceList.flink;
2251    while (DeviceListList != &(tdsaAllShared->MainDeviceList))
2252    {
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)
2259        {
2260            TI_DBG4(("tiTGTGetDeviceHandles: valid deviceindex %d devicePresent %d\n", deviceIndex, devicePresent));
2261
2262            tiDev[deviceIndex] = &(oneDeviceData->tiDeviceHandle);
2263            devicePresent++;
2264        }
2265        else
2266        {
2267            tiDev[deviceIndex] = agNULL;
2268            TI_DBG4(("tiTGTGetDeviceHandles: not valid deviceindex %d devicePresent %d\n", deviceIndex, devicePresent));
2269        }
2270        deviceIndex++;
2271
2272        if (devicePresent >= deviceToReturn )
2273        {
2274            break;
2275        }
2276        DeviceListList = DeviceListList->flink;
2277    }
2278
2279    return devicePresent;
2280}
2281
2282
2283
2284
2285/******************************************************************************
2286 *
2287 *  tiTGTGetDeviceInfo
2288 *
2289 *  Purpose: This routine is called to to return the device information for
2290 *           specified device handle.
2291 *
2292 *  Parameters:
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.
2297 *
2298 *  Return:
2299 *     tiSuccess: if the device handle is valid.
2300 *     tiError  : if the device handle is not valid.
2301 *
2302 *  Note:
2303 *
2304 ******************************************************************************/
2305osGLOBAL bit32
2306tiTGTGetDeviceInfo(
2307        tiRoot_t            *tiRoot,
2308        tiDeviceHandle_t    *tiDeviceHandle,
2309        tiDeviceInfo_t      *tiDeviceInfo)
2310{
2311    tdsaDeviceData_t       *oneDeviceData = agNULL;
2312
2313
2314    TI_DBG4 (("tiTGTGetDeviceInfo: start\n"));
2315
2316    if (tiDeviceHandle == agNULL)
2317    {
2318        TI_DBG4 (("tiTGTGetDeviceInfo: tiDeviceHandle is NULL\n"));
2319        return tiError;
2320    }
2321
2322    oneDeviceData = (tdsaDeviceData_t *)tiDeviceHandle->tdData;
2323
2324    if (oneDeviceData == agNULL)
2325    {
2326        TI_DBG4 (("tiTGTGetDeviceInfo: oneDeviceData is NULL\n"));
2327        return tiError;
2328    }
2329
2330    /* filling in the link rate */
2331    if (oneDeviceData->registered == agTRUE)
2332    {
2333        tiDeviceInfo->info.devType_S_Rate = oneDeviceData->agDeviceInfo.devType_S_Rate;
2334    }
2335    else
2336    {
2337        tiDeviceInfo->info.devType_S_Rate = oneDeviceData->agDeviceInfo.devType_S_Rate & 0x0f;
2338    }
2339
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);
2343
2344    tiDeviceInfo->localName     = (char *)&(oneDeviceData->tdPortContext->sasLocalAddressHi);
2345    tiDeviceInfo->localAddress  = (char *)&(oneDeviceData->tdPortContext->sasLocalAddressLo);
2346
2347    return tiSuccess;
2348}
2349
2350/*****************************************************************************
2351 *! \brief ttdssIOAbortedHandler
2352 *
2353 *  Purpose:  This function processes I/Os completed and returned by SAS/SATA lower
2354 *            layer with agIOStatus = OSSA_IO_ABORTED
2355 *
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
2361 *                             of abort request
2362 *  \param  agOtherInfo        Residual count
2363 *  \return: None
2364 *
2365 *
2366 *****************************************************************************/
2367/* see itdosIOCompleted() and itdinit.c and  itdIoAbortedHandler in itdio.c*/
2368osGLOBAL void
2369ttdssIOAbortedHandler (
2370        agsaRoot_t              *agRoot,
2371        agsaIORequest_t         *agIORequest,
2372        bit32                   agIOStatus,
2373        bit32                   agIOInfoLen,
2374        void                    *agParam,
2375        bit32                   agOtherInfo
2376)
2377{
2378    tdsaRootOsData_t       *osData = (tdsaRootOsData_t *)agRoot->osData;
2379    tiRoot_t               *tiRoot = (tiRoot_t *)osData->tiRoot;
2380    tdIORequestBody_t      *tdIORequestBody;
2381
2382    TI_DBG1(("itdssIOAbortedHandler: start\n"));
2383    tdIORequestBody = (tdIORequestBody_t *)agIORequest->osData;
2384
2385    if (agIOStatus != OSSA_IO_ABORTED)
2386    {
2387        TI_DBG1(("itdssIOAbortedHandler: incorrect agIOStatus 0x%x\n", agIOStatus));
2388
2389    }
2390
2391    ostiTargetIOError(
2392            tiRoot,
2393            tdIORequestBody->tiIORequest,
2394            tiIOFailed,
2395            tiDetailAborted
2396    );
2397
2398    return;
2399}
2400
2401
2402