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