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
TDTraceInit(void)99 void TDTraceInit(void)
100 {
101 osti_memset(&TraceData, 0, sizeof(TraceData));
102 }
103
TDTraceAdd(ttdsaXchg_t * ttdsaXchg,tdsaDeviceData_t * oneDeviceData)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
ttdsaSSPReqReceived(agsaRoot_t * agRoot,agsaDevHandle_t * agDevHandle,agsaFrameHandle_t agFrameHandle,bit32 agInitiatorTag,bit32 parameter,bit32 agFrameLen)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
dumpCDB(bit8 * cdb)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
tdsaProcessCDB(agsaSSPCmdInfoUnit_t * cmdIU,ttdsaXchg_t * ttdsaXchg)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
tiTGTIOStart(tiRoot_t * tiRoot,tiIORequest_t * tiIORequest,bit32 dataOffset,bit32 dataLength,tiSgl_t * dataSGL,void * sglVirtualAddr)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 *****************************************************************************/
tiTGTIOStartDif(tiRoot_t * tiRoot,tiIORequest_t * tiIORequest,bit32 dataOffset,bit32 dataLength,tiSgl_t * dataSGL,void * sglVirtualAddr,tiDif_t * difOption)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
ttdssIOPrepareSGL(tiRoot_t * tiRoot,tdIORequestBody_t * tdIORequestBody,tiSgl_t * tiSgl1,tiSgl_t * tiSgl2,void * sglVirtualAddr)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
dumpresp(bit8 * resp,bit32 len)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
ttdsaSendResp(agsaRoot_t * agRoot,ttdsaXchg_t * ttdsaXchg)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
ttdsaIOCompleted(agsaRoot_t * agRoot,agsaIORequest_t * agIORequest,bit32 agIOStatus,bit32 agIOInfoLen,agsaFrameHandle_t agFrameHandle,bit32 agOtherInfo)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
ttdsaTMProcess(tiRoot_t * tiRoot,ttdsaXchg_t * ttdsaXchg)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
tiTGTIOAbort(tiRoot_t * tiRoot,tiIORequest_t * taskTag)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
tiTGTIOAbortAll(tiRoot_t * tiRoot,tiDeviceHandle_t * tiDeviceHandle)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
tiTGTSendTmResp(tiRoot_t * tiRoot,tiIORequest_t * tiTMRequest,bit32 status)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 *****************************************************************************/
tiTGTSenseBufferGet(tiRoot_t * tiRoot,tiIORequest_t * tiIORequest,bit32 length)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
tiTGTSetResp(tiRoot_t * tiRoot,tiIORequest_t * tiIORequest,bit32 dataSentLength,bit8 ScsiStatus,bit32 senseLength)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
tiTGTGetDeviceHandles(tiRoot_t * tiRoot,tiPortalContext_t * tiPortalContext,tiDeviceHandle_t * tiDev[],bit32 maxDevs)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
tiTGTGetDeviceInfo(tiRoot_t * tiRoot,tiDeviceHandle_t * tiDeviceHandle,tiDeviceInfo_t * tiDeviceInfo)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
ttdssIOAbortedHandler(agsaRoot_t * agRoot,agsaIORequest_t * agIORequest,bit32 agIOStatus,bit32 agIOInfoLen,void * agParam,bit32 agOtherInfo)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