xref: /freebsd/sys/dev/pms/RefTisa/tisa/sassata/sas/tgt/ttdio.c (revision a4e5e0106ac7145f56eb39a691e302cabb4635be)
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
67 unsigned __int64
68 GetHiResTimeStamp(void);
69 #endif
70 #undef TD_DEBUG_TRACE_ENABLE
71 #define TD_DEBUG_IO_TRACE_BUFFER_MAX  1024
72 
73 
74 typedef struct TDDebugTraceEntry_s
75 {
76     bit64             Time;
77     ttdsaXchg_t       ttdsaXchg;
78     tdsaDeviceData_t  oneDeviceData;
79 } TDDebugTraceEntry_t;
80 
81 typedef struct TDDebugTrace_s
82 {
83     bit32                 Idx;
84     bit32                 pad;
85     TDDebugTraceEntry_t  Data[TD_DEBUG_IO_TRACE_BUFFER_MAX];
86 } TDDebugTrace_t;
87 
88 void TDTraceInit(void);
89 void 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 
97 TDDebugTrace_t TraceData;
98 
99 void TDTraceInit(void)
100 {
101     osti_memset(&TraceData, 0, sizeof(TraceData));
102 }
103 
104 void 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 
132 osGLOBAL void
133 ttdsaSSPReqReceived(
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 
312 void
313 dumpCDB(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 
323 osGLOBAL void
324 tdsaProcessCDB(
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  *****************************************************************************/
484 osGLOBAL bit32
485 tiTGTIOStart( 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  *****************************************************************************/
686 osGLOBAL 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 
702 osGLOBAL bit32
703 ttdssIOPrepareSGL(
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 */
734 void
735 dumpresp(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 
747 osGLOBAL bit32
748 ttdsaSendResp(
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 
825 osGLOBAL void
826 ttdsaIOCompleted(
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 
1458 osGLOBAL void
1459 ttdsaTMProcess(
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  *****************************************************************************/
1646 osGLOBAL bit32
1647 tiTGTIOAbort (
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 
1751 osGLOBAL bit32
1752 tiTGTIOAbortAll(
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  *****************************************************************************/
1819 osGLOBAL bit32
1820 tiTGTSendTmResp(
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  *****************************************************************************/
1974 osGLOBAL 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  *****************************************************************************/
2014 osGLOBAL void
2015 tiTGTSetResp( 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 
2194 osGLOBAL bit32
2195 tiTGTGetDeviceHandles(
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  ******************************************************************************/
2305 osGLOBAL bit32
2306 tiTGTGetDeviceInfo(
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*/
2368 osGLOBAL void
2369 ttdssIOAbortedHandler (
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